【问题标题】:D3 Reusable Chart Function Creating Multiple ChartsD3 可重用图表函数创建多个图表
【发布时间】:2013-04-02 11:09:16
【问题描述】:

我已经构建了一个可重复使用的图表函数(向 Mike Bostock 致敬 - http://bost.ocks.org/mike/chart/):

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;
}

通过调用该函数初始效果很好:

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

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

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

【问题讨论】:

    标签: jquery d3.js


    【解决方案1】:

    我会将实现更改为更多可重用:

    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); 
    });
    

    【讨论】:

    • 在尝试将 g 附加到 svgEnter 时,在这种情况下使用它时,我得到“svgEnter.selectAll 不是函数”:force.nodes(d); node = svgEnter.selectAll(".node") .data(d) .enter().append("g")
    • 您是否已经附加了svg 元素,即svgEnter.append('svg')?否则,我需要更多的上下文才能调试它。你能为它创建一个最小的 jsFiddle 吗?
    • var svgEnter = svg.enter().append('svg');。已在代码中修复:jsfiddle.net/bMjJm 和答案中。
    【解决方案2】:

    现在有一个框架可以创建可重复使用的 d3 图表(基于 Mike Bostock 的文章 - http://bost.ocks.org/mike/chart/):

    d3.chart

    关于此的大量文章 - http://weblog.bocoup.com/reusability-with-d3/http://weblog.bocoup.com/introducing-d3-chart/

    【讨论】:

      猜你喜欢
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-14
      • 1970-01-01
      • 2013-10-08
      • 2019-10-30
      • 1970-01-01
      相关资源
      最近更新 更多