vue+echarts,生成的3D饼图每部分和数据的位置对应不上怎么办?
图片展示
问题描述:每块颜色的部分和百分数的位置对应不上

代码展示
<template>
<div class="chart-container">
<div class="chart" :ref="refName" id="chart-panel"></div>
<!-- 底座背景 -->
<div class="bg"></div>
</div>
</template>
<script>
import * as echarts from 'echarts';
require('echarts/theme/macarons') // echarts theme
import 'echarts-gl' // 3d图表库
import resize from './mixins/resize'
import { getPie3D, getParametricEquation } from '@/utils/chart.js' //工具类js,页面路径自己修改
const color1 = ["#00a8ff ", "#878ffa", "#3bedde", "#44da84"]
const color2 = ["#00a8ff", "#878ffa", "#3bedde", "#44da84", "#317bf6"]
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
},
refName: {
type: String,
required: true,
default: ''
},
chartData: {
type: Array,
required: true,
default: []
}
},
watch: {
chartData: {
deep: true,
handler(val) {
// 避免处理同一个数据地址引起无限监听
const temVal = JSON.parse(JSON.stringify(val))
this.setLabel(temVal);
this.setOptions(temVal)
}
}
},
data() {
return {
statusChart: null,
option: {}
}
},
created() {
this.setLabel(this.chartData)
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
// 初始化label样式
setLabel(chartData) {
chartData.forEach((item, index) => {
item.itemStyle = {
color: item.color
}
item.label = {
normal: {
show: true,
color: item.color,
formatter: function (data) {
//let a = data.name
let b = data.percent.toFixed(0) + "%"
//let c = a + ' ' + b
return b
},
fontWeight: 900,
fontSize: 13,
color: '#64e7ff',
}
}
item.labelLine = {
normal: {
lineStyle: {
width: 1,
color: '#64e7ff',
type: 'dashed'//设置为虚线
}
}
}
})
},
initChart() {
// 使用同一个组件时,需要动态给定ref,在窗口大小改变时都动态变化
this[this.refName] = echarts.init(this.$refs[this.refName]);
this.setOptions(this.chartData)
},
setOptions(chartData) {
// 传入数据生成 option, 构建3d饼状图, 参数工具文件已经备注的很详细
chartData ? this.option = getPie3D(chartData, 0, 240, 28, 26, 0.5) : ""
this[this.refName].setOption(this.option)
// 是否需要label指引线,如果要就添加一个透明的2d饼状图并调整角度使得labelLine和3d的饼状图对齐,并再次setOption
this.option.series.push({
name: "人员比例", //自己根据场景修改
backgroundColor: 'transparent',
type: 'pie',
label: {
opacity: 1,
fontSize: 13,
lineHeight: 20
},
startAngle: -30, // 起始角度,支持范围[0, 360]。
clockwise: false, // 饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式
radius: ['30%', '50%'],
center: ['50%', '45%'],
data: chartData,
itemStyle: {
opacity: 0 //这里必须是0,不然2d的图会覆盖在表面
}
})
this[this.refName].setOption(this.option);
// 添加图例配置
/* this.option.legend = {
show: true,
orient: 'horizontal',
left: 'center', // 水平居中
bottom: '0px', // 调整底部距离
data: chartData.map(item => item.name),
itemWidth: 8, // 设置图例项的宽度
itemHeight: 8, // 设置图例项的高度
formatter: function (name) {
return name;
}
}; */
// 更新图表配置
this[this.refName].setOption(this.option);
},
// 自适应宽高
// 使用同一个组件时,需要动态给定ref,在窗口大小改变时都动态变化
changeSize(refName) {
this[refName].resize();
},
}
}
</script>
<style lang="scss" scoped>
.chart-container {
position: relative;
width: 100%;
height: 100%;
//margin-bottom:15 px; /* 调整图表向上移动的距离,根据需要自行调整 */
.chart {
z-index: 1;
}
.chart,
.bg {
width: 100%;
height: 100%;
}
.bg {
position: absolute;
width: 280px;
height: 58%;
bottom: 25px;
left: 50%;
z-index: 0;
background: no-repeat center;
background-image: url('../../assets/images/pie_bottom.png');
background-size: 100% 100%;
transform: translateX(-50%);
}
}
</style>