需求:三级分类的饼图
- 1、一级分类通过左右箭头切换的方式展现
- 2、二级分类通过饼图的形式展现(默认不显示每块区域name,高亮时候显示name)
- 3、三级分类通过鼠标放在饼图某一区域上时以文字的形式呈现(自定义提示文字)
<template>
<div class="w100 h100">
<!-- 左右切换箭头及一级分类名字 -->
<div>
<div class="title">{{ pieData[index].name }}</div>
<div v-if="index > 0" @click="onLeft" class="left">《</div>
<div v-if="index < pieData.length - 1" @click="onRight" class="right">
》
</div>
</div>
<div ref="pie" class="w100 h100"></div>
</div>
</template>
<script>
import { ququ } from "../../public/static/theme/ququ";
export default {
data() {
return {
size: null, //基准字体大小——控制标题和图例的大小
pieChart: null,
pieData: [
{
name: "服装",
children: [
{
name: "上衣",
value: 100,
children: [
{
name: "男士",
value: 10,
},
{
name: "女士",
value: 30,
},
],
},
{
name: "裤子",
value: 210,
children: [
{
name: "男士",
value: 10,
},
{
name: "女士",
value: 30,
},
],
},
{
name: "裙子",
value: 400,
children: [
{
name: "男士",
value: 10,
},
{
name: "女士",
value: 30,
},
],
},
{
name: "棒球服",
value: 233,
children: [
{
name: "男士",
value: 10,
},
{
name: "女士",
value: 30,
},
],
},
{
name: "羽绒服",
value: 280,
children: [
{
name: "男士",
value: 10,
},
{
name: "女士",
value: 30,
},
],
},
],
},
{
name: "手机",
children: [
{
name: "apple",
value: 220,
children: [
{
name: "大屏",
value: 110,
},
{
name: "小屏",
value: 30,
},
],
},
{
name: "华为",
value: 410,
children: [
{
name: "大屏",
value: 150,
},
{
name: "小屏",
value: 230,
},
],
},
],
},
],
index: 0, // 当前一级分类的索引
};
},
mounted() {
/**
* 需求:三级分类的饼图
* 1、一级分类通过左右箭头切换的方式展现
* 2、二级分类通过饼图的形式展现(默认不显示每块区域name,高亮时候显示name)
* 3、三级分类通过鼠标放在饼图某一区域上时以文字的形式呈现(自定义提示文字)
*/
this.init();
this.getData();
// 监听屏幕大小变化
window.addEventListener("resize", this.screenResize);
// 一进来主动调取屏幕适配
this.screenResize();
},
beforeDestroy() {
window.removeEventListener("resize", this.screenResize);
},
methods: {
// 初始化图表
init() {
this.$echarts.registerTheme("ququ", ququ);
this.pieChart = this.$echarts.init(this.$refs.pie, "ququ");
let initOption = {
// 标题
title: {
text: "▍三级饼图", // ▍ 任意打一个字,调出搜狗输入法卡片,右键单击——表情符号——符号大全
left: 40,
top: 40,
textStyle: {
color: "#fff",
},
},
// 提示框设置
tooltip: {
trigger: "item",
show: true,
// 自定义提示文字
formatter: (arg) => {
let str = "";
arg.data.children.forEach((item) => {
str += `${item.name}:${item.value}<br/>`;
});
return str;
},
},
// 图例
legend: {
show: true,
top: 130,
icon: "circle",
textStyle: {
color: "#fff",
},
},
series: [
{
type: "pie",
radius: "50%", // 饼图的大小
center: ["50%", "50%"], // 饼图的位置——正中心
label: {
show: false, // 隐藏饼图每块区域的名称
},
// 每块区域高亮时候的样式
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
label: {
show: true, //高亮时候显示每块区域的name
},
labelLine: {
show: false, // 隐藏名字和图之间默认的一条线
},
},
},
],
};
this.pieChart.setOption(initOption);
},
// 切换一级分类
onLeft() {
this.index--;
this.getData();
},
onRight() {
this.index++;
this.getData();
},
// 获取并处理数据,然后渲染图表
getData() {
let dataOption = {
series: [
{
name: this.pieData[this.index].name,
data: this.pieData[this.index].children,
},
],
};
// 生成图表
this.pieChart.setOption(dataOption);
},
// 监听屏幕变化
screenResize() {
this.$nextTick(() => {
// 获取图表区域的宽度,作为基准值来设置其他需要动态改变的尺寸
let width = this.$refs.pie.offsetWidth;
this.size = (width / 100) * 3.6; // 定义一个基准尺寸
// 拆分option:3、受屏幕大小影响的配置在屏幕改变的时候set
let screenOption = {
title: {
textStyle: {
fontSize: this.size,
},
},
legend: {
itemWidth: this.size / 2,
itemHeight: this.size / 2,
},
};
this.pieChart.setOption(screenOption);
// 更新图表
this.pieChart.resize();
});
},
},
};
</script>
<style scoped lang="less">
.left,
.right,
.title {
color: #fff;
position: absolute;
z-index: 999;
}
.left {
left: 60px;
top: 50%;
transform: translateY(-50%);
}
.right {
right: 60px;
top: 50%;
transform: translateY(-50%);
}
.title {
right: 60px;
bottom: 60px;
font-size: 30px;
}
</style>