有条件 fill/color 的 voronoi 段
Conditionally fill/color of voronoi segments
我正在尝试根据 'd.lon' 值有条件地为这些 voronoi 片段着色。如果它是正的,我希望它是绿色的,如果它是负的,我希望它是红色的。但是目前它返回的每个段都是绿色的。
即使我将 < 操作数换成 >,它仍然 returns 绿色。
现场示例: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.lon
是 undefined
三元运算符被评估为 false
,这给你"green".
检查这个:
var d = {};
console.log(d.lon < 0 ? "red" : "green");
这也解释了你所说的:
Even if I swap my < operand to >, it still returns 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 表示 "it's not working!")结束。
我正在尝试根据 'd.lon' 值有条件地为这些 voronoi 片段着色。如果它是正的,我希望它是绿色的,如果它是负的,我希望它是红色的。但是目前它返回的每个段都是绿色的。
即使我将 < 操作数换成 >,它仍然 returns 绿色。
现场示例: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.lon
是 undefined
三元运算符被评估为 false
,这给你"green".
检查这个:
var d = {};
console.log(d.lon < 0 ? "red" : "green");
这也解释了你所说的:
Even if I swap my < operand to >, it still returns 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 表示 "it's not working!")结束。