2021年3月6日 星期六

jQuery Mobile 學習筆記 (二十) : 用 jqPlot 繪圖 (1) : 折線圖

我在 "jQuery Mobile 智慧型手機程式開發" 這本書中看到作者將 jqPlot 繪圖函式庫用在 jQuery Mobile 網頁中, 所以我也想要測試看看. 其實我以前就在 PC 上測試過了, 現在只不過是換到手機平台來測而已, 所以完全可用以前的範例來改, 參考 :


jqPlot 的教學文件與豐富範例參考 :


本系列測試文章索引參考 :


以下測試也是使用 CDN 取得函式庫資源, 例如 jsdelivr :

<script src="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.css" rel="stylesheet">

jqPlot 是純粹用 jQuery 繪圖的分散式函式庫 (不是 all-in-one), 優點是輕量且簡單易學, 其核心算圖器是繪製折線圖, 若要繪製其他統計圖例如長條圖, 圓餅圖, K 線圖等, 只要匯入各圖的算圖器 (renderer) 即可, 支援之算圖器如下表 :


 統計圖 jqPLot 算圖器
 長條圖 jqplot.barRenderer
 圓餅圖 jqplot.pieRenderer
 儀表圖 jqplot.meterGaugeRenderer
 區域圖 jqplot.blockRenderer
 K 線圖 jqplot.ohlcRenderer
 泡泡圖 jqplot.bubleRenderer
 貝茲曲線圖 jqplot.BeizierRenderer
 甜甜圈圖 jqplot.donutRenderer


jqPlot 用來繪圖的畫布是一個 div 元素 :

<div id="chart"></div>

可以用 style 的 width 與 height 來設定畫布的大小 : 

<div id="chart" style="width:300px; height:200px;"></div>

但對於行動設備如手機而言不太需要, 因為其螢幕小且可直放與橫放, 圖形會自動縮放, 讓圖形占據螢幕寬度即可. 只要呼叫 $.jqplot() 傳入畫布容器 id 與繪圖資料 data 即可, 介面如下 :

$.jqplot(id, data [, options]);

其中 data 是一個陣列, 若是二維陣列, 例如 data=[[2,4,6,8,10]], 則它代表 Y 軸座標值, jqPlot 會以 [[1, 2, 3, ...]] 作為預設之 X 軸座標. 如果要自訂 X 軸座標, 則 data 須用三維陣列, 最內層是 [X, Y] 座標對, 例如 data=[[[1, 2], [2, 4], [3, 6], [4, 8], [5, 10]]], 多一軸的原因是為了可同時在畫布上繪製多組圖形. 

備選參數 options 是一個物件, 其屬性可用來設定圖形的標題 (title), 座標軸標籤 (label), 與圖例 (legend) 等. 

首先測試折線圖 : 



<!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">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.js"></script>
  </head>
  <style>
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>jqPlot 折線圖</h1>
      </header>
      <article data-role="content">
        <div id="chart"></div>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        var data=[[100, 100, 75, 99, 89, 100, 85, 95, 77]];
        $.jqplot('chart', data);
        });
    </script>
  </body>
</html>

結果如下 : 




可見預設的 X 座標是 [1, 2, 3, 4, ..], 此例測試網頁 QR code 如下 :




繪製多個圖形只要傳入參數 data 的內層有多個一維陣列即可 : 



<!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">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.js"></script>
  </head>
  <style>
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>jqPlot 折線圖</h1>
      </header>
      <article data-role="content">
        <div id="chart"></div>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        var data=[[100, 100, 75, 99, 89, 100, 85, 95, 77],
                  [78, 55, 66, 60, 80, 75, 80, 83, 71],
                  [45, 49, 53, 56, 72, 50, 75, 78, 67]];
        $.jqplot('chart', data);
        });
    </script>
  </body>
</html>

此例 data 最內層為三個一維陣列, 故繪製三個圖形, 結果如下 : 




測試網頁 QR code 如下 :




上面範例均以預設的 X 座標值 [1, 2, 3, 4, ...] 繪製, 若要自訂 X 座標值, 則 data 須為三維陣列, 因為要多一個最內層用來放 [X, Y] 座標對, 例如上面測試 2 可以改用此方式來繪製, 結果相同 :



<!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">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.js"></script>
  </head>
  <style>
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>jqPlot 折線圖</h1>
      </header>
      <article data-role="content">
        <div id="chart"></div>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        var data=[[[1, 100], [2, 100], [3, 75], [4, 99], [5, 89], [6, 100], [7, 85], [8, 95], [9, 77]],
                 [[1, 78], [2, 55], [3, 66], [4, 60], [5, 80], [6, 75], [7, 80], [8, 83], [9, 71],
                 [[1, 45], [2, 49], [3, 53], [4, 56], [5, 729], [6, 50], [7,75], [8, 78], [9, 67]];
        $.jqplot('chart', data);
        });
    </script>
  </body>
</html>

結果與上面測試 2 相同, 測試網頁 QR code 如下 :




下面範例將傳入 options 物件來設定圖形之標題與 X, Y 軸標籤 :



