HighCharts实现3D不同高度圆环图、3D饼图 您所在的位置:网站首页 立体圆环图 HighCharts实现3D不同高度圆环图、3D饼图

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

2024-06-03 12:41| 来源: 网络整理| 查看: 265

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

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

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

其中用到了一个 fontChart 的方法,这样是为了在window变化(改变缩放)的时候能够让字体也达到自适应,因为默认的单位是px,如果不使用的话,当我们去减小屏幕缩放的时候,这时候屏幕分辨率就会变大,但是我们的字体还是xxpx,就会让我们的字体看上去特别小,所以这里使用了这个方法,fontChart方法如下:

scr/utils/echartPxToRem.js

export function fontChart(res) { let docEl = document.documentElement, clientWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; if (!clientWidth) return; // 此处的3840 为设计稿的宽度,记得修改! let fontSize = clientWidth / 1920; return res * fontSize; }

 接下来正题:

 第一步首先安装 highcharts 

npm install highcharts --save

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

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

 然后封装成组件

一.  3D饼图

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: 18, //延y轴向内的倾斜角度 beta: 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: "{point.y}", 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); }; 二. 3D不同高度环形图 

 Vue2写法 

import highcharts from "highcharts"; import { fontChart } from "@/utils/echartPxToRem"; export default { props: { id: { type: String, required: true, }, dataList: { type: Array, default: () => ([ { name: "红草莓", y: 10254, h: 0, bfb: 0 }, { name: "白草莓", y: 6894, h: 0, bfb: 0 }, { name: "红颜草莓", y: 7667, h: 0, bfb: 0 }, { name: "甜宝草莓", y: 4287, h: 0, bfb: 0 }, { name: "红颜草莓", y: 8687, h: 0, bfb: 0 }, { name: "甜宝草莓", y: 16112, h: 0, bfb: 0 } ]) } }, watch: { dataList() { this.$nextTick(() => { this.initOption(); }); }, }, mounted() { // this.$nextTick(() => { this.initOption(); // }); window.addEventListener("resize", this.initOption); }, destroyed() { window.removeEventListener("resize", this.initOption); }, methods: { initOption() { let quantity = 0; // 总数 this.dataList.forEach((item) => { quantity += item.y; }); this.dataList.forEach((item) => { item.bfb = parseInt((item.y / quantity) * 100); item.h = item.bfb * 1.5 >= 70 ? 70 : item.bfb * 1.5 // item.h = parseInt(0.86 * item.bfb); // 最高高度60,根据比例渲染高度 // console.log(this.dataList, "dataList----->>>"); }); // 修改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(this.id, { chart: { animation: false, backgroundColor: "none", type: "pie", //饼图 margin: [0, 0, 0, 0], options3d: { enabled: true, //使用3d功能 alpha: 58, //延y轴向内的倾斜角度 beta: 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(-20), y: fontChart(30), symbolWidth: fontChart(10), symbolHeight: fontChart(10), symbolRadius: "50%", // 修改成圆 itemMarginBottom: fontChart(8), useHTML: true, //labelFormat: '{name};;;;{y}', labelFormatter: function () { return ( '' + this.name + ':;;' + this.y + "" ); }, itemStyle: { color: "#f4f4f6", fontSize: fontChart(12), }, }, title: { // enabled: false, text: "", }, subtitle: { text: "", }, plotOptions: { pie: { allowPointSelect: false, // 禁用点击 cursor: "pointer", depth: fontChart(15), showInLegend: true, size: "75%", // 外圈直径大小 innerSize: fontChart(95), // 内圈直径大小 center: ["30%", "50%"], colors: [ "rgb(235,147,39)", "rgb(234,219,54)", "rgb(12,214,137)", "rgb(25,234,219)", "rgb(13,145,239)", "rgb(167,67,234)", ], dataLabels: { useHTML: true, enabled: true, //是否显示饼图的线形tip distance: 5, borderColor: '#007acc', align: "center", // verticalAlign: 'top', position: "right", format: "{point.bfb}%", // formatter: (point,b) => { // console.log(point,'ponit-->>') // console.log(b,'ponit-->>') // }, color: "#ffffff", style: { textOutline: "none", fontSize: fontChart(13), }, }, }, }, credits: { enabled: false, // 禁用版权信息 }, series: [ { type: "pie", name: "数量", data: this.dataList, }, ], }); }, }, };

Vue3写法 

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 = () => { let quantity = 0; // 总数 props.dataList.forEach((item) => { quantity += item.y; }); props.dataList.forEach((item) => { item.bfb = parseInt((item.y / quantity) * 100); item.h = item.bfb * 1.5 >= 70 ? 70 : item.bfb * 1.5 // item.h = parseInt(0.86 * item.bfb); // 最高高度60,根据比例渲染高度 // console.log(props.dataList, "dataList----->>>"); }); // 修改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: 58, //延y轴向内的倾斜角度 beta: 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};;;;{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: fontChart(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, }, ], }); };


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有