You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
6.6 KiB
268 lines
6.6 KiB
<template>
|
|
<div class="bodycontainer">
|
|
<div class="labels">
|
|
<div
|
|
class="label-item"
|
|
v-for="(item, index) in pieData"
|
|
:key="index"
|
|
:style="{
|
|
backgroundImage: `url(${require('@/assets/sentimeent/' +
|
|
(item.name === '小程序' ? '其他' : item.name) +
|
|
'.png')})`,
|
|
backgroundSize: '100% 100%',
|
|
}"
|
|
>
|
|
<div class="label-content">
|
|
<div class="percent" :style="{ color: getItemColor(index) }">
|
|
{{ getItemPercent(item) }}%
|
|
</div>
|
|
<div class="name">{{ item.name }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="chart-container">
|
|
<div ref="chart" style="width: 400px; height: 300px;"></div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import * as echarts from "echarts";
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
chart: null,
|
|
total: 0,
|
|
currentSelected: null,
|
|
pieData: [
|
|
{ value: 15, name: "上级下发" },
|
|
{ value: 3, name: "部门转发" },
|
|
{ value: 10, name: "小程序" },
|
|
{ value: 4, name: "无效" },
|
|
],
|
|
colorMap: ["#37a4ff", "#00ffde", "#ff7e2b", "#fbe84f"],
|
|
};
|
|
},
|
|
computed: {
|
|
legendData() {
|
|
return this.pieData.map((item) => ({
|
|
name: item.name,
|
|
value: item.value,
|
|
color: item.color,
|
|
}));
|
|
},
|
|
},
|
|
mounted() {
|
|
this.calculateTotal();
|
|
this.initChart();
|
|
},
|
|
methods: {
|
|
calculateTotal() {
|
|
this.total = this.pieData.reduce((sum, item) => sum + item.value, 0);
|
|
},
|
|
initChart() {
|
|
this.chart = echarts.init(this.$refs.chart);
|
|
|
|
const option = {
|
|
tooltip: {
|
|
trigger: "item",
|
|
formatter: "{a} <br/>{b}: {c} ({d}%)",
|
|
},
|
|
series: [
|
|
{
|
|
name: "数据集",
|
|
type: "pie",
|
|
radius: ["50%", "70%"],
|
|
avoidLabelOverlap: false,
|
|
itemStyle: {
|
|
borderRadius: 10,
|
|
borderColor: "#fff",
|
|
borderWidth: 2,
|
|
},
|
|
label: {
|
|
show: false,
|
|
position: "center",
|
|
},
|
|
emphasis: {
|
|
label: {
|
|
show: true,
|
|
fontSize: "18",
|
|
fontWeight: "bold",
|
|
formatter: (params) => {
|
|
const percentage = ((params.value / this.total) * 100).toFixed(1);
|
|
return `{b|${params.name}}\n{hr|}\n{d|${percentage}%}`;
|
|
},
|
|
rich: {
|
|
b: {
|
|
fontSize: 16,
|
|
fontWeight: "bold",
|
|
color: "#333",
|
|
lineHeight: 26,
|
|
},
|
|
hr: {
|
|
borderColor: "#fff",
|
|
width: "100%",
|
|
borderWidth: 1,
|
|
height: 0,
|
|
},
|
|
d: {
|
|
fontSize: 16,
|
|
color: "#333",
|
|
lineHeight: 26,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
data: this.pieData.map((item) => ({
|
|
value: item.value,
|
|
name: item.name,
|
|
itemStyle: { color: item.color },
|
|
})),
|
|
},
|
|
],
|
|
graphic: [
|
|
{
|
|
type: "text",
|
|
left: "center",
|
|
top: "center",
|
|
style: {
|
|
text: `总模块\n${this.total}`,
|
|
textAlign: "center",
|
|
fill: "#333",
|
|
fontSize: 18,
|
|
fontWeight: "bold",
|
|
},
|
|
},
|
|
],
|
|
};
|
|
|
|
this.chart.setOption(option);
|
|
|
|
// 添加点击事件
|
|
this.chart.on("click", (params) => {
|
|
this.currentSelected = params;
|
|
this.updateCenterText();
|
|
});
|
|
|
|
// 响应式调整
|
|
window.addEventListener("resize", this.resizeHandler);
|
|
},
|
|
updateCenterText() {
|
|
if (this.currentSelected) {
|
|
const percentage = ((this.currentSelected.value / this.total) * 100).toFixed(1);
|
|
const option = {
|
|
graphic: [
|
|
{
|
|
type: "text",
|
|
left: "center",
|
|
top: "center",
|
|
style: {
|
|
text: `${this.currentSelected.name}\n${percentage}%`,
|
|
textAlign: "center",
|
|
fill: this.currentSelected.color,
|
|
fontSize: 18,
|
|
fontWeight: "bold",
|
|
},
|
|
},
|
|
],
|
|
};
|
|
this.chart.setOption(option);
|
|
} else {
|
|
const option = {
|
|
graphic: [
|
|
{
|
|
type: "text",
|
|
left: "center",
|
|
top: "center",
|
|
style: {
|
|
text: `总模块\n${this.total}`,
|
|
textAlign: "center",
|
|
fill: "#333",
|
|
fontSize: 18,
|
|
fontWeight: "bold",
|
|
},
|
|
},
|
|
],
|
|
};
|
|
this.chart.setOption(option);
|
|
}
|
|
},
|
|
resizeHandler() {
|
|
this.chart && this.chart.resize();
|
|
},
|
|
getItemColor(index) {
|
|
return this.colorMap[index] || "#ffffff";
|
|
},
|
|
getItemPercent(item) {
|
|
const total = this.pieData.reduce((sum, i) => sum + i.value, 0);
|
|
if (total === 0) return 0;
|
|
|
|
let percent = (item.value / total) * 100;
|
|
|
|
// 保留一位小数
|
|
return percent.toFixed(1);
|
|
},
|
|
},
|
|
beforeDestroy() {
|
|
window.removeEventListener("resize", this.resizeHandler);
|
|
this.chart && this.chart.dispose();
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.bodycontainer {
|
|
padding: 20px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
|
|
.labels {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 0 20px;
|
|
|
|
.label-item {
|
|
position: relative;
|
|
width: 170px;
|
|
height: 65px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
|
|
.label-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
.percent {
|
|
font-size: 28px;
|
|
font-weight: bold;
|
|
font-family: Arial;
|
|
line-height: 1.2;
|
|
margin-top: -10px;
|
|
}
|
|
|
|
.name {
|
|
font-family: AlibabaPuHuiTiR;
|
|
font-size: 20px;
|
|
color: #b4f9ff;
|
|
line-height: 22px;
|
|
text-align: justifyLeft;
|
|
font-style: normal;
|
|
text-transform: none;
|
|
margin-top: 5px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.chart-container {
|
|
width: 400px;
|
|
height: 300px;
|
|
margin-top: 20px;
|
|
}
|
|
}
|
|
</style> |