如何将topojson的投影应用到d3中的voronoi?

时间:2015-08-21 22:17:01

标签: d3.js projection topojson voronoi

我注意到直线弯曲到投影,但Voronoi区域是直线。

enter image description here

是否有可能“强制”Voronoi区域也被弯曲并应用于topojson的投影,如直线和纬度/经度坐标?

原始地图:http://bl.ocks.org/mbostock/7608400

我的代码的一部分:

var projection = d3.geo.kavrayskiy7()
    .center([center_lon, center_lat])
    .scale(zoom)
    .translate([width / 2, height / 2])

var graticule = d3.geo.graticule();

var path = d3.geo.path()
    .projection(projection);

var voronoi = d3.geom.voronoi()
    .x(function(d) { return d.x; })
    .y(function(d) { return d.y; })
    .clipExtent([[0, 0], [width, height]]);

var svg = d3.select(that.el).append("svg")
    .attr("width", width)
    .attr("height", height);

svg.append("path")
    .datum(graticule)
    .attr("class", "graticule")
    .attr("d", path);

svg.append("path")
    .datum(graticule.outline)
    .attr("class", "graticule outline")
    .attr("d", path);

d3.json("/static/app/custom_vizs/components/voronoi/readme-world.json", function(error, world) {
    var countries = topojson.feature(world, world.objects.countries).features,
        neighbors = topojson.neighbors(world.objects.countries.geometries);

    svg.selectAll(".country")
        .data(countries)
        .enter().insert("path", ".graticule")
        .attr("class", "country")
        .attr("d", path);

    var format = d3.format(",");

    var get_points_by_id = d3.map(),
        positions = [];

    var src = _(data).chain().groupBy(src_field).each(function(v, k, o) { o[k] = v; }).value();
    var dst = _(data).chain().groupBy(dst_field).each(function(v, k, o) { o[k] = v; }).value();

    var uniques = _(dst).extend(src);

    var max = 0;

    var points = _(uniques).map(function(v, k) {
        var o = {};

        o.id = k;
        o.value = _(v).pluck(count_field).reduce(function(memo, num) { return memo + parseFloat(num); }, 0);

        max = Math.max(max, o.value);

        if(v[0][src_field] === k) {
            o.lat = v[0][src_lat_field];
            o.lon = v[0][src_lon_field];
        }
        else {
            o.lat = v[0][dst_lat_field];
            o.lon = v[0][dst_lon_field];
        }

        return o;
    });

    points.forEach(function(d) {
        get_points_by_id.set(d.id, d);
        d.outgoing = [];
        d.incoming = [];
    });

    data.forEach(function(connection) {
        var source = get_points_by_id.get(connection[src_field]),
            target = get_points_by_id.get(connection[dst_field]),
            link = {source: source, target: target};
        source.outgoing.push(link);
        target.incoming.push(link);
    });

    points = points.filter(function(d) {
        if (d.count = Math.max(d.incoming.length, d.outgoing.length)) {
        d[0] = +d.lon;
        d[1] = +d.lat;
        var position = projection(d);
        d.x = position[0];
        d.y = position[1];
        return true;
        }
    });

    voronoi(points)
        .forEach(function(d) { d.point.cell = d; });

    var point = svg.append("g")
        .attr("class", "points")
        .selectAll("g")
        .data(points.sort(function(a, b) { return b[count_field] - a[count_field]; }))
        .enter().append("g")
        .attr("class", "point");

    point.append("path")
        .attr("class", "point-cell")
        .attr("d", function(d) { return d.cell.length ? "M" + d.cell.join("L") + "Z" : null; });

    point.append("g")
        .attr("class", "point-arcs")
        .selectAll("path")
        .data(function(d) { return d.outgoing; })
        .enter().append("path")
        .attr("d", function(d) { return path({type: "LineString", coordinates: [d.source, d.target]}); });

    point.append("circle")
        .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
        .attr("r", function(d, i) { return d.value/max*max_circle_size; });

    point.append("title")
        .text(function(d) {
            return d.id + ": " +
                format(d.outgoing.length) + " distinct outgoing, " +
                format(d.incoming.length) + " distinct incoming, " +
                format(d.value) + " total";
        });
});

1 个答案:

答案 0 :(得分:1)

我不这么认为。刻度线(曲线)具有起点和终点。你如何定义voronoi图?也许每个细胞?我觉得它不会起作用。