~~~ L O A D I N G ~~~~~ L O A D I N G ~~~~~ L O A D I N G ~~~

資視就是力量 - Highcharts / 金字塔圖表

Oct 9, 2020 Max Lee

本章節範例:https://codepen.io/max-lee/pen/wvGVGyR

相信大家在學生時期都有在課本中看過人口金字塔,而今天我們就是要用臺灣的人口統計資料來實作「金字塔圖表」。


實作目標


那上圖就是我們今天要製作圖表,其實分析一下可以發現金字塔圖表只是一個「雙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. 創建圖表與區塊設定

資料備妥後,剩下就是圖表的設定跟創建了,不過要做出金字塔圖表有幾個重點要注意:

  1. 初始的X軸刻度會是上低下高,所以記得要把 reversed 屬性關掉翻轉回來。
  2. 因為男性這側的Y軸刻度會是負數,所以記得要用 formatter 來取絕對值,才不會出現負號。
  3. 提示框內容裡也會出現負數,一樣要透過格式化屬性處理。
  4. 數據列的 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 }
  ]
});

groupPaddingpointPadding 都設為 0,才能移除長條圖之間的間距,也才會有這種階梯狀的圖形效果。


那今天就正式完成了最後一個實作範例了,不過 Highcharts 的圖表應用當然還有百百種,可以到 官方DEMO 去挖挖寶,也希望大家可以發揮創意,組合自己獨特的圖表內容與功能。

那麼明天就要進入本系列的最後一個階段了,就是在前端框架-Vue 底下使用 Highcharts,透過 Vue 的元件和資料綁定的機制來協助我們開發。


- 此篇文章為「iT邦幫忙鐵人賽」參賽文章,同步發表於 iT邦幫忙 -