如何将d3瓣叶解决方案中的圆缩放到长/纬度组合的频率?

2nbm6dog  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(100)

所以我正在学习D3,并试图用传单绘制Map。我的数据包含了几千个格子和格子。我能在d3的传单Map上画圆。我如何将这些圆圈的大小缩放到某个组合在我的数据中出现的次数?
以下是我的src代码:

<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js and the geo projection plugin -->
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>

<!-- Load Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin=""/>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA==" crossorigin=""></script>

<!-- Create an element where the map will take place -->
<div id="mapid"></div>

<style>
#mapid { height: 2000px; }
</style>
<script>

var map = L
  .map('mapid')
  .setView([52.5200, 13.4050], 5);   // center position + zoom

// Add a tile to the map = a background. Comes from OpenStreetmap
L.tileLayer(
    'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a>',
    maxZoom: 14,
    }).addTo(map)

L.svg().addTo(map);

d3.csv("longAndLat.csv", function(data) {

    d3.select("#mapid")
    .select("svg")
    .selectAll("myCircles")
    .data(data)
    .enter()
    .append("circle")
        .attr("cx", function(d){ return map.latLngToLayerPoint([d.sub_district_lat, d.sub_district_long]).x })
        .attr("cy", function(d){ return map.latLngToLayerPoint([d.sub_district_lat, d.sub_district_long]).y })
        .attr("r", 12)
        .style("fill", "red")
        .attr("stroke", "red")
        .attr("stroke-width", 1)
        .attr("fill-opacity", .2)

// Function that update circle position if something change
function update() {
  d3.selectAll("circle")
    .attr("cx", function(d){ return map.latLngToLayerPoint([d.sub_district_lat, d.sub_district_long]).x })
    .attr("cy", function(d){ return map.latLngToLayerPoint([d.sub_district_lat, d.sub_district_long]).y })
}

// If the user change the map (zoom or drag), I update circle position:
map.on("moveend", update)

});
</script>

我得到了以下结果:Circles drawn from my data on the map如何将这些圆圈缩放到它们出现的频率?

avkwfej4

avkwfej41#

首先,我建议您使用最新版本的D3,也就是V7而不是V4。这样,您就可以使用d3.group以各种方式对数据进行分组。你的代码似乎可以在V7中正常工作,所以你可以这样做:

let positions = [
  {sub_district_lat: 59.3293, sub_district_long:18.0686},
  {sub_district_lat: 59.9139, sub_district_long:10.7522},
  {sub_district_lat: 59.3293, sub_district_long:18.0686},
];
let data = Array.from(
  d3.group(positions, o => [
    o.sub_district_lat, o.sub_district_long
  ].toString()))
  .map(a => ({
    cnt: a[1].length,
    sub_district_lat: a[1][0].sub_district_lat, sub_district_long: a[1][0].sub_district_long
  }));

请注意,我已经提出了几点来模拟您的数据。这是在行动:

var map = L
  .map('mapid')
  .setView([59.5, 14], 5);   // center position + zoom

// Add a tile to the map = a background. Comes from OpenStreetmap
L.tileLayer(
    'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a>',
    maxZoom: 14,
    }).addTo(map)

L.svg().addTo(map);

    let positions = [
      {sub_district_lat: 59.3293, sub_district_long:18.0686},
      {sub_district_lat: 59.9139, sub_district_long:10.7522},
      {sub_district_lat: 59.3293, sub_district_long:18.0686},
    ];
    let data = Array.from(
      d3.group(positions, o => [
        o.sub_district_lat, o.sub_district_long
      ].toString()))
      .map(a => ({
        cnt: a[1].length,
        sub_district_lat: a[1][0].sub_district_lat, sub_district_long: a[1][0].sub_district_long
      }));

    d3.select("#mapid")
    .select("svg")
    .selectAll("myCircles")
    .data(data)
    .enter()
    .append("circle")
        .attr("cx", function(d){ return map.latLngToLayerPoint([d.sub_district_lat, d.sub_district_long]).x })
        .attr("cy", function(d){ return map.latLngToLayerPoint([d.sub_district_lat, d.sub_district_long]).y })
        .attr("r", d => 12*d.cnt)
        .style("fill", "red")
        .attr("stroke", "red")
        .attr("stroke-width", 1)
        .attr("fill-opacity", .2)

// Function that update circle position if something change
function update() {
  d3.selectAll("circle")
    .attr("cx", function(d){ return map.latLngToLayerPoint([d.sub_district_lat, d.sub_district_long]).x })
    .attr("cy", function(d){ return map.latLngToLayerPoint([d.sub_district_lat, d.sub_district_long]).y })
}

// If the user change the map (zoom or drag), I update circle position:
map.on("moveend", update)
#mapid { height: 500px; }
<script src="https://d3js.org/d3.v7.js"></script>
<script src="https://d3js.org/d3-geo-projection.v3.min.js"></script>

<!-- Load Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin=""/>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA==" crossorigin=""></script>

<!-- Create an element where the map will take place -->
<div id="mapid"></div>

相关问题