如何在d3中动态改变点半径和JSON路径的样式?

时间:2017-10-31 11:19:46

标签: css json d3.js

我需要动态帮助"突出显示"世界地图上的城市,使用D3和geoJSON创建。

我在一个旋转的地球仪上工作,上面有295个城市标记。每300毫升,其中一个城市需要突出显示",意思是1)改变颜色和2)增加其半径(然后保持这种方式)。这个要点到目前为止显示了视觉效果:gist example

到目前为止采取的步骤:

1)我开始使用" circle" d3中的元素:通过更改类(以及使用CSS样式)和半径来轻松完成突出显示。但是:圆圈仍然可以看到"背面"全球......

2)解决地球背面没有圆圈的问题。问题,这篇文章向我展示了JSON路径会有所帮助:http://bl.ocks.org/PatrickStotz/1f19b3e4cb848100ffd7。 我现在用这些路径重写了代码,并且地球背面的标记有正确的剪裁,但现在我陷入动态访问每个城市的半径和风格......

关于更改半径的问题: 我明白使用 path.pointRadius()我可以改变城市标记的半径。但是,我想动态地(每300毫秒),并且每次只对标记的子选择。那就是我被困的地方......

关于改变风格的问题: 另外我想改变颜色,但为路径分配样式让我对如何访问JSON" Point"和"路径"元素......

显示我失败的CSS样式的代码段尝试:

              svg.append('g')
                .selectAll("path")
                    .data(data,function(d,i){ return d.id })    
                    .enter()
                    .append("path")
                    .datum(function(d) {
                            return {
                                type: "Point",
                                coordinates: [d.lon, d.lat],
                                class: "nohighlight" //MY ATTEMPT AT CHANGING CLASS... Not working...
                            }; })
                    .attr("class","city") //this class is assigned to the "correct" paths. Can I access them individually??
                    .attr("d", pathproj);

代码段显示了突出显示需要发生的时间循环:

 //Highlighting the cities one by one:
    var city_idx = 0; //data.id starts at 1        

    //Every 300 msec: highlight a new city:
    var city_play = setInterval(function() {

                      city_idx++;

                      var filtered = data.filter(function(d) {
                                          return d.id === city_idx;
                                        });  

                      // CHANGE CLASS? 
                      // CHANGE RADIUS?



                  //Stop when all cities are highlighted
                            if(city_idx>=geo_data.length){
                                            clearInterval(city_play) //terminates calls to update function within setInterval function.
                                    };
                  }, 300); // end timer city play setInterval

块构建器中的完整代码:

blockbuilder - globe and city markers

如果我能进一步澄清,请告诉我!

1 个答案:

答案 0 :(得分:0)

我们可以这样做: 属于城市的所有路径都给出一个类

.selectAll("path")
.data(data,function(d,i){ return d.id })    
.enter()
.append("path")
.classed("city", true) <--- so all cities point will have class city

接下来在计时器块中动态更改半径和类:

var city_play = setInterval(function() {
                        city_idx++;
                        // Control the radius of ALL circles!
                        pathproj.pointRadius(function(d,i) { 
                            //your biz logic 
                            if (i < city_idx){
                              return 4
                            } else 
                              return 2
                        });

                          // CHANGE CLASS? 
                          // CHANGE RADIUS?
                          //select all elements with class city
                            d3.selectAll(".city").attr("class", 
                            function(d, i){
                            if (i < city_idx){
                              return "city highlight"
                            } else 
                              return "city"
                          }).attr("d", pathproj)


                          var len =  d3.selectAll(".city").data().length;
                          console.log(city_idx, len)
                      //Stop when all cities are highlighted
                                if(city_idx>=len){
                                                clearInterval(city_play) //terminates calls to update function within setInterval function.
                                        };
                      }, 300);

工作代码here