4

我想要一个简单的图表,如:

财务图表

我拥有的数据是具有两个属性的简单交易列表:

  • 时间戳
  • 数量

我试过 d3.layout.histogram().bins() 但它似乎只支持计算交易。

我一定不是唯一一个在寻找那个的人,是吗?

4

2 回答 2

8

好的,所以 IRC 的人帮我指出了nest,效果很好(这是 CoffeeScript):

nested_data = d3.nest()
  .key((d) -> d3.time.day(d.timestamp))
  .rollup((a) -> d3.sum(a, (d) -> d.amount))
  .entries(incoming_data)  # An array of {timestamp: ..., amount: ...} objects

# Optional
nested_data.map (d) ->
  d.date = new Date(d.key)

这里的技巧是d3.time.day它需要一个时间戳,并告诉你该时间戳属于哪一天(晚上 12 点)。这个函数和其他的,比如d3.time.week,等等。可以很好地对时间序列进行分类。

另一个技巧是nest().rollup()函数,在按 分组后key(),对给定 的所有事件求和day

我想要的最后一件事是在我没有交易的日子插入空值。这是代码的最后一部分:

# Interpolate empty vals
nested_data.sort((a, b) -> d3.descending(a.date, b.date))
ex = d3.extent(nested_data, (d) -> d.date)
each_day = d3.time.days(ex[0], ex[1])

# Build a hashmap with the days we have
data_hash = {}
angular.forEach(data, (d) ->
  data_hash[d.date] = d.values
)

# Build a new array for each day, including those where we didn't have transactions
new_data = []
angular.forEach(each_day, (d) ->
  val = 0
  if data_hash[d]
    val = data_hash[d]
  new_data.push({date: d, values: val})
)

final_data = new_data

希望这对某人有帮助!

于 2013-10-17T18:20:34.177 回答
1

直方图代码不支持这一点,但您可以轻松地自己进行分箱。假设您对每笔交易都有一个日期和一个计数,您可以像这样按天分类。

var bins = {};
transactions.forEach(function(t) {
    var key = t.date.toDateString();
    bins[key] = bins[key] || 0;
    bins[key] += t.amount;
});

如果需要,您显然可以将日期字符串解析回日期;在这里使用的重点.toDateString()是时间部分被切掉,所有东西都按天分类。如果您想按另一个时间间隔分箱,您可以使用相同的技术并提取日期的不同部分。

于 2013-10-16T17:29:25.123 回答