【问题标题】:"Time Line" row chart using dc.js with a date scale使用带有日期刻度的 dc.js 的“时间线”行图
【发布时间】:2019-01-22 10:29:56
【问题描述】:

我想使用 dc.js 创建一个“时间轴”类型的行图。我可以在 d3 中生成此图表,但无法在 dc 中复制。

行图将有一个时间轴 x 轴,条形图将从轴上的某个时间点开始,并在轴上的另一个时间点结束。

The D3 version looks like this

每一行数据都有一个ID、一个startDate和一个endDate:

{
"id": 31,
"startDate": "2016-9-22",
"endDate": "2019-1-15"
},
{
"id": 29,
"startDate": "2016-9-21",
"endDate": "2016-9-28"
}

为了在 D3 中实现这一目标,我设置了一个规模:

let xScale = d3.scaleTime()
            .domain([d3.min(data, function(d){ return new Date(d.startDate)}), d3.max(data, function(d){ return new Date(d.endDate)})])
            .range([0, 500]); 

然后我附加矩形,使用 xScale 设置 x 和 width 属性:

svg.selectAll('rect')
          .data(data)
          .enter()
          .append('rect')
          .attr('x', function(d){ return xScale(new Date(d.startDate))})
          .attr('width', function(d) { return xScale(new Date(d.startDate)) - xScale(new Date(d.endDate))})

在 dc.js 中我已经完成了一部分,但是有一些我不理解的行为

我定义了交叉过滤器、维度和 xScale:

let ndx = crossfilter(data);
let idDim = ndx.dimension(function(d){ return d.id});
let xScale = d3.scaleTime()
            .domain([d3.min(data, function(d){ return new Date(d.dateCreate)}), d3.max(data, function(d){ return new Date(d.dateCompleted)})])
            .range([0, 500])

然后我创建一个组:

let idGroup = idDim.group().reduceSum(function(d){ return new Date(d.dateCompleted)});

(对于这个例子,我只是想让条的宽度从 0 点延伸到 dateCompleted,我会担心稍后设置 x 属性)

我创建这样的图表:

idChart
            .dimension(idDim)
            .group(idGroup)
            .height(500)
            .width(500)
            .x(xScale)
dc.renderAll()

结果是出现了条形,并且大致位于正确的位置,只是它们比应有的长得多并且平移了 -9746 像素。

dc.js version looks like this

我假设我没有正确解析日期,有人知道我哪里出错了吗?如何停止此翻译?就像我说的,我认为一旦我有了这个工作,设置 x 属性应该很容易。

【问题讨论】:

  • 行图总是从零开始,所以我想你很难把它变成时间线。 dc.js 是 not all that hard to link external charts
  • 谢谢 Gordon,我在以“正确”方式连接图表时有点迷失了方向,相反,我触发了一个从 dc.js .on('renderlet') 更新 d3 图表的函数功能。它是非正统但有效的。如果您认为它对人们有用,我可以发布一个关于如何使用 dc.register 连接图表的详细问题。
  • 当然,谢谢,那太好了!也许我们也可以变成an example

标签: dc.js


【解决方案1】:

我发现在将数据提供给交叉过滤器之前“清理”和规范化数据效果更好,更容易理解并且速度更快。

例如,不要在每次需要日期时都执行 new Date(d.xxx),而是通过循环遍历每个数据并一劳永逸地转换它来启动代码 另外,我使用 d3 将日期作为字符串转换为 js Date

var day = d3.time.format("%Y-%m-%d");
data.forEach(function(d){
{ 
  d.id = +d.id; //convert the id to an int, json is string only
  d.startDate = day(d.startDate)
  d.endDate = day(d.endDate)
})

【讨论】:

  • 谢谢 Xavier,我现在已经实现了。虽然它对制作浮动 dc 行图没有帮助,但它确实让我的代码更加理智。
猜你喜欢
  • 1970-01-01
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
相关资源
最近更新 更多