想要实现的效果:
1、默认选中外层的第一个。
2、点击外层的饼图,里层的饼图实时变动。
3、始终保持外层饼图有选中的状态
效果如下:
实现如下:
1、数据结构
let chartsArray = [
{
name: '外层1',
value: 2,
selected:true,
children: [
{
name: '内层1-1',
value: 3,
},
{
name: '内层1-2',
value: 4,
},
{
name: '内层1-3',
value: 4,
},
],
},
{
name: '外层2',
value: 5,
children: [
{
name: '内层2-1',
value: 3,
},
{
name: '内层2-2',
value: 4,
},
],
},
{
name: '外层3',
value: 6,
children: [
{
name: '内层3-1',
value: 3,
},
{
name: '内层3-2',
value: 4,
},
],
}
],
2、完整代码
<div id="chartsDiv"></div>
import {ref, markRaw} from 'vue';
import * as echarts from 'echarts';
const myChart2 = ref();
let firstArray = chartsArray;
let firstTotal =0;
let secondArray = chartsArray[0].children;
let secondTotal = 0;
function initCharts() {
firstTotal = 0;
secondTotal = 0;
firstArray.forEach(item=>{
firstTotal += item.value;
})
secondArray.forEach(item=>{
secondTotal += item.value
})
var option = {
color: [
'#FF8585',
'#FF9D4D',
'#DE85EF',
'#7686A3',
'#5ED2A5',
'#6597FF',
'#8070F8',
],
tooltip: {
trigger: 'item',
formatter: function (params) {
var color = params.color; // 获取数据点的颜色
var icon =
'+
color +
';">';
var seriesName = params.name; // 数据系列名称
var value = params.value; // 数据值
return (
icon +
seriesName +
'
' +
' ' +
value +
' (' +
params.percent +
'%)'
); // 返回自定义的字符串
},
backgroundColor: '#000000',
textStyle: {
color: '#fff',
},
},
legend: {
type: 'scroll',
orient: 'vertical',
right: '10px',
top: 'middle',
icon: 'circle',
textStyle: {
color: '#8C8C8C',
},
height: '300',
formatter: function (name) {
let tempItem = firstArray.find((item) => item.name == name);
let percent = 0;
if (!tempItem) {
tempItem = secondArray.find((item) => item.name == name);
percent = ((tempItem.value / secondTotal) * 100).toFixed(2) + '%';
} else {
percent = ((tempItem.value / firstTotal) * 100).toFixed(2) + '%';
}
let number = tempItem ? tempItem.value : 0;
if (name.length > 6) {
return (
name.substr(0, 3) +
'...' +
name.substr(name.length - 2, 2) +
':' +
number +
'(' +
percent +
')'
);
} else {
return name + ':' + number + '(' + percent + ')';
}
},
},
series: [
{
type: 'pie',
right: '150px',
radius: ['55%', '70%'],
padAngle: 1,
selectedMode: 'single',
labelLine: {
length: 15,
lineStyle: {
color: '#999',
},
},
label: {
formatter: '{b}\n {c} ({value|{d}%})',
minMargin: 10,
edgeDistance: 120,
lineHeight: 15,
rich: {
b: {
color: 'rgba(0, 0, 0, 0.65)',
fontSize: 14,
fontWeight: 'bold',
lineHeight: 33,
},
},
},
data: firstArray,
},
{
type: 'pie',
right: '150px',
padAngle: 2,
radius: [0, '40%'],
label: {
show: false,
},
labelLine: {
show: false,
},
data: secondArray,
},
],
};
const chartDom = document.getElementById('chartsDiv');
if (chartDom) {
if (!myChart2.value) {
myChart2.value = markRaw(echarts.init(chartDom));
}
myChart2.value.clear();
option && myChart2.value.setOption(option);
//监听饼图的点击事件
myChart2.value.on('click', function (params) {
// 判断点击的是否为外层,内层点击不做处理
if (params.componentIndex != 0) {
return;
}
let item = chartsArray[params.dataIndex];
secondArray = [];
secondTotal = 0;
item &&
item.children &&
item.children.forEach((element) => {
secondArray.push({ name: element.name, value: element.value});
secondTotal += element.failNum;
});
//获取当前的charts 配置 设置第二层的数据
let tempOption = myChart2.value.getOption();
tempOption.series[1].data = secondArray;
myChart2.value.setOption(tempOption);
//始终保持当前有选中的状态
myChart2.value.dispatchAction({
type: 'select',
seriesIndex: 0,
dataIndex: params.dataIndex,
});
});
}
}
监听浏览器的大小,动态的改变echarts
onMounted(() => {
window.addEventListener('resize', () => {
if (myChart2.value) {
myChart2.value.resize();
}
});
});
onUnmounted(() => {
window.removeEventListener('resize', () => {
if (myChart2.value) {
myChart2.value.dispose();
}
});
});
其中:
markRaw是使echarts不具有响应式。