You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
12 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="chart-container">
<div class="chart" :class="{'activehide':isActive}" ref="chart"></div>
<!-- 底座背景 -->
</div>
</template>
<script>
import { getPie3D, getParametricEquation } from "../../../utils/echart.js"; //工具类js页面路径自己修改
const color = ["#005aff", "#f8b551"];
export default {
name: "chart",
props: ["list", "colorlist"],
data() {
return {
optionData: [],
statusChart: null,
option: {},
isActive:false,
// color:["#005aff", "#f8b551",'#7CDCAC'],
};
},
watch: {
list: function (newVal, oldVal) {
console.log(newVal, oldVal)
if(newVal.length < 0){
return
}
if(newVal.length == oldVal.length){
return
}
if (this.list.length > 0) {
this.setLabel();
this.isActive = false
setTimeout(() => {
this.initChart();
}, 1000);
}else{
this.optionData = []
this.isActive = true
// setTimeout(() => {
// this.initChart();
// }, 1000);
}
},
colorlist: function (newVal, oldVal) {},
},
created() {
// console.log(this.list);
// this.color = this.colorlist
},
mounted() {
// this.setLabel();
// this.initChart();
//根据窗口变化自动调节图表大小
const that = this;
window.onresize = function () {
that.changeSize();
};
},
methods: {
// 初始化label样式
setLabel() {
const that = this;
this.optionData = this.list;
this.optionData.forEach((item, index) => {
// item.itemStyle = {
// color: that.color[index],
// };
item.label = {
normal: {
show: true,
// color: that.color[index],
formatter: ["{b|{b}}:", "{d|{d}%}"].join(""), // 用\n来换行
rich: {
b: {
color: "#fff",
lineHeight: 25,
align: "left",
},
c: {
fontSize: 22,
color: "#fff",
textShadowColor: "#1c90a6",
textShadowOffsetX: 0,
textShadowOffsetY: 2,
textShadowBlur: 5,
},
d: {
color: "#fff",
align: "left",
textShadowOffsetX: 0,
textShadowOffsetY: 2,
textShadowBlur: 5,
},
},
},
};
item.labelLine = {
normal: {
lineStyle: {
width: 1,
color: "rgba(255,255,255,0.7)",
},
},
};
});
},
// 图表初始化
initChart() {
this.statusChart = this.$echarts.init(this.$refs.chart);
// 传入数据生成 option, 构建3d饼状图, 参数工具文件已经备注的很详细
this.optionData = this.list;
this.option = getPie3D(this.optionData, 0.8, 240, 50, 26, 0.5);
this.statusChart.setOption(this.option);
// 是否需要label指引线如果要就添加一个透明的2d饼状图并调整角度使得labelLine和3d的饼状图对齐并再次setOption
this.option.series.push({
// backgroundColor: "transparent",
type: "pie",
label: {
// show: true,
opacity: 1,
alignTo: "labelLine",
color: "#FFFFFF",
fontSize: 12,
// lineHeight: 20,
},
labelLine: {
length: 30,
length2: 0,
maxSurfaceAngle: 100,
},
startAngle: -40, // 起始角度,支持范围[0, 360]。
clockwise: false, // 饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式
radius: ["50%", "70%"],
center: ["50%", "50%"],
data: this.optionData,
itemStyle: {
opacity: 0, //这里必须是0不然2d的图会覆盖在表面
},
});
this.statusChart.setOption(this.option);
this.bindListen(this.statusChart);
},
// 监听鼠标事件,实现饼图选中效果(单选),近似实现高亮(放大)效果。
// optionName是防止有多个图表进行定向option传递单个图表可以不传默认是opiton
bindListen(myChart, optionName = "option") {
let selectedIndex = "";
let hoveredIndex = "";
// 监听点击事件,实现选中效果(单选)
myChart.on("click", (params) => {
// 从 option.series 中读取重新渲染扇形所需的参数,将是否选中取反。
const isSelected =
!this[optionName].series[params.seriesIndex].pieStatus.selected;
const isHovered =
this[optionName].series[params.seriesIndex].pieStatus.hovered;
const k = this[optionName].series[params.seriesIndex].pieStatus.k;
const startRatio =
this[optionName].series[params.seriesIndex].pieData.startRatio;
const endRatio =
this[optionName].series[params.seriesIndex].pieData.endRatio;
// 如果之前选中过其他扇形,将其取消选中(对 option 更新)
if (selectedIndex !== "" && selectedIndex !== params.seriesIndex) {
this[optionName].series[selectedIndex].parametricEquation =
getParametricEquation(
this[optionName].series[selectedIndex].pieData.startRatio,
this[optionName].series[selectedIndex].pieData.endRatio,
false,
false,
k,
this[optionName].series[selectedIndex].pieData.value
);
this[optionName].series[selectedIndex].pieStatus.selected = false;
}
// 对当前点击的扇形,执行选中/取消选中操作(对 option 更新)
this[optionName].series[params.seriesIndex].parametricEquation =
getParametricEquation(
startRatio,
endRatio,
isSelected,
isHovered,
k,
this[optionName].series[params.seriesIndex].pieData.value
);
this[optionName].series[params.seriesIndex].pieStatus.selected =
isSelected;
// 如果本次是选中操作,记录上次选中的扇形对应的系列号 seriesIndex
selectedIndex = isSelected ? params.seriesIndex : null;
// 使用更新后的 option渲染图表
myChart.setOption(this[optionName]);
});
// 监听 mouseover近似实现高亮放大效果
myChart.on("mouseover", (params) => {
// 准备重新渲染扇形所需的参数
let isSelected;
let isHovered;
let startRatio;
let endRatio;
let k;
// 如果触发 mouseover 的扇形当前已高亮,则不做操作
if (hoveredIndex === params.seriesIndex) {
// 否则进行高亮及必要的取消高亮操作
} else {
// 如果当前有高亮的扇形,取消其高亮状态(对 option 更新)
if (hoveredIndex !== "") {
// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 false。
isSelected =
this[optionName].series[hoveredIndex].pieStatus.selected;
isHovered = false;
startRatio =
this[optionName].series[hoveredIndex].pieData.startRatio;
endRatio = this[optionName].series[hoveredIndex].pieData.endRatio;
k = this[optionName].series[hoveredIndex].pieStatus.k;
// 对当前点击的扇形,执行取消高亮操作(对 option 更新)
this[optionName].series[hoveredIndex].parametricEquation =
getParametricEquation(
startRatio,
endRatio,
isSelected,
isHovered,
k,
this[optionName].series[hoveredIndex].pieData.value
);
this[optionName].series[hoveredIndex].pieStatus.hovered = isHovered;
// 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
hoveredIndex = "";
}
// 如果触发 mouseover 的扇形不是透明圆环,将其高亮(对 option 更新)
if (
params.seriesName !== "mouseoutSeries" &&
params.seriesName !== "pie2d"
) {
// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
isSelected =
this[optionName].series[params.seriesIndex].pieStatus.selected;
isHovered = true;
startRatio =
this[optionName].series[params.seriesIndex].pieData.startRatio;
endRatio =
this[optionName].series[params.seriesIndex].pieData.endRatio;
k = this[optionName].series[params.seriesIndex].pieStatus.k;
// 对当前点击的扇形,执行高亮操作(对 option 更新)
this[optionName].series[params.seriesIndex].parametricEquation =
getParametricEquation(
startRatio,
endRatio,
isSelected,
isHovered,
k,
this[optionName].series[params.seriesIndex].pieData.value + 60
);
this[optionName].series[params.seriesIndex].pieStatus.hovered =
isHovered;
// 记录上次高亮的扇形对应的系列号 seriesIndex
hoveredIndex = params.seriesIndex;
}
// 使用更新后的 option渲染图表
myChart.setOption(this[optionName]);
}
});
// 修正取消高亮失败的 bug
myChart.on("globalout", () => {
// 准备重新渲染扇形所需的参数
let isSelected;
let isHovered;
let startRatio;
let endRatio;
let k;
if (hoveredIndex !== "") {
// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
isSelected = this[optionName].series[hoveredIndex].pieStatus.selected;
isHovered = false;
k = this[optionName].series[hoveredIndex].pieStatus.k;
startRatio = this[optionName].series[hoveredIndex].pieData.startRatio;
endRatio = this[optionName].series[hoveredIndex].pieData.endRatio;
// 对当前点击的扇形,执行取消高亮操作(对 option 更新)
this[optionName].series[hoveredIndex].parametricEquation =
getParametricEquation(
startRatio,
endRatio,
isSelected,
isHovered,
k,
this[optionName].series[hoveredIndex].pieData.value
);
this[optionName].series[hoveredIndex].pieStatus.hovered = isHovered;
// 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
hoveredIndex = "";
}
// 使用更新后的 option渲染图表
myChart.setOption(this[optionName]);
});
},
// 自适应宽高
changeSize() {
this.statusChart.resize();
},
},
};
</script>
<style lang='scss' scoped>
.chart-container {
position: relative;
width: 100%;
height: 100%;
.chart,
.bg {
width: 100%;
height: 100%;
}
.bg {
position: absolute;
bottom: 50px;
left: 50%;
z-index: -1;
width: 180px;
height: 73px;
background: no-repeat center;
background-image: url("https://ks3-cn-beijing.ksyun.com/sxjg-elevator/datav-platform-2.0/images/chart_opacity_bg.png");
background-size: 100% 100%;
transform: translateX(-50%);
}
}
.activehide{
display: none;
}
</style>