无法隐藏旋转地球后面的城市

时间:2016-12-13 10:39:30

标签: javascript css d3.js

我已经组建了一个jsfiddle,我实施了一个Bostock旋转地球仪。

然后我尝试绘制几个标记(城市)。这只是部分成功。由于某些原因,并非所有人都被绘制 - 并且,我假设出于类似的原因 - 旨在隐藏这些无形城市(即在地球后面)的脚本不能正常工作。当你将它们滚出视线时,标记仍然不经意地跳舞。

我把以下小提琴放在一起:http://jsfiddle.net/Guill84/jg3axLmx/1/

以下是用于“隐藏”地球背后标记的脚本:

function position_cities() {
   var centerPos = projection.invert([380,380]);
   var arc = d3.geo.greatArc();
   svg.selectAll(".cities")
     .style("fill", "blue")
     .attr("cx", function(d) {
       return projection([d.lon, d.lat])[0];
     })
     .attr("cy", function(d) {
       return projection([d.lon, d.lat])[1];
     })
     .style({
       "color": "#FFF",
       "display": function(d) { 
         var x = projection([d.lon, d.lat])[0];
         var y = projection([d.lon, d.lat])[1];
         var d = arc.distance({
           source: [d.lat, d.lon],
           target: centerPos
         });
         return (d > 1.57) ? 'none' : 'inline';
       }
     });
 }

此外 - 你知道如何为这些标记添加标签,并使它们成方形而不是圆形吗?

上述问题与此类似: Cannot hide labels 'behind' spinning D3 Globe

在这里,您可以看到巴西仍然可见的标记 Here you can see a marker in Brazil that is still visible

3 个答案:

答案 0 :(得分:1)

我可以回答子问题:

  

此外 - 你知道如何为这些标记添加标签,并使它们成方形而不是圆形吗?

第72行,而不是这样做:

      .append("circle")
        .attr("cx", function(d) {
           return projection([d.lon, d.lat])[0];
           })
        .attr("cy", function(d) {
           return projection([d.lon, d.lat])[1];
           })

添加“g”元素:

      .append("g")
        .attr("transform", function(d) {
           return "translate("+ 
                    projection([d.lon, d.lat])[0] +
                    "," +
                    projection([d.lon, d.lat])[1]+
                    ")";
           })

然后

     cities.append("circle") 
           .attr("cx", 0)
           .attr("cy", 0)

    cities.append("text").text("New York");

你可以摆弄文字的x和y坐标。此外,每当您用来更改城市的cx和cy属性时,您需要更改g元素的“transform”属性(如上所示)。

关于你的主要问题,我可以给出的最好的线索是d3.geo.greatArc();已被弃用,所以也许你应该寻找一种新的方法来计算地球上的弧距。

答案 1 :(得分:1)

在js小提琴中,你提供的是你设置城市一次,但从不再打电话给他们。在startAnimation方法中,您更新城市显示的标签的方式也必须同样更新。如果不是,显示将取决于第一次加载。

对于形状更改,您在此处创建时会定义它:

var cities = svg.selectAll("circle")
            .data([
            {"code":"RIO","city":"RIO DE JANEIRO","country":"BRAZIL","lat":-22.90,"lon":-43.24},
            {"code":"BSB","city":"BRASILIA","country":"BRAZIL","lat":-15.67,"lon":-47.43},
            {"code":"ZNZ","city":"ZANZIBAR","country":"TANZANIA","lat":-6.13,"lon":39.31},
            {"code":"TYO","city":"TOKYO","country":"JAPAN","lat":35.68,"lon":139.76}
            ])
            .enter()
            .append("circle")
            .attr("cx", function(d) {
               return projection([d.lon, d.lat])[0];
               })
            .attr("cy", function(d) {
               return projection([d.lon, d.lat])[1];
               })
            .attr("r", 3)
            .style("fill", "red")
            .attr("d", path)
            .attr("class", "cities")
            .attr("id", function(d){ return d.code})

诸如cx,cy之类的属性与SVG圆形形状以及指定的圆形标记相关。要创建新形状,您需要在此处更改相对于所需形状的标记和属性。

答案 2 :(得分:1)

你几乎拥有它,

如评论中所述,中心点为400,400:

var centerPos = projection.invert([400,400]);

您在此处的源坐标中混合了订单纬度和经度:

var d = arc.distance({source: [d.lat, d.lon], target: centerPos});
  return (d > 1.57) ? 'none' : 'inline';

这应该是:

var d = arc.distance({source: [d.lon, d.lat], target: centerPos});
  return (d > 1.57) ? 'none' : 'inline';

小提琴:http://jsfiddle.net/L51y3c1b/

相关问题