echarts画3D图没有highcharts方便,所以这里画立体图选择了highcharts
首先安装依赖:
npm install highcharts --save
新建页面:index.vue
optionData是需要传入的数据
<template>
<div class="safeEvent">
<Pie3D :optionData="optionData" style="width:400px;height:200px" />
</div>
</template>
<script>
import Pie3D from "./pie.vue";
export default {
name: "home",
data() {
return {
optionData: [
{
name: "数据一",
value: 20,
},
{
name: "数据二",
value: 15,
},
{
name: "数据三",
value: 35,
},
{
name: "数据四",
value: 10,
},
{
name: "数据五",
value: 20,
},
],
};
},
components: {
Pie3D,
},
};
</script>
<style scoped>
.safeEvent{
background: #072956;
height: 100vh;
padding:50px
}
</style>
新建组件:Pie3D.vue
单独把饼图提出来作为子组件,方便复用
class=bg是为了设置背景图片
id写成动态的,方便一个页面多次引用
chart定义在data外,优化页面卡顿
<!-- 透明3D饼图样式-->
<template>
<div id="" style="height: 100%">
<div class="bg" :id="id" style="height: 100%"></div>
</div>
</template>
<script>
import Highcharts from "highcharts/highstock";
import HighchartsMore from "highcharts/highcharts-more";
import HighchartsDrilldown from "highcharts/modules/drilldown";
import Highcharts3D from "highcharts/highcharts-3d";
HighchartsMore(Highcharts);
HighchartsDrilldown(Highcharts);
Highcharts3D(Highcharts);
let chart = null;
export default {
name: "",
props: {
optionData: {
type: Array,
default: () => {
return [];
},
},
id: {
type: String,
default: () => {
return "main" + Math.random();
},
},
},
watch: {
optionData: {
deep: true,
handler() {
this.$nextTick(() => {
this.dealData();
this.init();
});
},
},
},
data() {
return {
dataList: [],
};
},
mounted() {
this.init();
window.addEventListener("resize", () => {
this.init();
chart.reflow();
});
},
created() {
this.dealData();
},
methods: {
dealData() {
this.dataList = this.optionData.map((item) => {
item["y"] = item["value"];
return item;
});
},
init() {
let color1 = [
"rgba(135,208,81,0.6)",
"rgba(48,154,227,0.6)",
"rgba(67,106,218,0.6)",
"rgba(217,95,95,0.6)",
"rgba(205,217,101,0.6)",
];
let _this=this
chart = Highcharts.chart(this.id, {
colors: color1,
chart: {
type: "pie",
backgroundColor: null,
animation: false,
marginTop: 20,
spacingTop: 0,
options3d: {
enabled: true,
alpha: 50,
},
spacingTop: 0,
spacingLeft: 0,
spacingRight: 0,
},
legend: { //图例
align: "center", //程度标的目标地位
layout: "horizontal",
verticalAlign: "top", //垂直标的目标地位
padding: 2,
margin: 0,
itemStyle: {
cursor: "pointer",
color: "#FFFFFF",
fontWeight: 100,
backgroundColor: ["#ccc"],
},
itemHoverStyle: {
color: "#FFFFFF",
},
},
tooltip: { //提示框
backgroundColor: "rgba(20,77,155,0.9000)",
borderColor: "#34A6FF",
color: "#fff",
useHTML: true,
pointFormat: '<div style="color: #fff">{point.percentage:.1f}%</div>',
itemStyle: {
color: "#FFFFFF",
},
formatter: function () {
let s =
'<div style="color: #fff">' +
this.key +
":" +
this.y +
"%</div>";
return s;
},
},
title: { //标题
text: null,
},
credits: {
enabled: false, //不显示LOGO
},
plotOptions: {
pie: {
allowPointSelect: false,
cursor: "pointer",
depth: 20,
textShadow: false,
softConnector: false,
states: {
inactive: {
opacity: 1,
size: "100%",
},
},
},
},
series: [
{
type: "pie",
name: "",
showInLegend: true, // 默认值
data: this.dataList,
dataLabels: {
enabled: true,
alignTo: "toPlotEdges",
y: -14,
connectorColor: "rgba(133, 205, 247, 1)", //引导线
connectorShape: function (labelPosition, connectorPosition) {
var touchingSliceAt = connectorPosition.touchingSliceAt,
alignment = labelPosition.alignment,
left = 0,
right = 0;
if (alignment == "left") {
left = labelPosition.x + this.dataLabel.bBox.width + 14;
right = labelPosition.x + 2;
} else {
left = labelPosition.x - this.dataLabel.bBox.width - 14;
right = labelPosition.x - 2;
}
return [
"M",
left,
labelPosition.y,
"L",
right,
labelPosition.y,
"L",
touchingSliceAt.x,
touchingSliceAt.y,
];
},
formatter: function () {
let dd = _this.optionData.filter(item=>{
if(item.name===this.key){
return item
}
})
return dd[0].y+'%' || '' ;
},
distance: 20,
style: {
color: "#FFFFFF",
fontSize: "12px",
textOutline: "none",
fontWeight: "400",
},
},
},
],
});
},
},
};
</script>
<style scoped>
.bg {
z-index: 999;
width: 100%;
height: 100%;
position: relative;
background-image: url("../assets/dizuo.png");
background-size: 65% 70%;
background-repeat: no-repeat;
background-position-x: center;
background-position-y: 80%;
}
</style>