项目需求是环状进度条,在环状进度条上进行分隔,根据数据动态展示百分比
对比antd的进度条,实现起来比较麻烦,决定用echarts进行绘制
使用echarts绘制环状进度条
import * as echarts from 'echarts';
import { useEffect } from 'react';
import { useSelector } from 'umi';
import styles from './index.less';
const PieChat = () => {
// score 是后端返回的百分比
const score = useSelector((state) => state.screen.score);
let config = {
color: ['#3AC5FE', '#3AC5FE'],
// data里的第一项是达标,第二项则是不达标
data: [
{
name: '',
value: score,
},
{
name: '',
value: 100 - score,
},
],
};
var modelOption = {
// backgroundColor: '#0a1723',
color: [
{
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 1,
colorStops: [
{
offset: 0,
color: config.color[0],
},
{
offset: 1,
color: config.color[1],
},
],
global: false,
},
'rgba(58, 197, 254,0.5)',
],
series: [
//环形
{
name: '',
type: 'pie',
radius: ['63%', '77%'],
center: ['50%', '50%'],
emphasis: {
scale: false,
label: {
show: false,
},
},
zlevel: 1,
labelLine: {
show: false,
},
data: config.data,
},
//环形分割线
{
name: '分割线',
type: 'gauge',
radius: '84%', //配合splitLine里的length一起调
clockwise: true,
startAngle: '90',
center: ['50%', '50%'],
endAngle: '-269.9999',
splitNumber: 20,
zlevel: 2,
detail: {
offsetCenter: [10, 20],
formatter: ' ',
},
axisLine: {
lineStyle: {
width: 0,
opacity: 0,
},
},
axisTick: {
show: false,
},
markArea: {
itemStyle: {
color: '#0056FF',
},
},
splitLine: {
show: true,
length: 21, //配合radius一起调
padding: [0, 0, 0],
lineStyle: {
color: '#121d43',
// color: '#0056FF',
width: 5,
opacity: 0.8,
},
},
axisLabel: {
show: false,
},
},
],
};
useEffect(() => {
var modelChart = echarts.init(document.getElementById('modelPieChart'));
modelOption && modelChart.setOption(modelOption);
window.addEventListener('resize', () => {
modelChart && modelChart.resize();
});
}, []);
return (
<div className={styles.pieChat}>
<div id='modelPieChart' style={{ height: '300px' }} />
</div>
);
};
export default PieChat;
将所绘制的图形用div包裹,设置样式
.pieChat {
position: absolute;
top: 30px;
width: 100%;
height: 300px;
transform: rotateX(60deg);
transform-style: preserve-3d;
// 旋转效果,打开时需要将上面的注释
// animation: rotate 10s linear 0s infinite;
}
@keyframes rotate {
0% {
transform: rotateX(60deg) rotateZ(0);
transform-style: preserve-3d;
}
100% {
transform: rotateX(60deg) rotateZ(360deg);
transform-style: preserve-3d;
}
}
这里耗费了大量时间,在网上找了很多方法,开始尝试canvas,three.js。短时间内无法实现,想用transform属性,但网上的资料只有其倾斜的方法,在实际操作时,图片由于倾斜会导致变形,达不到预期的效果。 最后通过组长研究,不到一会,就实现了。transform-style: preserve-3d;这个属性很重要,需要牢记。