将d3图表绘制到Leaflet / Mapbox地图上

时间:2015-04-27 10:28:37

标签: javascript svg d3.js leaflet mapbox

我有一个径向d3图表,我想在lat,long坐标上绘制/叠加到Leaflet / Mapbox地图上。

我环顾四周,解决方案似乎都是使用cx,cy位置在地图上绘制圆圈,这不是我需要的。

我可以将图表周围的SVG添加到地图中吗?

下面是代码和径向图表的链接(这个问题可能有也可能没用,因为我只想知道如何在地图上绘制SVG)

D3 CHART代码

var width = 300;
var height = 300;
var twoPi = 2 * Math.PI; // Full circle
var formatPercent = d3.format(".0%");

var data = [{
  "range": "0-20",
  "count": 20
}, {
  "range": "21-40",
  "count": 10
}, {
  "range": "41-60",
  "count": 17
}, {
  "range": "61-80",
  "count": 49
}, {
  "range": "81-100",
  "count": 90
}];

var max = d3.max(data, function(d) {
  return +d.count;
});

var percent = d3.max(data, function(d) {
  return +d.count / 10;
});

var radiusBackground = .25;
var radiusForeground = .25;
var gap = 28;
var maxCount = max + percent;

var svg = d3.select(map.getPanes().overlayPane).append("svg")
    .attr("width", 1000)
    .attr("height", 1000)
    .attr("transform", "translate(" + map.latLngToLayerPoint(latLng).x + "," + map.latLngToLayerPoint(latLng).y + ")");

var g = svg.append("g")
  .attr("transform", "translate(" + width / 10 + "," + height / 10 + ")")
  .attr("class", "leaflet-zoom-hide");

var background = g.selectAll(".twoPi")
    .data(data).enter()
    .append("path")
    .attr("class", "twoPi")
    .each(full);

var foreground = g.selectAll(".outerPath")
        .data(data).enter()
        .append("path")
        .attr("class", "outerPath")
        .each(drawArc);


map.on("viewreset", update);
update();

function update() {
    foreground.attr("transform", 
        function(d) { 
        return "translate("+ 
        map.latLngToLayerPoint(latLng).x/10000 +","+ 
        map.latLngToLayerPoint(latLng).y/10000 +")";
        }
    )
    background.attr("transform", 
        function(d) { 
        return "translate("+ 
        map.latLngToLayerPoint(latLng).x/10000 +","+ 
        map.latLngToLayerPoint(latLng).y/10000 +")";
        }
    )
}

function full() {

  var arc = d3.svg.arc()
    .startAngle(0)
    .endAngle(twoPi)
    .innerRadius(0 + gap * radiusBackground)
    .outerRadius(26 + gap * radiusBackground);

  d3.select(this)
    .attr("transform", "translate(" + (width / 2.5) + "," + (height / 2.5) + ")")
    .attr("d", arc)
    .style("opacity", "0.5");
  radiusBackground++;
}

function drawArc(d, i) {

  var arc = d3.svg.arc()
    .startAngle(0)
    .endAngle(twoPi * (d.count / maxCount))
    .innerRadius(0 + gap * radiusForeground)
    .outerRadius(26 + gap * radiusForeground);

  d3.select(this)
    .attr("transform", "translate(" + (width / 2.5) + "," + (height / 2.5) + ")")
    .attr("d", arc)
    .attr("id", "path" + i)
    .on("mouseover", function() {
      d3.select(this)
        .style("fill", "red")
        .style("cursor", "pointer");
    })
    .on("mouseout", function() {
      d3.select(this)
        .style("fill", "#8FAAE5");
    })
  radiusForeground++;

  var text = g.append("text")
    .attr("x", 12 + radiusForeground)
    .attr("dy", 20)
    .style("pointer-events", "none");

  text.append("textPath")
    .attr("fill", "white")
    .attr("xlink:href", "#path" + i)
    .text(d.count);
}

CODEPEN LINK TO D3 CHART

地图代码(目前我认为错误)

    L.mapbox.accessToken = 'ACCESS TOKEN HERE';

var map = L.mapbox.map('map', 'NAME HERE', {zoomControl: false}).setView([53.4054, -2.9858], 16);
var myLayer = L.mapbox.featureLayer().addTo(map);

var geojson = [
    {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [53.4054, -2.9858]
        },
        "properties": {
            "icon": {
                "className": "sensor-icon",
                //"html": "▼",
                "iconSize": null
            }
        }
    },
];


myLayer.on('layeradd', function(e) {
    var marker = e.layer,
        feature = marker.feature;
        marker.setIcon(L.divIcon(feature.properties.icon));
    });
    myLayer.setGeoJSON(geojson);

    new L.Control.Zoom({ position: 'bottomleft' }).addTo(map);

    var latLng = new L.LatLng(geojson[0].geometry.coordinates[0], geojson[0].geometry.coordinates[1]);

提前谢谢

1 个答案:

答案 0 :(得分:0)

您需要使用http://leafletjs.com/reference.html#map-panes。具体来说,您将执行map.getPanes().overlayPane,它将返回一个可以附加SVG的元素。