將網頁圖表輸出成圖檔也是常常被 PM 大人要求的功能,這周就來記錄一下如何在 Vue3 框架中,將 Chart.js 圖表輸出成 PNG 圖片。
圖表 DOM 元素
首先設定圖表的 DOM 元素,記得 <canvas> 裡面要加上 ref=”chartElement”。
<template>
<main>
<button @click="downloadChart" style="margin-bottom: 20px">切換數據</button>
<div class="canvas-box">
<!-- 生成圖表的 canvas -->
<canvas ref="chartElement"></canvas>
</div>
</main>
</template>圖表初始化
<script setup>
import { ref, shallowRef, computed, watch, nextTick, onMounted } from 'vue';
import Chart from 'chart.js/auto';
// 要跑圖表折線的資料陣列
const dataArray = ref([10, 20, 15, 25]);
// 取得要放圖表的 canvas 元素
const chartElement = ref(null);
// 儲存 new Chart 生成的圖表
const dataChart = shallowRef(null);
const init = (ws) => {
dataChart.value = new Chart(chartElement.value.getContext('2d'), {
type: 'line',
data: {
labels: ['鋼鐵人', '蜘蛛人', '美國隊長', '雷神'],
datasets: [
{
label: '出勤次數',
data: ws.value,
backgroundColor: '#B7EDA1',
borderColor: '#1BAD4F',
borderWidth: 1,
fill: true,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
},
});
};
function downloadChart() {
// 將 Canvas 轉換為圖片
// 取得 canvas DOM 元素
const chartInstance = chartElement.value;
// 創建下載連結並觸發點擊
const imageURL = chartInstance.toDataURL('image/png');
// 創建下載連結並觸發點擊
const downloadLink = document.createElement('a');
downloadLink.href = imageURL;
const fileName = `myFlieName.png`;
downloadLink.download = fileName;
downloadLink.click();
}
onMounted(() => {
nextTick(() => {
init(dataArray);
});
});下載函式
這裡要取得 canvas DOM 元素,使用 toDataURL 的方式來輸出圖片。
要注意的是 Composition API 與 Option API 的取得 DOM 的寫法不同。
Composition API 範例程式碼
function downloadChart() {
// 將 Canvas 轉換為圖片
// 取得 canvas DOM 元素
const chartInstance = chartElement.value;
// 創建下載連結並觸發點擊
const imageURL = chartInstance.toDataURL('image/png');
// 創建下載連結並觸發點擊
const downloadLink = document.createElement('a');
downloadLink.href = imageURL;
const fileName = `myFlieName.png`;
downloadLink.download = fileName;
downloadLink.click();
}Option API 範例程式碼
downloadChart() {
// 將 Canvas 轉換為圖片
const chartInstance = this.$refs.chartElement.$el;
// 創建下載連結並觸發點擊
const imageURL = chartInstance.toDataURL("image/png");
// 創建下載連結並觸發點擊
const downloadLink = document.createElement("a");
downloadLink.href = imageURL;
const fileName = `${vm.fileName}圖.png`;
downloadLink.download = fileName;
downloadLink.click();
},幫圖片加上背景
下載圖表後,我發現 PNG 圖檔的背景式透明的,在這裡要以 Chart.js plugin 的方式幫圖表加上背景顏色。
const plugin = {
id: 'customCanvasBackgroundColor',
beforeDraw: (chart, args, options) => {
const { ctx } = dataChart.value;
ctx.save();
ctx.globalCompositeOperation = 'destination-over';
ctx.fillStyle = options.color || '#99ffff';
ctx.fillRect(0, 0, chart.width, chart.height);
ctx.restore();
},
};在 init 函式的 new Chart 方法要加上,plugins 屬性:
const init = (ws) => {
dataChart.value = new Chart(chartElement.value.getContext('2d'), {
type: 'line',
data: {
labels: ['鋼鐵人', '蜘蛛人', '美國隊長', '雷神'],
datasets: [
{
label: '出勤次數',
data: ws.value,
backgroundColor: '#B7EDA1',
borderColor: '#1BAD4F',
borderWidth: 1,
fill: true,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
},
// plugins 加在這裡
plugins: [plugin],
});
};這樣輸出成 PNG ,就不會是透明背景了。
