d3.js fisheye distortion on map

I'm trying to distort a d3.geo.path() map with the fisheye.js plugin (https://github.com/d3/d3-plugins/tree/master/fisheye).

To distort an object the plugin needs x & y attributes.

In the d3.js wiki it says:

A projection function takes a two-element array of numbers representing the coordinates of a location, [longitude, latitude], and returns a similar two-element array of numbers representing the projected pixel position [x, y]. For example, a rudimentary spherical Mercator projection:

https://github.com/mbostock/d3/wiki/Geo-Paths

So the distortion should be possible, I just can't wrap my head around it.

I'm using the world-50m.json for my projection. Once loaded there is an the arcs array. I think those are the coordinates I need to manipulate. But this is guesswork...

Thanks,

Kim

Answers:

Answer

I found your post looking for the answer, and it doesn't appear to be out there on the internets. But, like you say, it's possible!

Following the documentation from the fisheye.js (https://github.com/d3/d3-plugins/tree/master/fisheye), in the mousemove callback you need to use fisheye on the coordinates.

Since fisheye uses the .x and .y attributes, I modified the fisheye code to just use the two pair [x,y] to avoid making that intermediate data structure every time in the callback.

Then you can do it like this:

canvas.on("mousemove", function() {
    // console.log("mouse:");
    // console.log(d3.mouse(this));
    var here = d3.mouse(this);
    // console.log(here); // [1030, 125]
    // console.log(projection.invert(here)); // [-72.4713375653601, 45.14035261565636]
    var inverted = projection.invert([here[0],here[1]]); // [-72.4713375653601, 45.14035261565636]
    // console.log(inverted); // [-72.4713375653601, 45.14035261565636]
    // burlington is lat 44, lon -73
    fisheye.focus(inverted);

    // of course, the path function takes [longitude, latitude], so -72, 44 for burlington
    // https://github.com/mbostock/d3/wiki/Geo-Paths
    // (so that's what it gives back)

    states.attr("d",null)
        .attr("d", function(d) {
            // console.log("original:");
            // console.log(d.geometry);

            if (d.geometry.type === "Polygon") {
                var b = d.geometry.coordinates.map(function(d) { return d.map(function(f) { return fisheye(f);}); });
            }
            else {
                var b = d.geometry.coordinates.map(function(d) { return d.map(function(f) { return f.map(function(g) { return fisheye(g); }); }); });
            }
            // console.log(b);
            var c = {type: d.geometry.type, coordinates: b};

            // console.log("new:");
            // console.log(c);

            return path(c);
    });

You can view a live version here: http://panometer.org/instruments/teletherms/?window=25&var=maxT&year=1914&city=BURLINGTON%20WSO%20AP,%20VT

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.