2017-02-08 5 views
1

Я полностью новичок, и я строю карту с более чем 5000 муниципалитетами. В этом случае данные очень разбросаны, например, население находится в диапазоне от 10 000 до 11 500 000 человек. Поэтому в исследовании в Интернете я нашел пошаговое руководство для построения карты в JS D3. И я преуспею в этом. Но масштаб - моя проблема.D3 Javascript Map Scale Scattered Data

Шкала определяется в соответствии с приведенным ниже кодом, который принимает диапазон от min до max, разделенный на 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]); 
+0

Любая причина для тега R? – Gregor

+0

Тот же вопрос для тега CSS. –

ответ

0

По определению, Quantize шкалы являются линейными:

Quantize весы вариант линейных шкал с дискретным, а не непрерывного диапазона.

Однако, мы можем добиться того, что вы хотите, смешивая несколько шкал: d3.scale.pow() и d3.scale.threshold().

Во-первых, мы используем масштаб мощности для определения экспоненциального набора пределов. Предположим, что минимум равен 0, а максимум - десять миллионов. Так, 15 цветов (то, что вы используете сейчас), вы можете использовать это:

var min = 0, max = 10000000; 
 

 
var logScale = d3.scale.pow() 
 
\t .exponent(2) 
 
\t .domain([0,15]) 
 
\t .range([min,max]); 
 
\t 
 
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() 
 
\t .exponent(2) 
 
\t .domain([0,15]) 
 
\t .range([min,max]); 
 
\t 
 
var limits = d3.range(15).map(d=>logScale(d)); 
 

 
limits.shift(); 
 

 
var myScale = d3.scale.threshold() 
 
\t .domain(limits) 
 
\t .range("abcdefghijklmno".split("")); 
 
\t 
 
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 больше в этом предлагаемом решении.

+0

Отлично! Большое спасибо. – lfelipe