javascript - 使用 D3,如何在平移后更新 map 上的圆圈?

标签 javascript d3.js geometry maps

我正在使用 D3 制作 map 。我已将点和圆添加到 map 中。当我平移地球仪(这是一张立体图)时,点会更新到新位置,但圆圈会发生变化。如何以与圆圈类似的方式更新点?

我使用以下方法添加点和圆:

// POINTS
svg.append("g").attr("class","points")
    .selectAll("text").data(places.features)
    .enter().append("path")
    .attr("class", "point")     
    .style("pointRadius", 2)
    .style("fill", "red");

// CIRCLES
svg.append("g").attr("class","circles")
    .selectAll("path").data(places.features)      
    .enter().append("circle")        
    .attr('cx', function(d) { return proj(d.geometry.coordinates)[0]})
    .attr('cy', function(d) { return proj(d.geometry.coordinates)[1]})    
    .attr("r", 4)   
    .style('fill', 'green')
    .attr("d", path); 

然后,当平移 map 时,我调用一个名为 refresh 的函数来更新这些对象:

function refresh() {

      // redraw land
      svg.selectAll(".land").attr("d", path);  

      // redraw circles
      svg.selectAll(".point").attr("d", path.projection(proj));

      // redraw circles
      svg.selectAll(".circles").attr("d", path.projection(proj));  

    }

此处显示了一个工作示例(需要链接到world-110m.json才能使其工作)。我应该以不同的方式添加圆圈以便可以重新绘制它们吗?

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

<style>
.land {

  fill: rgb(117, 87, 57);
  stroke-opacity: 1;
  stroke: #fff;
  stroke-width: 0.75;
}

</style>
<head>

  <!-- libraries -->
  <script src="http://d3js.org/d3.v3.min.js"></script>
  <script src="http://d3js.org/queue.v1.min.js"></script>
  <script src="http://d3js.org/topojson.v0.min.js"></script>

</head>

<body>
  <div class="map"></div>
</body>

<script>

// Lots of code from:
// http://bl.ocks.org/3757125
// http://bl.ocks.org/3795040

// data
var places = {"type": "FeatureCollection","features": [
{ "type": "Feature", "properties": { "id": 34, "status": 1}, "geometry": { "type": "Point", "coordinates": [  55.321249, 24.104000 ] }},
{ "type": "Feature", "properties": { "id": 34, "status": 1}, "geometry": { "type": "Point", "coordinates": [  55.321249, 24.104000 ] }},
{ "type": "Feature", "properties": { "id": 272, "status": 1}, "geometry": { "type": "Point", "coordinates": [  54.002962, 23.455742 ] }},
{ "type": "Feature", "properties": { "id": 272, "status": 1}, "geometry": { "type": "Point", "coordinates": [  54.002962, 23.455742 ] }},
{ "type": "Feature", "properties": { "id": 350, "status": 1}, "geometry": { "type": "Point", "coordinates": [ 136.321249,-24.496000 ] }},
{ "type": "Feature", "properties": { "id": 427, "status": 0}, "geometry": { "type": "Point", "coordinates": [ 136.321249,-26.296000 ] }},
{ "type": "Feature", "properties": { "id": 427, "status": 0}, "geometry": { "type": "Point", "coordinates": [ 136.321249,-26.296000 ] }},
{ "type": "Feature", "properties": { "id": 96, "status": 0}, "geometry": { "type": "Point", "coordinates": [ 138.259022,-24.491771 ] }}]};


var width = 700,
    height = 700;

var proj = d3.geo.orthographic()
    .translate([width / 2, height / 2])
    .clipAngle(90)
    .scale(310);

var sky = d3.geo.orthographic()
    .translate([width / 2, height / 2])
    .clipAngle(90)
    .scale(360);

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

d3.select(window)
    .on("mousemove", mousemove)
    .on("mouseup", mouseup);


