Angular14中基于Highcharts实现带三角指示器双表盘的速度仪表盘
在Angular 14中实现带双层表盘与三角指示器的Highcharts速度表
完全可以实现这个需求,核心思路是利用Highcharts的多系列仪表盘能力+自定义图形渲染API,下面是具体实现方案:
1. 基础环境准备
确保Angular项目已安装依赖包:
npm install highcharts highcharts-angular
2. 实现双层仪表盘
通过添加两个gauge类型的系列,分别配置内层、外层表盘的半径、刻度、颜色等参数:
import { Component } from '@angular/core'; import * as Highcharts from 'highcharts'; import highchartsGauge from 'highcharts/modules/gauge'; highchartsGauge(Highcharts); @Component({ selector: 'app-speed-gauge', template: `<highcharts-chart [Highcharts]="Highcharts" [options]="chartOptions"></highcharts-chart>` }) export class SpeedGaugeComponent { Highcharts = Highcharts; chartOptions: Highcharts.Options = { chart: { type: 'gauge', plotBackgroundColor: null, plotBackgroundImage: null, plotBorderWidth: 0, plotShadow: false }, title: { text: '速度表' }, pane: { startAngle: -150, endAngle: 150, background: [ // 内层表盘背景 { backgroundColor: { linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, stops: [[0, '#FFF'], [1, '#EEE']] }, borderWidth: 0, outerRadius: '80%', innerRadius: '60%' }, // 外层表盘背景 { backgroundColor: { linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, stops: [[0, '#DDD'], [1, '#BBB']] }, borderWidth: 0, outerRadius: '100%', innerRadius: '82%' } ] }, yAxis: [ // 内层轴配置 { min: 0, max: 100, lineWidth: 0, tickPositions: [0, 25, 50, 75, 100], tickWidth: 2, tickLength: 10, tickPosition: 'inside', labels: { distance: 20, style: { fontSize: '12px' } }, title: { text: '内层速度', y: 40 }, plotBands: [{ from: 0, to: 60, color: '#55BF3B' }, { from: 60, to: 80, color: '#DDDF0D' }, { from: 80, to: 100, color: '#DF5353' }], radius: '80%', innerRadius: '60%' }, // 外层轴配置 { min: 0, max: 200, lineWidth: 0, tickPositions: [0, 50, 100, 150, 200], tickWidth: 2, tickLength: 10, tickPosition: 'inside', labels: { distance: 20, style: { fontSize: '12px' } }, title: { text: '外层速度', y: 70 }, plotBands: [{ from: 0, to: 120, color: '#55BF3B' }, { from: 120, to: 160, color: '#DDDF0D' }, { from: 160, to: 200, color: '#DF5353' }], radius: '100%', innerRadius: '82%' } ], series: [ // 内层指针 { type: 'gauge', name: '内层速度', data: [75], yAxis: 0, dial: { radius: '80%', baseWidth: 4, baseLength: '10%', rearLength: '0%' } }, // 外层指针 { type: 'gauge', name: '外层速度', data: [140], yAxis: 1, dial: { radius: '100%', baseWidth: 4, baseLength: '10%', rearLength: '0%' } } ] }; }
3. 添加外层三角指示器
利用Highcharts的renderer API,在图表加载完成后绘制自定义三角形指示器:
// 在chartOptions的chart属性中添加events配置 chart: { type: 'gauge', plotBackgroundColor: null, plotBackgroundImage: null, plotBorderWidth: 0, plotShadow: false, events: { load: function(this: Highcharts.Chart) { const chart = this; // 基于外层轴的数值计算三角位置(示例对应140的位置) const outerAxis = chart.yAxis[1] as Highcharts.Axis; const angle = outerAxis.toRad(outerAxis.translate(140, false, true, false, true)); const radius = outerAxis.radius; const centerX = chart.plotLeft + chart.plotWidth / 2; const centerY = chart.plotTop + chart.plotHeight / 2; // 定义三角形的三个顶点坐标 const x = centerX + radius * Math.cos(angle); const y = centerY + radius * Math.sin(angle); // 绘制三角形并设置样式 chart.renderer.polygon([ [x, y], [x - 10, y + 15], [x + 10, y + 15] ]) .attr({ fill: '#FF0000', stroke: '#000', 'stroke-width': 1 }) .add(); } } },
4. 动态更新指示器
如果需要根据数据变化更新三角位置,可在组件中添加更新方法,先销毁旧图形再重新绘制:
// 组件内添加更新方法 updateTriangle(newValue: number) { const chart = this.Highcharts.charts[0]; if (!chart) return; // 移除旧的三角指示器 if (chart.triangle) { chart.triangle.destroy(); } // 计算新位置并绘制 const outerAxis = chart.yAxis[1] as Highcharts.Axis; const angle = outerAxis.toRad(outerAxis.translate(newValue, false, true, false, true)); const radius = outerAxis.radius; const centerX = chart.plotLeft + chart.plotWidth / 2; const centerY = chart.plotTop + chart.plotHeight / 2; const x = centerX + radius * Math.cos(angle); const y = centerY + radius * Math.sin(angle); chart.triangle = chart.renderer.polygon([ [x, y], [x - 10, y + 15], [x + 10, y + 15] ]) .attr({ fill: '#FF0000', stroke: '#000', 'stroke-width': 1 }) .add(); }
关键注意事项
- 必须正确引入Highcharts的gauge模块,否则仪表盘无法渲染。
- 计算三角位置时,使用Highcharts轴的
translate和toRad方法保证坐标准确性。 - 动态更新时要销毁旧图形,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Bakeetha
相关产品推荐
相关产品推荐

