2012-08-29 76 views
19

我正在d3.js中構建一個條形圖,其中每個條形圖表示一個月內的總TB個案。數據本質上包含一個日期(最初以%Y-%m格式串入,但使用d3.time.format.parse解析)和一個整數。我希望軸標籤相對靈活(僅顯示年份邊界,每個月的標籤等),但我也希望條形圖間隔均勻。d3.js - 在時間尺度上均勻間隔的條形圖

我可以得到靈活的軸標籤,當我用一個日期刻度:

var xScaleDate = d3.time.scale() 
    .domain(d3.extent(thisstat, function(d) { return d.date; })) 
    .range([0, width - margin.left - margin.right]); 

...但酒吧不是均勻由於每月不同的天數(例如,二月和三月的間隔明顯比其他月份更接近)。我可以用線性度得到均勻間隔條:

var xScaleLinear = d3.scale.linear() 
     .domain([0, thisstat.length]) 
     .range([0, width - margin.left - margin.right]); 

...但我無法弄清楚如何再有基於日期軸標籤。我試過同時使用這兩種尺度,只從xScaleDate生成一個軸,只是爲了看看會發生什麼,但尺度自然不能很好地對齊。

有沒有一種簡單的方法來實現這個,我失蹤了?

+0

這聽起來像問題是,D3是從實際的時間戳設置XPOS。如何計算'data.monthsFromJan2000'或類似的數據,並將其用作xpos的數據輸入?這樣他們將平均分配。爲了標記目的,您還可以存儲'data.year'和'data.month'。 – Plato

回答

-1

嘗試d3.scale.ordinal

var y = d3.scale.ordinal() 
    .domain(yourDomain) 
    .rangeRoundBands([0, chartHeight], 0.2); 

Tweek 0.2參數。

+1

OP需要時間尺度的特徵。序號不會削減它。順便說一句,.rangeRoundBands不適用於D3.Scale.TimeScale。 – ninjaPixel

1

我有同樣的問題,我最終接受了一些月份比其他人長,並調整列欄寬度,以便酒吧之間的差距保持不變。因此調整在crossfilter主頁演示的barPath功能(http://square.github.com/crossfilter/ - 使用D3)我得到了這樣的事情:

var colWidth = Math.floor(x.range()[1]/groups.length) - 1;//9; 
if (i < n - 1) { 
    //If there will be column on the right, end this column one pixel to the left 
     var nextX = x(groups[i+1].key) 
     colWidth = nextX - x(d.key) - 1; 
} 
path.push("M", x(d.key), ",", height, "V", yVal, "h",colWidth,"V", height); 
9

您可以組合順序和時間尺度:

// Use this to draw x axis 
var xScaleDate = d3.time.scale() 
    .domain(d3.extent(thisstat, function(d) { return d.date; })) 
    .range([0, width - margin.left - margin.right]); 

// Add an ordinal scale 
var ordinalXScale = d3.scale.ordinal() 
    .domain(d3.map(thisstat, function(d) { return d.date; })) 
    .rangeBands([0, width], 0.4, 0); 

// Now you can use both of them to space columns evenly: 
columnGroup.enter() 
    .append("rect") 
    .attr("class", "column") 
    .attr("width", ordinalXScale.rangeBand()) 
    .attr("height", function (d) { 
     return height - yScale(d.value); 
    }) 
    .attr("x", function (d) { 
     return xScaleDate(d.date); 
    }) 
    .attr("y", function (d){ 
     return yScale(d.value); 
    }); 

我創建了一個例子前一陣子來證明這種方法:http://codepen.io/coquin/pen/BNpQoO