【MVC】AngularJs+KendoUI開發報表Demo(導出Excel和折線圖)

廢話寫在最前面

做angular開發已經有很長一段時間了,它的優勢已經不用贅述了,尤其是雙向綁定和高度模塊化,真是裝逼利器,甚是好用...

至於KendoUi,接觸時間不長,名字看上去是UI框架,但個人覺得更偏js。特別是自定義控件和Grid,是在客戶端解析,節約了不少的內存和數據交互的開銷。

兩大框架各有所長,但稍有不慎就會陷入無盡的苦惱。特別是在沒有裝js開發插件的IDE中,沒有任何錯誤提示,只能通過瀏覽器的調式一步一步修改。

做這個小例子,我就是這麼過來的。做的時間不長,很多地方值得商榷,抽這個時間把整個過程詳細記錄下來,僅爲以後的開發以此爲參考和教訓吧...

這裏綜合做了一個例子:包括Grid的顯示、導出Excel、Echart查看走勢圖...

敲黑板了

先放個最後的效果圖,就只做了一個Grid報表而已,【大神可以出門溜達了】很簡單...真的很簡單的功能...

導出Excel沒做,結合NPOI後續再更新吧。

用到的另外兩個框架:

H-UIBootStrap

主要是樣式的優化,H-UI還是咱國人自己寫的呢...

後臺

1.構建model

