2015-01-12 157 views
2

我有一個包含兩組數據的集合(用Backbone.js集合表示)(對於這個例子 - 在真實世界的應用程序中,會有更多)。我想在小型d3.js條形圖中表示每組數據。當我渲染第一個條形圖時,一切看起來都很棒,但是當我渲染第二個條形圖時,第一個條形圖會重新寫入,並且看起來更暗且模糊(更容易查看,請參閱此小提琴http://jsfiddle.net/mjmitche/avo5nnus/15/)。如果有三組數據,第一組將會變得非常黑暗和模糊(覆蓋兩次),第二組黑暗和模糊(因爲只覆蓋一次),第三次正常。呈現多個D3圖表而不互相覆蓋

我明白這個問題。當我使用D3,添加垂直引導,例如,我用這個代碼

d3.selectAll('svg') 

所以在第二次通過收集,這是呈現被再次選擇,並寫在第一個SVG。在小提琴中注意,在兩個圖表渲染完畢後,第一個圖像的顏色是否更深(如同墨水的兩倍)和模糊(因爲數字已渲染兩次)。

開始,而不是使用d3.selectAll('svg'),我試圖d3.select('svg')但那麼只有第一張圖有垂直導軌,但是當你使用它d3.select總是選擇發現的第一個項目。

如何使用d3圖表爲每個數據提供兩組數據而不必連續寫入第一組數據?

var myModel = Backbone.Model.extend({}); 

var collection = Backbone.Collection.extend({ 
    model: myModel, 
    initialize: function() { 

    } 

}); 
var MainView = Backbone.View.extend({ 
    el: ('.container'), 
    initialize: function(){ 
     c = new collection({}); 
     c.reset([{stats: [1,2,3]}, {stats: [4,3,2] }]); 
     this.render(); 
    }, 
    render: function(){ 
     c.each(this.addChart, this); 
    }, 
    addChart: function(chart){ 
     alert("pause to view first chart, very clear, no overlap, second time through not so"); 
     var view = new D3View({model: chart}); 
     console.log(view, "view"); 
     this.$("#d3results").append(view.render().el); 
    } 

}); 

var D3View = Backbone.View.extend({ 

    initialize: function(){ 

    }, 

    render: function(){ 
     console.log("render in d3view"); 


    var modeldata = this.model.toJSON(); 
     var bardata = modeldata.stats; 
     console.log(bardata, "bardata"); 
    var margin = { top: 30, right: 30, bottom: 40, left:70 } 

    var height = 200 - margin.top - margin.bottom, 
     width = 300 - margin.left - margin.right, 
     barWidth = 50, 
     barOffset = 5; 

    var tempColor; 

    var colors = d3.scale.linear() 
    .domain([0, bardata.length*.33, bardata.length*.66, bardata.length]) 

    var yScale = d3.scale.linear() 
      .domain([0, d3.max(bardata)]) 
      .range([0, height]); 

    var xScale = d3.scale.ordinal() 
      .domain(d3.range(0, bardata.length)) 
      .rangeBands([0, width], 0.2) 

    var tooltip = d3.select('body').append('div') 
      .style('position', 'absolute') 
      .style('padding', '0 10px') 
      .style('background', 'white') 
      .style('opacity', 0) 

    var myChart = d3.select('#d3results').append('svg') 
     .style('background', '#fff') 
     .attr('width', width + margin.left + margin.right) 
     .attr('height', height + margin.top + margin.bottom) 
     .append('g') 
     .attr('transform', 'translate('+ margin.left +', '+ margin.top +')') 
     .selectAll('rect').data(bardata) 
     .enter().append('rect') 
      .style('fill', function(d,i) { 
       return colors(i); 
      }) 
      .attr('width', xScale.rangeBand()) 
      .attr('x', function(d,i) { 
       return xScale(i); 
      }) 
      .attr('height', 0) 
      .attr('y', height) 
    myChart.transition() 
     .attr('height', function(d) { 
      return yScale(d); 
     }) 
     .attr('y', function(d) { 
      return height - yScale(d); 
     }) 
     .delay(function(d, i) { 
      return i * 20; 
     }) 



    var vGuideScale = d3.scale.linear() 
     .domain([0, d3.max(bardata)]) 
     .range([height, 0]) 

    var vAxis = d3.svg.axis() 
     .scale(vGuideScale) 
     .orient('left') 
     .ticks(10) 

    var vGuide = d3.selectAll('svg').append('g') 
     vAxis(vGuide) 
     vGuide.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')') 
     vGuide.selectAll('path') 
      .style({ fill: 'none', stroke: "#000"}) 
     vGuide.selectAll('line') 
      .style({ stroke: "#000"}) 

    var hAxis = d3.svg.axis() 
     .scale(xScale) 
     .orient('bottom') 
     .tickValues(xScale.domain().filter(function(d, i) { 
      return !(i % (bardata.length/5)); 
     })) 





     return this; 
    } 
}); 

view = new MainView(); 

回答

1

最簡單的解決是保持引用您的svg你不需要selectAll

var mySVG = d3.select('#d3results').append('svg'); 

var myChart = mySVG 
    .style('background', '#fff') 
    .attr('width', width + margin.left + margin.right) 

.... 

var vGuide = mySVG.append('g') 
    vAxis(vGuide) 

.... 

更新fiddle