1. 程式人生 > >chart.js angular組件封裝(ng6)、實戰配置、插件編寫

chart.js angular組件封裝(ng6)、實戰配置、插件編寫

UNC 小結 鉤子 也有 idt 文件 lob 函數 ===

前言

項目需要使用chart.js插件,由於項目是使用angular開發,那麽我第一步就是先把chart.js改造成angular組件來使用。

本項目代碼都可以在github上下載:項目git地址

angular改造

1、搭建angular項目步驟省略了,可以自行查詢ng官方文檔

2、創建一個chart-js的組件

ng g c chart-js

chart-js.component.html

<div style="display: block; height: 100%">
  <canvas #canvas></canvas>
</div>

chart-js.component.ts

import {
  Component,
  OnInit,
  ViewChild,
  ElementRef,
  AfterViewInit,
  Input,
  OnChanges,
  SimpleChanges,
  OnDestroy
} from "@angular/core";
import "chart.js";

declare var window: any;
@Component({
  selector: 'chart-js',
  templateUrl: './chart-js.component.html',
  styleUrls: ['./chart-js.component.css']
})
export class ChartJsComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy {

  @ViewChild("canvas") canvas: ElementRef;

  @Input() config;

  private chart;

  constructor() { }

  ngOnInit() {
  }
  // 子組件加載完成後,渲染圖標
  ngAfterViewInit() {
    this.render();
  }
  // 渲染圖表
  render() {
    this.chart = new window.Chart(
      this.canvas.nativeElement.getContext("2d"),
      this.config
    );
    this.chart.height = "100%";
  }
  // 判斷Input參數config 是否變化,如果變化,觸發更新繪圖
  ngOnChanges({ config }: SimpleChanges) {
    if (config && !config.isFirstChange()) {
      this.destroyChart();
      this.render();
    }
  }
  // 銷毀chart  
  ngOnDestroy() {
    this.destroyChart();
  }
  // 銷毀chart主體
  destroyChart() {
    if (this.chart) {
      this.chart.destroy();
      this.chart = undefined;
    }
  }
}

好了angular組件就這樣改造完成了,接下來我們看下如何調用把

// html
<div style="width:50%;margin:0 auto;">
  <chart-js [config]="config"></chart-js>
</div>

// ts
// 一份簡單的配置,後續會詳細解釋配置的含義
this.config = {
      type: 'bar',
      data: {
        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
        datasets: [{
          label: '# of Votes',
          data: [12, 19, 3, 5, 2, 3],
          backgroundColor: [
            'rgba(255, 99, 132, 0.2)',
            'rgba(54, 162, 235, 0.2)',
            'rgba(255, 206, 86, 0.2)',
            'rgba(75, 192, 192, 0.2)',
            'rgba(153, 102, 255, 0.2)',
            'rgba(255, 159, 64, 0.2)'
          ],
          borderColor: [
            'rgba(255,99,132,1)',
            'rgba(54, 162, 235, 1)',
            'rgba(255, 206, 86, 1)',
            'rgba(75, 192, 192, 1)',
            'rgba(153, 102, 255, 1)',
            'rgba(255, 159, 64, 1)'
          ],
          borderWidth: 1
        }]
      },
      options: {
        scales: {
          yAxes: [{
            ticks: {
              beginAtZero:true
            }
          }]
        },
        onHover(event, elements) {
          console.log(event,elements);
        },
      }
    }

看下效果吧:
技術分享圖片

配置詳解

具體配置可以參考下面鏈接,非常全面
Chart.js中文文檔

配置一個復合圖表

