# https://groups.google.com/g/jqplot-dev/c/tDkY2z0q2t4
作者建議使用者改用 Chart.js 這個函式庫, 此乃以 Canvas 為基礎的開源 Javascript 圖表函式庫, 據說 Angular Chart 也是以 Chart.js 為基礎建構的, 相關網站參考 :
# https://www.chartjs.org/
# https://github.com/chartjs/Chart.js
教學文件與範例參考 :
# https://www.chartjs.org/docs/latest/
# https://www.chartjs.org/samples/latest/
# [Day 30]Chart.js - 輕鬆完成資料視覺化
# [十分鐘學習] Chart.js - 圖表繪製
Chart.js 最新版為 v2.9.3, 可從 GitHub 下載, 原始檔約 420 KB, 壓縮檔約 170 KB :
# https://github.com/chartjs/Chart.js/releases/tag/v2.9.3
# https://github.com/chartjs/Chart.js/releases/tag/v2.9.3
將 Chart.js 放在專案目錄下就可以馬上用它來繪製 line (折線圖), bar (柱狀圖), radar (雷達圖), polarArea, pie (圓餅圖), doughnut, bubble (泡泡圖) 等七種圖表, 網頁模板如下:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<script src="js/Chart.min.js"></script>
</head>
<body>
<script>
//your codes
</script>
</body>
</html>
或者也可以使用 CDN, 例如 cdn.js.com 或 jsdelivr.com :
# https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js
# https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js
模板如下 :
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
</head>
<body>
<script>
//your codes
</script>
</body>
</html>
Chart.js 是基於 Canvas 的圖表函式庫, 其 HTML 部分使用 canvas 元素做為畫布, 依照官網教學文件中的範例, 此 canvas 元素可用 width 與 height 屬性設定畫布大小 :
<canvas id="myChart" width="400p" height="300"></canvas>
接著呼叫 canvas 元素的 getContext('2d') 方法取得畫布的 Context 物件 :
var ctx=document.getElementById('myChart').getContext('2d');
最後用 new Chart(ctx, options) 建立圖表物件 :
var myChart=new Chart(ctx, options)
其中第一參數 ctx 為上面呼叫 getContext() 所傳回之 Context 物件, 第二參數 options 為選項物件, 其 labels 屬性可設定 X 軸刻度標籤; dataset 屬性可設定資料集之標題 label 與資料 data 等屬性. 下面參考官網教學範例改寫如下 :
測試 1 : 繪製柱狀圖 (1) [看原始碼]
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Chart.js test</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
</head>
<body>
<canvas id="myChart" width="400" height="300"></canvas>
<script>
var ctx=document.getElementById('myChart').getContext('2d');
var myChart=new Chart(ctx, {
type: 'bar',
data: {
labels: ['一月', '二月', '三月'],
datasets: [{
label: '銷售業績(百萬)',
data: [60, 49, 72]
}]
}
});
</script>
</body>
</html>
此例顯示 1~3 月氏銷售業績柱狀圖, 但是奇怪的是, canvas 中的 width 與 height 屬性設定沒有作用, 畫布佔據了整個頁面, 我找到下面這篇文章 :
# https://stackoverflow.com/questions/37621020/setting-width-and-height
試了全部方法只有其中編號 48 回應的做法有效, 亦即在 canvas 外再包覆一層 div 元素, 然後設定此 div 之尺寸即可 :
<div style="width: 400px; height: 300px">
<canvas id="myChart"></canvas>
</div>
測試 2 : 繪製柱狀圖 (2) : 設定畫布尺寸 [看原始碼]
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Chart.js test</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
</head>
<body>
<div style="width: 400px; height: 300px">
<canvas id="myChart"></canvas>
</div>
<script>
var ctx=document.getElementById('myChart').getContext('2d');
var myChart=new Chart(ctx, {
type: 'bar',
data: {
labels: ['一月', '二月', '三月'],
datasets: [{
label: '銷售業績(百萬)',
data: [60, 49, 72]
}]
}
});
</script>
</body>
</html>
結果如下, 畫布大小與所指定之尺寸相同 :
另外一篇文章也提供了一個解決辦法 :
其中編號 2 的回應是先取得 canvas 的父元素 (即 div), 然後設定其 width 與 height 屬性 :
ctx.canvas.parentNode.style.width="300px";
ctx.canvas.parentNode.style.height="500px";
事實上官方教學文件也有提到這個方法 :
例如 :
測試 3 : 繪製柱狀圖 (3) : 利用 canvas 父元素設定畫布尺寸 [看原始碼]
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Chart.js test</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
</head>
<body>
<div>
<canvas id="myChart"></canvas>
</div>
<script>
var ctx=document.getElementById('myChart').getContext('2d');
ctx.canvas.parentNode.style.width="400px";
ctx.canvas.parentNode.style.height="300px";
var myChart=new Chart(ctx, {
type: 'bar',
data: {
labels: ['一月', '二月', '三月'],
datasets: [{
label: '銷售業績(百萬)',
data: [60, 49, 72]
}]
}
});
</script>
</body>
</html>
此例 div 元素沒有指定大小, 而是用 parentNode 屬性取得 canvas 元素之父元素 (div) 後設定其尺寸, 結果與上面範例 2 相同.
如果配合使用 jQuery, 可以用選擇器取得 canvas 物件後直接當作 Context 物件傳給 new Chart() , 不可呼叫 getContext('2d'), 因為 jQuery 物件並無此方法. 如果要取得 Context 物件, 應先取出 jQuery 物件中的 DOM 元素, 這有兩個方法 :
$('#myChart')[0].getContext("2d");
或者 :
$('#myChart').get(0).getContext("2d");
用索引 [0] 或呼叫 get(0) 就能從 jQuery 物件中取出 DOM 物件了, 例如 :
測試 4 : 繪製柱狀圖 (4) : 搭配 jQuery [看原始碼]
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Chart.js test</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
</head>
<body>
<div style="width: 400px; height: 300px">
<canvas id="myChart"></canvas>
</div>
<script>
var ctx=$('#myChart');
//var ctx=$('#myChart')[0].getContext("2d");
var myChart=new Chart(ctx, {
type: 'bar',
data: {
labels: ['一月', '二月', '三月'],
datasets: [{
label: '銷售業績(百萬)',
data: [60, 49, 72]
}]
}
});
</script>
</body>
</html>
此例中的 ctx 可以是 canvas 元素之 jQuery 物件, 也可以是 DOM 物件.
上面範例中的圖形預設背景與外框均為灰色, 可以用下列屬性設定 :
- backgroundColor : 設定背景色
- borderWith : 設定邊框寬度 (單位 px)
- borderColor : 設定邊框顏色
測試 5 : 繪製柱狀圖 (5) : 設定框邊與背景色 [看原始碼]
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Chart.js test</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
</head>
<body>
<div style="width: 400px; height: 300px">
<canvas id="myChart"></canvas>
</div>
<script>
var ctx=$('#myChart');
var myChart=new Chart(ctx, {
type: 'bar',
data: {
labels: ['一月', '二月', '三月'],
datasets: [{
label: '銷售業績(百萬)',
data: [60, 49, 72],
backgroundColor: [
"#FF0000",
"#00FF00",
"#0000FF"
],
borderColor: [
"#000000",
"#000000",
"#000000"
],
borderWidth: 1
}]
}
});
</script>
</body>
</html>
結果如下 :
如果需要設定透明度則可呼叫 rgba(R, G, B, A) 函數, 其參數依序為紅 R, 綠 G, 藍 B, 與透明度 A, 顏色值範圍 0~255, 透明度範圍 0~1. 例如 :
測試 6 : 繪製柱狀圖 (6) : 設定框邊與背景色 [看原始碼]
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Chart.js test</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
</head>
<body>
<div style="width: 400px; height: 300px">
<canvas id="myChart"></canvas>
</div>
<script>
var ctx=$('#myChart');
var myChart=new Chart(ctx, {
type: 'bar',
data: {
labels: ['一月', '二月', '三月'],
datasets: [{
label: '銷售業績(百萬)',
data: [60, 49, 72],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)'
],
borderWidth: 1
}]
}
});
</script>
</body>
</html>
結果如下 :
可見經過設定, 外觀比預設要好看多了, 但比起 jqPlot 會自動派顏色來說, 這似乎有點麻煩.
如果要繪製寬高比為 1:1 的圖形, 可以將 canvas 的 width 與 height 都設為 1, 然後用外層包覆的 div 控制寬或高 :
<div style="width:400px;">
<canvas id="myChart" width="1" height="1"></canvas>
</div>
例如 :
測試 7 : 繪製柱狀圖 (7) : 寬高比 1:1 的設定方法 [看原始碼]
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Chart.js test</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
</head>
<body>
<div style="width:400px;">
<canvas id="myChart" width="1" height="1"></canvas>
</div>
<script>
var ctx=document.getElementById('myChart').getContext('2d');
//ctx.canvas.parentNode.style.width="300px";
var myChart=new Chart(ctx, {
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
}
}]
}
}
});
</script>
</body>
</html>
因為畫布寬高比已經設定為 1:1, 所以只須設定 width 或 height 其中一個即可, 此例是在 canvas 父元素 div 中設定 width (也可以在程式中用 parentNode 設定), 結果如下 :
只要用 rgba() 善加設定, Chart.js 的繪圖效果真的很棒.
沒有留言 :
張貼留言