问题
I've implemented an infographic / map using crossfilter and d3.js.
What I would like is to add the functionality of rendering different data entries as points of interest on the map:
For example here we have cities in Mexico and data to indicate a metric of tequila consumption.
What I would like to make is, for instance, tequila consumption in different cities of Europe.
How can I overlay such information over my map of Europe.
The thing is, it's very clear how to do this with d3.js but it is unclear how to achieve this with a map that is working with dc.js, i.e. crossfilter.
All of my code can be found here.
This is the part most closely related to the map itself:
//This is the data for the Map
d3.json("data/europe.json", function (error, eu) {
console.log('map', eu)
usChart
.width(590)
.height(500)
.projection(projection
.scale((1200 + 1) / 2 )
.translate([660 / 4, 3360 / 4])
.precision(.1))
.dimension(countries)
.group(countriesJobsdSum)
.filterHandler( function(dimension, filter) {
dimension.filter(
function(d) {return usChart.filter() != null ? d.indexOf(usChart.filter()) >= 0 : true;}); // perform filtering
return filter; // return the actual filter value
})
.colors(d3.scale.quantize().range(
["#8c857d", "#d982ab", "#d9525e", "#a63f52", "#8c6976", "#55b1b1", "#637e9e"])
)
.colorDomain([0, 200])
.colorCalculator(function (d) { return d ? usChart.colors()(d) : '#ccc'; })
.overlayGeoJson(eu.features, "countries", function (d) {
return d.properties.name;
//return d.properties.Country;
})
.transitionDuration(0)
.title(function (d) {
return "Country: " + d.key + "\nNumber of Jobs: " + numberFormat(d.value ? d.value : 0) ;
});
回答1:
You can use
.on("renderlet", drawAdditionalStuffInMap)
to draw additional things in the map, the function would look like this:
function drawAdditionalStuffInMap(_chart, selection) {
var svg = _chart.svg();
svg.selectAll("g.additionalStuff").remove();
var group = svg.selectAll("g.additionalStuff");
if (group.empty()) {
group = svg.append("g").classed("additionalStuff", true);
}
//you need to implement calculateAdditionalDataPoints
var additionalData = calculateAdditionalDataPoints();
var additionalNodes = group.selectAll("circle").data(additionalData, function(x) { return x.id; });
_chart.dimension().top(Infinity).map(function(d) {
d.location = proj([d.long, d.lat]);
return d;
});
additionalNodes.enter()
.append("circle")
.attr("x", 0)
.attr("y", 0)
.attr("r", 100)
.attr("transform", function(d){ return "translate(" + d.location[0] + "," + d.location[1] + ")"; });
additionalNodes.exit().remove();
}
The above code requires you to use the projection of the map as the proj function and that all data points have the longitude and latitude stored as long and lat inside them. It draws circles of radius 100 at the currently selected Datapoints. If you dont support zooming and panning on your map you can calculate d.location once for all data points outside of this function.
来源:https://stackoverflow.com/questions/33039404/geochoroplethchart-map-that-displays-cities-points-of-interest-with-tags