javascriptd3.jsnvd3.js

Multiple NVD3 charts on page. How to simplify the javascript code and wrap function?


I am currently using NVD3 on website to graph charts with one of the pages having 6 charts. I have currently just add 6 functions for each the six graphs but I feel that this is not the most elegant way of approaching the problem. Below is an example of the relevant html/javascript code:

<div id="chicago" class='with-3d-shadow with-transitions chart'>
  <svg> </svg>
</div>

nv.addGraph(function() {
  var chicago = nv.models.lineChart()
      .margin({top: 30, right: 60, bottom: 50, left: 80})
      .x(function(d,i) { return i })
      .color(d3.scale.category10().range());

  chicago.transitionDuration(500);

  chicago.xAxis.tickFormat(function(d) {

      var dx = testdata[0].values[d] && testdata[0].values[d].x || 0;
      if (dx > 0) {
          return d3.time.format('%x')(new Date(dx))
      }
      return null;
  });

  chicago.yAxis
      .axisLabel('Price ($/Dth)')
      .tickFormat(function(d) { return '$' + d3.format(',.2f')(d) });

  nv.log(testdata);
  d3.select('#chicago svg')
      .datum(testdata)
      .call(chicago);

  nv.utils.windowResize(chicago.update);

  return chicago;
});

How would I wrap that function so I can reuse it multiple times without have to repeat it and replace the name (in this case 'chicago') for every graph?


Solution

  • It's quite simple, this is one way of doing it.

    HTML :

    <div id='chart1'>
        <h3>My Chart 1</h3>
        <svg></svg>
    </div>
    <div id='chart2'>
        <h3>My Chart 2</h3>
        <svg></svg>
    </div>
    <div id='chart3'>
        <h3>My Chart 3</h3>
        <svg></svg>
    </div>
    

    JavaScript :

    // Call my charts , pass in my div id here
    drawChart('chart1');
    drawChart('chart2');
    drawChart('chart3');
    
    //Donut chart example
    function drawChart(div) {
        var width = height = 400;
        
        nv.addGraph(function () {
            var chart = nv.models.pieChart()
                .x(function (d) {
                return d.label
            }).y(function (d) {
                return d.value
            }).width(width)
              .height(height)
              .showLabels(true)
              .labelThreshold(.05)
              .labelType("percent")
              .donut(true);
    
            d3.select("#" + div + " svg")
                .datum(exampleData())
                .attr('width', width).attr('height', height)
                .transition().duration(350)
                .call(chart);
    
            return chart;
        });
    }
    

    Here is a working version of it.