學到新資視了 - Highcharts / 金字塔圖表
Oct 9, 2020 Max Lee
相信大家在學生時期都有在課本中看過人口金字塔,而今天我們就是要用臺灣的人口統計資料來實作「金字塔圖表」。
實作目標
那上圖就是我們今天要製作圖表,其實分析一下可以發現金字塔圖表只是一個「雙X軸長條圖」,倒是它的Y軸座標比較特別,最小刻度竟然在中間,越往兩側值越高。下面就來看看這是如何做到的吧!
**提醒:**長條圖中垂直的座標軸為X軸,水平為Y軸,剛好跟其他圖表類型相反。
這次的原始資料如下:
const colors = ["#66BAB7", "#EB7A77"];
const age = ["0-9","10-19","20-29","30-39","40-49","50-59","60-69","70-79","80+"];
const male = [1046336, 1248418, 1653942, 1848095, 1818996, 1789423, 1376599, 594861, 339574];
const female = [970889, 1142606, 1533181, 1851812, 1875771, 1849072, 1489570, 712084, 438873];
動手開發
1. 容器準備
無論如何,第一步永遠都是把要放圖表的容器先準備好。
<div id="barChart"></div>
2. 資料準備
其實今天的原始資料都已經可以直接拿來使用了,但再來就是Y軸的秘密了,男性的資料我們要稍微動一下手腳。透過 map
把男性資料乘以 -1
,這樣數據列剛好一組正數一組負數,自然就會往兩邊延伸了。
const maleSeries = male.map(val => val * -1);
3. 創建圖表與區塊設定
資料備妥後,剩下就是圖表的設定跟創建了,不過要做出金字塔圖表有幾個重點要注意:
- 初始的X軸刻度會是上低下高,所以記得要把
reversed
屬性關掉翻轉回來。 - 因為男性這側的Y軸刻度會是負數,所以記得要用
formatter
來取絕對值,才不會出現負號。 - 提示框內容裡也會出現負數,一樣要透過格式化屬性處理。
- 數據列的
stacking
屬性要記得設定,才會有堆疊效果。
只要有做到以上幾點,金字塔圖表就能輕輕鬆鬆做出來了,大家也試著做做看吧!
let myChart = Highcharts.chart("container", {
chart: { type: "bar" },
credits: { text: "數據來源: 內政部戶政司" },
colors: colors,
title: { text: "2018 臺灣人口金字塔" },
tooltip: {
headerFormat: "<b>{point.key}歲</b><br/>",
pointFormatter() {
let value = Math.abs(this.y);
let formatValue = Highcharts.numberFormat(value, 0, "", ",");
return `${formatValue}人`;
}
},
xAxis: [
{
categories: age,
reversed: false,
labels: { format: "{value}歲" }
},
{
categories: age,
opposite: true,
reversed: false,
labels: { format: "{value}歲" }
}
],
yAxis: {
title: { text: undefined },
labels: {
formatter() {
return `${Math.abs(this.value / 10000)}萬人`
}
}
},
plotOptions: {
series: {
groupPadding: 0,
pointPadding: 0,
stacking: "normal"
}
},
series: [
{ name: "男性", data: maleSeries },
{ name: "女性", data: female, xAxis: 1 }
]
});
groupPadding
和pointPadding
都設為0
,才能移除長條圖之間的間距,也才會有這種階梯狀的圖形效果。
那今天就正式完成了最後一個實作範例了,不過 Highcharts 的圖表應用當然還有百百種,可以到 官方DEMO 去挖挖寶,也希望大家可以發揮創意,組合自己獨特的圖表內容與功能。
那麼明天就要進入本系列的最後一個階段了,就是在前端框架-Vue 底下使用 Highcharts,透過 Vue 的元件和資料綁定的機制來協助我們開發。
- 此篇文章為「iT邦幫忙鐵人賽」參賽文章,同步發表於 iT邦幫忙 -