В Javascript / D3, как сопоставить цветовую шкалу 5 цветов (шестнадцатеричный формат) с 17 цветами - PullRequest
2 голосов
/ 08 марта 2019

Допустим, у меня есть массив 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', что по сути является цветовой шкалой, которую я хочу.

Есть ли способчтобы сделать это исключительно с использованием шестнадцатеричных шестнадцатеричных значений?В настоящее время я использую ужасающий подход, который преобразует шестнадцатеричные значения в значения 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 Ответ

2 голосов
/ 08 марта 2019

Одним из вариантов может быть использование d3-интерполятора:

d3.interpolateRgbBasis (colors) <>

Возвращает равномерный нерациональный 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>
...