2016-09-28 9 views
0

この例でわかるように、序数軸(目盛り)の目盛りラベルは、ドメインの拡大に伴って混雑し、読みにくくなります。リニア軸のように自動的に調整するにはどうすればよいですか?D3で序数目盛りラベルを自動的に調整する方法

(私は代わりにリニアスケールを使うことができると思いますが、this questionとMike Bostock自身の答えは、このタイプのデータに秩序の尺度が適していることを示唆しています。便利なパディング設定が便利です修正棒グラフ、)

var x0 = d3.scaleBand() 
 
    .domain(d3.range(1,6)) 
 
    .range([0,200]); 
 

 
var x = d3.scaleBand() 
 
    .domain(d3.range(1,51)) 
 
    .range([0,200]); 
 

 
var xLinear = d3.scaleLinear() 
 
    .domain([1,50]) 
 
    .range([0,200]); 
 

 
d3.select('svg').append('g') 
 
    .attr('transform', 'translate(10,10)') 
 
    .call(d3.axisBottom(x0)); 
 

 
d3.select('svg').append('g') 
 
    .attr('transform', 'translate(10,50)') 
 
    .call(d3.axisBottom(x)); 
 

 
d3.select('svg').append('g') 
 
    .attr('transform', 'translate(10,100)') 
 
    .call(d3.axisBottom(xLinear));
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<svg width='300' height='150'></svg>

答えて

0

このソリューションは、私たちがする必要はありませんので、エッジケースを扱う非常にスマートな組み込み関数d3.ticks()、を利用しています。

var dataSmall = d3.range(1,8), 
 
    dataLarge = d3.range(1, 51); 
 

 
var xS = d3.scaleBand() 
 
    .domain(dataSmall) 
 
    .rangeRound([0,200]); 
 

 
var xL = d3.scaleBand() 
 
    .domain(dataLarge) 
 
    .rangeRound([0,200]); 
 

 
function makeAxis(scale) { 
 
    var n=5, 
 
     data = scale.domain(), 
 
     dataLength = data.length; 
 
    
 
    return d3.axisBottom(scale).tickValues( 
 
    dataLength > n ? d3.ticks(data[0], data[dataLength-1], n) : data); 
 
} 
 

 
d3.select('svg').append('g') 
 
    .attr('transform', 'translate(10,10)') 
 
    .call(makeAxis(xS)); 
 

 
d3.select('svg').append('g') 
 
    .attr('transform', 'translate(10,50)') 
 
    .call(makeAxis(xL));
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<svg width='300' height='150'></svg>

0

あなたはフィルタリングする必要がある、ここのようにして、手動でダニ:。http://bl.ocks.org/mbostock/3212294(これはD3 v3のある、v4のバージョンを参照してください。以下)

var x0 = d3.scaleBand() 
 
    .domain(d3.range(1,6)) 
 
    .range([0,200]); 
 

 
var x = d3.scaleBand() 
 
    .domain(d3.range(1,51)) 
 
    .range([0,200]); 
 

 
var tickValues = x 
 
    .domain() 
 
    .filter(function(d, i) { return !((i + 1) % Math.floor(x.domain().length/10)); }); 
 
      
 
var xLinear = d3.scaleLinear() 
 
    .domain([1,50]) 
 
    .range([0,200]); 
 

 
d3.select('svg').append('g') 
 
    .attr('transform', 'translate(10,10)') 
 
    .call(d3.axisBottom(x0)); 
 

 
d3.select('svg').append('g') 
 
    .attr('transform', 'translate(10,50)') 
 
    .call(d3.axisBottom(x).tickValues(tickValues)); 
 

 
d3.select('svg').append('g') 
 
    .attr('transform', 'translate(10,100)') 
 
    .call(d3.axisBottom(xLinear));
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<svg width='300' height='150'></svg>

+0

ありがとう、私はまた、より簡単に、より堅牢な実装を発見しました。 – bongbang

+0

リニアスケール?あなたはおそらくあなたのソリューションを、少なくともアイデアを共有することができますか?それは、ツールにネイティブに組み込まれていないものを解決する方法は、常に面白いです。 – Nixie

+0

いいえ、序数。私の答えは掲載されています。 – bongbang