2012-11-22 9 views
10

範囲です。このために私は、スタックレイアウトを使用して、私は現時点ではJSONで私のデータセットを更新します。表示のみ全体値Iは、ウェブサイトのビューのリアルタイム表現を表示するd3jsを使用してい0-1又は0-2

y軸に表示されるビューが1つしかない場合(グラフのビューの量に関連するダイナミック)、軸のラベルは次のとおりです。1 =>0, 0.2, 0.4, 0.6, 0.8, 1、軸のラベルは2 =>0, 0.5, 1, 1.5, 2それはページのビューを表示するので、これは私のデータセットの意味がない、とあなたは半分のビューを持つことができません。

私はこれだけのスケールのうち、全体の値を取得する必要がありますthe documentation of rangeRound()によると

var y_inverted = d3.scale.linear().domain([0, 1]).rangeRound([0, height]); 

に私のy軸をベースd3jsでリニアスケールを持っています。私の軸を描画するために私が使用します。

var y_axis = svg.append("g") 
    .attr("class", "y axis") 
    .attr("transform", "translate(0,0)") 
    .call(y_inverted.axis = d3.svg.axis() 
     .scale(y_inverted) 
     .orient("left") 
     .ticks(5)); 

それは私が呼び出すことによって、この毎秒更新リアルタイムアプリケーションであるため:私が使用するデータを知っているよう

function update(){ 
    y_inverted.domain([yStackMax, 0]); 
    y_axis.transition() 
     .duration(interval) 
     .ease("linear") 
     .call(y_inverted.axis); 
} 

yStackMaxは限り、stacklayoutから計算されるが、 y値には整数のみが含まれています。

var yStackMax = d3.max(layers, function(layer) { 
    return d3.max(layer, function(d) { 
     return d.y0 + d.y; 
    }); 
}); 

私はy軸に適切な値を得るためにいくつかのことを試みました。

d3.svg.axis() 
    .scale(y_inverted) 
    .orient("left") 
    .ticks(5).tickFormat(d3.format(",.0f")) 

は私に最も近いSOFARを手に入れたが、それはまだそれが2だときyStackMaxは、2ティック1ですが、yStackMaxあれば、それはまた、動作するはずときのみ1つの目盛りを持つことで基本的に私が欲しいもの0, 0, 0, 1, 1, 1

を表示します12または1,000,000

+0

あなたは答えの一つに満足している場合は、それを受け入れてください。 – Juve

答えて

10

短い回答:ダニの数を動的に設定できます。 2つだけ目盛りラベルを表示するために1にそれを設定します。

var maxTicks = 5, minTicks = 1; 
if (yStackMax < maxTicks) { 
    y_axis.ticks(minTicks) 
} 
else { 
    y_axis.ticks(maxTicks) 
} 

ロング回答(トピックオフビット予定):あなたの例で遊んでいる間 を私はすべてのあなたの書式にはむしろ「完全なソリューション」を思い付きました問題。それを使用してお気軽に:)

var svg = d3.select("#svg") 
var width = svg.attr("width") 
var height = svg.attr("height") 
var yStackMax = 100000 
var interval = 500 
var maxTicks = 5 
var minTicks = 1 

var y_inverted = d3.scale.linear().domain([0, 1]).rangeRound([0, height]) 
var defaultFormat = d3.format(",.0f") 

var format = defaultFormat 

var y_axis = d3.svg.axis() 
    .scale(y_inverted) 
    .orient("left") 
    .ticks(minTicks) 
    .tickFormat(doFormat) 

var y_axis_root; 
var decimals = 0; 

function countDecimals(v){ 
    var test = v, count = 0; 
    while(test > 10) { 
     test /= 10 
     count++; 
    } 
    return count; 
} 

function doFormat(d,i){ 
    return format(d,i) 
} 

function init(){ 
    y_axis_root = svg.append("g") 
     .attr("class", "y axis") 
     // I modified your example to move the axis to a visible part of the screen 
     .attr("transform", "translate(150,0)") 
     .call(y_axis) 
} 

// custom formatting functions: 
function toTerra(d) { return (Math.round(d/10000000000)/100) + "T" } 
function toGiga(d) { return (Math.round(d/10000000)/100) + "G" } 
function toMega(d) { return (Math.round(d/10000)/100) + "M" } 
function toKilo(d) { return (Math.round(d/10)/100) + "k" } 

// the factor is just for testing and not needed if based on real world data 
function update(factor){ 
    factor = (factor) || 0.1; 
    yStackMax*=factor 
    decimals = countDecimals(yStackMax) 
    console.log("yStackMax decimals:",decimals, factor) 
    if  (yStackMax < maxTicks) { 
     format = defaultFormat 
     y_axis.ticks(minTicks) 
    } 
    else { 
     y_axis.ticks(maxTicks) 
     if  (decimals < 3) format = defaultFormat 
     else if(decimals < 6) format = toKilo 
     else if(decimals < 9) format = toMega 
     else if(decimals < 12) format = toGiga 
     else     format = toTerra 
    } 

    y_inverted.domain([yStackMax, 0]); 
    y_axis_root.transition() 
     .duration(interval) 
     .ease("linear") 
     .call(y_axis); 
} 

init() 
setTimeout(update, 200) 
setTimeout(update, 400) 
setTimeout(update, 600) 

をあなたは、このHTMLスニペットと一緒にそれを試すことができます。

<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
     <script type="text/javascript" src="http://mbostock.github.com/d3/d3.v2.js"></script> 
    </head> 

    <body> 
     <div><svg id="svg" width="200" height="300"></svg></div> 
     <script src="axis.js"></script> 
     <button id="button1" onclick="update(10)">+</button> 
     <button id="button2" onclick="update(0.1)">-</button> 
    </body> 
</html> 

を私はそれは少しオフトピックです知っているが、私は通常の例/ソリューションを実行している提供したいです。実際の問題へのボーナスとして追加の書式のものを考えています。あなたはダニの一定数を求める場合

5

(axis.ticks経由())そして、d3は、多くのダニことをお渡ししようとします - しかし、かなりの値を使用しようとします。それはあなたのデータとは関係ありません。

あなたの解決策は、すべての値を整数値に丸めるためにtickFormatを使用し、ユーブが答えたように1ティックだけ質問するか、またはaxis.tickValues([...])を使用してティック値を明示的に設定します。 d3.range

rangeRoundはスケールの出力範囲に関連しているため、この場合は役に立ちません。この場合、0と高さの間にプロットするピクセルオフセットです。

4

Superbogglyの回答から、これが私にとってうまくいきました。まず私は、MAX(最大)y.domain().slice(-1)[0]を使用してyのドメインからの番号を持って、私はd3.range() ...

var y_max = y.domain().slice(-1)[0] 
    var yAxis = d3.svg.axis() 
     .scale(y) 
     .tickValues(d3.range(y_max+1)) 
     .tickFormat(d3.format(",.0f")) 
3

それとも、彼らはあり、「隠す」としてダニを聞かせてを使用しているからダニ値の配列を構築しましたここでは小数

d3.svg.axis() 
    .scale(y_inverted) 
    .orient("left") 
    .ticks(5).tickFormat(function(d) { 
       if (d % 1 == 0) { 
       return d3.format('.f')(d) 
       } else { 
       return "" 
       } 
      }); 
1

コードです:。ところで

var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left") 
    .tickFormat(d3.format(".2s")); 
関連する問題