2014-03-18 47 views
1

我的数据是这样的:D3的对象键连接阵列内

[ 
    { 
     name: "Joel Spolsky", 
     values: [ 
       { 
        timestamp: 1380432214730, 
        value: 55 
       }, 
       { 
        timestamp: 1380432215730, 
        value: 32 
       }, 
       { 
        timestamp: 1380432216730, 
        value: 2 
       }, 
       { 
        timestamp: 1380432217730, 
        value: 37 
       }, 

       // etc 
       ]  
    }, 
    { 
     name: "Soul Jalopy", 
     values: [ 
       { 
        timestamp: 1380432214730, 
        value: 35 
       }, 
       { 
        timestamp: 1380432215730, 
        value: 72 
       }, 
       { 
        timestamp: 1380432216730, 
        value: 23 
       }, 
       { 
        timestamp: 1380432217730, 
        value: 3 
       }, 

       // etc 
       ]  
    }, 

    // and so on 
] 

我通过这些数据转化为d3.layout.stack所以yy0得到补充。然后我绘制这个堆叠的布局。

当数据发生变化时,我将新数据加入到旧数据中。

我可以加入群组上name这样的:

var nameGroups = this.chartBody.selectAll(".nameGroup") 
     .data(this.layers, function (d) { 
       return d.name; 
      }); 

但我有麻烦时间戳加入矩形(或“条”)。我可以做(到目前为止)最好是加入他们的values键:

var rects = nameGroups.selectAll("rect") 
     .data(function (d) { 
       return d.values; 
       }); 

如何加入对timestamp关键这个“内部数据”?

我试过,包括数组索引:

var rects = nameGroups.selectAll("rect") 
     .data(function (d, i) { 
       return d.values[i].timestamp; 
       }); 

但是,这并不工作,因为(我认为)时间戳每个数组索引匹配。也就是说,连接不会查看匹配的所有时间戳值,只是该索引处的值。

UPDATE

这里是我的完整更新功能:

updateChart: function (data) { 
    var that = this, 
     histogramContainer = d3.select(".histogram-container"), 
     histogramContainerWidth = parseInt(histogramContainer.style('width'), 10), 
     histogramContainerHeight = parseInt(histogramContainer.style('height'), 10), 
     width = histogramContainerWidth, 
     height = histogramContainerHeight, 
     nameGroups, rects; 

    /* 
    FWIW, here's my stack function created within my 
    init function: 

    this.stack = d3.layout.stack() 
     .values(function (d) { return d.values; }) 
     .x(function (dd) { return dd.timestamp; }) 
     .y(function (dd) { return dd.value; }); 

    */ 

    // save the new data 
    this.layers = this.stack(data); 

    // join the new data to the old via the "name" key 
    nameGroups = this.chartBody.selectAll(".nameGroup") 
     .data(this.layers, function (d, i) { 
      return d.name; 
     }); 

    // UPDATE 
    nameGroups.transition() 
     .duration(750); 

    // ENTER 
    nameGroups.enter().append("svg:g") 
     .attr("class", "nameGroup") 
     .style("fill", function(d,i) { 
      //console.log("entering a namegroup: ", d.name); 
      var color = (that.colors[d.name]) ? 
        that.colors[d.name].value : 
        Moonshadow.helpers.rw5(d.name); 
      return "#" + color; 
     }); 

    // EXIT 
    nameGroups.exit() 
     .transition() 
     .duration(750) 
     .style("fill-opacity", 1e-6) 
     .remove(); 

    rects = nameGroups.selectAll("rect") 
     .data(function (d) { 

      // I think that this is where the change needs to happen 

      return d.values; 

     }); 

    // UPDATE 
    rects.transition() 
     .duration(750) 
     .attr("x", function (d) { 
      return that.xScale(d.timestamp); 
     }) 
     .attr("y", function(d) { 
      return -that.yScale(d.y0) - that.yScale(d.y); 
     }) 
     .attr("width", this.barWidth) 
     .attr("height", function(d) { 
      return +that.yScale(d.y); 
     }); 

    // ENTER 

    rects.enter().append("svg:rect") 
     .attr("class", "stackedBar") 
     .attr("x", function (d) { 
      return that.xScale(d.timestamp); }) 
     .attr("y", function (d) { 
      return -that.yScale(d.y0) - that.yScale(d.y); }) 
     .attr("width", this.barWidth) 
     .attr("height",function (d) { 
      return +that.yScale(d.y); }) 
     .style("fill-opacity", 1e-6) 
     .transition() 
     .duration(1250) 
     .style("fill-opacity", 1); 

    // EXIT 

    rects.exit() 
     .transition() 
     .duration(750) 
     .style("fill-opacity", 1e-6) 
     .transition() 
     .duration(750) 
     .remove(); 
} 
+0

那会是'd.values [0] .timestamp',不是吗? –

+0

嗯。它不需要像d.values [i] .timestamp?因此,它将加入每个rect的'timestamp'而不仅仅是第一个? –

+0

取决于你想要做什么。你能告诉我们完整的代码吗?我不太确定你在尝试做这种匹配。 –

回答

1

你没有真正传递的一个关键功能,在你的代码。关键功能是.data()的可选第二个参数(请参阅the documentation)。所以你的情况,则代码应该是

.data(function(d) { return d.values; }, 
     function(d) { return d.timestamp; }) 

这里的第一个函数告诉D3如何从嵌套的上层和第二提取值如何,在第一个参数中提取的阵列中的每个项目,拿到钥匙。