【问题标题】:Conditionally fill/color of voronoi segments有条件地填充/颜色的voronoi段
【发布时间】:2017-04-08 21:14:36
【问题描述】:

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

即使我将 ,它仍然返回绿色。

此处的示例: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)
});

【问题讨论】:

    标签: d3.js voronoi


    【解决方案1】:

    这是正在发生的事情:您的 row 函数正在修改 rows 数组的对象。在您使用填充多边形的函数时,已经没有 d.lon 了,并且由于 d.lonundefined,因此三元运算符被评估为 false,这给了您“绿色”。

    检查一下:

    var d = {};
    
    console.log(d.lon < 0 ? "red" : "green");

    这也解释了你所说的:

    即使我将 ,它仍然返回绿色。

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

    话虽如此,您必须保留原来的 rows 结构,并在对象中使用 lon 属性。

    一个解决方案是摆脱行功能...

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

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

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

    现在您有两个数组:rows,您可以像现在一样使用它来创建多边形,以及data,其中包含lon 值。

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

    【讨论】:

    • 谢谢 Gerado :) 我已经更新了我的示例代码,并将示例链接到您的建议。您会看到我可以成功记录数据和行数组。我正在尝试实施您将所有内容保存在一个数组中的第二个建议,我无法遍历行数据并在我的条件 .style 填充语句中访问 .lon 值。
    • 正如我所说,帮助您解决第二个建议的唯一方法是提供一个工作代码(将该代码放在 Plunker/Fiddle 的链接中?CodePen/Whatever,以便我们修改它)。关于第一个建议,你做错了。试试这个:.style("fill", function(d,i) { return data[i].lon &lt; 0 ? "red" : "green";} ).
    • 非常感谢 :D 这正是我想要做的。标记为正确。
    • @GerardoFurtado 嗨,谢谢你们的这篇文章。我有一个非常相似的问题,一个 D3 V4 示例直接受此启发:bl.ocks.org/mbostock/7608400。我试图通过在数组中添加第三个参数来更改其中一个 typeAirport 函数(就像您对行所做的那样),但无法获取数组的内容......我应该写一个新问题吗?在此先感谢,祝您有美好的一天
    • @Raphadasilva 是的,请发布一个新问题。
    猜你喜欢
    • 2014-10-27
    • 2015-04-04
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多