<!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">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.js"></script>
  </head>
  <style>
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>jqPlot 折線圖</h1>
      </header>
      <article data-role="content">
        <div id="chart"></div>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        var data=[[100, 100, 75, 99, 89, 100, 85, 95, 77],
                  [78, 55, 66, 60, 80, 75, 80, 83, 71],
                  [45, 49, 53, 56, 72, 50, 75, 78, 67]];
        var options={title: "月收盤價",
                     axes: {xaxis: {label: "月份"},
                            yaxis: {label: "價格"}}
                     };
        $.jqplot('chart', data, options);
        });
    </script>
  </body>
</html>

此例用 options 物件之 title 屬性設定圖形標題, 用 axes/xaxis/label 屬性設定 X 軸標籤; 用 axes/yaxis/label 屬性設定 Y 軸標籤, 結果如下 :




測試網頁 QR code 如下 :




要在圖形上設定圖例 (legend) 必須添加 series 與 legend 這兩個屬性, series 用來設定每一組值的屬性, 例如 label 是該組數據的標題, 主要用在顯示此圖形之圖例時, 另外 showMarker 則用來設定是否要顯示資料點 (預設 true). 其次 legend 屬性的 show 用來控制圖例是否顯示, location 則用來指定圖例的位置, 例如 "ne" 是東北方, "sw" 則是西南方等等, 例如 :



<!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">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.js"></script>
  </head>
  <style>
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>jqPlot 折線圖</h1>
      </header>
      <article data-role="content">
        <div id="chart"></div>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        var data=[[100, 100, 75, 99, 89, 100, 85, 95, 77],
                  [78, 55, 66, 60, 80, 75, 80, 83, 71],
                  [45, 49, 53, 56, 72, 50, 75, 78, 67]];
        var options={title: "月收盤價",
                     axes: {xaxis: {label: "月份"},
                            yaxis: {label: "價格"}},
                     series: [{label: "A 股"},
                              {label: "B 股"},
                              {label: "C 股"}],
                     legend: {show: true,
                              location: "ne"}
                     };
        $.jqplot('chart', data, options);
        });
    </script>
  </body>
</html>

結果如下 :




測試網頁 QR code 如下 :



X, Y 軸屬性 axes 除了 label 外, 還可以用 min, max 設定軸刻度範圍的最小值與最大值, 例如 :



<!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">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.js"></script>
  </head>
  <style>
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>jqPlot 折線圖</h1>
      </header>
      <article data-role="content">
        <div id="chart"></div>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        var data=[[100, 100, 75, 99, 89, 100, 85, 95, 77],
                  [78, 55, 66, 60, 80, 75, 80, 83, 71],
                  [45, 49, 53, 56, 72, 50, 75, 78, 67]];
        var options={title: "月收盤價",
                     axes: {xaxis: {label: "月份",
                                    min: 0,
                                    max: 10},
                            yaxis: {label: "價格",
                                    min: 0,
                                    max: 120}}
                     };
        $.jqplot('chart', data, options);
        });
    </script>
  </body>
</html>

結果如下 :




測試網頁 QR code 如下 :



也可以用 numberTicks 指定刻度的數目, 或用 tickInterval 指定刻度的距離, 例如 :



<!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">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.js"></script>
  </head>
  <style>
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>jqPlot 折線圖</h1>
      </header>
      <article data-role="content">
        <div id="chart"></div>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        var data=[[100, 100, 75, 99, 89, 100, 85, 95, 77],
                  [78, 55, 66, 60, 80, 75, 80, 83, 71],
                  [45, 49, 53, 56, 72, 50, 75, 78, 67]];
        var options={title: "月收盤價",
                     axes: {xaxis: {label: "月份",
                                    min: 0,
                                    max: 10,
                                    numberTicks: 11},
                            yaxis: {label: "價格",
                                    min: 0,
                                    max: 120,
                                    tickInterval: 10}}
                     };
        $.jqplot('chart', data, options);
        });
    </script>
  </body>
</html>

此例用 numberTicks 指定 X 軸刻度數目 (0~10 共 11 個), 用 tickInterval 指定 Y 軸刻度之間距, 注意, numberTicks 須考慮 min, max 範圍長度, 若不整除將出現小數, 結果如下 : 




測試網頁 QR code 如下 :



也可以用 ticks 屬性自訂刻度, 例如 :


<!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">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jqplot@1.0.9/jquery.jqplot.min.js"></script>
  </head>
  <style>
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>jqPlot 折線圖</h1>
      </header>
      <article data-role="content">
        <div id="chart"></div>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        var data=[[100, 100, 75, 99, 89, 100, 85, 95, 77],
                  [78, 55, 66, 60, 80, 75, 80, 83, 71],
                  [45, 49, 53, 56, 72, 50, 75, 78, 67]];
        var options={title: "月收盤價",
                     axes: {xaxis: {label: "月份",
                                    min: 0,
                                    max: 10,
                                    ticks: [0,1,2,3,4,5,6,7,8,9,10]},   
                            yaxis: {label: "價格",
                                    min: 0,
                                    max: 120,
                                    ticks: [0,10,20,30,40,50,60,70,80,90,100,110,120]}}
                     };
        $.jqplot('chart', data, options);
        });
    </script>
  </body>
</html>

結果如下 : 




可見與測試 7 的差別是刻度變成實數了. 測試網頁 QR code 如下 :



沒有留言 :