2013-04-02 31 views
1

我已经建立了一个可重复使用的图表功能(帽尖麦克·博斯托克 - http://bost.ocks.org/mike/chart/):D3可重复使用的图表功能创建多个图表

d3.csv("data.csv", function (data) { 
d3.select("#chart") 
    .datum(data) 
    .call(chartBubble().width(800)); 
}); 

function chartBubble() { 
    var width = 800, 
     height = 800; 

    function chart() { 
    var svg = d3.select("#chart").append("svg") 
      .attr("width", width) 
      .attr("height", height); 

    // generate rest of chart here 
    } 

    chart.width = function(value) { 
    if (!arguments.length) return width; 
    width = value; 
    return chart; 
    }; 

    return chart; 
} 

这通过调用函数的伟大工程initialy

当我想通过调用来更改宽度时,会出现创建重复svg图表对象的问题:

$("#button").click(function(){ 
    d3.select("#chart") 
    .call(chartBubble().width(500)); 
}); 

回答

4

我会改变的实施是可重复使用:

function chartBubble() { 
    var width = 800, 
     height = 800; 

    function chart(selection) { 
    selection.each(function (d, i) { 
     var chartElem = d3.select(this); 
     var svg = chartElem.selectAll('svg').data([d]); 

     var svgEnter = svg.enter().append('svg'); 

     // Now append the elements which need to be inserted 
     // only once to svgEnter. 
     // e.g. 'g' which contains axis, title, etc. 

     // 'Update' the rest of the graph here. 
     // e.g. set the width/height attributes which change: 
     svg 
      .attr('width', width) 
      .attr('height', height); 

    }); 
    } 

    chart.width = function(value) { 
    if (!arguments.length) return width; 
    width = value; 
    return chart; 
    }; 

    return chart; 
} 

那么你将在多创建图表以同样的方式:

// Bubble is created separately and is initialized 
var bubble = chartBubble().width(800); 

d3.csv("data.csv", function (data) { 
d3.select("#chart") 
    .datum(data) 
    .call(bubble); 
}); 

然后当它涉及到更新通过更新data或通过更改其他属性,您可以采用统一的方式执行此操作,这与您的实施非常接近:

$("#button").click(function(){ 
    // The advantage of defining bubble is that we can now change only 
    // width while preserving other attributes. 
    bubble.width(500); 
    d3.select("#chart") 
    //.datum(newData) 
    .call(bubble); 
}); 
+0

感谢!我将重新编写我的代码并回复给您。 – greenafrican

+0

在试图将g附加到svgEnter时,我得到的“svgEnter.selectAll不是一个函数”,在这种情况下使用它时:'force.nodes(d); ()添加(“g”)' – greenafrican

+0

您是否已经附加了一个'svg'元素,即'svgEnter.append(').dat(d) .enter()。append(“g”)' SVG“)'?否则,我需要更多的上下文才能调试它。你可以为它创建一个最小的jsFiddle吗? –