如何使用d3生成尽可能多的颜色?

use*_*036 16 javascript svg d3.js

我正在使用d3.js构建一个饼图,并可视化一个大数据集.图表上可以显示超过137个项目.我只有10种颜色使用此功能.

d3.scale.category10().range()
Run Code Online (Sandbox Code Playgroud)

通过探索其他选项:https: //github.com/mbostock/d3/wiki/Ordinal-Scales

d3.scale.category20().range()

var chart = nv.models.pieChart()
    .x(function(d) {
        return d.key
    })
    .y(function(d) {
        return d.y
    })
    .color(d3.scale.category10().range())
    .width(width)
    .height(height);
Run Code Online (Sandbox Code Playgroud)

如何使用d3生成尽可能多的颜色?

jnn*_*nnn 23

我有同样的问题,所以我写了一个小工具来生成很多感性上不同的颜色:类别颜色生成器.

此工具生成颜色列表.然后,您可以使用该列表:

color = d3.scale.ordinal()
    .domain(YOUR_DATA_CATEGORIES)
    .range(["#30c514", "#9321ff", ...]);
Run Code Online (Sandbox Code Playgroud)

如果两个亮度不够,还有一个通用版本.

以下是一些预生成的示例颜色集.


Dav*_*mon 14

当你使用很多类别时,不可能使用感知上不同的颜色.好消息是,在饼图中,每个旁边只有两种颜色,然后所有颜色都不需要不同,只需要相邻.

我要做的是生成两种不同的色标,两者都使用d3.interpolateHcl().HCL和Lab是更好的颜色模型,可以生成自然的色彩渐变,也是category20()用于生成感知上不同颜色的颜色.

var colorScales =[
  d3.scale.linear()
    .interpolate(d3.interpolateHcl) 
    .range(["#9AF768", "#F27A4D"]),
  d3.scale.linear()
    //.domain([0,1])
    .interpolate(d3.interpolateHcl) 
    .range(["#112231","#3C769D"])
];
Run Code Online (Sandbox Code Playgroud)

将您想要的颜色放入range([...])并应用这些功能添加一些随机性.我正在使用i数据索引在两种颜色方案之间交替.

.color(function(d,i) {
  return colorScales[i%2]       
          (Math.random());
})
Run Code Online (Sandbox Code Playgroud)

更多关于色彩理论和色彩模型:

和一个很好的HCL色彩空间colorpicker:

UPDATE

较新版本的d3提供了更多颜色方案和内插器以及更复杂的模型.有一些类型的方案,我认为这个用例最有用的是顺序多色调插值器.

我开发了一个交互式小部件来探索这些比例和插值器,同时改变颜色的数量.见下文.

注意,这些方案也难以提供几种感知上不同的颜色.

const categorical = [{
    "name": "interpolateViridis"  },
  { "name": "interpolateInferno"  },
  { "name": "interpolateMagma"    },
  { "name": "interpolatePlasma"   },
  { "name": "interpolateWarm"     },
  { "name": "interpolateCool"     },
  { "name": "interpolateCubehelixDefault"  },
  { "name": "interpolateRainbow"  },
  { "name": "interpolateSinebow"  }
]

const width = 600,
  height = 80;

const svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")


const unit = (s) => width / s.n;
const state = {
  n: 12,
  colorScale: d3.scaleSequential(d3[categorical[8].name])
};

const update = () => {

  bars.data(d3.range(0, 1, 1 / state.n))
    .enter().append("rect")
    .attr("class", "bars")
    .attr("y", 0)
    .attr("height", height)
    .attr("width", unit(state))
    .attr("x", (d, i) => i * unit(state))
    .style("fill", state.colorScale)
    .merge(bars);
    
  bars.exit().remove();

}

const bars = svg.selectAll(".bars");

update()

const sequentialButtons = d3.select(".categoricalButtons")
  .selectAll("button")
  .data(categorical)
  .enter().append("button")
  .text(d => d.name)
  .on("click",  (buttonValue) =>{ 
    state.colorScale = d3.scaleSequential(d3[buttonValue.name]);
    update();
    });

const itemsInput = d3.select('#items')
  .on('change',(d,i,arr)=>{
    state.n = arr[i].value;
    update();
    });
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<div class="categoricalButtons">Color Scales: </div>
<div><input id="items" type="number" value="12"></div>
Run Code Online (Sandbox Code Playgroud)


id.*_*.ot 8

我们可以使用自定义颜色,例如您可以创建自己的颜色范围:.range(["#fff","#000","#333"]);.这是一个类似的StackOverflow线程:https://stackoverflow.com/a/13013162/1848540