|
@@ -1,254 +1,267 @@
|
|
|
<template>
|
|
|
- <div ref="chartContainer" class="chart-container"></div>
|
|
|
+ <div id="echart-container" ref="chartContainer" class="chart-container"></div>
|
|
|
</template>
|
|
|
|
|
|
-<script setup>
|
|
|
-import { onMounted, ref, nextTick } from 'vue'
|
|
|
-import Highcharts from "highcharts"; //为防止报错在页面上再次引入Highcharts
|
|
|
-// 引用所需外部资源
|
|
|
-import Highcharts3d from "highcharts/highcharts-3d";
|
|
|
+<script>
|
|
|
+// import Highcharts from "highcharts";
|
|
|
+import Highcharts from 'highcharts'
|
|
|
+import Highcharts3D from 'highcharts/highcharts-3d'
|
|
|
+import backgroundImg from '@/assets/img/底.png' // 修正图片路径
|
|
|
|
|
|
-// 注册Highcharts 3D模块
|
|
|
-// Highcharts3D(Highcharts);
|
|
|
-
|
|
|
-
|
|
|
-// 数据
|
|
|
-const data = [
|
|
|
- { name: '风险个案', count: 35, h: 70 },
|
|
|
- { name: '风险事件', count: 30, h: 60 },
|
|
|
- { name: '风险信息', count: 30, h: 60 }
|
|
|
-]
|
|
|
-const chartContainer = ref(null)
|
|
|
-onMounted(() => {
|
|
|
- const chart = Highcharts.chart(chartContainer.value, {
|
|
|
- chart: {
|
|
|
- type: 'pie', // 饼图类型
|
|
|
- backgroundColor: 'transparent',
|
|
|
- options3d: {
|
|
|
- enabled: true, // 启用 3D
|
|
|
- alpha: 65, // 3D 角度
|
|
|
- beta: 0, // 旋转角度
|
|
|
- depth: 50 // 深度
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- },
|
|
|
- title: {
|
|
|
- text: ''
|
|
|
- },
|
|
|
- plotOptions: {
|
|
|
- pie: {
|
|
|
- innerSize: '60%', // 环形图内圆的大小
|
|
|
- depth: 45, // 环形图的 3D 深度
|
|
|
- dataLabels: {
|
|
|
- enabled: true,
|
|
|
- format: '{point.name}: {point.percentage:.1f}%' // 显示数据标签
|
|
|
+Highcharts3D(Highcharts)
|
|
|
+export default {
|
|
|
+ components: {},
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ id: 'echart-container',
|
|
|
+ optionData: [
|
|
|
+ { name: '风险个案', y: 35, h: 22, color: '#27c3e8' },
|
|
|
+ { name: '风险事件', y: 30, h: 15, color: '#3b76f6' },
|
|
|
+ { name: '风险信息', y: 30, h: 15, color: '#26b99a' }
|
|
|
+ ]
|
|
|
+ // optionData: [
|
|
|
+ // { name: "个人网银", y: 520, h: 40 }, //模块名和所占比,也可以{name: '测试1',y: 12}
|
|
|
+ // { name: "个人手机银行", y: 140, h: 11 }, //模块名和所占比,也可以{name: '测试1',y: 12}
|
|
|
+ // { name: "企业网银", y: 1, h: 17 }, //模块名和所占比,也可以{name: '测试1',y: 12}
|
|
|
+ // { name: "企业手机银行", y: 350, h: 28 }, //模块名和所占比,也可以{name: '测试1',y: 12}
|
|
|
+ // ],
|
|
|
+ // optionData: [
|
|
|
+ // { name: "个人网银", y: 1, h: 25 }, //模块名和所占比,也可以{name: '测试1',y: 12}
|
|
|
+ // { name: "个人手机银行", y: 1, h: 25 }, //模块名和所占比,也可以{name: '测试1',y: 12}
|
|
|
+ // { name: "企业网银", y: 1, h: 25 }, //模块名和所占比,也可以{name: '测试1',y: 12}
|
|
|
+ // { name: "企业手机银行", y: 1, h: 25 }, //模块名和所占比,也可以{name: '测试1',y: 12}
|
|
|
+ // ],
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.init()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ init() {
|
|
|
+ // 修改3d饼图绘制过程
|
|
|
+ let 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
|
|
|
}
|
|
|
- },
|
|
|
- // 为每个环块设置不同的深度
|
|
|
- point: {
|
|
|
- events: {
|
|
|
- mouseOver: function () {
|
|
|
- this.update({
|
|
|
- depth: this.h // 使用 h 值调整深度
|
|
|
- });
|
|
|
- }
|
|
|
+ console.log('this.chart.is3d', this.chart.is3d)
|
|
|
+ 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
|
|
|
+ console.log('@@@!', this)
|
|
|
+ if (seriesOptions.grouping !== false) {
|
|
|
+ z = 0
|
|
|
}
|
|
|
- }
|
|
|
- },
|
|
|
- series: [
|
|
|
- // {
|
|
|
- // name: '风险类型',
|
|
|
- // data: data.map(item => ({
|
|
|
- // name: item.name,
|
|
|
- // y: item.count,
|
|
|
- // h: item.h, // 将 h 值传递给每个数据项
|
|
|
- // depth: item.h // 设置环块的深度为 h 值
|
|
|
- // }))
|
|
|
- // },
|
|
|
- {
|
|
|
- name: '风险类型',
|
|
|
- data: data.map(item => ({
|
|
|
- name: item.name,
|
|
|
- y: item.count,
|
|
|
- h: item.h, // 将 h 值传递给每个数据项
|
|
|
- depth: item.h // 设置环块的深度为 h 值
|
|
|
- })),
|
|
|
- // showInLegend: true,
|
|
|
- dataLabels: {
|
|
|
- padding: -10,
|
|
|
- shadow: true,
|
|
|
- style: {
|
|
|
- fontWeight: 'bold',
|
|
|
- fontSize: '14px',
|
|
|
- color: "#fff",
|
|
|
- textOutline: '1px 1px transparent',
|
|
|
- },
|
|
|
- formatter: function (params) {
|
|
|
- return this.key + '<br/>' + '<p style="color:#00afff">' + (this.y / this.total * 100).toFixed(2) + '%</p>';
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
- ],
|
|
|
- tooltip: {
|
|
|
- pointFormat: '{series.name}: <b>{point.y}</b><br/>'
|
|
|
- },
|
|
|
- credits: {
|
|
|
- enabled: false,
|
|
|
- //href: "http://www.hcharts.cn", //自定义链接
|
|
|
- //text:"", //自定义内容
|
|
|
- },
|
|
|
-
|
|
|
- })
|
|
|
-
|
|
|
- // nextTick(() => {
|
|
|
- // init()
|
|
|
- // })
|
|
|
+ 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 + 1) / 100
|
|
|
+ return ret
|
|
|
+ })
|
|
|
+ })(Highcharts)
|
|
|
|
|
|
+ //日总存煤量
|
|
|
+ let mychart = Highcharts.chart('echart-container', {
|
|
|
+ chart: {
|
|
|
+ type: 'pie',
|
|
|
+ backgroundColor: 'transparent',
|
|
|
+ margin: [0, 0, 0, 0],
|
|
|
+ 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
|
|
|
+ })
|
|
|
+ })
|
|
|
+ // 添加底部背景图(居中显示)
|
|
|
+ // const centerX = this.plotLeft + this.plotWidth / 2
|
|
|
+ // const centerY = this.plotTop + this.plotHeight / 2
|
|
|
+ // const radius = 140 // 与innerSize一致
|
|
|
+ // this.renderer
|
|
|
+ // .image(
|
|
|
+ // backgroundImg, // 使用导入的图片路径
|
|
|
+ // centerX - radius,
|
|
|
+ // // centerY - radius + maxHeight, // 向下偏移maxHeight实现底部对齐
|
|
|
+ // centerY - radius-50, // 向下偏移maxHeight实现底部对齐
|
|
|
+ // radius * 2,
|
|
|
+ // radius * 2
|
|
|
+ // )
|
|
|
+ // .add()
|
|
|
|
|
|
-})
|
|
|
+ const chart = this
|
|
|
+ const options3d = chart.options.chart.options3d
|
|
|
+ const alpha = options3d.alpha
|
|
|
+ const radius = 180 // 外半径 = size/2 = 180/2
|
|
|
|
|
|
+ // 计算3D倾斜导致的垂直偏移量
|
|
|
+ const deltaY = radius * Math.sin(alpha * Math.PI / 180) * 0.5
|
|
|
|
|
|
-// function init () {
|
|
|
-// // 修改3d饼图绘制过程
|
|
|
-// // let each = HighCharts.each,
|
|
|
-// let 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));
|
|
|
-// console.log(ret);
|
|
|
-// ret.zTop = (ret.zOut + 1) / 100;
|
|
|
-// return ret;
|
|
|
-// });
|
|
|
-// }(HighCharts));
|
|
|
+ // 获取图表中心坐标
|
|
|
+ const centerX = chart.plotLeft + chart.plotWidth / 2 -10
|
|
|
+ const centerY = chart.plotTop + chart.plotHeight - deltaY - 20
|
|
|
|
|
|
-// //日总存煤量
|
|
|
-// HighCharts.chart(chartContainer.value, {
|
|
|
-// chart: {
|
|
|
-// type: 'pie',
|
|
|
-// backgroundColor: 'transparent',
|
|
|
-// events: {
|
|
|
-// load: function () {
|
|
|
-// let 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
|
|
|
-// });
|
|
|
-// });
|
|
|
-// }
|
|
|
-// },
|
|
|
-// options3d: {
|
|
|
-// enabled: true,
|
|
|
-// alpha: 65
|
|
|
-// },
|
|
|
-// },
|
|
|
-// title: {
|
|
|
-// text: ''
|
|
|
-// },
|
|
|
-// legend: { //图例
|
|
|
-// layout: "horizontal",
|
|
|
-// verticalAlign: "bottom",
|
|
|
-// align: "center",
|
|
|
-// y: 15,
|
|
|
-// x: 0,
|
|
|
-// useHTML: true,
|
|
|
-// symbolWidth: 10,
|
|
|
-// symbolHeight: 10,
|
|
|
-// labelFormatter: function () {
|
|
|
-// return this.name + '<span style="margin-left: 10px">' + this.y + '</span>吨';
|
|
|
-// },
|
|
|
-// itemStyle: {
|
|
|
-// color: '#fff',
|
|
|
-// fontSize: '14px',
|
|
|
-// }
|
|
|
-// },
|
|
|
-// tooltip: {
|
|
|
-// enabled: false,
|
|
|
-// },
|
|
|
-// credits: {
|
|
|
-// enabled: false,
|
|
|
-// },
|
|
|
-// plotOptions: {
|
|
|
-// pie: {
|
|
|
-// center: ['50%', '68%'],
|
|
|
-// size: 250,
|
|
|
-// innerSize: 140,
|
|
|
-// colors: ['#249ba5', '#2765b0', '#78c5ef', '#f6c155', '#ef8036', '#be30ff']
|
|
|
-// }
|
|
|
-// },
|
|
|
-// series: [
|
|
|
-// {
|
|
|
-// name: '青磁窑矿',
|
|
|
-// data: this.optionData,
|
|
|
-// showInLegend: true,
|
|
|
-// dataLabels: {
|
|
|
-// padding: -10,
|
|
|
-// shadow: true,
|
|
|
-// style: {
|
|
|
-// fontWeight: 'bold',
|
|
|
-// fontSize: '14px',
|
|
|
-// color: "#fff",
|
|
|
-// textOutline: '1px 1px transparent',
|
|
|
-// },
|
|
|
-// formatter: function () {
|
|
|
-// return this.key + '<br/>' + '<p style="color:#00afff">' + (this.y / this.total * 100).toFixed(2) + '%</p>';
|
|
|
-// },
|
|
|
-// },
|
|
|
-// }
|
|
|
-// ]
|
|
|
-// })
|
|
|
-// }
|
|
|
+ // 添加背景图(自动对齐)
|
|
|
+ chart.renderer
|
|
|
+ .image(
|
|
|
+ backgroundImg,
|
|
|
+ centerX - radius * 0.8, // 宽度缩放80%
|
|
|
+ centerY - radius * 0.6, // 高度缩放60%
|
|
|
+ radius * 1.6, // 宽度
|
|
|
+ radius * 1.2 // 高度
|
|
|
+ )
|
|
|
+ .attr({
|
|
|
+ // opacity: 0.8 // 添加透明度
|
|
|
+ })
|
|
|
+ .add()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ options3d: {
|
|
|
+ enabled: true,
|
|
|
+ alpha: 65
|
|
|
+ }
|
|
|
+ },
|
|
|
+ title: {
|
|
|
+ text: ''
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ //图例
|
|
|
+ enabled: false,
|
|
|
+ layout: 'horizontal',
|
|
|
+ verticalAlign: 'bottom',
|
|
|
+ align: 'center',
|
|
|
+ y: 15,
|
|
|
+ x: 0,
|
|
|
+ useHTML: true,
|
|
|
+ symbolWidth: 10,
|
|
|
+ symbolHeight: 10,
|
|
|
+ labelFormatter: function () {
|
|
|
+ return this.name
|
|
|
+ },
|
|
|
+ itemStyle: {
|
|
|
+ color: 'black',
|
|
|
+ fontSize: '14px'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ enabled: false
|
|
|
+ },
|
|
|
+ credits: {
|
|
|
+ enabled: false
|
|
|
+ },
|
|
|
+ plotOptions: {
|
|
|
+ pie: {
|
|
|
+ // dataLabels: {
|
|
|
+ // enabled: false,
|
|
|
+ // },
|
|
|
+ allowPointSelect: false,
|
|
|
+ center: ['50%', '50%'],
|
|
|
+ size: 180,
|
|
|
+ innerSize: 120,
|
|
|
+ colors: ['#21B1C4', '#7343D1', '#28A429', '#C6B031', '#9B2020', '#2862D7']
|
|
|
+ },
|
|
|
+ // series: {
|
|
|
+ // events: {
|
|
|
+ // //控制图标的图例legend不允许切换
|
|
|
|
|
|
+ // // eslint-disable-next-line
|
|
|
+ // legendItemClick: function (event) {
|
|
|
+ // console.log("@", 1111);
|
|
|
+ // return false; //return true 则表示允许切换
|
|
|
+ // },
|
|
|
+ // },
|
|
|
+ // },
|
|
|
+ series: {
|
|
|
+ events: {
|
|
|
+ legendItemClick: function () {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '风险分布图',
|
|
|
+ data: this.optionData,
|
|
|
+ showInLegend: true,
|
|
|
+ dataLabels: {
|
|
|
+ padding: -10 ,
|
|
|
+ shadow: true,
|
|
|
+ style: {
|
|
|
+ fontWeight: 'bold',
|
|
|
+ fontSize: '14px',
|
|
|
+ color: '#fff',
|
|
|
+ textOutline: '1px 1px transparent'
|
|
|
+ },
|
|
|
+ formatter: function () {
|
|
|
+ return `<span style="color:#ffffff;font-weight: bold;">${this.point.name}:</span>
|
|
|
+ <span style="color: ${this.point.color}; font-weight: bold;">${this.y}</span>`
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ // 解决圆环高度上下颠倒问题 !!!!
|
|
|
+ Highcharts.addEvent(mychart, 'redraw', function () {
|
|
|
+ var each = Highcharts.each,
|
|
|
+ points = mychart.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
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
-<style scoped>
|
|
|
+<style scoped lang="scss">
|
|
|
.chart-container {
|
|
|
margin: 0 auto;
|
|
|
width: 444px;
|