Last active
November 2, 2015 13:48
-
-
Save cgat/988fbca1b228a1b44ad4 to your computer and use it in GitHub Desktop.
Chloropleth Charts with leaflet in DC.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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