#javascript #d3.js #colors
#javascript #d3.js #Цвет
Вопрос:
Допустим, у меня есть массив javascript ['#1147FF', '#86D8FF', '#FFEF67', '#FF7D11', '#F30000']
. Если я перейду на этот веб-сайт с цветовыми шкалами здесь и перейду с 5 шагов на 17 шагов, он выдает '#1147ff','#4f6cff','#6990ff','#7bb4ff','#86d8ff','#b4dddb','#d3e3b7','#ebe991','#ffef67','#ffd453','#ffb83f','#ff9b2a','#ff7d11','#fd6a0b','#fa5405','#f73902','#f30000'
, по сути, ту цветовую шкалу, которую я хочу.
Есть ли способ сделать это, используя исключительно шестнадцатеричные значения 6? В настоящее время я использую ужасный подход, который преобразует шестнадцатеричные значения в значения rgb, а затем зацикливает значения rgb (ниже приведен грубый пример того, что я имею в виду, игнорировать green
в именах переменных):
green0pct = { r: 17, g: 71, b: 255 };
green7p5pct = { r: 134, g: 216, b: 255 };
green15pct = { r: 252, g: 233, b: 70 };
green22p5pct = { r: 255, g: 125, b: 17 };
green30pct = { r: 243, g: 0, b: 0 };
for (let j = 0; j <= 30; j ) {
if (j % 2 === 0) {
if (j < 7.5) {
newR = green0pct.r - (j * (green0pct.r - green7p5pct.r) / 7.5);//
newG = green0pct.g - (j * (green0pct.g - green7p5pct.g) / 7.5);
newB = green0pct.b - (j * (green0pct.b - green7p5pct.b) / 7.5);
} else if (j < 15) {
newR = green7p5pct.r - ((j - 7.5) * (green7p5pct.r - green15pct.r) / 7.5);
newG = green7p5pct.g - ((j - 7.5) * (green7p5pct.g - green15pct.g) / 7.5);
newB = green7p5pct.b - ((j - 7.5) * (green7p5pct.b - green15pct.b) / 7.5);
} else if (j < 22.5) {
newR = green15pct.r - ((j - 15) * (green15pct.r - green22p5pct.r) / 7.5);
newG = green15pct.g - ((j - 15) * (green15pct.g - green22p5pct.g) / 7.5);
newB = green15pct.b - ((j - 15) * (green15pct.b - green22p5pct.b) / 7.5);
} else {
newR = green22p5pct.r - ((j - 22.5) * (green22p5pct.r - green30pct.r) / 7.5);
newG = green22p5pct.g - ((j - 22.5) * (green22p5pct.g - green30pct.g) / 7.5);
newB = green22p5pct.b - ((j - 22.5) * (green22p5pct.b - green30pct.b) / 7.5);
}
displayPct = playerOrTeam === 'Team' ? (j - 15) / 2 : j - 15;
greenScale.push({ text: `${displayPct}%`, col: `rgb(${newR},${newG},${newB})` });
}}
Ответ №1:
Одним из вариантов может быть использование d3-интерполятора:
d3.interpolateRgbBasis(цвета) <>
Возвращает единообразный нерациональный интерполятор B-сплайнов через указанный массив цветов, которые преобразуются в цветовое пространство RGB. Неявные контрольные точки генерируются таким образом, что интерполятор возвращает цвета [0] при t = 0 и цвета [colors.length — 1] при t = 1. (источник)
На самом базовом уровне вы могли бы создать новый список из n цветов на основе массива цветов и интерполятора с:
// Starting colors:
var colors = ['#1147FF', '#86D8FF', '#FFEF67', '#FF7D11', '#F30000'];
// Create an interpolator:
var interpolate = d3.interpolateRgbBasis(colors);
// Make 17 new colors:
var n = 17;
var newColors = d3.range(n).map(function(d) {
return interpolate(d/(n-1)); // d/(n-1) will range from 0 through 1
})
Вот демонстрация:
var colors = ['#1147FF', '#86D8FF', '#FFEF67', '#FF7D11', '#F30000'];
var interpolate = d3.interpolateRgbBasis(colors);
var n = 17;
var newColors = d3.range(n).map(function(d) {
return interpolate(d/(n-1));
})
console.log(newColors);
d3.select("svg")
.selectAll("rect")
.data(newColors)
.enter()
.append("rect")
.attr("fill", function(d) { return d; })
.attr("width", 10)
.attr("height",10)
.attr("x", function(d,i) {
return i*12;
})
.attr("y", 20);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>
Комментарии:
1. это потрясающе. Я также понял, что могу просто создать линейную шкалу с domain [1, 5, 9, 13, 17] и диапазон
['#1147FF', '#86D8FF', '#FFEF67', '#FF7D11', '#F30000']
, и использовать это для генерации любых цветов, которые мне нужны. Также нравится этот ответ, хотя