var svg = d3.select("body").select('.map').append("svg")
            .attr("width", width)
            .attr("height", height)
            .on("mousedown", mousedown)

queue()
    .defer(d3.json, "data/world-110m.json")   
    .await(ready);

var div = d3.select("body").append("div")   
    .attr("class", "tooltip")     
    .style("opacity", 0);

function ready(error, world) {
  var globe_highlight = svg.append("defs").append("radialGradient")
        .attr("id", "globe_highlight")
        .attr("cx", "75%")
        .attr("cy", "25%");
      globe_highlight.append("stop")
        .attr("offset", "5%").attr("stop-color", "#ffd")
        .attr("stop-opacity","0.6");
      globe_highlight.append("stop")
        .attr("offset", "100%").attr("stop-color", "#ba9")
        .attr("stop-opacity","0.2");

  svg.append("circle")
    .attr("cx", width / 2).attr("cy", height / 2)
    .attr("r", proj.scale())
    .attr("class", "noclicks")
    .style("fill", "url(#ocean_fill)");

  svg.append("path")
    .datum(topojson.object(world, world.objects.land))
    .attr("class", "land noclicks")
    .attr("d", path);

  // POINTS
  svg.append("g").attr("class","points")
      .selectAll("text").data(places.features)
      .enter().append("path")
      .attr("class", "point")     
      .style("pointRadius", 2)
      .style("fill", "red");

  // CIRCLES
  svg.append("g").attr("class","circles")
      .selectAll("path").data(places.features)      
      .enter().append("circle")        
      .attr('cx', function(d) { return proj(d.geometry.coordinates)[0]})
      .attr('cy', function(d) { return proj(d.geometry.coordinates)[1]})    
      .attr("r", 4)   
      .style('fill', 'green')
      .attr("d", path);

  refresh();
}


function refresh() {

  // redraw land
  svg.selectAll(".land").attr("d", path);  

  // redraw circles
  svg.selectAll(".point").attr("d", path.projection(proj));

  // redraw circles
  svg.selectAll(".circles").attr("d", path.projection(proj));  

}


// modified from http://bl.ocks.org/1392560
var m0, o0;
function mousedown() {
  m0 = [d3.event.pageX, d3.event.pageY];
  o0 = proj.rotate();
  d3.event.preventDefault();
}

function mousemove() {
  if (m0) {
    var m1 = [d3.event.pageX, d3.event.pageY]
      , o1 = [o0[0] + (m1[0] - m0[0]) / 6, o0[1] + (m0[1] - m1[1]) / 6];
    o1[1] = o1[1] > 30  ? 30  :
            o1[1] < -30 ? -30 :
            o1[1];
    proj.rotate(o1);
    sky.rotate(o1);
    refresh();
  }
}

function mouseup() {
  if (m0) {
    mousemove();
    m0 = null;
  }
}
</script>
</html>

最佳答案

circle 元素没有 d 属性,只有 path 元素有。因此,您可能想要附加一个路径而不是

此外,您还将类分配给父 g 元素,因此您在 refresh 中的选择实际上引用了 g'不是形状本身。您应该将类​​放在形状上,或者将您的选择更改为:

svg.selectAll(".point")
    .selectAll("path")
        .attr("d", path.projection(proj));

关于javascript - 使用 D3,如何在平移后更新 map 上的圆圈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18968055/

相关文章:

javascript - d3 直线和圆数据

algorithm - 如何用不相交的线连接两种类型的点?

css - 导航中的三 Angular 形边缘呈锯齿状

c++ - 如何将多面体网格拆分为一组具有签名面的不同多面体?

javascript - CSS背景图片动态调整大小

javascript - 我可以在n秒后调用事件监听器吗

javascript - PreloadJS无法找到音频

javascript - 在 JavaScript 中使用命名空间

javascript - d3 拖动行为 : registering, 监听并触发拖动命名空间中的不同类型?

javascript - 为什么在 d3 中追加元素后 .duration 会充当 .delay ?