經常可以看到一個數據表中包含幾種方式的展示具體看圖:
技術分享圖片
既有柱狀圖也有折線圖。像這樣的該如何進行配置呢?
只需要在dataset裏面新增一種數據類型並制定相應的type即可,具體如下

        datasets: [
          {
            label: '# of Votes',
            data: [12, 19, 3, 5, 2, 3],
            backgroundColor: [
              'rgba(255, 99, 132, 0.2)',
              'rgba(54, 162, 235, 0.2)',
              'rgba(255, 206, 86, 0.2)',
              'rgba(75, 192, 192, 0.2)',
              'rgba(153, 102, 255, 0.2)',
              'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
              'rgba(255,99,132,1)',
              'rgba(54, 162, 235, 1)',
              'rgba(255, 206, 86, 1)',
              'rgba(75, 192, 192, 1)',
              'rgba(153, 102, 255, 1)',
              'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
          },
          {
            type: "line", // 將此數據集類型變為折線圖
            label: "Line Dataset",
            data: [3, 5, 7, 16]
          }
        ]

查看完整配置代碼

chart.js 插件編寫

插件擴展分為全局插件和內聯插件

【內聯插件】

插件也可以直接在圖表插件配置(即內聯插件)中定義

var chart = new Chart(ctx, {
    plugins: [
        {
            beforeInit: function(chart, options) {
                //..
            }
        }
    ]
});

【全局插件】

插件可以在全局範圍內註冊,應用於所有圖表(即全局插件)

Chart.pluginService.register({
    // plugin implementation
});

【編寫一個插件】
回顧下上面我們畫的圖表
技術分享圖片

如果這個時候產品跟我們說,想在這個圖表上添加一個背景色,且背景色可以設置。

我們趕緊翻到柱狀/條形圖(Bar)的配置這裏查看,發現並沒有這個配置項,只能對各個柱狀/條形圖填充色。並不能對整個背景填充顏色

怎麽辦?編寫插件吧。

查看下文檔發現插件提供了一些鉤子函數給我們:
技術分享圖片

那麽我們開始正式編寫插件

        beforeDraw: function(chartInstance) {
            // chartInstance === 畫布實例
            
            // 首先我們去獲取配置表,看是否配置了chartAreaBackground,如果沒有配置則不執行
            if (!chartInstance.options.chartAreaBackground) return;
            var ctx = chartInstance.chart.ctx; // 獲取畫布上下文
            var chartArea = chartInstance.chartArea; // 畫布區域
            var left = chartArea.left;
            var right = chartArea.right;
            var yOptions = chartInstance.scales["y-axis-0"];
            var yAxesTop = yOptions.paddingTop;
            var yAxesBottom = yOptions.paddingBottom;
            var top = chartArea.top + yAxesTop;
            var bottom = chartArea.bottom - yAxesBottom;
            var width = right - left; // 獲取到畫布寬度
            var height = bottom - top; // 獲取畫布的高度
            ctx.fillStyle = chartInstance.options.chartAreaBackground; // 獲取背景色
            ctx.fillRect(left, top, width, height); // 舉行填充
          }

如果對區域的位置不清楚的可以看下面的標註:
技術分享圖片

插件編寫好了。如何使用呢?
插件裏面通過判斷chartInstance.options.chartAreaBackground 這個是否配置。那麽很明顯,我們對這個進行配置就可以了

options:{
    chartAreaBackground:'#f5f5f5'
}

再來看下效果:
技術分享圖片
灰色背景色已經出現了。說明內聯插件我們已經配置成功了。

【把上面的插件改造成全局插件】
新建文件 chart-plugin.ts

import * as Chart from "chart.js";

const drawBgColorFactory = function (Chart) {
  const drawBgColor = {
    beforeDraw: function(chartInstance) {
      // chartInstance === 畫布實例
      console.log(chartInstance);
      // 首先我們去獲取配置表,看是否配置了chartAreaBackground,如果沒有配置則不執行
      if (!chartInstance.options.chartAreaBackground) return;
      var ctx = chartInstance.chart.ctx; // 獲取畫布上下文
      var chartArea = chartInstance.chartArea; // 畫布區域
      var left = chartArea.left;
      var right = chartArea.right;
      var yOptions = chartInstance.scales["y-axis-0"];
      var yAxesTop = yOptions.paddingTop;
      var yAxesBottom = yOptions.paddingBottom;
      var top = chartArea.top + yAxesTop;
      var bottom = chartArea.bottom - yAxesBottom;
      var width = right - left; // 獲取到畫布寬度
      var height = bottom - top; // 獲取畫布的高度
      ctx.fillStyle = chartInstance.options.chartAreaBackground; // 獲取背景色
      ctx.fillRect(left, top, width, height); // 舉行填充
    }
  };

  Chart.pluginService.register(drawBgColor);
};


drawBgColorFactory(Chart);

這樣我們就在全局註冊成功了

小結

那麽至此全局插件,局部插件我們都已經實現了,如果想要實現更加復雜的插件,則需要在項目中更加深入的去學習chart.js插件

chart.js angular組件封裝(ng6)、實戰配置、插件編寫