d3对象的分层数组的访问者

时间:2013-06-12 15:56:50

标签: d3.js

我正在通过json以d3格式向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”的最新值。

因此每个顶级数组元素都是一个具有多个属性的对象,其中一个属性是“history”,它本身就是一个对象数组(具有time和balance_of_power属性)。

可以找到一个工作示例here

要生成圆环图的数据,我使用一个函数,该函数从每个历史数组中获取最新元素(数据按时间排序),并生成另一个名为“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。 / p>

有没有办法只修改饼值的访问者?

修改

我将.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;
})

1 个答案:

答案 0 :(得分:0)

是的,您的代码看起来像这样。

time = "...";
pie = d3.layout.pie()
        .value(function(d) {
            var h = d.history[0];
            for(var i = 0; i < d.history.length; i++) {
                if(d.history[i].time == time) {
                    h = d.history[i];
                    break;
                }
            }
            return h.balance_of_power;
        });

但是,当时间不在历史记录中时,您需要处理此案例。