学习传送门:Sequential scales | D3 by Observable
是一种在D3.js中用于将一个范围内的连续值射到另一个范围内的连续值的方法。该比例尺通常用于将数值型数据映射到图表元素的属性上,例如颜色、大小、透明度等。它通常会根据所提供的输入和输出范,生成一个可以将一个连续输入域映射到一个输出范围的函数,使用该函数对图表元素进行样式设置。
1.盒子容器
?<span id="color">颜色</span>
? ? <div id="colorRef" ref="colorRef" :class="$style.colorRef"></div>
2.设置顺序尺,这里我们采用的是连续比例尺?scaleSequential
const colorScale = d3.scaleSequential(d3.interpolateReds).domain([0, 100]);
d3.select('#colorRef')
.style('background', `linear-gradient(to right, ${colorScale(0)}, ${colorScale(100)})`)
.on('click', function (event, d) {
// 获取点击位置的X坐标
const clickX = d3.pointer(event)[0];
// 获取容器的宽度
const containerWidth = this.clientWidth;
// 计算点击位置所对应的比例值(0 到 1)
const clickedRatio = clickX / containerWidth;
// 根据比例值和域范围获取对应的数据值
const dataValue = clickedRatio * (colorScale.domain()[1] - colorScale.domain()[0]) + colorScale.domain()[0];
// 在控制台打印点击位置所对应的数据值
document.getElementById('color').style.color = colorScale(dataValue);
});
这块主要是d3提供的一些颜色范围,?更改代码里面的d3.interpolateReds可看到不同颜色的卡尺
注意:与下面scaleOrdinal不同的是顺序比例尺的range是用于限制颜色范围,比如说将上面的红色限制范围在2个红色之间;添加了range,最终呈现会以range为主
colorScale.range([d3.rgb(255, 240, 240), d3.rgb(165, 0, 38)]); // 设置输出范围为两种红色的渐变
const colorScale = d3
? ? ? ? .scaleSequential(d3.interpolateBlues)
? ? ? ? .domain([0, 100])
? ? ? ? .range([d3.rgb(255, 240, 240), d3.rgb(165, 0, 38)]);
这段代码显示的颜色,是以range为主的红色
在测试颜色的时候,我发现d3.interpolateRainbow使用上面的scaleSequential用起来有点不符合我想要的const color = d3.scaleSequential(d3.interpolateRainbow).domain([0,100]);展示界面并不是彩虹色
是因为彩虹色(Rainbow)并不是线性分布的颜色。因此,在使用彩虹色的连续比例尺时,不适合直接将颜色线性地映射到 linear-gradient
中。彩虹色在颜色空间上的分布并不是简单的线性或均匀的。所以这我们采用svg绘制渐变色带
?// 创建一个更广泛的连续彩虹色比例尺
? ? ? const rainbowScale = d3.scaleSequential(d3.interpolateRainbow).domain([-100, 100]); // 更广泛的数据范围
? ? ? const numSteps = 100;
? ? ? const svg = d3.select('#colorRef').append('svg').attr('width', 300).attr('height', 30);
? ? ? const gradient = svg
? ? ? ? .append('defs')
? ? ? ? .append('linearGradient')
? ? ? ? .attr('id', 'gradient')
? ? ? ? .attr('x1', '0%')
? ? ? ? .attr('x2', '100%')
? ? ? ? .attr('spreadMethod', 'pad');
? ? ? for (let i = 0; i <= numSteps; i++) {
? ? ? ? gradient
? ? ? ? ? .append('stop')
? ? ? ? ? .attr('offset', i / numSteps)
? ? ? ? ? .attr('stop-color', rainbowScale(i * (200 / numSteps) - 100));
? ? ? }
? ? ? svg
? ? ? ? .append('rect')
? ? ? ? .attr('x', 0)
? ? ? ? .attr('y', 0)
? ? ? ? .attr('width', 300)
? ? ? ? .attr('height', 30)
? ? ? ? .style('fill', 'url(#gradient)');
该比例尺通常用于将类别(如颜色、图案等)映射到图表元素(如点、线条、柱状图等)的属性(如颜色、样式等)上。例如,可以使用Ordinal将一组设备类型(如手机、平板电脑、笔记本电等)映射到一组颜色(如红色、绿色、蓝色等)以区分它们在一个图表中的区别。
??const color = d3.scaleOrdinal().domain(cityData).range(d3.schemeBlues[9]);
上面写法等同于:const color = d3.scaleOrdinal(d3.schemeBlues[9]).domain(cityData);
等同于:const color = d3.scaleOrdinal(cityData,d3.schemeBlues[9]);
d3.select('#colorRef')
.selectAll('.color-block')
.data(cityData)
.enter()
.append('div')
.attr('class', 'color-block')
.style('background-color', d => color(d))
.on('click', function (event, d) {
// 在这里可以添加点击颜色块时的交互逻辑
console.log('Selected color:', d);
});
这里需要加一个css样式:
?.colorRef {
? ? width: 400px;
? ? height: 100px;
? ? border: 1px solid pink;
? ? box-sizing: border-box;
? ? display: flex;
????????
.color-block {
? flex: 1;
}
? }
以上大致是d3对于色卡的基本使用,具体可参照官网自行测试?