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

4
我有一个径向D3图表,我想在经纬度坐标的Leaflet/Mapbox地图上绘制/覆盖它。
我查找了一些解决方案,但似乎都是使用cx、cy位置绘制圆形到地图上,这不是我需要的。
那我能否将SVG包围图表添加到地图上?
下面是径向图表的代码和链接(可能对本问题没有用处,因为我只想知道如何将SVG绘制到地图上)。
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);
}

D3图表的CodePen链接

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

    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

你好,如下所示:var svg = d3.select(map.getPanes().overlayPane)? - Alan
嗨,这不是CSS显示问题。我认为可能与SVG元素的转换有关。函数latLngToLayerPoint返回:2629044,3094583,当我使用这些数字进行转换时,SVG消失了? - Alan
我非常确定在update()函数中latLng未定义,因为它仅在分层事件函数的范围内定义。如果您检查SVG元素,可能会发现其transform属性无效,这可能会导致问题。 - Ethan Jewett
它不是未定义的,它具有来自map.latLngToLayerPoint(latLng).x和map.latLngToLayerPoint(latLng).y的值? - Alan
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接