我想要一个简单的图表,如:
我拥有的数据是具有两个属性的简单交易列表:
- 时间戳
- 数量
我试过 d3.layout.histogram().bins() 但它似乎只支持计算交易。
我一定不是唯一一个在寻找那个的人,是吗?
我想要一个简单的图表,如:
我拥有的数据是具有两个属性的简单交易列表:
我试过 d3.layout.histogram().bins() 但它似乎只支持计算交易。
我一定不是唯一一个在寻找那个的人,是吗?
好的,所以 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
希望这对某人有帮助!
直方图代码不支持这一点,但您可以轻松地自己进行分箱。假设您对每笔交易都有一个日期和一个计数,您可以像这样按天分类。
var bins = {};
transactions.forEach(function(t) {
var key = t.date.toDateString();
bins[key] = bins[key] || 0;
bins[key] += t.amount;
});
如果需要,您显然可以将日期字符串解析回日期;在这里使用的重点.toDateString()
是时间部分被切掉,所有东西都按天分类。如果您想按另一个时间间隔分箱,您可以使用相同的技术并提取日期的不同部分。