Reputation: 5237
Can someone tell me why my d3 chart is not appearing in my popups? Full jsfiddle here. .
The dataset shown for my popups is hypothetical for now, just trying to test and make sure I can get the basics working.
here's my code:
var onEachFeature = function onEachFeature(feature,layer){
var div = $('<div id="chart"><h3>Ethnic Group Distribution</h3><svg/></div>')[0];
var popup = L.popup().setContent(div);
layer.bindPopup(popup);
//Width and height
var w = 400;
var h = 300;
var barPadding = 1;
var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
//Create SVG element
var svg = d3.select("chart")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return i * (w / dataset.length);
})
.attr("y", function(d) {
return h - (d * 4);
})
.attr("width", w / dataset.length - barPadding)
.attr("height", function(d) {
return d * 4;
});
};
L.geoJson(afghanDistricts, {
onEachFeature: onEachFeature
}).addTo(map);
Upvotes: 1
Views: 339
Reputation: 28688
You don't need jQuery to compile the popup's content string to DOM, L.Popup
's setContent
method already does that for you:
setContent( <String|HTMLElement> htmlContent )
Sets the HTML content of the popup.
http://leafletjs.com/reference.html#popup-setcontent
You can't initialize the chart when the popup isn't open. The content div
element will only be attached to the DOM when the popup is open. It gets removed again the popup closes. So you'll need to initialize the chart everytime the popup opens. You can do that by using the popupopen
event of your map instance:
L.mapbox.map(...).on('popupopen', function () {
// Do stuff
});
Fired when a popup is opened (using openPopup method).
http://leafletjs.com/reference.html#map-popupopen
When using D3's select
method to fetch an element by unique identifier, you'll need to prefix a #
character:
D3.selector('#chart')
For example, you can select by tag ("div"), class (".awesome"), unique identifier ("#foo"), attribute ("[color=red]"), or containment ("parent child").
https://github.com/mbostock/d3/wiki/Selections
Also you don't need to add an svg
element in the content since you're already appending a new svg
element: .append("svg")
. That creates a new svg
element and appends it.
Here's a working snippet:
var afghanDistricts = {"type":"FeatureCollection","features":[{"type":"Feature","properties":{"stroke":"#555555","stroke-width":2,"stroke-opacity":1,"fill":"#555555","fill-opacity":0.5,"Pashtun":0.43,"Tajik":0.12,"Uzbek":0.05,"Turkmen":"0.00","Hazara":"0.00","District":"Argo","Province":"Kandahar"},"geometry":{"type":"Polygon","coordinates":[[[61.69921875,32.08257455954592],[61.69921875,32.879587173066305],[62.666015625,32.879587173066305],[62.666015625,32.08257455954592],[61.69921875,32.08257455954592]]]}},{"type":"Feature","properties":{"Pashtun":0.32,"Tajik":"0.20","Uzbek":0.01,"Turkmen":0.02,"Hazara":"0.00","District":"Jurm","Province":"Farah"},"geometry":{"type":"Polygon","coordinates":[[[62.75390625,32.95336814579932],[62.75390625,33.76088200086917],[63.69873046874999,33.76088200086917],[63.69873046874999,32.95336814579932],[62.75390625,32.95336814579932]]]}},{"type":"Feature","properties":{"Pashtun":0.05,"Tajik":"0.50","Uzbek":0.21,"Turkmen":"0.00","Hazara":"0.00","District":"Ragh","Province":"Ghor"},"geometry":{"type":"Polygon","coordinates":[[[63.74267578125,33.54139466898275],[63.74267578125,34.43409789359469],[65.14892578125,34.43409789359469],[65.14892578125,33.54139466898275],[63.74267578125,33.54139466898275]]]}},{"type":"Feature","properties":{"Pashtun":"0.00","Tajik":0.01,"Uzbek":"0.10","Turkmen":"0.20","Hazara":"0.40","District":"Highan","Province":"Kabul"},"geometry":{"type":"Polygon","coordinates":[[[64.53369140625,35.15584570226544],[64.53369140625,35.94243575255426],[65.56640625,35.94243575255426],[65.56640625,35.15584570226544],[64.53369140625,35.15584570226544]]]}},{"type":"Feature","properties":{"Pashtun":"0.00","Tajik":0.01,"Uzbek":"0.20","Turkmen":"0.30","Hazara":0.04,"District":"Nusay","Province":"Kunduz"},"geometry":{"type":"Polygon","coordinates":[[[65.58837890625,33.30298618122413],[65.58837890625,34.32529192442733],[66.90673828125,34.32529192442733],[66.90673828125,33.30298618122413],[65.58837890625,33.30298618122413]]]}},{"type":"Feature","properties":{"Pashtun":"0.20","Tajik":"0.00","Uzbek":"0.00","Turkmen":"0.10","Hazara":"0.20","District":"Zebak","Province":"Logar"},"geometry":{"type":"Polygon","coordinates":[[[65.98388671875,34.72355492704219],[65.98388671875,35.53222622770337],[66.95068359374999,35.53222622770337],[66.95068359374999,34.72355492704219],[65.98388671875,34.72355492704219]]]}},{"type":"Feature","properties":{"Pashtun":"0.10","Tajik":"0.10","Uzbek":0.28,"Turkmen":"0.10","Hazara":"0.00","District":"Wakhan","Province":"Nimruz"},"geometry":{"type":"Polygon","coordinates":[[[67.32421875,34.43409789359469],[67.32421875,35.42486791930558],[68.37890625,35.42486791930558],[68.37890625,34.43409789359469],[67.32421875,34.43409789359469]]]}}]}
L.mapbox.accessToken = 'pk.eyJ1IjoiZG9zcyIsImEiOiI1NFItUWs4In0.-9qpbOfE3jC68WDUQA1Akg';
var map = L.mapbox.map('mapbox', null, {
'center': [0, 0],
'zoom': 0
}).on('popupopen', function () {
var w = 400;
var h = 300;
var barPadding = 1;
var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13, 11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
var svg = d3.select("#chart")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return i * (w / dataset.length);
})
.attr("y", function(d) {
return h - (d * 4);
})
.attr("width", w / dataset.length - barPadding)
.attr("height", function(d) {
return d * 4;
});
});
var geojson = new L.GeoJSON(afghanDistricts, {
onEachFeature: function (feature, layer) {
layer.bindPopup(new L.popup().setContent('<div id="chart"><h3>Ethnic Group Distribution</h3></div>'));
}
}).addTo(map);
map.fitBounds(geojson.getBounds());
body {
margin: 0;
padding: 0;
}
#mapbox {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 500px;
}
<html>
<head>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<link type="text/css" rel="stylesheet" href="//api.mapbox.com/mapbox.js/v2.3.0/mapbox.css" />
<script type="application/javascript" src="//api.mapbox.com/mapbox.js/v2.3.0/mapbox.js"></script>
<script type="application/javascript" src="//d3js.org/d3.v3.min.js"></script>
</head>
<body>
<div id="mapbox"></div>
</body>
</html>
Upvotes: 1
Reputation: 32327
Instead of doing:
var svg = d3.select("chart")//not work because chart is not bound to the DOM
.append("svg")
.attr("width", w)
do this:
var svg = d3.select(div)//the div which holds the tooltip
.append("svg")
working code here
Upvotes: 1