我有一个choropleth的工作示例,它从.csv文件中获取数据值并计算颜色范围。
一个地区可以采用四种可能的颜色,具体取决于人口。
对于我正在尝试开发的应用程序,我需要服务器从数据库加载数据。作为一个虚拟的例子,我做了一条返回json的路线。 json.features包含geojson信息和json.features.properties.value - 人口值。
这是我使用的功能。它正确绘制地图,工具提示上的人口值也是正确的。颜色域是[98,629725]。然而,只有一个区域采用非常暗的颜色,只有四个区域采用更亮的一个,而所有其他区域采用另一种颜色。如果你看一下我在顶部提供的链接 - 颜色的分布更均匀。但是在用这段代码制作的地图中 - 我有5000种人口和90000人口的地方颜色相同。
我现在卡住了,因为我真的没有看到问题出在哪里,而且我对如何调查它并不了解。您能否建议在这种情况下首先要检查的是什么?也许你已经看到这段代码出了问题?
function draw_map (dataroute) {
var w = 500;
var h = 800;
var projection = d3.geo.transverseMercator()
.rotate([-27,-65,0])
.translate([w/2, h/2])
.scale([3500])
var path = d3.geo.path()
.projection(projection);
var color = d3.scale.quantize()
.range(["#c6dbef","#6baed6","#2171b5","#084594"])
.domain([0, 100]);
var svg = d3.select("#map")
.attr("width", w)
.attr("height", h);
svg.append("rect")
.attr("class", "background")
.attr("width", w)
.attr("height", h);
var g = svg.append("g")
queue()
.defer(d3.json, dataroute)
.await(ready);
function ready(error, json) {
if (error) throw error;
color.domain([
d3.min(json.features, function(d) { return d.properties.value; }),
d3.max(json.features, function(d) { return d.properties.value; })
]);
console.log([
d3.min(json.features, function(d) { return d.properties.value; }),
d3.max(json.features, function(d) { return d.properties.value; })
]);
// returns [98, 629725]
g.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d",path)
.style("fill", colormap)
.style("stroke", "#08306b")
.attr("class", "feature")
.on("mouseover", function(d) {
d3.select(this)
.style("fill", "#08306b");
var coordinates = [0, 0];
coordinates = d3.mouse(this);
var target = d3.select("#tooltip")
.style("left", coordinates[0] + "px")
.style("top", coordinates[1]-80 + "px");
target.select("#name")
.text(d.properties.text);
target.select("#stat")
.text(json.statdata_name + ": " + d.properties.value);
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function(d){
// If this is active node, keep the color on mouseout
d3.select(this)
.style("fill", colormap(d));
d3.select("#tooltip").classed("hidden", true);
});
}
//Return color for path
var colormap = function(d) {
var value = d.properties.value;
//console.log(value);
// If value exists, map to color
if (value) {
return color(value);
//console.log(color(value));
// if not, set color red
} else {
console.log("Undefined: " + d.properties.text + " " + value)
return "red";
}
}
}
在使用.csv文件的原始版本中,代码如下:
//Width and height
var w = 800;
var h = 800;
active = d3.select(null);
previous = d3.select(null);
var projection = d3.geo.transverseMercator()
.rotate([-27,-65,0])
.translate([w/2, h/2])
.scale([3500])
var path = d3.geo.path()
.projection(projection);
var color = d3.scale.quantize()
.range(["#c6dbef","#6baed6","#2171b5","#084594"])
.domain([0, 100]);
var svg = d3.select("#map")
.attr("width", w)
.attr("height", h);
svg.append("rect")
.attr("class", "background")
.attr("width", w)
.attr("height", h)
.on("click", reset);
var g = svg.append("g")
// Click to zoom
function clicked(d) {
// If this node is zoomed, unzoom
if (active.node() === this) {
d3.select(this).style("fill",colormap)
return reset();
} else {
// Otherwise recolor previous one, to avoid contamination
previous.style("fill",colormap)
}
active.classed("active", false);
active = d3.select(this).classed("active", true);
// store previous to uncolor it after clicking new one
previous = d3.select(this)
d3.select(this).style("fill","#08306b")
var bounds = path.bounds(d),
dx = bounds[1][0] - bounds[0][0],
dy = bounds[1][1] - bounds[0][1],
x = (bounds[0][0] + bounds[1][0]) / 2,
y = (bounds[0][1] + bounds[1][1]) / 2,
scale = .3 / Math.max(dx / w, dy / h),
translate = [w / 2 - scale * x, h / 2 - scale * y];
g.transition()
.duration(750)
.style("stroke-width", 1.5 / scale + "px")
.attr("transform", "translate(" + translate + ")scale(" + scale + ")");
}
function reset() {
active.classed("active", false);
active = d3.select(null);
g.transition()
.duration(750)
.style("stroke-width", "1px")
.attr("transform", "");
}
queue()
.defer(d3.json, "/static/finland.geojson")
.defer(d3.csv, "/static/kuntavakiluku.csv")
.await(ready);
var finland_geojson_data
var csv_data
function ready(error, json, data) {
if (error) throw error;
finland_geojson_data = json;
csv_data = data;
color.domain([
d3.min(data, function(d) { return d.Vakiluku; }),
d3.max(data, function(d) { return d.Vakiluku; })
]);
console.log(data.length);
for (var i = 0; i < data.length; i++) {
var dataState = data[i].Kunta;
var dataValue = parseInt(data[i].Vakiluku);
//Find the corresponding state inside the GeoJSON
for (var j = 0; j < json.features.length; j++) {
var jsonState = json.features[j].properties.text;
//console.log(jsonState)
if (dataState == jsonState ) {
//Copy the data value into the JSON
json.features[j].properties.value = dataValue;
//Stop looking through the JSON
break;
}
}
}
g.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d",path)
.style("fill", colormap)
.style("stroke", "#08306b")
.attr("class", "feature")
.on("mouseover", function(d) {
d3.select(this)
.style("fill", "#08306b");
var coordinates = [0, 0];
coordinates = d3.mouse(this);
var target = d3.select("#tooltip")
.style("left", coordinates[0] + "px")
.style("top", coordinates[1]-80 + "px");
target.select("#kunta")
.text(d.properties.text);
target.select("#vakiluku")
.text("Väestö: " + d.properties.value);
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function(d){
// If this is active node, keep the color on mouseout
if (active.node() === this) {
d3.select(this).style("fill","#08306b")
} else {
d3.select(this)
.style("fill", colormap(d));
}
d3.select("#tooltip").classed("hidden", true);
})
.on("click",clicked);
}
//Return color for path
var colormap = function(d) {
var value = d.properties.value;
// If value exists, map to color
if (value) {
return color(value);
// if not, set color red
} else {
console.log("Undefined: " + d.properties.text + " " + value)
return "red";
}
}
答案 0 :(得分:1)
量化比例是具有谨慎范围的线性比例(正如您在注释中提供的@seb链接中所见)。
所以在你的情况下,如果你提供4种颜色,那么比喻说,域将分为4个部分(你的比例是一个“地图”)。
因此,域的第一个季度将是第一个颜色等。
在你的探索中,域名是[98,629725],所以第一种颜色将从98开始,结束于(629725-98)/ 4 + 98 = 157'504.75
在代码中:
var scale = d3.scale.quantize()
.range(["#c6dbef", "#6baed6", "#2171b5", "#084594"])
.domain([98, 629725]);
所以你可以测试一下,例如here(检查控制台输出!)
你可以看到157504第二次产生col1,157505。 因此,毫不奇怪,5000和90000属于同一“部分”。