D3 Javascript Map Scale Scattered Data

时间:2017-02-08 18:17:33

标签: javascript d3.js svg

我完全是初学者,我正在制作一个超过5,000个城市的地图。在这种情况下,数据非常分散,例如人口在10,000到11,500,000之间。因此,在互联网研究中,我找到了一个在JS D3中构建地图的演练。我按照这些步骤成功了。但规模是我的问题。

根据下面的代码定义刻度,该刻度采用最小到最大范围除以15个相等的线性极限。问题是这需要的第一个范围是0到766,000,涉及95%以上的城市。所以我有一张单色地图。由于分散的数据,我认为对数标度更适合于显示更真实的数据扩散。有人可以帮我弄这个吗?

var quantize = d3.scale.quantize()
  .range(d3.range(15).map(function(i) { return 'q' + i + '-15'; }));
var formatNumber = d3.format(",");
var legendX = d3.scale.linear();

var legendXAxis = d3.svg.axis()
.scale(legendX)
.orient("bottom")
.tickSize(4)
.tickFormat(function(d) {
    return formatNumber(d);
});

var legendSvg = d3.select('#legend').append('svg')
.attr('width', '100%')
.attr('height', '55');

var g = legendSvg.append('g')
    .attr("class", "legend-key YlGnBu")
    .attr("transform", "translate(" + 25 + "," + 25 + ")");

g.selectAll("rect")
    .data(quantize.range().map(function(d) {
      return quantize.invertExtent(d);
    }))
.enter().append("rect");

  var legendWidth = d3.select('#map').node().getBoundingClientRect().width - 50;

  var legendDomain = quantize.range().map(function(d) {
    var r = quantize.invertExtent(d);
    return r[1];
  legendDomain.unshift(quantize.domain()[0]);

1 个答案:

答案 0 :(得分:0)

根据定义,量化比例是线性的:

  

量化量表是线性量表的变体,具有离散而非连续的范围。

但是,我们可以通过混合一些比例来实现您想要的效果:d3.scale.pow()d3.scale.threshold()

首先,我们使用功率标度来定义一组指数限制。假设最小值为0,最大值为1000万。因此,对于15种颜色(您现在使用的颜色),您可以使用:

var min = 0, max = 10000000;

var logScale = d3.scale.pow()
	.exponent(2)
	.domain([0,15])
	.range([min,max]);
	
var limits = d3.range(15).map(d=>logScale(d));

console.log(limits);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

现在,我们在阈值范围内使用此limits数组:

  

阈值比例类似于量化比例,除了它们允许您将域的任意子集映射到范围内的离散值。 (强调我的)

这是比例:

var myScale = d3.scale.threshold()
    .domain(limits)
    .range(your colors here);

这是一个演示(我用的是颜色字母):

var min = 0, max = 10000000;

var logScale = d3.scale.pow()
	.exponent(2)
	.domain([0,15])
	.range([min,max]);
	
var limits = d3.range(15).map(d=>logScale(d));

limits.shift();

var myScale = d3.scale.threshold()
	.domain(limits)
	.range("abcdefghijklmno".split(""));
	
console.log(myScale(90))
console.log(myScale(50000))
console.log(myScale(800000))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

PS :请注意,您必须重构大部分代码,因为您在此建议的解决方案中不再使用quantize