本文适合对 D3 API 稍有熟悉的人阅读,如果你是的话,继续看下去吧~
附 D3API 文档地址
对设计图的思考
先看我们要实现的设计图:
这个环形图适合多个共同展示, 高亮的环形表达的意义是,当前数据在总数的占比。so 实现这个图需要两个数据,一个是 当前数据num
,一个是总数sum
。
数据明确了,再看设计部分:
经过和设计师的沟通讨论,得出以下几点:
- 该组件背景为 0.1 透明度的黑色;
- 该组件六边环形未被填充的地方为镂空透明;
- 该组件环形填充的部分并不是直角截断,而是一个扇形截断:
所以最终组件应该实现为下面这个样子,这个也是我们做出的最终效果:
那么我们开始实现吧!
具体思路
这个环形图只要实现难点在于环形高亮的绘制,我想了两个方案,
给扇形应用环形蒙版
- 绘制一个高亮扇形
- 绘制一个环形蒙版(这里我用 ppt 画的,只有这种横着的六边形,将就下哈哈哈)
- 将蒙版应用在扇形上即可
但是这个方案有一些问题
,因为绘制扇形的时候需要用 translate 修改它的位置(因为默认圆心是从左上角的顶点),导致将环形蒙版应用到扇形上时,也被 translate 了,位置对不齐。。
所以采用了第二个方案:
给环形应用扇形蒙版,亲测可行~
实现步骤
新建一个 svg,这里模拟了数据 num 和 sum
// 数据
var num = 2546;
var sum = 2800;
// 新建 svg
var width = 100;
var height = 64;
var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);
定义两个渐变颜色供之后使用:环形的渐变,字体的渐变
//设置线性渐变颜色
renderLinearColor = (props) => {
const {
defs } = this;
const {
hexagonColor, textColor} = props;
// 六边形渐变颜色
let linearGradient1 = defs.append("linearGradient")
.attr("id","linearColor1")
.attr("x1","0%")
.attr("y1","0%")
.attr("x2","50%")
.attr("y2","100%");
linearGradient1.append("stop"