1.1用戶實體

 public class Customer
    {
        public int Id_int { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public decimal SalaryDecimal { get; set; }
        public string Province { get; set; }
        public string City { get; set; }
        public string Area { get; set; }
        public DateTime CreateDateTime { get; set; }
    }

1.2傳遞參數DTO

查詢條件。我把所有的查詢條件封裝成了一個對象,雖然也可以直接用拼接參數的方式傳值...

 /// <summary>
    /// 查詢參數對象
    /// </summary>
    public class CustomerParam
    {
        public string name { get; set; }
        public string stime { get; set; }
        public string etime { get; set; }
        public string area { get; set; }
        public string code { get;set; }
        public int page { get; set; }
        public int pageSize { get; set; }
        public string sort { get; set; }
    }

1.3統計結果集DTO

我做了兩個彙總(總工資、總年齡),也封裝成了對象。

 /// <summary>
    /// 統計DTO
    /// </summary>
    public class SumDto
    {
        /// <summary>
        /// 總工資
        /// </summary>
        public decimal SumMoney { get; set; }

        /// <summary>
        /// 總年齡
        /// </summary>
        public long TotalAge { get; set; }

2.查詢用戶列表方法

這裏模擬了55條記錄,如果需要用到數據庫,EF操作表就ok了。

  /// <summary>
        /// 客戶分頁列表
        /// </summary>
        /// <returns></returns>
        public PagedList<Customer> GetCustomers(CustomerParam param, out SumDto sumDto)
        {
            var list = new List<Customer>();
            for (int i = 0; i < 55; i++)
            {
                var costomer = new Customer()
                {
                    CreateDateTime = DateTime.Now.AddMinutes(i),
                    SalaryDecimal = 100 + i,
                    Age = 20 + i,
                    Area = "渝北區" + i,
                    City = "成都" + i,
                    Code = "Customer" + i,
                    Id_int = i,
                    Name = "我叫張三" + i,
                    Province = "重慶" + i
                };
                list.Add(costomer);
            }

            #region 搜索條件

            var i_list = list.ToList();
            if (!string.IsNullOrEmpty(param.stime) && !string.IsNullOrEmpty(param.etime))
            {
                //time
                var s_time = Convert.ToDateTime(param.stime);
                var e_time = Convert.ToDateTime(param.etime);
                i_list = i_list.FindAll(c => c.CreateDateTime >= s_time && c.CreateDateTime <= e_time);
            }
            //code or name
            if (!string.IsNullOrEmpty(param.name))
            {
                i_list = i_list.FindAll(c => c.Code.Contains(param.name) || c.Name.Contains(param.name));
            }

            #endregion

            sumDto = new SumDto()
            {
                SumMoney = i_list.Sum(o => o.SalaryDecimal),
                TotalAge = i_list.Sum(o => o.Age)
            };

            return new PagedList<Customer>(i_list, param.page, param.pageSize);//自己寫的擴展方法
        }
PagedList的重寫構造方法, 我在另一篇博客裏有記載:

LINQ擴展

3.控制器層

3.1Action指向視圖

public ActionResult KendoView_()
        {
            return View();
        }

3.2查詢數據源

 /// <summary>
        /// 獲取數據源
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public JsonResult GetUsers(CustomerParam query)
        {
            var sumDto = new SumDto();//用來做統計的對象
            query.page -= 1;//視圖傳過來的值是1,索引是從0開始,所以-1
            UserService _userService = new UserService();
            var userlist = _userService.GetCustomers(query, out sumDto);
            return Json(new
            {
                data = userlist,
                total = userlist.TotalCount,
                TongJi = sumDto
            });
        }
注意:控制器方法必須註明爲HttpPost方式

前臺

1.佈局頁面(引入樣式和js)

包括:KendoUI、JQ、Angular、H-ui、BootStrap...相關文件,要去官網或者官方qq羣裏下載。

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>

    <!--CSS-->
    <link href="~/static/h-ui/css/H-ui.min.css" rel="stylesheet" type="text/css" />
    <link href="~/static/h-ui.admin/css/H-ui.admin.css" rel="stylesheet" type="text/css" />
    <link href="~/lib/Hui-iconfont/1.0.7/iconfont.css" rel="stylesheet" type="text/css" />
    <link href="~/lib/icheck/icheck.css" rel="stylesheet" type="text/css" />
    <link href="~/static/h-ui.admin/skin/default/skin.css" rel="stylesheet" type="text/css" id="skin" />
    <link href="~/static/h-ui.admin/css/style.css" rel="stylesheet" type="text/css" />
    <link href="~/Scripts/toastr.css" rel="stylesheet" />
    <link href="~/Scripts/bootstrap.min.css" rel="stylesheet" />
    <link href="~/Scripts/KendoUI/styles/kendo.common-bootstrap.min.css" rel="stylesheet" />
    <link href="~/Scripts/KendoUI/styles/kendo.bootstrap.min.css" rel="stylesheet" />
    <!--JS-->
    <script src="~/lib/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
    <script src="~/lib/layer/2.1/layer.js" type="text/javascript"></script>
    <script src="~/static/h-ui/js/H-ui.js" type="text/javascript"></script>
    <script src="~/static/h-ui.admin/js/H-ui.admin.js" type="text/javascript"></script>
    <script src="~/Scripts/toastr.js"></script>
    <script src="~/Scripts/toastr.setting.js"></script>
    <!--angular-->
    <script src="~/Scripts/angular-1.4.2/angular.min.js"></script>
    <script src="~/lib/My97DatePicker/WdatePicker.js" type="text/javascript"></script>

    <!--bootstrap-->
    <script src="~/Scripts/bootstrap.min.js"></script>
    <!--kendo-->
    <script src="~/Scripts/KendoUI/kendo.all.min.js"></script>
    <script src="~/Scripts/KendoUI/kendo.angular.min.js"></script>
    <script src="~/Scripts/KendoUI/js/messages/kendo.messages.zh-CN.min.js"></script>
    <script src="~/Scripts/KendoUI/js/cultures/kendo.culture.zh-CN.min.js"></script>

    <!--自己重寫的樣式-->
    <style>
        body {
            color: #797979;
            background: #fff;
            padding: 0px !important;
            margin: 0 !important;
            font-size: 12px;
            color: black;
        }
        .k-grid .k-grid-header table thead tr th {
            color: deepskyblue;
            text-align: center;
        }
        .k-grid-header th.k-header > .k-link {
            color: deepskyblue;
        }
        .k-grid tr td {
            padding: 3px;
            padding-left: 5px;
            padding-right: 5px;
        }
        .btn {
            font-size: 12px;
        }
        .color-green {
            background-color: aquamarine;
        }

        .widget .widget-content {
            background-color: #fff;
        }
        .widget .widget-header {
            margin-bottom: 15px;
            border-bottom: 1px solid #ececec;
            *zoom: 1;
        }
        .widget.box {
            border: 1px solid #d9d9d9;
        }
        .widget.box .widget-header {
            background: #f1f2f7;
            border-bottom-color: #d9d9d9;
            line-height: 32px;
            padding-left: 12px;
            margin-bottom: 0;
        }
        .widget.box .widget-header .toolbar.no-padding {
            margin: -1px;
        }
         .widget.box .widget-header .toolbar.no-padding .btn {
             font-size: 13px;
             line-height: 23px;
             margin-top: 0;
        }
    </style>
</head>
<body>
    <div>
        @RenderBody()
    </div>
</body>
</html>

自己重寫了一部分樣式,也只是爲了好看而已...

2.視圖

2.1靜態頁面

@{
    ViewBag.Title = "KendoGrid Test";
    Layout = "~/Views/Shared/_LayoutKendo.cshtml";
    ViewBag.stime = DateTime.Now.AddDays(-7).ToString("yyyy-MM-dd");//查詢開始時間
    ViewBag.etime = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd");//結束時間
}

<section ng-app="MyApp" ng-controller="myController" class="wrapper" style="padding-top: 15px" ng-init="ChangeTableHeight()">
    <nav class="breadcrumb">
        <i class="Hui-iconfont"></i> 首頁
        <span class="c-gray en">></span> @ViewBag.Title
        <a title="刷新" href="javascript:location.replace(location.href);" style="line-height: 1.6em; margin-top: 3px" class="btn btn-success radius r">
            <i class="Hui-iconfont"></i>
        </a>
    </nav>
    <div class="page-container">
        <!--搜索條件-->
        <div class="text-c">
            員工姓名:
            <input type="text" class="input-text" style="width: 250px" placeholder="請輸入員工姓名" data-toggle="tooltip" data-placement="top" title="員工姓名" ng-model="query.name">
            創建時間:
            <input type="text" name="stime" style="width: 120px;" class="input-text Wdate" id="stime"
                   ng-model="query.stime" onfocus="WdatePicker({ maxDate: '#F{$dp.$D(\'logmax\')||\'%y-%M-%d\'}' })">
            -
            <input type="text" name="etime" style="width: 120px;" class="input-text Wdate" id="logmax" ng-model="query.etime" onfocus="WdatePicker({ minDate: '#F{$dp.$D(\'stime\')}', maxDate: '%y/%M/%d' })">
            <button class="btn btn-success" ng-click="SearchList()"><i class="Hui-iconfont"></i> 搜索</button>
        </div>

        <!--操作-->
        <div class="cl pd-5 bg-1 bk-gray mt-20">
            <span class="l">
                <a class="btn btn-danger radius" id="delmany" href="javascript:;">
                    <i class="Hui-iconfont"></i> 批量刪除
                </a>
                <a href="javascript:;" data-title="添加員工" class="btn btn-primary radius" id="user_add">
                    <i class="Hui-iconfont"></i> 添加員工
                </a>
            </span>
        </div>

        <!--Grid-->
        <div kendo-grid="Grid" options="GridOptions"></div>
    </div>

</section>

2.2js

<script type="text/javascript">
    var app = angular.module("MyApp", ["kendo.directives"]);
    var myController = app.controller("myController", ["$scope", "$http", function ($scope, $http) {
        //查詢條件
        $scope.query = {
            stime: '@ViewBag.stime',
            etime: '@ViewBag.etime',
            area: '',
            code: "",
            name: ''
        }
        //統計結果集
        $scope.TongJi = {
            SumMoney: 0.00,
            TotalAge: 0
        }

        //數據源
        $scope.GridDataSoruce = function () {
            return {
                pageSize: 10,
                page: 1,
                serverPaging: true,
                serverSorting: true,
                serverFiltering: true,
                serverGroupable: false,
                sort: { field: "SalaryDecimal", dir: "DESC" },
                transport: {
                    read: function (options) {
                        //JQuery時間選擇器在angular中傳不了值到後臺
                        if ($("#stime").val() && $("#etime").val()) {
                            $scope.query.stime = $("#stime").val();
                            $scope.query.etime = $("#etime").val();
                        }
                        $http.post("GetUsers", $.extend({}, options.data, $scope.query), {
                            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                            transformRequest: function (data) {
                                //排序
                                if (data.sort) {
                                    var rtStr = "";
                                    //var sortStr = "{0}-{1}#";
                                    for (var i = 0, len = data.sort.length; i < len; i++) {
                                        var nowS = data.sort[i];
                                        rtStr += (nowS.field + '-' + nowS.dir + '#'); //sortStr.format(nowS.field, nowS.dir);
                                    }
                                    if (rtStr.length > 0) {
                                        rtStr = rtStr.substring(0, rtStr.length - 1);
                                    }
                                    data.sort = rtStr;
                                }
                                return $.param(data);//參數
                            }
                        }).then(function (response) {
                            var dt = response.data;
                            options.success(dt);
                            //統計結果集
                            if (dt.TongJi)
                                $scope.TongJi = dt.TongJi;
                        }, function (error) {
                            console.log(error);
                            options.error(error.statusText);
                        });
                        console.log($scope.query);
                    }
                },
                schema: {
                    type: "json",
                    data: "data",
                    total: "total",
                    errors: "errors",
                    model: {
                        fields: {
                            CreateDateTime: { type: "date" }
                        }
                    }
                }
            }
        }

        //綁定數據源&表頭
        $scope.GridOptions = {
            dataSource: $scope.GridDataSoruce(),
            groupable: false,
            sortable: true,
            pageable: {
                refresh: false,
                pageSizes: [5, 10],
                buttonCount: 5,
                numeric: true    //如果不設true,會提示‘拖拽表頭...’
            },
            columnMenu: true,
            scrollable: true,
            selectable: false,
            dataBound: function () {
                //設置序號
                var rows = this.items();
                var page = this.pager.page() - 1;
                var pagesize = this.pager.pageSize();
                $(rows).each(function () {
                    if (rows.length > 0) {
                        var index = $(this).index();
                        var XuHao = index + 1 + page * pagesize;
                        var rowLable = $(this).find(".row-number").html(XuHao);
                    }
                });
            },
            columns: [
            {
                field: "", title: "序號", width: 60,
                attributes: { style: "text-align:center" },
                template: "<span class='row-number'></span>",
                footerTemplate:"<span>彙總:</span>"
            },
                {
                    field: "SalaryDecimal", title: "工資", width: 100, format: "{0:0.00}",
                    template: "<p style='text-align:center;color:pink'>¥{{dataItem.SalaryDecimal}}</p>",
                    footerTemplate: "<div style='text-align:right;color:red'>¥<span ng-bind='TongJi.SumMoney | number:2'></span></div>"
                },
                { field: "Name", title: "員工姓名", width: 150 },
                { field: "Code", title: "員工編碼", width: 150 },
                {
                    field: "Age", title: "年齡", width: 100,
                    template: "<p style='text-align:right;color:pink'>{{dataItem.Age}}歲</p>",
                    footerTemplate: "<div style='text-align:right;color:red'>共<span ng-bind='TongJi.TotalAge'></span>歲</div>"
                },
                { field: "CreateDateTime", title: "創建時間", format: "{0:yyyy-MM-dd HH:mm:ss}", width: 180 },    //格式化時間
                {
                    title: "地址",
                    columns: [
                        {
                            field: "Province", title: "省", width: 100,
                            template: "<p style=\"text-align:right;color:green\">{{dataItem.Province}}</p>"
                        },
                         {
                             field: "City", title: "市", width: 100,
                             template: "<p style=\"text-align:right;color:red\">{{dataItem.City}}</p>"
                         },
                          {
                              field: "Area", title: "區", width: 100,
                              template: "<p style=\"text-align:right;color:blue\">{{dataItem.Area}}</p>"
                          }
                    ]
                },
                {
                    title: "操作", width: 80, sortable: false, attributes: { style: "text-align:center" },
                    template: function (item) {
                        var showItem = '<a href="#" ng-click=\'showSelect(' + item.Id_int + ')\' title="得到用戶標記" class="ml-5" style="text-decoration: none"><i class="Hui-iconfont"></i></a>';
                        //var res = showItem.format(item.Code, "");
                        return showItem;
                    }
                }
            ]
        }

        $scope.SearchList = function () {
            $scope.Grid.setDataSource(new kendo.data.DataSource($scope.GridDataSoruce()));
        }

        $scope.showSelect = function (id) {
            alert(id);
            //操作...
        }

        //改變table高度
        $scope.ChangeTableHeight = function () {
            var prrGrid = $("div[options='GridOptions']");
            var dataArea = prrGrid.find(".k-grid-content");
            var bottomArea = prrGrid.find(".k-grid-pager");
            var sxHeight = window.innerHeight - prrGrid.offset().top - 20;
            var diif = prrGrid.height() - sxHeight;
            prrGrid.height(sxHeight);
            dataArea.height(dataArea.height() - diif);
        }
    }]);

</script>

注意1.頁面初始化方法ChangeTableHeight(),該方法會填充table的空白,即使沒有這麼多數據。如果不加此方法,table的行高會依賴實際數據量..

如果屏蔽該方法,效果:

   2.不知道是不是JQ和angular有衝突,用JQ的時間選擇器傳值,控制器始終獲取不到值。所以,在傳值之前, 手動將兩個時間控件的值賦值給參數對象.


    3.post請求的時候,參數名必須和控制器方法的參數名一樣,大小寫也必須一樣。

我兩邊的名字都叫query

沒有上傳項目文件,因爲複製上面的代碼,完全可以正常運行。

後記:

1.這篇博文僅僅是給自己還有更多初學者作爲參考筆記,主要是Kendo-Grid和Angular結合的使用,諸多查詢效率、代碼可讀性、代碼註釋的問題沒有解決,還請諸位看官高擡貴手。

2.今天是自己在這家公司的最後一天了,所以纔有時間和閒心來總結過去的開發,寫這篇文章。來這裏2年左右了,細細回想起當初一起加班到凌晨、一起做活動的時光,心中也是各種滋味...看看現在的時間,2017.4.21 下午2.09分,還有不到4個小時就下班了。

很多同事都是不打不相識呢,特別是分公司的幾位哥,當初做你們需求的時候真是想把你們拉過來當面打一頓,哈哈...現在我們的關係非常好,私底下也成爲了朋友。

擡頭望望窗外,陽光明媚,工位上的幾盆綠蘿,只有託付給以後的同事了...

兄弟們,保重,加油!



-----------------------------------2017.4.27更新-------------------------------

3.NPOI導出Excel

關於NPOI,我之前用一個系列詳細做過記錄

【一步一步學NPOI】

3.1DataTable導出Excel方法

/// <summary>
        /// 導出Excel
        /// </summary>
        /// <param name="dt">數據源</param>
        public static void ExportExcel(DataTable dt, string fileName)
        {
            HSSFWorkbook hssfworkbook = new HSSFWorkbook();
            //創建Excel工作表  
            var sheet1 = hssfworkbook.CreateSheet("用戶列表");

            var row0 = sheet1.CreateRow(0);
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                var row1 = sheet1.CreateRow(i + 1);
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    var cell0 = row0.CreateCell(j);
                    cell0.SetCellValue(dt.Columns[j].ToString());
                    var cell1 = row1.CreateCell(j);
                    cell1.SetCellValue(dt.Rows[i][j].ToString());
                }
            }
            //絕對路徑-文件名
            string excelName = string.Format(@"D:/{0}_{1}.xlsx", fileName, DateTime.Now.ToString("yyyy_MM_dd"));
            //保存
            FileStream file = new FileStream(excelName, FileMode.Create, FileAccess.Write);
            hssfworkbook.Write(file);
            file.Close();
        }
