基于外部数据的D3地图中的颜色区域



我正在尝试在荷兰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>

最新更新