highchart立体几何

本文介绍了如何使用Vue和Highcharts库创建一个3D动态饼图,展示了如何处理数据更新、3D效果和自定义图形布局。组件通过props接收数据,实现实时图表更新和事件响应。
摘要由CSDN通过智能技术生成

<template>
  <div id="" style="height: 100%;z-index: 4; position: relative;">
    <div class="myChart" ref="mychart" v-show="props.dataObj.length>0"></div>
    <div class="bg" v-show="props.dataObj.length>0"></div>
  </div>
</template>

<script lang="ts" setup>
import {
  ref,
  nextTick,
  getCurrentInstance,
  ComponentInternalInstance,
  onMounted,
  watch, onBeforeUnmount
} from "vue";
import HighCharts from "highcharts";
import {debounce} from "@/utils/debounce";
import Logo from "@/layout/components/Sidebar/Logo.vue";

const {
  appContext: {
    config: {
      globalProperties: {$highcharts, $utils}
    }
  }
} = getCurrentInstance() as ComponentInternalInstance;

const props = withDefaults(
  defineProps<{
    percentage: any[],
    dataObj: { [key: string]: any },
  }>(),
  {}
);
let colors = [
  "#39dda0",
  "#eed44a",
  "#33ecff",
  "#f6804d",
  "#bfef45",
  "#c59da4",
  "#73a0fa",
  "#0ea999",
  "#f5f136",
  "#ffb148",
  "#9A6324",
  "#fffac8",
  "#ffd8b1",
  "#000075",
  "#a9a9a9",
  "#ffffff"
];
let echartInstance = ref(null);
let dataPei: any = ref([]);
let mychart = ref(null);
let pirChart: any = ref(null)
const count = ref(null);
const initChart = (data: any) => {
  // dataPei= [["菏泽",1909],["济南",2350],["青岛",1234],["淄博",1102],["德州",1154],["烟台",210],["潍坊",450]]
  //  echartInstance.value =$highcharts.chart(mychart.value, {
  var each = $highcharts.each,
    round = Math.round,
    cos = Math.cos,
    sin = Math.sin,
    deg2rad = $highcharts.deg2rad;
  $highcharts.wrap($highcharts.seriesTypes.pie.prototype, 'translate', function (proceed:any) {
    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) {
      var ret = proceed.apply(this, [].slice.call(arguments, 1));
      ret.zTop = (ret.zOut + 1 ) / 100;
      return ret;
    });
  }($highcharts));
  pirChart.value = $highcharts.chart(mychart.value, {
    colors: [
      "#39dda0",
      "#33ecff",
      "#eed44a",
      "#f6804d",
      "#bfef45",
      "#c59da4",
      "#73a0fa",
      "#0ea999",
      "#f5f136",
      "#ffb148",
      "#9A6324",
      "#fffac8",
      "#ffd8b1",
      "#000075",
      "#a9a9a9",
      "#ffffff"
    ],

    chart: {
      animation: false,
      backgroundColor: '',
      type: "pie",
      events: {
        load: function () {
          let each = $highcharts.each,
            points = this.series[0].points;
          each(points, function (p) {
            p.graphic.attr({
              translateY: -p.shapeArgs.ran,
            });
            p.graphic.side1.attr({
              translateY: -p.shapeArgs.ran,
            });
            p.graphic.side2.attr({
              translateY: -p.shapeArgs.ran,
            });
          });
        },
      },
      options3d: {
        enabled: true,
        alpha: 65, //延y轴向内的倾斜角度
        // 外旋转角度
        beta: 0,

      },
    },

    title: {
      text: ""
    },
    credits: {
      enabled: false
    },
    tooltip: {
      useHTML: true,
      formatter(params) {
        dataPei.forEach(item => {
          if (item[0] == this.point.options.name) {
            count.value = item[2];
          }
        });
        var value = this.point.options.y.toFixed(2);
        return `<p style="color: #00090a;font-size:12px">${this.point.options.name}: ${value.replace(/\.?0+$/, "")}个 ( ${this.point.percentage.toFixed(2)}% )</p>`;
      }
    },
    legend: {
      // verticalAlign: "top",
      squareSymbol: false,
      itemStyle: {
        color: "#fff",
        fontSize: 12,
        fontWeight: "400",
        fontFamily: "微软雅黑",
        cursor: "default"
      },
      itemHoverStyle: {
        // cursor: "default"
        color: "#fff",
        fontSize: 12,
      },
      // layout: "vertical",
      verticalAlign: "bottom",
      align: "center",
      // x: -30, // 控制图例距离图表区域左侧的距离,值为负数表示向左移动
      itemMarginTop: 2,
      itemMarginBottom: 2,
      symbolWidth: 10,
      symbolHeight: 8,
      symbolRadius: 0,
      enabled: true,
      padding: 0
    },
    plotOptions: {
      pie: {
        allowPointSelect: false,
        depth: 35,
        size: "80%",
        innerSize: "60%",
        showInLegend: true,
        center: ["50%", "60%"],// 设置饼图的中心位置
        dataLabels: {
          enabled: true,
          zIndex: 9999, // 根据需要调整这个值
          useHTML: true,
          distance: 15,
          formatter(params) {
            dataPei.forEach(item => {
              if (item[0] == this.point.options.name) {
                count.value = item[2];
              }
            });
            var value = this.point.options.y.toFixed(2);
            return `<div style="color: #ffffff;font-size:12px;font-weight: normal"><div>${this.point.options.name}</div> <div>${this.point.percentage.toFixed(2)}% </div><div>${value.replace(/\.?0+$/, "")}个</div> </div>`;
          }
        },
      },

    },
    series: [{
      type: "pie",
      // innerSize: "55%",
      backgroundColor: "transparent",
      // name: "",
      // colorByPoint: true, // 启用为每个数据点设置颜色
      showInLegend: true, // 是否打开图例
      center: ['50%', '50%'], // 设置饼图的中心位置
      // size: '85%', // 设置饼图的大小
      data: dataPei
    }]
  });

  $highcharts.addEvent(pirChart.value, 'redraw', function () {
    var each = $highcharts.each,
      points = pirChart.value.series[0].points;
      each(points, function (p: any) {
        p.graphic.attr({
          translateY: -p.shapeArgs.ran
        });
        p.graphic.side1.attr({
          translateY: -p.shapeArgs.ran
        });
        p.graphic.side2.attr({
          translateY: -p.shapeArgs.ran
        });
      });
  })
}
  const resizeHandler = debounce(() => {
    if (pirChart.value) {
      pirChart.value.resize();
    }
  }, 200)

  onBeforeUnmount(() => {
    window.removeEventListener("resize", initChart)
  })
  onMounted(() => {
 
    window.addEventListener("resize", initChart)
  });

  watch(
    () => props.dataObj,
    () => {
      dataPei = props.dataObj;
      initChart(props.dataObj);

    },
    {deep: true}
  );
</script>

<style lang="scss" scoped>
.myChart {
  z-index: 1;
  position: absolute;
  width: 100%;
  top: -5%;
  height: 100%;
  margin: 0 auto;
}

.bg {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 54%;
  height: 100%;
  margin-left: 23%;
  background-image: url(/src/assets/networkBasicResources/bg-chart.png);
  background-size: 100% 100%;
  transform: rotateX(64deg);
  //opacity: 0.5;
}

//:deep(.highcharts-series-group .highcharts-point) {
//  opacity: 1.0 !important;
//}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值