【图表】highcharts 3D立体透明饼图 带背景 vue

1,645 阅读1分钟

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>