因爲NPOI是基於DataTable操作的,所以寫了一個IEnumerable轉DataTable的擴展方法:

   public static DataTable ToTable<T>(this IEnumerable<T> list)
        {
            //屬性集合
            List<PropertyInfo> userList = new List<PropertyInfo>();

            DataTable dt = new DataTable("MyTable");
            Type type = typeof(T);

            Array.ForEach<PropertyInfo>(type.GetProperties(), p => { userList.Add(p); dt.Columns.Add(p.Name, p.PropertyType); });
            foreach (var item in list)
            {
                var row = dt.NewRow();
                userList.ForEach(u => row[u.Name] = u.GetValue(item, null));
                dt.Rows.Add(row);
            }
            return dt;
        }

3.2前端

頁面上一個按鈕控件就不記錄了;

Angular方法:

 //導出excel
        $scope.Excel = function () {
            $.post('ExportExcel', {}, function (data) {
                if (!data.success) {
                    layer.alert('出錯了:'+data.message, { icon: 2 });
                }
            });
        }
控制器:(注意:我是將導出的數據源保存到Session

   public JsonResult ExportExcel()
        {
            if (Session["userlist"] != null)
            {
                var dataSoruce = Session["userlist"] as DataTable;
                Helper.ExportExcel(dataSoruce, "用戶列表");
                return Json(new
                {
                    success = true
                });
            }
            else
            {
                return Json(new
                {
                    success = false,
                    message = "獲取用戶數據源session失敗"
                });
            }
        }
大功告成:在本地已經生成了相應的Excel



Echart生成折線圖

祭出echart官網:

多說兩句,echart是百度開發的客戶端生成的圖形報表第三方組件。想起前幾年做折線圖報表,不知道有第三方框架,硬生生用reportviewer和rdlc來做的,同樣實現了這功能。可,人都是會變得,有了框架,誰還走那麼多冤枉路呢?

這裏我選取前十條記錄的年齡和薪水來做折線圖。

(才吃晚飯,先出去帶幺兒散散步再回來寫....)

查看折線圖的按鈕

頁面上放了一個按鈕,彈出一個新視圖來show折線圖。(說明一下:靜態的樣式都是用的h-ui的樣式

按鈕標籤:

 <button class="btn btn-secondary radius " ng-click="Zhexian()"><i class="Hui-iconfont Hui-iconfont-tongji-xian"> </i>走勢圖</button>

click方法:用了layer,單獨彈出一個新頁面。

  //查看折線圖(單獨打開一個視圖)
        $scope.Zhexian = function () {
            layer.open({
                type: 2,
                title: '薪水年齡折線圖',
                shadeClose: true,
                shade: 0.4,
                area: ['60%', '60%'],
                content: "/kendo/Zhexian"	//控制器方法
            });
        }

控制器Zhexian方法:

   public ActionResult Zhexian()
        {
            return View();
        }

折線圖View

靜態頁面很簡單,只有一個div,用來做畫板。因爲要用到angular,所以外層加了一個section。

@{
    ViewBag.Title = "Zhexian";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<section ng-app="MyApp" ng-controller="myController" class="wrapper" style="padding-top: 15px" ng-init="init()">
    <div id="main" style="width: 100%;height:500px;"></div>
</section>

注意這個angular的初始化方法,init。這個方法裏面就去控制器裏查詢需要畫折線圖的數據。

該頁面完整的腳本:

var app = angular.module("MyApp", ["kendo.directives"]);
    var myController = app.controller("myController", ["$scope", "$http", function ($scope, $http) {
        $scope.xAxis_data = [];//X軸數據

        $scope.series = [];//折線的對象數組
        //我要統計兩條折現,所以創建兩個對象
        //折線對象1
        $scope.series_obj_a = {
            name: '年齡',
            type: 'line',
            stack: '總量'
        };
        //折線對象2
        $scope.series_obj_b = {
            name: '工資',
            type: 'line',
            stack: '總量'
        };

        $scope.series_obj_a_data = [];//折線對象1上的值
        $scope.series_obj_b_data = [];//折線對象2上的值

        //初始化方法,得到待折線圖的數據
        $scope.init = function () {
            $.post('/kendo/GetZhexianData', {}, function (data) {
                for (var i = 0; i < data.length; i++) {
                    $scope.xAxis_data.push(data[i].UserName);//X軸-用戶名
                  
                    $scope.series_obj_a_data.push(data[i].Age);//年齡
                    $scope.series_obj_b_data.push(data[i].Salary);//薪水
                }
                $scope.series_obj_a.data = $scope.series_obj_a_data;
                $scope.series_obj_b.data = $scope.series_obj_b_data;

                $scope.series.push($scope.series_obj_a);
                $scope.series.push($scope.series_obj_b);
                console.log($scope.series);

                $scope.MakeZhexian();
            });
        }

        //畫折線圖
        $scope.MakeZhexian = function () {
            var myChart = echarts.init(document.getElementById('main'));

            var option = {
                title: {
                    text: '選擇前十組數據'
                },
                tooltip: {
                    trigger: 'axis'
                },
                legend: {
                    data: ['工資', '年齡']
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true
                },
                toolbox: {
                    feature: {
                        saveAsImage: {}
                    }
                },
                xAxis: {
                    type: 'category',
                    boundaryGap: false,
                    data: $scope.xAxis_data
                },
                yAxis: {
                    type: 'value'
                },
                series: $scope.series
            };

            myChart.setOption(option);
        }

    }]);
說明:

1.初始化加載時post到控制器裏,得到數據源

 /// <summary>
        /// 畫折線圖的數據源
        /// </summary>
        /// <returns></returns>
        public JsonResult GetZhexianData()
        {
            var userlist = Session["userlist"] as List<UserDto>;//這裏可以用讀取數據庫的之,爲了方便,我就只取了session
            return Json(userlist.Select(u => new
            {
                UserName = u.UserName,
                Salary = u.Salary,
                Age = u.Age
            }).Take(10));//只模擬前10條記錄
        }

2.畫板上的看到的線條,本質是一個對象數組,每個折線圖就是一個對象。

series: $scope.series

3.最終生成兩條折線圖(工資、年齡),所以我創建了兩個折線圖對象。


最後的效果










發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章