我通过 json 以如下格式向 d3 提供数据:
[
{
"outcome_id":22,
"history":[
{
"time":"2013-05-06T16:38:55+03:00",
"balance_of_power":0.2
},
{
"time":"2013-05-07T00:38:55+03:00",
"balance_of_power":0.2222222222222222
},
{
"time":"2013-05-07T08:38:55+03:00",
"balance_of_power":0.36363636363636365
}
],
"winner":true,
"name":"Pauline"
},
{
"outcome_id":23,
"history":[
{
"time":"2013-05-06T16:38:55+03:00",
"balance_of_power":0.2
},
{
"time":"2013-05-07T00:38:55+03:00",
"balance_of_power":0.1111111111111111
},
{
"time":"2013-05-07T08:38:55+03:00",
"balance_of_power":0.09090909090909091
}
],
"winner":false,
"name":"Romain"
}
]
我使用这些数据绘制了一个多系列折线图(以显示“balance_of_power”随时间的演变)和一个圆环图来表示所有系列的“balance_of_power”的最新值。
因此,每个顶级数组元素都是一个具有多个属性的对象,其中一个是“历史”,它本身就是一个对象数组(具有 time 和 balance_of_power 属性)。
可以在此处找到一个工作示例。
为了生成圆环图的数据,我使用了一个函数,该函数从每个历史数组中获取最新元素(数据按时间排序)并生成另一个名为“last_balance”的属性。
例如,第一个元素变为:
{
"outcome_id":22,
"history":[...],
"winner":true,
"name":"Pauline",
"last_balance":0.36363636363636365
}
然后我从饼图布局值中指定正确的访问器:
pie = d3.layout.pie().value(function(d) { return d.latest_balance; })
现在我想摆脱额外的步骤并更改访问器函数,以便我可以直接从初始数据结构中读取值,并且还可以在作为参数给出的时间内访问任何 balance_of_power。
有没有办法只修改 pie value 的访问器?
编辑
我将 .value 函数更改为:
.value(function(d) {
var h = d.history[0];
d.history.forEach(function(elt, i, a) {
console.log("======"); // start debug
console.log("search for:"+selected_time.toString());
console.log("current value:"+d.history[i].time.toString());
console.log("test:"+(d.history[i].time == selected_time));
console.log("======"); // end debug
if(d.history[i].time == selected_time) {
h = d.history[i];
}
});
return h.balance_of_power;
})
但是比较总是失败,即使值看起来相同,所以前面的代码总是返回初始值。
这是 javascript 控制台在最后一次迭代中显示的内容:
====== final_balance_donut_chart.js?body=1:11
search for:Thu Jun 06 2013 16:06:00 GMT+0200 (CEST) final_balance_donut_chart.js?body=1:12
current value:Thu Jun 06 2013 16:06:00 GMT+0200 (CEST) final_balance_donut_chart.js?body=1:13
test:false final_balance_donut_chart.js?body=1:14
======
编辑 2
出于某种原因,我不得不将两次都转换为字符串才能完成这项工作。
这是.value的最终代码:
.value(function(d) {
var h = d.history[0];
d.history.forEach(function(elt) {
if(elt.time.toString() == selected_time.toString()) {
h = elt;
}
});
return h.balance_of_power;
})