D3 Reusable Chart Function Creating Multiple Charts

时光总嘲笑我的痴心妄想 提交于 2020-01-01 19:47:45

问题


I've built a reusable chart function (hat tip to 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;
}

This works great initialy by calling the function:

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

The problem, which creates a duplicate svg chart object, arises when I want to change the width by calling:

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

回答1:


I would change the implementation to be more reusable:

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

Then you would create the chart in much the same way:

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

Then when it comes to updating the chart either by updating the data or by changing other attributes, you have a uniform way of doing it, very close to your implementation:

$("#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); 
});



回答2:


There's a framework out there now which can create reusable d3 charts (based on Mike Bostock's article - http://bost.ocks.org/mike/chart/):

d3.chart

An extensive article on this - http://weblog.bocoup.com/reusability-with-d3/ and http://weblog.bocoup.com/introducing-d3-chart/



来源:https://stackoverflow.com/questions/15762580/d3-reusable-chart-function-creating-multiple-charts

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!