iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
自我挑戰組

以網頁呈現資料視覺化系列 第 14

Day14 老人護眼模式

  • Zoom

你是不是常常有看東西覺得模糊需要放大鏡呢?今天要來介紹完整的圖表的放大、縮小、以及拖曳平移的功能。
今天的主角就是chartjs-plugin-zoom,它也是chart.js的plugin之一,雖然在前天的外掛也有部分的zoom-in功能,但這個簡單好用又完整,首先除了原本的chart.js我們要再掛上hammer和本身的chartjs-plugin-zoom:

<script src="https://cdn.jsdelivr.net/npm/hammerjs@2.0.8/hammer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom@1.1.1/dist/chartjs-plugin-zoom.min.js"></script>

然後再圖表的配置物件(config)加上這些功能的設定,其中我們先將拖曳放大(drag)的功能關閉,平移(pan)功能開啟(enabled: true),因為這兩個在控制上會有衝突,所以我們等會做個按鈕切換:

        options: {
          plugins: {
            zoom: {
              pan: {
                enabled: true,
                mode: 'xy',
              },
              zoom: {
                mode: 'xy',
                drag: {
                  enabled: false,
                },
              },
            }
          }
        },

另外此套件還提供滾輪(wheel)和pinch的控制方式,但這對一般用滑鼠控制比較雞肋,這裡就不特別介紹,詳細可以參考官網內的option說明。其中pan和zoom(drag、wheel和pinch都算在裡面)都提供方式的選擇(mode),預設是xy,也可以單獨選擇x或y。
另外zoom-in時可以有顏色區塊差異,如下設定以及結果:

backgroundColor: RGBwithA(CHART_COLORS.orange, 0.2), 
borderColor: CHART_COLORS.yellow,
borderWidth: 2,

https://ithelp.ithome.com.tw/upload/images/20210915/20141158258tnkeM8E.jpg

  • Button function

四種功能(drag、pan、wheel、pinch)都有提供使用額外按鍵去啟動(例如要按著shift)以區隔的選項,但這不太直覺,所以我們做一個按鈕來開啟或關閉拖曳平移(pan),但這邊有一點比較奇怪是如果一開始是先開啟drag而關閉pan,再開啟pan時會沒反應,但開啟或關閉drag都是正常的:

function panSwitch(chart, buttonId) {
  let button = document.getElementById(buttonId);
  let panState = chart.options.plugins.zoom.pan.enabled;
  if (panState) {
    chart.options.plugins.zoom.zoom.drag.enabled = true;
    chart.options.plugins.zoom.pan.enabled = false;
    button.className = "btn btn-sm btn-outline-secondary";
  } else {
    chart.options.plugins.zoom.zoom.drag.enabled = false;
    chart.options.plugins.zoom.pan.enabled = true;
    button.className = "btn btn-sm btn-outline-secondary active";
  }
  chart.update();
}

方向的模式也可以用按鈕做切換:

function modeSwitch(chart, buttonId) {
  let button = document.getElementById(buttonId);
  let modeState = chart.options.plugins.zoom.zoom.mode;
  if (modeState == "xy") {
    chart.options.plugins.zoom.zoom.mode = "x";
    chart.options.plugins.zoom.pan.mode = "x";
    button.innerHTML = "X";
  } else if (modeState == "x") {
    chart.options.plugins.zoom.zoom.mode = "y";
    chart.options.plugins.zoom.pan.mode = "y";
    button.innerHTML = "Y";
  } else if (modeState == 'y') {
    chart.options.plugins.zoom.zoom.mode = "xy";
    chart.options.plugins.zoom.pan.mode = "y";
    button.innerHTML = "XY";
  }
  chart.update();
}

另外還可以是按鈕的zoom-in和zoom-out,這有function可以直接接,只要填入比例係數:

<button type="button" class="btn btn-sm btn-outline-secondary" onclick="myChart.zoom(1.2)">Zoom-In</button>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="myChart.zoom(0.8)">Zoom-Out</button>

最後一個最重要,就是當我們zoom-in時要退回原本的大小,要reset zoom,這也是有function可以接:

<button type="button" class="btn btn-sm btn-outline-secondary" onclick="myChart.resetZoom()">Reset Zoom</button>

成果如下:
切成X方向的drag zoom-in:
https://ithelp.ithome.com.tw/upload/images/20210915/20141158KNIWcV75ig.jpg
切成Y方向的drag zoom-in:
https://ithelp.ithome.com.tw/upload/images/20210915/20141158hOmazI3nQQ.jpg


上一篇
Day13 在圖表做標記仿前朝的飄逸 就當我為highlight你伏筆
下一篇
Day15 這什麼水平
系列文
以網頁呈現資料視覺化30

尚未有邦友留言

立即登入留言