geoChoroplethChart map that displays cities / points of interest with tags
Asked Answered
E

1

3

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:

enter image description here

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) ;
        }); 
Embouchure answered 9/10, 2015 at 13:21 Comment(0)
B
3

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.

Biased answered 18/2, 2016 at 8:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.