D3.js:计算条形图的x轴时间刻度?

D3.js:计算条形图的x轴时间刻度?,d3.js,D3.js,我有以下数据集: var data = [ { "air_used": 0.660985, "datestr": "2012-12-01 00:00:00", "energy_used": 0.106402 }, { "air_used": 0.824746, "datestr": "2013-01-01 00:00:00", "energy_used": 0.250462 } ... ] 我想画一个条形图(用于空气)和

我有以下数据集:

var data = [
  {
    "air_used": 0.660985, 
    "datestr": "2012-12-01 00:00:00", 
    "energy_used": 0.106402
  }, 
  {
    "air_used": 0.824746, 
    "datestr": "2013-01-01 00:00:00", 
    "energy_used": 0.250462
  } ...
]
我想画一个条形图(用于空气)和线形图(用于能源),如下所示:

我的问题是,目前我使用的x标度,图表看起来是这样的-基本上,条形图位于错误的位置,最后一个条形图从图表上脱落:

下面是一个包含完整代码和工作图的JSFIDLE:

为了达到我想要的效果,我认为我需要修改x比例,以便在第一个数据点之前和最后一个数据点之后有额外的宽度,并且使所有的条都向左移动每个条宽度的一半

有人能帮我弄清楚我需要用x-scale做什么吗

我已经尝试在域中添加一个额外的月份-这会阻止最后一个条从图的末尾脱落,但它也会添加一个我不想要的额外的记号,并且它不会固定线图和记号的位置


如果可能的话,我想继续使用x轴的时间刻度,而不是顺序刻度,因为我想使用D3聪明的基于时间的刻度格式化程序和日期解析器,例如
xAxis.ticks(D3.time.weeks,2)

将您的域从数据的实际范围扩展到+1和-1个月。这将在图表的两侧填充额外的月份,然后更新条形图宽度,使数据元素的计数增加2

var barRawWidth = width / (data.length + 2);
看这把小提琴:

如果你想隐藏上下限月份,你可以这样做:只需加减20天,而不是一个月,但可能有更优雅的方法

var xExtent = d3.extent(data, function(d) { return d.date; });
var nxExtent = [d3.time.day.offset(xExtent[0], -20), d3.time.day.offset(xExtent[1], 20)];
x.domain(nxExtent);

正如评论中指出的,我认为最好的方法是使用
d3.scale.ordinal
。请注意,使用它并不会阻止您使用
d3.time
解析器,但是您需要考虑条的宽度,以便将行与条对齐

下面是一个示例解决方案:

上述解决方案的相关代码如下:

// Map data set to dates to provide the whole domain information
var x = d3.scale.ordinal()
    .domain(data.map(function(d) {
        return d.date;
    }))
    .rangeRoundBands([0, width], 0.1);

...

// Use x.rangeBand() to align line with bars
var line = d3.svg.line()
    .x(function(d) { return x(d.date) + x.rangeBand() / 2; })
    .y(function(d) { return y(d.energy_used); });

...

// Use x.rangeBand() to set bar width
bars.enter().append("rect")
    .attr("class", "air_used")
    .attr("width", x.rangeBand())
    ...

请注意,在创建x刻度时,日期解析代码已上移,使
d.date
可用。除此之外,
d3.time
语句根本没有被修改

我已经有了一个基本的修复,但是(1)它感觉很粗糙,(2)x轴线现在不在它应该去的地方:而且,月份是不同的宽度,正如在这个问题中:修复月份是不同的宽度问题,您应该考虑基于时间戳的月/年部分来创建轴序号,然后使用自定义格式化程序来指定嘀嗒标签。然后,您可以使用范围带来处理条形宽度:这不是有一个很大的缺点,即缺少的值不能在比例中考虑吗?例如,如果我从您的示例数据中删除二月,那么图表将直接从一月到三月。@explunit是的,这是正确的。使用顺序刻度,即使值为0,也需要传递所有数据。