查看: 209|回复: 0

Vue集成Highcharts饼图组件封装与动态数据渲染

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在Vue项目中使用Highcharts绘制饼图,常见做法是把图表容器封装成公共组件,再通过配置对象控制标题、提示框、图例、扇区点击和数据。原文示例适用于需要多个饼图、数据异步加载后再创建图表的页面。Highcharts与ECharts的差异原文也提到:ECharts免费,Highcharts商业用途需授权,个人使用会在图表上显示logo,选型时需结合授权场景。

一、安装与目录组织
先安装依赖:npm install highcharts。在components/commons下新建chart.vue作为图表基础组件;创建chart-options/options.js集中存放配置模型;业务页面引入chart组件和options。这样容器与配置分离,多个饼图可复用。

二、封装chart.vue
组件接收id和option两个props,id对应Highcharts渲染容器的DOM id,option是Highcharts配置对象。模板中保留一个带id的div。mounted中原文给出静态数据创建方式HighCharts.chart(this.id,this.option)的注释;动态数据场景下通过methods中的me()在数据准备好后执行创建。整理后的关键代码:
  1. <template>
  2.   <div class='x-bar'>
  3.     <div :id='id' :option='option'></div>
  4.   </div>
  5. </template>
  6. <script>
  7. import HighCharts from 'highcharts'
  8. export default {
  9.   props: {
  10.     id: { type: String },
  11.     option: { type: Object }
  12.   },
  13.   mounted() {
  14.     // 静态数据:HighCharts.chart(this.id, this.option)
  15.   },
  16.   methods: {
  17.     me() {
  18.       HighCharts.chart(this.id, this.option)
  19.     }
  20.   }
  21. }
  22. </script>
复制代码
这里需要注意:Highcharts.chart第一个参数是DOM id,模板中div的id必须与传入的id一致;动态数据不要在option尚未合并前调用me(),否则会拿到空series或空data。

三、配置options.js
options.js用构造函数维护pie配置,包含chart.type='pie'、title.text、tooltip.headerFormat/pointFormat、plotOptions.pie的allowPointSelect、cursor、dataLabels、showInLegend和events.click,以及series数组。series中colorByPoint为true,data初始为空,后续动态接收数据。funcc(op)通过Object.assign把传入的op.pie合并到this.pie。原文中let $back = $('#myBack')未被实际使用;如果项目没有引入jQuery,这行会带来额外依赖或报错,整理时可删除或确认已引入。关键配置如下:
  1. let Options = function() {
  2.   this.pie = {
  3.     chart: {
  4.       type: 'pie',
  5.       plotBackgroundColor: null,
  6.       plotBorderWidth: null,
  7.       plotShadow: false
  8.     },
  9.     title: { text: '' },
  10.     tooltip: {
  11.       headerFormat: '{series.name}<br>',
  12.       pointFormat: '{point.name}: <b>{point.percentage:.1f}%</b>'
  13.     },
  14.     plotOptions: {
  15.       pie: {
  16.         allowPointSelect: true,
  17.         cursor: 'pointer',
  18.         dataLabels: { enabled: true },
  19.         showInLegend: true,
  20.         events: {
  21.           click: function(e) {
  22.             // alert(e.point.url);
  23.             // window.open(e.point.url);
  24.             // location.href = e.point.url;
  25.           }
  26.         }
  27.       }
  28.     },
  29.     series: [{
  30.       name: '',
  31.       colorByPoint: true,
  32.       data: []
  33.     }]
  34.   }
  35. }
  36. Options.prototype.funcc = function(op) {
  37.   if (op.pie != null) {
  38.     this.pie = Object.assign(this.pie, op.pie)
  39.   }
  40. }
  41. export default new Options()
复制代码
tooltip的pointFormat使用point.percentage并保留一位小数;数据点若需要点击跳转,可按事件注释中的e.point.url、window.open或location.href实现,但原文只是预留注释,没有启用跳转。

四、业务页面引用与动态渲染
页面中放两个容器pie1、pie2,分别用x-chart渲染,传入id1/id2和option1/option2。data中option1、option2初始为null,等chartPie1等异步方法合并配置后再赋值。chartPie1返回Promise,内部调用options.funcc合并title和series;series.data支持数组简写和对象写法:['A', p1]、['B', p2]、['C', p3],D点用{name:'D', y:p4, url:'', sliced:true, selected:true}强调扇区,E点为['E', p5],p1到p5表示百分占比。合并后把options.pie赋给this.option1,resolve后在then中调用this.$refs.XChart1.me()创建图表。关键代码:
  1. <template>
  2.   <div class='pie'>
  3.     <div id='pie1'>
  4.       <x-chart ref='XChart1' :id='id1' :option='option1'></x-chart>
  5.     </div>
  6.     <div id='pie2'>
  7.       <x-chart ref='XChart2' :id='id2' :option='option2'></x-chart>
  8.     </div>
  9.   </div>
  10. </template>
  11. <script>
  12. import XChart from 'components/chart.vue'
  13. import options from './chart-options/options'
  14. export default {
  15.   data() {
  16.     return {
  17.       id1: 'pie1',
  18.       option1: null,
  19.       id2: 'pie2',
  20.       option2: null
  21.     }
  22.   },
  23.   components: { XChart },
  24.   methods: {
  25.     chartPie1() {
  26.       return new Promise((resolve, reject) => {
  27.         options.funcc({
  28.           pie: {
  29.             title: { text: '饼图1name' },
  30.             series: [{
  31.               name: '情况占比',
  32.               data: [
  33.                 ['A', p1],
  34.                 ['B', p2],
  35.                 ['C', p3],
  36.                 { name: 'D', y: p4, url: '', sliced: true, selected: true },
  37.                 ['E', p5]
  38.               ]
  39.             }]
  40.           }
  41.         })
  42.         let option1 = options.pie
  43.         this.option1 = option1
  44.         resolve()
  45.       }).then(resp => {
  46.         this.$refs.XChart1.me()
  47.       })
  48.     }
  49.   }
  50. }
  51. </script>
复制代码
原文data里还出现let option = options.bar,但后续实际使用的是options.pie,该变量未参与渲染,可视为遗留代码;整理时不必保留。另原文components: {XChart}后使用了中文逗号,复制到项目时必须改为英文逗号,否则编译会报语法错误。id重复也会导致Highcharts找不到容器或渲染到错误节点,页面中pie1/pie2与id1/id2需保持唯一对应。

五、排查与适用场景
如果图表不显示,优先检查:依赖是否安装、chart.vue的div id是否与传入id一致、me()是否在option赋值后调用、series.data是否已传入、funcc合并时是否覆盖了series、页面是否存在重复id、components对象是否使用英文逗号。该方案适合Vue2页面中多个Highcharts饼图复用同一配置模型、异步请求数据后渲染的场景;如果只是静态图表,可在mounted中直接创建;如果需要点击扇区跳转,可启用events.click中的e.point.url逻辑。选型上需注意Highcharts商业授权和个人使用logo显示的限制。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-24 11:57 , Processed in 0.024319 second(s), 28 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部