我正在尝试在荷兰12个省的D3中制作一张地图,并根据外部JSON文件中的一些模拟数据为它们进行着色:
[{"_id":"Groningen","value":52},
{"_id":"Friesland","value":18},
{"_id":"Drenthe","value":87},
{"_id":"Overijssel","value":93},
{"_id":"Flevoland","value":60},
{"_id":"Gelderland","value":7},
{"_id":"Utrecht","value":26},
{"_id":"Noord-Holland","value":52},
{"_id":"Zuid-Holland","value":72},
{"_id":"Zeeland","value":41},
{"_id":"Noord-Brabant","value":78},
{"_id":"Limburg","value":19}]
这是我到目前为止的代码。它成功地生成了它们的映射,但现在,现在每个省都会根据该省名称的长度(愚蠢)为每个省涂上颜色:
var width = 960,
height = 500,
centered;
// Define color scale
var color = d3.scaleLinear()
.domain([1, 20])
.clamp(true)
.range(['steelblue', "yellow"]);
var projection = d3.geoMercator()
.scale(5500)
.center([6, 52.1])
.translate([width / 2, height / 2]);
var path = d3.geoPath()
.projection(projection);
// Set svg width & height
var svg = d3.select('svg')
.attr('width', width)
.attr('height', height);
// Add background
svg.append('rect')
.attr('class', 'background')
.attr('width', width)
.attr('height', height)
var g = svg.append('g');
var effectLayer = g.append('g')
.classed('effect-layer', true);
var mapLayer = g.append('g')
.classed('map-layer', true);
// Load map data
d3.json('data/provincesNL2.json', function(error, mapData) {
var features = mapData.features;
// Draw each province as a path
mapLayer.selectAll('path')
.data(features)
.enter().append('path')
.attr('d', path)
.attr('vector-effect', 'non-scaling-stroke')
.attr('fill', fillFn)
});
// Get province name
function nameFn(d){
return d && d.properties ? d.properties.PROVINCIE : null;
}
// Get province name length
function nameLength(d){
var n = nameFn(d);
return n ? n.length : 0;
}
// Get province color
function fillFn(d){
return color(nameLength(d));
};
我只是不知道如何实现JSON文件的值以表示每个省的颜色沿着颜色尺度。我不是在JavaScript上经验丰富,我认为这不太困难,但我只是无法弄清楚。非常感谢您的帮助!
您应该使用数据对象的最小值和最大值为颜色刻度指定域。
var colour = d3.scaleLinear()
.domain([
d3.min(dataObject, function(d) { return d.value }),
d3.max(dataObject, function(d) { return d.value })
])
.clamp(true)
.range(['steelblue', "yellow"]);
在fill
属性的回调函数中,您应该找到(您可以通过各种方式,取决于数据结构)当前省的值并将其传递给colour
功能。
.attr("fill", function(d, i) {
var value = // here you should get for current data item ;
return colour(value); // use this value for colour scale
})
检查荷兰地图的此示例(我对您的数据进行了一些修改,以简化示例和硬编码的topojson对象)。
有几种方法可以做到这一点,一种是使用d3.map。这使您可以使用map.get(key)
查找地图中的值。
一般设置看起来像:
var lookup = d3.map(array, function(d) { return d.key; })
其中 array
是您的数据数组,而 key
是数据阵列中每个项目的某些属性,可以用作标识符。要查找值,您可以使用:
lookup.get(value)
其中值是识别值/键 - 这将返回数据数组中的整个对象。对于您的数据,这可能看起来像:
var lookup = d3.map(data, function(d) { return d._id; });
lookup.get("Drenthe") // {"_id":"Drenthe","value":87}
要为地图上色,您可以从元素的基准中获取识别值/键。这是用于为数据上色的d3.map的工作示例:
var color = d3.scaleLinear()
.domain([0,100])
.range(["orange", "steelblue"])
var data = [{"_id":"Groningen","value":52},
{"_id":"Friesland","value":18},
{"_id":"Drenthe","value":87},
{"_id":"Overijssel","value":93},
{"_id":"Flevoland","value":60},
{"_id":"Gelderland","value":7},
{"_id":"Utrecht","value":26},
{"_id":"Noord-Holland","value":52},
{"_id":"Zuid-Holland","value":72},
{"_id":"Zeeland","value":41},
{"_id":"Noord-Brabant","value":78},
{"_id":"Limburg","value":19}];
var lookup = d3.map(data, function(d) { return d._id; });
// test a value:
console.log(lookup.get("Drenthe").value);
var svg = d3.select("body")
.append("svg")
.attr("width",400)
.attr("height",100);
var squares = svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("fill",function(d) { return color(lookup.get(d._id).value) })
.attr("x", function(d,i) { return i * 20; })
.attr("y", 40)
.attr("width",16)
.attr("height",16);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>