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))
Но мне интересно, можно ли это сделать и в меньших строках кода?
Ответы
Ответ 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);})