0
点赞
收藏
分享

微信扫一扫

HighCharts实现3D不同高度圆环图、3D饼图

大师的学徒 2022-04-04 阅读 99
Vue3前端

最近做可视化比较多,就常用的图表类型做了一下总结。

因为做可视化的图表代码量非常大,所以会把echarts图表单独抽离出来,封装成一个组件,也可以复用,所以这里我直接把封装的组件直接放在这里,是可以直接拿来用的,根据所需稍作修改即可。

这里都是用的vue3,其实和vue2差不多,在写法上稍作修改即可

第一步首先安装 highcharts 

npm install highcharts --save

第二步 main.js 引入 3d相关 

import highcharts from 'highcharts'
import highcharts3d from 'highcharts/highcharts-3d'

highcharts3d(highcharts)

 接下来封装成组件

一.  3D饼图

 

<template>
  <div :id="id" style="width: 100%; height: 100%"></div>
</template>
<script setup>
import highcharts from "highcharts";
import { fontChart } from "@/utils/echartPxToRem";
import { onMounted, watch, onUnmounted } from "vue";

const props = defineProps({
  id: {
    type: String,
    required: true,
  },
  pieData: {
    type: Array,
    default: () => ([
      ["综采", 3],
      ["综掘", 6],
      ["胶带运输", 4],
      ["排水", 3],
      ["通风", 3],
      ["压风", 4],
    ]),
  },
});

watch(
  () => props.pieData,
  (newValue) => {
    initOption();
  },
  {
    deep: true,
  }
);

onMounted(() => {
  initOption();
  window.addEventListener("resize", initOption);
});

onUnmounted(() => {
  window.removeEventListener("resize", initOption);
});
//  初始化echarts
const initOption = () => {
  let option = {
    chart: {
      backgroundColor: "none",
      type: "pie", //饼图
      margin: [0, 0, 0, 100],
      options3d: {
        enabled: true, //使用3d功能
        alpha: fontChart(18), //延y轴向内的倾斜角度
        beta: fontChart(0),
      },
    },
    title: {
      text: "", //图表的标题文字
    },
    plotOptions: {
      pie: {
        allowPointSelect: true, //每个扇块能否选中
        cursor: "pointer", //鼠标指针
        depth: fontChart(105), //饼图的厚度
        showInLegend: true, // 是否显示图例
        // center: ['30%', '60%'],
        size: "78%",
        dataLabels: {
          enabled: true, //是否显示饼图的线形tip
          distance: -fontChart(35),
          align: "center",
          // position:'center',
          format: "<b>{point.y}</b>",
          style: {
            fontSize: fontChart(13),
          },
        },
        events: {
          //点击事件
          click: () => {},
        },
      },
    },
    colors: ["#59678c", "#1760bc", "#1890ff", "#06c8cd", "#03ac32", "#acff02"],
    legend: {
      align: "left", //水平方向位置
      verticalAlign: "top", //垂直方向位置
      layout: "vertical",
      x: fontChart(20),
      y: fontChart(40),
      symbolWidth: fontChart(10),
      symbolHeight: fontChart(10),
      symbolRadius: 0,
      itemMarginBottom: fontChart(4),
      itemStyle: {
        color: "#f4f4f6",
        fontSize: fontChart(14),
      },
    },
    credits: {
      enabled: false, // 禁用版权信息
    },
    series: [
      {
        type: "pie",
        name: "", //统一的前置词,非必须
        data: props.pieData,
      },
    ],
  };
  highcharts.chart(props.id, option);
};
</script>

二. 3D不同高度环形图 

 

<template>
  <div :id="id" style="width: 100%; height: 100%"></div>
</template>
<script setup>
import highcharts from "highcharts";
import { fontChart } from "@/utils/echartPxToRem";
import { onMounted, watch, onUnmounted } from "vue";

const props = defineProps({
  id: {
    type: String,
    required: true,
  },
  dataList: {
    type: Array,
    default: () => ([
      {
        name: "红草莓",
        y: 15687,
        h: 16,
        bfb: 29,
      },
      {
        name: "白草莓",
        y: 15687,
        h: 12,
        bfb: 8,
      },
      {
        name: "红颜草莓",
        y: 15687,
        h: 5,
        bfb: 11,
      },
      {
        name: "甜宝草莓",
        y: 15687,
        h: 9,
        bfb: 11,
      },
      {
        name: "红颜草莓",
        y: 15687,
        h: 8,
        bfb: 13,
      },
      {
        name: "甜宝草莓",
        y: 15687,
        h: 36,
        bfb: 18,
      },
    ]),
  },
});

watch(
  () => props.dataList,
  (newValue) => {
    initOption();
  },
  {
    deep: true,
  }
);

onMounted(() => {
  initOption();
  window.addEventListener('resize', initOption)
});

