Highcharts|How to using Angular to synchronize multiple chart

highcharts logo


scenario

Highcharts 做為一家專業圖表視覺化工具,在巨量資料的呈現,以及效能的表現,可算是佼佼者,並且在圖表上的視覺設定,或是需要客製化的部份,都有很多可以調整的設定,並在社群上可以找到大量的範例,不論是官方或是使用者,讓新進的使用者可以較快上手 Highcharts 的使用。

此次的範例為使用 Angular,並套用 HIghcharts 的方式建立多個 Charts ,可以讓數值進行同步顯示。


安裝 Highcharts

npm install highcharts highcharts-angular


在 Module 中加入 Highcharts 模組

import { HighchartsChartModule } from 'highcharts-angular'; 
@NgModule({
imports: [
... HighchartsChartModule


在 Component 中加入 Highcharts 套件

import * as Highcharts from 'highcharts';


建立 Highcharts Components

透過 ngFor 將多個 Chart Config 進行迴圈,呈現多組 Charts,並在最外層包一個 synchronizeTooltips 處理同步事件。

<div (mousemove)="synchronizeTooltips($event)">
  <highcharts-chart [Highcharts]="Highcharts" style="width: 100%;display:
  block;margin:10px 0;" [options]="chartOption" *ngFor="let chartOption of
  chartOptions">
</highcharts-chart>
</div>


在 component 中將 Highcharts 實體化,並實作 synchronizeTooltips 的事件。

export class SyncHighchartComponent implements OnInit {
  Highcharts: typeof Highcharts = Highcharts;
  @Input() public chartOptions: Array = [];

  constructor() { }

  synchronizeTooltips = e => {

    for (let i = 0; i < Highcharts.charts.length; ++i) {
      if (!Highcharts.charts[i]) continue;
      let chart = Highcharts.charts[i];

      let event = chart.pointer.normalize((e as (MouseEvent | PointerEvent | TouchEvent)));
      let point = undefined;
      for (let j = 0; j < chart.series.length && !point; ++j) {
        point = chart.series[j].searchPoint(event, true);
      }

      if (!point) return;

      if (e.type === "mousemove") {
        point.onMouseOver();
        // console.log(chart.xAxis[0]);
        chart.xAxis[0].drawCrosshair(event, point);
      } else {
        point.onMouseOut();
        chart.tooltip.hide(point);
        chart.xAxis[0].hideCrosshair();
      }
    }
  };

  ngOnInit(): void {
  }

}


取用 Highcharts Component 在其他應用

套用上面建立的 highcharts component,selector 為 app-sync-highchart,並將整理好的 chart config list 指給 input 參數。

<app-sync-highchart [chartOptions]="shortSeriesChartOption"></app-sync-highchart>


接著在程式中,整理好需要的設定值,像是 title、xAxis type、tooltip 等等的格式或樣式。

              {
                chart: {
                  height: 200,
                  zoomType: 'x',
                  marginLeft: 40, // Keep all charts left aligned
                  spacingTop: 20,
                  spacingBottom: 20,
                  className: "chart-short"
                },
                loading: {
                  hideDuration: 1000,
                  showDuration: 1000
                },
                title: {
                  text: 'CPU',
                  align: 'left',
                  margin: 0,
                  x: 30,
                  style: {
                    fontSize: '18px'
                  }
                },
                credits: {
                  enabled: false
                },
                legend: {
                  enabled: false
                },
                plotOptions: {
                  series: {
                    stacking: 'normal',
                    states: {
                      inactive: {
                        opacity: 1
                      }
                    },
                  },
                  areaspline: {
                    fillOpacity: 0.5
                  }
                },
                xAxis: {
                  crosshair: true,
                  events: {
                    setExtremes: function (e) {
                      var thisChart = this.chart;

                      if (e.trigger !== "syncExtremes") {
                        // Prevent feedback loop
                        Highcharts.each(Highcharts.charts, function (chart) {

                          if (!chart) {
                            return;
                          }


                          if (chart !== thisChart && chart.options.chart.className === thisChart.options.chart.className) {
                            if (!chart) return;
                            if (chart.xAxis[0].setExtremes) {
                              // It is null while updating
                              chart.xAxis[0].setExtremes(e.min, e.max, undefined, false, {
                                trigger: "syncExtremes"
                              });
                            }
                          }
                        });
                      }
                    }
                  },
                  labels: {
                    format: '{value:%m-%d}'
                  },
                  type: "datetime"
                },
                yAxis: {
                  title: {
                    text: null
                  }
                },
                tooltip: {
                  shared: true,
                  positioner: function () {
                    return {
                      x: this.chart.chartWidth - 200, // right aligned
                      y: 10 // align to title
                    };
                  },
                  borderWidth: 0,
                  backgroundColor: 'none',
                  pointFormat: '{series.name}: {point.y}',
                  headerFormat: '',
                  shadow: false,
                  style: {
                    fontSize: '12px'
                  },
                  valueDecimals: 2,
                  valueSuffix: '%',
                },
                series: series
              }


最重要是將資料放入到 series 設定中,也可以同步設定透明度、顏色、chart type 等等。

[
  {
    "name": "bytes_recv",
    "type": "areaspline",
    "fillOpacity": 0.3,
    "data": [
      [
        1659715260000,
        0.08
      ],
      [
        1659715320000,
        0.04
      ],
      [
        1659715380000,
        0.04
      ]
    ],
    "color": "#FAA50C"
  },
  {
    "name": "bytes_sent",
    "type": "areaspline",
    "fillOpacity": 0.3,
    "data": [
      [
        1659715260000,
        0
      ],
      [
        1659715320000,
        0
      ],
      [
        1659715380000,
        0
      ]
    ],
    "color": "#AB4BEB"
  }
]


呈現結果

highcharts demo

highcharts demo


延伸閱讀
aa71435723的大頭照
Winston

Eggplant DAI 自動化測試專家。

留言