2014-03-18 73 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如何從嵌套的上層和第二提取值如何,在第一個參數中提取的陣列中的每個項目,拿到鑰匙。