d3 квантиль масштабной силы первый квантиль

Я строю тепловую карту с цветовым градиентом от зеленого к красному. Я хочу, чтобы ячейки со значением 0 были зелеными, а значения больше или равные 1 — других цветов. Я строю шкалу следующим образом:

var colors = [
  '#27C24C',
  '#7DB22E',
  '#D4A10F',
  '#F97C20',
  '#F35F40',
  '#FF0000'
];

var colorScale = d3.scale.quantile()
  .domain([0, d3.max(data, function (d) { return d.value; })])
  .range(colors);

Но это возвращает мне следующие квантили:

[239.16666666666677, 478.3333333333332, 717.5, 956.6666666666664, 1195.8333333333335]

Поэтому у меня есть следующая тепловая карта: Неправильная тепловая карта
Но я бы хотел, чтобы заостренная ячейка была второго оттенка зеленого, так как ее значение строго больше 0.


person Scentle5S    schedule 17.02.2016    source источник
comment
Можете ли вы поделиться своим набором данных? или лучше, если вы предоставите скрипку кода   -  person murli2308    schedule 17.02.2016


Ответы (2)


В этом случае нельзя использовать только квантильную шкалу. Напишите пользовательскую функцию масштабирования для отдельной обработки нулевого значения.

var colors = [
  // '#27C24C', this value must not be included in the internal range
  '#7DB22E',
  '#D4A10F',
  '#F97C20',
  '#F35F40',
  '#FF0000'
];

var colorScaleInternal = d3.scale.quantile()
  .domain([0, d3.max(data, function (d) { return d.value; })])
  .range(colors);

var colorScale = function(value) {
  return !!value ? colorScaleInternal(value) : '#27C24C';
};
person Hieu Le    schedule 17.02.2016
comment
Что означает !!? - person Scentle5S; 17.02.2016
comment
Два отрицательных оператора преобразуют тип значения в логический. Если значение равно нулю, !!value равно false. В противном случае это true. - person Hieu Le; 18.02.2016

Хотя мне не удалось найти поддержку этой функции в D3, я смог обойти ее, изменив массив диапазонов, отправляемый в d3. Идея состоит в том, чтобы проверить с помощью D3, повторяются ли квартили, и если да, то сохранить один и тот же цвет для всех них:

var scale = d3.scale.quantile().domain(domain).range(range);

var quantiles = scale.quantiles();
quantiles.unshift(d3.min(domain));

// Now that you have the quantiles, you can see if some of them are holding the same value, 
// and it that case set the minimum value to all of them.
var modifiedRange = [range[0]];
for (var i = 1; i < range.length; i++) {
    if (quantiles[i] === quantiles[i - 1]) {
        modifiedRange.push(modifiedRange[i - 1]);
    } else {
        modifiedRange.push(range[i]);
    }
}

// set the new scale
scale.range(modifiedRange);
person roee    schedule 21.11.2016