繪製動態圖表需要準備幾件事情:
一、取得資料來源:目前多用ajax取得資料。
二、資料有無依照時間序列變化:資料可能是依照時間變化跑的,或者只是依類別顯示。
三、要幫資料歸類出x軸(資料點的名稱)與y軸(數值變動)。
我們的專案是利用power shell 或 vbs 將伺服器監控的數據寫到SQL Server,再用Asp.net 網站讓管理人員查閱資料。作一隻簡單的泛型處理函式(ashx)將資料轉為json,讓chart.js讀取。
我們當初在紀錄資料時,每筆紀錄就包含日期、CPU使用率跟可用記憶體。很明顯這是隨時間序列變化的資料。搭配EF大概是這樣寫:
using ( xxxxxxxEntitiesdbm = new xxxxxxxEntities()) {
string vid="OOOp_WEB";
/*抓兩天以內的資料*/
DateTime lastdate = DateTime.Now.AddDays(-2);
var query1 = dbm.monitor_record
.Where(o => o.Server_id == vid && o.Recdate >= lastdate)
.Select ( o=> new{
x = o.Recdate,
y = o.CPU_Useage,
z = o.Available_Memory
}
) .ToList();
string vv = JsonConvert.SerializeObject(query1);
context.Response.Write(vv);
}
然後 chart.js的範例是參考Line (point data)的做法:
https://www.chartjs.org/samples/latest/scales/time/line-point-data.html
網頁須載入以下的js元件跟jquery。
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<script src="https://www.chartjs.org/dist/2.7.3/Chart.js"></script>
<script src="https://www.chartjs.org/samples/latest/utils.js"></script>
不過問題來了,我希望從ajax抓取資料,這點跟範例不同。由於ajax預設為非同步,相關事件是包在success的區塊內,因此修改成有結果再把資料傳給另一個函數繼續顯示。
/*以下的 javascript是放在載入頁面中*/
window.onload = function() {
$.ajax({
url: "../WebAPI/Hardware.ashx",
type: "POST",
data: {
ENCODED: "1",
},
dataType: "json",
success: function (Xresponse) {
DrawChart(Xresponse);
},
error: function () {
alert("無法載入。");
}
});
};
我的原始資料雖然能順利取得json,而且也帶有類別標籤x跟y,但直接帶到範例內的datasets ,無論怎樣都無法直接顯示。
看看原來範例,x是日期而y是數值,我並沒有搞錯啊?看來可能是解讀json的問題。不論陣列轉 json (array/object to json ) 的 JSON.stringify() 或 json轉陣列的 JSON.parse()都是過了,chart.js還是認不到資料。
後來爬文的結果,應該利用foreach 將資料拆開成三個陣列:
陣列一存資料標籤
陣列二存第一條線的數值
陣列二存第二條線的數值
利用javascript中陣列 push 新增元素的方式實作出來
var labelsx = [], dataCPU = [], dataMEMORY = [];
for (var rr in results) {
labelsx.push(results[rr].x);
dataCPU.push(parseFloat(results[rr].y));
dataMEMORY.push(parseFloat(results[rr].z));
}
接下來就能將資料以標準陣列的方式餵給chart.js
然後這個圖表包含cpu使用率跟記憶體,兩個y軸的數據差距很大,所以需要左右兩邊不同刻度的y軸。
大功告成,這樣圖表就會顯示出來了。