OnLeRo
OnLeRo

Reputation: 145

Using NVD3 chart in Leaflet control

I followed the Leaflet choropleth map tutorial and want now include a NVD3 chart into the control on the top-right corner. If I am making an extra <div> besides the map and include <svg> everything works fine. I am creating the info control like that:

var info = L.control();

info.onAdd = function(map) {
  this._div = L.DomUtil.create('div', 'info', ); // create a div with a class "info" 
  this.update();
  return this._div;
};

I fill it with content like that:

info.update = function(props) {
  this._div.innerHTML = (props ?
    '<h4>' + props.Name + '</h4>' + props.number :
    'Click on an area');
};

I tried to include here the same <div> that works when I put it next to the map <div>:

<div><svg/></div>

But nothing appears. That's my graph:

function exampleData() {
  return [{
      "label": "One",
      "value": 29.765957771107
    },
    {
      "label": "Two",
      "value": 0
    },
    {
      "label": "Three",
      "value": 32.807804682612
    },
    {
      "label": "Four",
      "value": 196.45946739256
    },
    {
      "label": "Five",
      "value": 0.19434030906893
    },
    {
      "label": "Six",
      "value": 98.079782601442
    },
    {
      "label": "Seven",
      "value": 13.925743130903
    },
    {
      "label": "Eight",
      "value": 5.1387322875705
    }
  ];
}

nv.addGraph(function() {
  var chart = nv.models.pieChart()
    .x(function(d) {
      return d.label
    })
    .y(function(d) {
      return d.value
    })
    .showLabels(true);

  d3.select("#chart svg")
    .datum(exampleData())
    .transition().duration(350)
    .call(chart);

  return chart;
});

I think it has something to do with L.DomUtil.create since here the <div> for the control panel is created. But I did not manage to tell NVD3 to render the plot within the control panel. Do you have an idea?
One strange thing happens too:
I see and empty area below the text in the control panel (where the graph should have be rendered). And if I click on my features the text changes as intended, but also the empty field below increases with every click. This just happens if I include the <div> containing <svg/> in info.update.

Upvotes: 0

Views: 212

Answers (1)

shabeer90
shabeer90

Reputation: 5151

The problem is not complicated it sounds. You'll probably have a laugh once you read my solution.

At the point you create the pieChart nv.addGraph(function() {..} in the line that you select the element to render the chart d3.select("#chart svg") the browser is assuming the DOM element exists, which is not the case.

You were right in assuming that it had to do something with L.DomUtil.create. This is the point where you call this.update(); to actually render the <div id="chart"> <svg/></div> required for your NVD3 pieChart.

So here is what I did to your code.

function createPieChart() {
  nv.addGraph(function() {
    var chart = nv.models.pieChart()
    ...  
    ...
    return chart;
  });
}

Wrapped it in a createPieChart() function so it could be accessed when required.

And inside your info.update() I'm calling the createPieChart() function once the innerHTML has been created.

// method that we will use to update the control based on feature properties passed
info.update = function(props) {
  this._div.innerHTML = (...); //WHICH DIV HAS TO BE GENERATED

  // Now we can create the Pie Chart  
  createPieChart();
};

And now it works as expected.

You can find a working version here

Hope it helps

Upvotes: 1

Related Questions