环形图
import * as d3 from 'd3';
export default function pieRatio(node, name, ratio, color) {
// 基础数据初始化
const svgObj = {
width: 124,
height: 124,
paddingTop: 28,
};
const radiusObj = {
innerRadius: 47,
outerRadius: 59,
};
const ratioObj = {
dx: svgObj.width / 2,
dy: svgObj.height / 2 + 4 + svgObj.paddingTop,
};
const dataset = [ratio, 100 - ratio];
// 转换数据
const pie = d3
.pie()
.sort(() => null)
.startAngle(-Math.PI * (5 / 6))
.endAngle(Math.PI * (5 / 6))
.value(d => d);
const shadowPie = d3
.pie()
.sort(() => -1)
.startAngle(-Math.PI * (5 / 6))
.endAngle(Math.PI * (5 / 6))
.value(d => d);
/**
const pie = d3
.pie()
.sort(() => null)
.startAngle(0)
.endAngle(360)
.value(d => d);
const shadowPie = d3
.pie()
.startAngle(0)
.endAngle(360)
.value(d => d);
*/
const pieData = pie(dataset);
const shadow = shadowPie([100]);
const arc = d3
.arc()
.innerRadius(radiusObj.innerRadius)
.outerRadius(radiusObj.outerRadius);
// 绘制
const svg = d3
.select(node)
.append('svg')
.attr('width', svgObj.width)
.attr('height', svgObj.height + svgObj.paddingTop);
// 阴影
svg
.append('g')
.attr('class', 'sexRatioGroup')
.selectAll('.sexRatioArcs')
.data(shadow)
.enter()
.append('g')
.attr('class', 'sexRatioArcs')
.attr('transform', `translate(${svgObj.width / 2},${svgObj.height / 2 + svgObj.paddingTop})`)
.append('path')
.attr('fill', '#1b5488')
.attr('stroke', 'none')
.attr('d', (d, i) => arc(d, i));
// 弧形
svg
.append('g')
.attr('class', 'sexRatioGroup')
.selectAll('.sexRatioArcs')
.data(pieData)
.enter()
.append('g')
.attr('class', 'sexRatioArcs')
.attr('transform', `translate(${svgObj.width / 2},${svgObj.height / 2 + svgObj.paddingTop})`)
.append('path')
.attr('fill', (d, i) => {
if (i === 0) return color;
return '#1b5488';
})
.attr('stroke', 'none')
.transition()
.delay(1200)
.duration(600)
.attrTween('d', d => {
const i = d3.interpolate(d.startAngle, d.endAngle);
const dN = d;
return t => {
dN.endAngle = i(t);
return arc(dN);
};
});
// 分类 name
svg
.append('g')
.attr('class', 'sexRatioName')
.append('text')
.text(() => `${name}`)
.attr('dx', ratioObj.dx)
.attr('dy', ratioObj.dy/5)
.attr('text-anchor', 'middle');
// ratio百分比
svg
.append('g')
.attr('class', 'sexRatioNum')
.append('text')
.attr('dx', ratioObj.dx)
.attr('dy', ratioObj.dy)
.attr('text-anchor', 'middle')
.transition()
.delay(600)
.duration(2000)
.tween('text', () => {
const i = d3.interpolateRound(0, ratio);
return function textContent(t) {
this.textContent = `${i(t)}%`;
};
});
}