onUnmounted(() => {
  window.removeEventListener("resize", initOption);
});
//  初始化echarts
const initOption = () => {
  // 修改3d饼图绘制过程
  var each = highcharts.each,
    round = Math.round,
    cos = Math.cos,
    sin = Math.sin,
    deg2rad = Math.deg2rad;
  highcharts.wrap(
    highcharts.seriesTypes.pie.prototype,
    "translate",
    function (proceed) {
      proceed.apply(this, [].slice.call(arguments, 1));
      // Do not do this if the chart is not 3D
      if (!this.chart.is3d()) {
        return;
      }
      var series = this,
        chart = series.chart,
        options = chart.options,
        seriesOptions = series.options,
        depth = seriesOptions.depth || 0,
        options3d = options.chart.options3d,
        alpha = options3d.alpha,
        beta = options3d.beta,
        z = seriesOptions.stacking
          ? (seriesOptions.stack || 0) * depth
          : series._i * depth;
      z += depth / 2;
      if (seriesOptions.grouping !== false) {
        z = 0;
      }
      each(series.data, function (point) {
        var shapeArgs = point.shapeArgs,
          angle;
        point.shapeType = "arc3d";
        var ran = point.options.h;
        shapeArgs.z = z;
        shapeArgs.depth = depth * 0.75 + ran;
        shapeArgs.alpha = alpha;
        shapeArgs.beta = beta;
        shapeArgs.center = series.center;
        shapeArgs.ran = ran;
        angle = (shapeArgs.end + shapeArgs.start) / 2;
        point.slicedTranslation = {
          translateX: round(
            cos(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad)
          ),
          translateY: round(
            sin(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad)
          ),
        };
      });
    }
  );
  (function (H) {
    H.wrap(highcharts.SVGRenderer.prototype, "arc3dPath", function (proceed) {
      // Run original proceed method
      var ret = proceed.apply(this, [].slice.call(arguments, 1));
      ret.zTop = (ret.zOut + 0.5) / 100;
      return ret;
    });
  })(highcharts);
  highcharts.chart(props.id, {
    chart: {
      animation: false,
      backgroundColor: "none",
      type: "pie", //饼图
      margin: [0, 0, 0, 0],
      options3d: {
        enabled: true, //使用3d功能
        alpha: fontChart(58), //延y轴向内的倾斜角度
        beta: fontChart(0),
      },
      events: {
        load: function () {
          var each = highcharts.each,
            points = this.series[0].points;
          each(points, function (p, i) {
            p.graphic.attr({
              translateY: -p.shapeArgs.ran,
            });
            p.graphic.side1.attr({
              translateY: -p.shapeArgs.ran,
            });
            p.graphic.side2.attr({
              translateY: -p.shapeArgs.ran,
            });
          });
        },
      },
    },
    legend: {
      enabled: true, // 关闭图例
      align: "right", //水平方向位置
      verticalAlign: "top", //垂直方向位置
      layout: "vertical",
      x: fontChart(0),
      y: fontChart(30),
      symbolWidth: fontChart(10),
      symbolHeight: fontChart(10),
      symbolRadius: "50%", // 修改成圆
      itemMarginBottom: fontChart(8),
      labelFormat: "{name}&nbsp;&nbsp;&nbsp;&nbsp;{y}",
      itemStyle: {
        color: "#f4f4f6",
        fontSize: fontChart(12),
      },
    },
    title: {
      // enabled: false,
      text: "",
    },
    subtitle: {
      text: "",
    },
    plotOptions: {
      pie: {
        allowPointSelect: false, // 禁用点击
        cursor: "pointer",
        depth: fontChart(45),
        showInLegend: true,
        size: "65%", // 外圈直径大小
        innerSize: 95, // 内圈直径大小
        center: ["30%", "50%"],
        colors: [
          "rgba(157, 88, 32, .9)",
          "rgba(169, 199, 62, .9)",
          "rgba(11, 146, 89, .9)",
          "rgba(16, 138, 174, .9)",
          "rgba(0, 77, 161, .9)",
          "rgba(60, 32, 173, .9)",
        ],
        dataLabels: {
          enabled: true, //是否显示饼图的线形tip
          distance: fontChart(0),
          align: "center",
          position: "center",
          format: "{point.bfb}%",
          // formatter: (point,b) => {
          //   console.log(point,'ponit-->>')
          //   console.log(b,'ponit-->>')
          // },
          style: {
            fontSize: fontChart(13),
          },
        },
      },
    },
    credits: {
      enabled: false, // 禁用版权信息
    },
    series: [
      {
        type: "pie",
        name: "Browser share",
        data: props.dataList,
      },
    ],
  });
};
</script>
举报

相关推荐

0 条评论