Подтвердить что ты не робот

D3: Создайте непрерывную цветовую шкалу со многими строками/входами для диапазона и динамически изменяющимися значениями домена

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

Я знаю, что могу сделать это, предоставив значения домена 17 между min и max, но я не знаю, как это сделать динамически, если пользователь может изменить набор данных (и таким образом изменить расцветку тепловая карта)

В сущности, я хотел бы следовать, но я знаю, что он не работает.

var colorScale = d3.scale.linear()
   .range(["#6363FF", "#6373FF", "#63A3FF", "#63E3FF", "#63FFFB", "#63FFCB",
           "#63FF9B", "#63FF6B", "#7BFF63", "#BBFF63", "#DBFF63", "#FBFF63", 
           "#FFD363", "#FFB363", "#FF8363", "#FF7363", "#FF6364"])
   .domain([d3.min(dataset, function(d) {return d;}),
            d3.max(dataset, function(d) {return d;})]);

Может кто-нибудь, пожалуйста, скажите мне, что мне нужно внести в "домен", чтобы заставить его работать?

EDIT: Я нашел что-то, что делает то, что я хочу. Используя R, я вычислил 256 цветов между 17 из выше с функциями designer.colors и поместил это в диапазон. Это дает ощущение непрерывной цветовой гаммы

var colorScale = d3.scale.linear()
    .range(["#6363FF", "#6364FF", "#6364FF", "#6365FF",
            "... several other lines with color codes ..."
            "#FF6764", "#FF6564", "#FF6464", "#FF6364"])
    .domain(d3.range(1,257));

var quantize = d3.scale.quantile()
   .range(d3.range(1,257))
   .domain([d3.min(dataset, function(d) {return d;}), 
            d3.max(dataset, function(d) {return d;})]);

Теперь я могу использовать цвет таким образом

colorScale(quantize(dataset))

Но мне интересно, можно ли это сделать и в меньших строках кода?

4b9b3361

Ответ 1

Вы хотите разбить проблему. Сначала определите масштаб для вашей карты тепла, которая отображает 0-1 в ваши цвета. Затем определите второй (динамический) масштаб, который сопоставляет ваш набор данных с 0-1. Затем вы можете комбинировать шкалы для рисования фигур.

var colours = ["#6363FF", "#6373FF", "#63A3FF", "#63E3FF", "#63FFFB", "#63FFCB",
               "#63FF9B", "#63FF6B", "#7BFF63", "#BBFF63", "#DBFF63", "#FBFF63", 
               "#FFD363", "#FFB363", "#FF8363", "#FF7363", "#FF6364"];

var heatmapColour = d3.scale.linear()
  .domain(d3.range(0, 1, 1.0 / (colours.length - 1)))
  .range(colours);

// dynamic bit...
var c = d3.scale.linear().domain(d3.extent(dataset)).range([0,1]);

// use the heatmap to fill in a canvas or whatever you want to do...
canvas.append("svg:rect")
  .data(dataset)
  .enter()
  // snip...
  .style("fill", function(d) {
     return heatmapColour(c(d));

Кроме того, вы можете использовать функцию d3.extent для получения минимального и максимального набора данных за один раз.

Ответ 2

Используйте пороговые масштабы. Вот краткий пример:

coffee> d3 = require 'd3'
coffee> color = d3.scale.threshold().domain([5,30,100]).range(["red","orange","green"]);
coffee> color 6
'orange'
coffee> color 3
'red'
coffee> color 33
'green'

Ответ 3

Используйте Количественная шкала плюс Цвет пивовара

// pick any number [3-9]
var numColors = 9;

var heatmapColour = d3.scale.quantize()
  .domain(d3.extent(dataset))
  .range(colorbrewer.Reds[numColors]);

// use the heatmap to fill in a canvas or whatever you want to do...
canvas.append("svg:rect")
  .data(dataset)
  .enter()
  // snip...
  .style("fill", function(d) {return heatmapColour(d);})