有条件地填充/着色voronoi段 [英] Conditionally fill/color of voronoi segments

查看:98
本文介绍了有条件地填充/着色voronoi段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据'd.lon'值为这些voronoi段着色.如果为正,我希望它为绿色,如果为负,我希望它为红色.但是目前,它会将每个段都返回为绿色.

I'm trying to conditionally color these voronoi segments based on the 'd.lon' value. If it's positive, I want it to be green, if it's negative I want it to be red. However at the moment it's returning every segment as green.

即使我换了<操作数>,它仍然返回绿色.

Even if I swap my < operand to >, it still returns green.

此处为实时示例: https://allaffects.com/world/

谢谢:)

JS

// Stating variables
var margin = {top: 20, right: 40, bottom: 30, left: 45},
width = parseInt(window.innerWidth) - margin.left - margin.right; 
height = (width * .5) - 10;

var projection = d3.geo.mercator()
.center([0, 5 ])
.scale(200)
.rotate([0,0]);

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

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

var voronoi = d3.geom.voronoi()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.clipExtent([[0, 0], [width, height]]);

var g = svg.append("g");

// Map data
d3.json("/world-110m2.json", function(error, topology) {

// Cities data
d3.csv("/cities.csv", function(error, data) {
g.selectAll("circle")
   .data(data)
   .enter()
   .append("a")
              .attr("xlink:href", function(d) {
                  return "https://www.google.com/search?q="+d.city;}
              )
   .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", 5)
   .style("fill", "red");

});

g.selectAll("path")
  .data(topojson.object(topology, topology.objects.countries)
      .geometries)
.enter()
  .append("path")
  .attr("d", path)
});

var voronoi = d3.geom.voronoi()
        .clipExtent([[0, 0], [width, height]]);

  d3.csv("/cities.csv", function(d) {
    return [projection([+d.lon, +d.lat])[0], projection([+d.lon, +d.lat]) [1]];
  }, function(error, rows) {
    vertices = rows;
      console.log(vertices);
      drawV(vertices);
    }
  );

      function polygon(d) {
          return "M" + d.join("L") + "Z";
      }

      function drawV(d) {
          svg.append("g")
            .selectAll("path")
            .data(voronoi(d), polygon)
           .enter().append("path")
            .attr("class", "test")
            .attr("d", polygon)

// This is the line I'm trying to get to conditionally fill the segment.
            .style("fill", function(d) { return (d.lon < 0 ? "red" : "green"     );} )
            .style('opacity', .7)
            .style('stroke', "pink")
            .style("stroke-width", 3);
      }

JS编辑

d3.csv("/static/cities.csv", function(data) {
    var rows = [];
    data.forEach(function(d){
        //Added third item into my array to test against for color
        rows.push([projection([+d.lon, +d.lat])[0], projection([+d.lon, +d.lat]) [1], [+d.lon]])
    });

    console.log(rows); // data for polygons and lon value
    console.log(data); // data containing raw csv info (both successfully log)

    svg.append("g")
    .selectAll("path")
    .data(voronoi(rows), polygon)
    .enter().append("path")
    .attr("d", polygon)
  //Trying to access the third item in array for each polygon which contains the lon value to test
    .style("fill", function(data) { return (rows[2] < 0 ? "red" : "green" );} ) 
    .style('opacity', .7)
    .style('stroke', "pink")
    .style("stroke-width", 3)
});

推荐答案

正在发生这种情况:您的行函数正在修改rows数组的对象.到了用于填充多边形的功能时,不再有d.lon,并且由于d.lonundefined,因此三元运算符的求值结果为false,这使您获得绿色".

This is what's happening: your row function is modifying the objects of rows array. At the time you get to the function for filling the polygons there is no d.lon anymore, and since d.lon is undefined the ternary operator is evaluated to false, which gives you "green".

检查:

var d = {};

console.log(d.lon < 0 ? "red" : "green");

其中也解释了你说的话:

Which also explains what you said:

即使我换了<操作数>,它仍然返回绿色.

Even if I swap my < operand to >, it still returns green.

因为d.lon是未定义的,所以使用什么运算符都没有关系.

Because d.lon is undefined, it doesn't matter what operator you use.

话虽如此,您必须保留原始的rows结构,并在对象中保留lon属性.

That being said, you have to keep your original rows structure, with the lon property in the objects.

一种解决方案是摆脱行函数...

A solution is getting rid of the row function...

d3.csv("cities.csv", function(data){
    //the rest of the code
})

...并在回调中创建您的rows数组:

... and creating your rows array inside the callback:

var rows = [];
data.forEach(function(d){
    rows.push([projection([+d.lon, +d.lat])[0], projection([+d.lon, +d.lat]) [1]])
});

现在有两个数组:rowsdata,其中rows可用于创建多边形,而data包含lon值.

Now you have two arrays: rows, which you can use to create the polygons just as you're using now, and data, which contains the lon values.

或者,您可以将所有内容保留在一个数组中(只需更改行函数即可),这是最佳解决方案,因为这样可以更轻松地在多边形的enter选择中获取d.lon值.但是,如果不使用您的实际代码对其进行测试,就很难提供有效的答案(通常以OP提示它不起作用!" 结束).

Alternatively, you can keep everything in just one array (just changing your row function), which is the best solution because it would make easier to get the d.lon values inside the enter selection for the polygons. However, it's hard providing a working answer without testing it with your actual code (it normally ends up with the OP saying "it's not working!").

这篇关于有条件地填充/着色voronoi段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