chart.js angular組件封裝(ng6)、實戰配置、插件編寫
前言
項目需要使用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)、實戰配置、插件編寫