Как инвертировать цветовые палитры d3 d3-шкала цветности d3.interpolateViridis - PullRequest
2 голосов
/ 11 мая 2019

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

Это цветовые схемы, которые я использую https://github.com/d3/d3-scale-chromatic

d3.interpolateViridis

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

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

require()('@observablehq/flare').then(data => {
const root = partition(data);
const color = 
d3.scaleOrdinal().range(d3.quantize(d3.interpolateViridis, 
data.children.length +1));

console.log(data.children.length)
root.each(d => d.current = d);

const svg = d3.select('#partitionSVG')
        .style("width", "50%")
        .style("height", "80%")
        .style("font", "10px sans-serif")

const g = svg.append("g")
        .attr('transform', 'translate(' + width/2 +  ',' + height/2 +')');

const path = g.append("g")
        .selectAll("path")
        .data(root.descendants().slice(1))
        .join("path")
        .attr("fill", d => {
            while (d.depth > 1)
                d = d.parent;
            return color(d.data.name);
        })
        .attr("fill-opacity", d => arcVisible(d.current) ? (d.children ? 0.6 : 0.4) : 0)
        .attr("d", d => arc(d.current));

1 Ответ

2 голосов
/ 11 мая 2019

Интерполятор просто получает число, идущее от 0 до 1, чтобы вернуть цвета. Например:

.style("background-color", function(_, i, n) {
    return d3.interpolateViridis(i / n.length)
})

const body = d3.select("body");
const data = d3.range(100);
const divs = body.selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .style("background-color", function(_, i, n) {
    return d3.interpolateViridis(i / n.length)
  })
div {
  width: 5px;
  height: 100px;
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Следовательно, единственное, что вам нужно, это передать число в противоположном диапазоне. Для моего примера выше это будет:

.style("background-color", function(_, i, n) {
    return d3.interpolateViridis((n.length - i)/n.length)
})

const body = d3.select("body");
const data = d3.range(100);
const divs = body.selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .style("background-color", function(_, i, n) {
    return d3.interpolateViridis((n.length - i)/n.length)
  })
div {
  width: 5px;
  height: 100px;
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Однако ваш случай еще проще: вы используете d3.quantize для генерации массива по порядковому масштабу. Как это:

const values = d3.quantize(d3.interpolateViridis, data.length);

const data = d3.range(100);
const values = d3.quantize(d3.interpolateViridis, data.length);
console.log(values)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Следовательно, все, что вам нужно, это обратить этот массив:

const values = d3.quantize(d3.interpolateViridis, data.length).reverse();

А вот и результат:

const body = d3.select("body");
const data = d3.range(100);
const values = d3.quantize(d3.interpolateViridis,
  data.length).reverse();
const divs = body.selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .style("background-color", function(_, i) {
    return values[i];
  })
div {
  width: 5px;
  height: 100px;
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
...