Skip to content

Instantly share code, notes, and snippets.

@cgat
Last active November 2, 2015 13:48
Show Gist options
  • Save cgat/988fbca1b228a1b44ad4 to your computer and use it in GitHub Desktop.
Save cgat/988fbca1b228a1b44ad4 to your computer and use it in GitHub Desktop.
Chloropleth Charts with leaflet in DC.js
//Sample usage
/* Inspired by this example http://bost.ocks.org/mike/leaflet/
map = new L.Map(...); //height and width should be set on your map, not the chart
dcMap = dc.leafletChloroplethChart('#my_map');
//Again, instead of specifying width and height, you specify the map instance.
dcMap.dimension(regionDim)
.group(regionDim.group().reduceSum(function (d) {
return d.duration;
}))
.map(map)
.colors(d3.scale.quantize().range(["#E2F2FF", "#C4E4FF", "#9ED2FF", "#81C5FF", "#6BBAFF", "#51AEFF", "#36A2FF", "#1E96FF", "#0089FF", "#0061B5"]))
.colorDomain([0, 25000])
.colorCalculator(function (d) { return d ? dcMap.colors()(d) : '#ccc'; })
.overlayGeoJson([featureCollection.features[0]], "duration", function(d) {
return d.properties.name;
});
*/
dc.leafletChloroplethChart = function (parent, chartGroup) {
var _chart = dc.geoChoroplethChart(parent, chartGroup);
var _map;
var _geoPath;
var _allFeatures;
var _topLeft, _bottomRight;
function projectPoint(x, y) {
var point = _map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
};
function svgSetup() {
//combine all features from all geoJson layers into one
//feature collection
if(_allFeatures===undefined) {
_allFeatures = { type: "FeatureCollection", features: [] };
for (var i = 0; i < _chart.geoJsons().length; ++i) {
var layerFeatuers = _chart.geoJsons()[i].data;
_allFeatures.features = _allFeatures.features.concat(layerFeatuers);
}
}
//now figure out the bounds of those objects are
var bounds = _chart.geoPath().bounds(_allFeatures),
topLeft = bounds[0],
bottomRight = bounds[1];
//now setup svg size and translate to center of svg
_chart.svg().attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");
for (var i = 0; i < _chart.geoJsons().length; ++i) {
var layerElement = _chart.selectAll('g.layer'+i);
layerElement.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
}
}
_chart.geoPath = function (){
return _geoPath;
};
_chart.map = function (map) {
_map = map;
var _transform = d3.geo.transform({point: projectPoint});
_geoPath = d3.geo.path().projection(_transform);
_chart.projection(_transform);
_map.on("viewreset", function() {
//When a zoom occurs, we want to redraw all the
//region paths, which will happen in doRedraw
//only if the projectFlag is set to true. Since this
//is not exposed, I trigger it by calling projection
//again.
_chart.projection(_transform);
_chart._doRedraw();
});
return _chart;
};
_chart.resetSvg = function () {
_chart.select("svg").remove();
var _svg = d3.select(_map.getPanes().overlayPane).append("svg");
_chart.svg(_svg);
// _svg.attr('width',(parseInt(_chart.root().style('width'))));
// _svg.attr('height', (parseInt(_chart.root().style('height'))));
return _svg;
};
_chart._doRedraw = (function (parentRedraw) {
return function() {
parentRedraw();
svgSetup();
};
})(_chart._doRedraw);
_chart._doRender = (function (parentRender) {
return function() {
parentRender();
svgSetup();
};
})(_chart._doRender);
return _chart;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment