Asp.net mvc 使用echart的一點點經驗
阿新 • • 發佈:2019-02-05
最近做專案需要用到圖表,發現echart是一個非常強大的工具。而我在使用它的三個月中,使用它的方法也在逐漸深入
最開始使用時,js和後臺程式碼都不是特別瞭解,於是使用最笨的辦法,仿照官網,將option在前臺配置好,使用ajax請求資料並填充資料,程式碼如下
前臺程式碼
後臺程式碼function GetStatic(u1,year1,month1,day1,year2,month2,day2) { $.ajax({ type: "GET", url: "GetFlowMoreDate", data: { uid: u1, year1: year1, month1: month1, day1: day1, year2: year2, month2: month2, day2: day2 }, dataType: "json", success: function (data) { var dataObj = eval("(" + data + ")"); var Total = new Array(); var StartTime = new Array(); var Max = new Array(); var Min = new Array(); for (var i = 0; i < dataObj.length; i++) { StartTime[i] = dataObj[i].StartTime; Max[i] = dataObj[i].Data1; Min[i] = dataObj[i].Data2 } echart( Max, Min, StartTime); } }) } function echart( Max, Min, StartTime) { // 路徑配置 require.config({ paths: { echarts: 'http://echarts.baidu.com/build/dist' } }); // 使用 require( [ 'echarts', 'echarts/chart/line', 'echarts/chart/bar' // 使用柱狀圖就載入bar模組,按需載入 ], function (ec) { // 基於準備好的dom,初始化echarts圖表 var myChart = ec.init(document.getElementById('main')); var option = { calculable: true, title: { text: ' ', subtext: ' ' }, tooltip: { trigger: 'axis' }, legend: { data: ['1', '2'], y: 25 }, grid: { x: 45, x2: 20 }, toolbox: { show: true, feature: { dataZoom: { show: true }, dataView: { show: true }, restore: { show: true }, saveAsImage: { show: true } } }, dataZoom: { y2: 370, show: true, realtime: true, start: 0, end: 100 }, calculable: true, xAxis: [ { type: 'category', boundaryGap: true, data: StartTime//x軸的一組數值 } ], yAxis: [ { type: 'value', axisLabel: { formatter: '{value} m³' } } ], series:[ { name: '1',//最高氣溫 type: 'line', data: Max,//y軸的一組數值 }, { name: '2',//最高氣溫 type: 'line', data: Min,//y軸的一組數值 }, ] }; myChart.hideLoading(); // 為echarts物件載入資料 myChart.setOption(option); } ); }
public JsonResult GetFlowMoreDate(string uid, int year1, int month1, int day1, int year2, int month2, int day2) { Guid u = Guid.Parse(CryptoUtils.DesDecrypt(uid)); JsonResult ret = new JsonResult(); ret.JsonRequestBehavior = JsonRequestBehavior.AllowGet; List<FlowStatisticContract> list = LoadService<IFlowStatisticService>().GetFlowMoreDate(u, year1, month1, day1, year2, month2, day2); string json = JsonConvert.SerializeObject(list); ret.Data = json; return ret; }
可是,多做了幾個頁面以後就發現,這樣做太麻煩。每一個頁面都需要配置一下echart的option,而且更重要的是,沒有辦法靈活的改變echart的option,比如多一個數據系列,或者改一個標題。使用mvc的viewdata也太麻煩。
於是我稍稍改了一下,將配置檔案抽離出來,不過剛開始並沒有想很深,只是想寫成一個普適的而且易配置的echart元件
前臺程式碼
function GetStatic(u, year, month, day) { $.ajax({ type: "GET", url: "GetFlowStatisticAll", data: { uid: u, year: year, month: month, day: day }, dataType: "json", success: function (e) { $("#loading").hide(); $("#table").children('tr').remove(); var data = JSON.parse(e); var option = { title: { text: '載入中', subtext: '純屬虛構' }, tooltip: { trigger: 'axis' }, legend: { data: []//顏色標條name,要與資料組的name一致 }, toolbox: { show: true, feature: { mark: { show: true }, dataView: { show: true, readOnly: false }, magicType: { show: true, type: ['line', 'bar'] }, restore: { show: true }, saveAsImage: { show: true } } }, dataZoom: { show: true, realtime: true, height: 20, start: 0, end: 100 }, calculable: true, xAxis: [ { type: 'category', boundaryGap: true, data: []//x軸的一組數值 } ], yAxis: [ { type: 'value', axisLabel: { formatter: '{value} m³' } } ], series: [ ] }; if (!data["nodata"]) { option["title"]["text"] = data["title"]; option["title"]["subtext"] = data["subtitle"]; for (var i = 0; i < 3; i++) { option["series"].push( { name: '', type: 'line', data: [],//新增y軸的第二組數值 markPoint: { symbolSize: 6, data: [ { type: 'max', name: '最大值' }, { type: 'min', name: '最小值' } ], }, } ); option["xAxis"][0]["data"] = data["x_data"]; option["series"][i]["name"] = data["name" + i]; option["series"][i]["data"] = data["y_data" + i]; option["legend"]["data"].push(data["name" + i]); } for (var i = 0; i < data["x_data"].length; i++) { var times = data["x_data"][i] + ""; if (times.length == 4) { times = times.substr(0, 4) + "-"; } else if (times.length == 6) { times = times.substr(0, 4) + "-" + times.substr(4, 2); } else if (times.length == 8) { times = times.substr(0, 4) + "-" + times.substr(4, 2) + "-" + times.substr(6, 2); } else if (times.length == 10) { times = times.substr(0, 4) + "-" + times.substr(4, 2) + "-" + times.substr(6, 2) + " " + times.substr(8, 2) + ":00"; } var time = "<th class='text-left'>" + times + "</th>"; var max = "<th class='text-right'>" + data["y_data0"][i].toFixed(2) + "</th>"; var min = "<th class='text-right'>" + data["y_data1"][i].toFixed(2) + "</th>"; var total = "<th class='text-right'>" + data["y_data2"][i].toFixed(2) + "</th>"; $("#table").prepend("<tr>" + time + max + min + total + "</tr>"); } $("#tablepanel").fadeIn(); $("#main").fadeIn(); echart(option); } else { $("#warning").fadeIn(); } } }) } function echart(option) { // 路徑配置 require.config({ paths: { echarts: 'http://echarts.baidu.com/build/dist' } }); // 使用 require( [ 'echarts', 'echarts/chart/line', 'echarts/chart/bar' // 使用柱狀圖就載入bar模組,按需載入 ], function (ec) { // 基於準備好的dom,初始化echarts圖表 var myChart = ec.init(document.getElementById('main')); myChart.setTheme(getTheme()); // 為echarts物件載入資料 myChart.setOption(option); } ); }
後臺程式碼
public JsonResult GetFlowStatisticAll(string uid, int year, int month, int day)
{
Guid u = Guid.Parse(CryptoUtils.DesDecrypt(uid));
JsonResult ret = new JsonResult();
ret.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
List<FlowStatisticContract> list = LoadService<IFlowStatisticService>().GetFlowStatisticByUidAndDate(u, year, month, day);
Dictionary<string, object> mydic = new Dictionary<string, object>();
if (list.Count != 0)
{
mydic.Add("nodata", false);
mydic.Add("max", "最大值");
mydic.Add("x_data", list.Select(p => p.StartTime));
mydic.Add("y_data0", list.Select(p => p.Data1));
mydic.Add("y_data1", list.Select(p => p.Data2));
mydic.Add("y_data2", list.Select(p => p.Data3));
mydic.Add("name0", "最大");
mydic.Add("name1", "最小");
mydic.Add("name2", "總量");
if (year == -1)
{
mydic.Add("title", "年度對比");
}
else if (month == -1)
{
mydic.Add("title", year + "年");
}
else if (day == -1)
{
mydic.Add("title", year + "年" + month + "月");
}
else
{
mydic.Add("title", year + "年" + month + "月" + day + "日");
}
mydic.Add("subtitle", "");
}
else
{
mydic.Add("nodata", true);
}
string json = JsonConvert.SerializeObject(mydic);
ret.Data = json;
return ret;
}
這樣子寫以後,用起來是簡單了,可是程式碼維護性太差。特別是那麼一大堆字典型別的東西,我估計自己隔了幾個月再想做點修改都不好改
再經過幾次測試以後。到目前為止,個人發現的最簡單的方式就是這樣
後臺程式碼
public JsonResult GetData(Guid id)
{
JsonResult json = new JsonResult();
string[] s = { "銷量" };
string[] s1 = { "襯衫", "羊毛衫", "雪紡衫", "褲子", "高跟鞋", "襪子" };
int[] d = { 5, 20, 40, 10, 10, 20 };
JObject option = new JObject()
{
new JProperty("tooltip", new JObject { new JProperty("show", true) }),
new JProperty("legend", new JObject { new JProperty("data", s) }),
new JProperty("xAxis", new JObject[] {new JObject { new JProperty("type", "category"), new JProperty("data", s1) } }),
new JProperty("yAxis", new JObject[] { new JObject { new JProperty("type", "value") } }),
new JProperty("series",new JObject []{new JObject { new JProperty("name", "銷量"), new JProperty("type", "bar"), new JProperty("data", d) } }),
};
json.Data = JsonConvert.SerializeObject(option);
return json;
}
前臺程式碼
function start() {
$.ajax({
type: "POST",
url: "/factory/GetData",
data: { id: "@Model.F_Uid" },
dataType: "json",
success: function (e) {
require.config({
paths: {
echarts: 'http://echarts.baidu.com/build/dist'
}
});
// 使用
require(
[
'echarts',
'echarts/chart/bar' // 使用柱狀圖就載入bar模組,按需載入
],
function (ec) {
// 基於準備好的dom,初始化echarts圖表
var myChart = ec.init(document.getElementById('main'));
// 為echarts物件載入資料
myChart.setOption(JSON.parse(e));
}
);
}
})
}
程式碼的可維護性上升了好多個級別,而且程式碼量更少了
其實還可以更加簡單的
可以直接使用匿名物件 ret.Data= new{Id=xx,Name=xx};
這時 MVC會將其自動序列化為 JSON 在前段也不需要再轉化
如果不希望使用JsonResult 的話 其實也可以在cshtml中 首先將其轉化為字串
string str=JsonConvert.SerializeObject(data)
然後使用@html.Raw(str)
算是新的兩種思路吧