echarts .NET類庫開源

前言:前端

  2012年從長沙跑到深圳,2016年又從深圳回到長沙,兜兜轉轉一圈,又回到了原點.4年在深圳就呆了一家公司,回長沙也是由於深圳公司無力爲繼,長沙股東老闆挽留,想一想本身年紀也不小了.就回來了,在長沙工做幾月,也沒什麼太多的不適應.不用趕着項目上線,不用加班,想一想其實也不錯. java

  從12年在長沙就想寫點開源的東西,不過實在不敢獻醜.此次機緣巧合,有個朋友一個項目須要用到大量報表,我找到百度的開源echarts項目(感謝開源,4年工做以來用到不少很好的開源項目,對工做助力頗多),看着就挺舒服的,又看到了@abel533寫的java類庫,萌生了想寫一個.net類庫的想法.項目後來沒作下去了,可是echart類庫卻是堅持寫下來了.斷斷續續幾個月的時間,終於有點樣子了.之因此寫這篇博客,是由於最近在園子裏看到不少看衰.net的文章,我沒法判斷對錯,也不想引發爭論,不過我只是簡單喜歡編程的人,可以作本身喜歡的事就好,其實好的環境須要你們一塊兒營造,我也想爲.net陣營作一些有意義的事情.git

 

源碼:github

源碼地址:https://github.com/idoku/EChartsSDKweb

示例地址:http://echarts.idoku.cn/編程

echart地址:http://echarts.baidu.com/json

 

先放幾張eharts的圖感覺一下:api

                      折線圖數據結構

                  柱狀圖echarts

                散點圖

 

            餅圖

 

正文

ECharts .Net類庫

當前版本1.0.1

Echarts

本項目是一個供.NET開發者使用的ECharts的開發包,主要目的是方便在.NET中構件Echarts中可能用的所有數據結構,完整的Option結構. ChartOption中的數據Series,包含Line-折線圖,Bar-柱狀圖,Pie-餅圖,Scatter-散點圖等,支持Echarts中全部圖表.支持全部Style類,如AreaStyle,ItemStyle,LineStyle等.支持多種Data數據類型,一個通用的Data數據,以及PieData,PolarData,TreeData等個性化數據結構.

你可使用本項目直接構件一個Option對象,使用方法JsonTools.ObjectToJson2(option),(直接使用Json方式返回存在問題,由於function不是標準化的json格式,轉換會報錯).

 

圖表類型

  • Line - 折線(面積)圖
  • Bar - 柱狀(條形)圖
  • Scatter - 散點(氣泡)圖
  • K - K線圖
  • Pie - 餅(圓環)圖
  • Radar - 雷達(面積)圖
  • Chord - 和絃圖
  • Force - 力導向佈局圖
  • Map - 地圖
  • Gauge - 儀表盤
  • Funnel - 漏斗圖
  • Heatmap - 熱力圖
  • EventRiver - 事件河流圖
  • Venn - 韋恩圖
  • Tree - 樹圖
  • Treemap - 矩形樹圖
  • WordCloud - 詞雲

Echarts組件

  • Axis - 座標軸
  • Grid - 網格
  • Title - 標題
  • Tooltip - 提示
  • Legend - 圖例
  • DataZoom - 數據區域縮放
  • DataRange - 值域漫遊
  • Toolbox - 工具箱
  • Timeline - 時間線

 

ChartOption說明

  1. ChartOption 是echarts的主要類.
  2. 使用JsonTools.ObjectToJson2方法返回給前端時,須要使用eval('(' + data + ')')轉換爲JSON結構.

 

Function說明

因爲json標準中不包含function類型,通常json庫都不支持這種類型,處理這種類型最簡單的方式是轉換json字符串時,對字符串進行處理.

讀者能夠自行使用其餘自定義方式實現,本項目使用的.net自帶的JRaw()方式.無論是:

    "formatter": function(params) {

            // for text color

            var color = colorList[params[0].dataIndex];

            var res = '<div style="color:' + color + '">';

            res += '<strong>' + params[0].name + '消費(元)</strong>'

            for (var i = 0, l = params.length; i < l; i++) {

                res += '<br/>' + params[i].seriesName + ' : ' + params[i].value

            }

            res += '</div>';

            return res;

            },

  

"color": (function (){
                        var zrColor = require('zrender/tool/color');
                        return zrColor.getLinearGradient(
                            0, 400, 0, 300,
                            [[0, 'green'],[1, 'yellow']]
                        )
                    })(),
 

 

均可以利用JRaw來實現.

option.ToolTip().Trigger(TriggerType.axis)
                .BackgroundColor("rgba(255,255,255,0.7)")
                .Formatter(new JRaw(@"function(params) {
            // for text color
            var color = colorList[params[0].dataIndex];
            var res = '<div style=""color:' + color + '"">';
            res += '<strong>' + params[0].name + '消費(元)</strong>'
            for (var i = 0, l = params.length; i < l; i++) {
                res += '<br/>' + params[i].seriesName + ' : ' + params[i].value 
            }
            res += '</div>';
            return res;
            }"))
 

            style.Emphasis().BarBorderColor("green").BarBorderWidth(5)
                .Color(new JRaw(@"(function (){
                        var zrColor = require('zrender/tool/color');
                        return zrColor.getLinearGradient(
                            0, 400, 0, 300,
                            [[0, 'red'],[1, 'orange']]
                        )
                    })()"))

  

                                                          

EchartsWeb

本項目經過ASP.NET MVC和ASP.NET web api模擬了echarts官網網站中的所有示例,主要目的是方便你們參考使用和調整結構.

地址:http://echarts.idoku.cn/

 

1.簡單Line示例

演示地址: http://echarts.idoku.cn/home/example?api=line1

 

例子中給出的json結構.

{
  "calculable": true,
  "title": {
    "text": "將來一週天氣變化",
    "subtext": "純虛構數據",
    "show": true
  },
  "tooltip": {
    "trigger": "axis"
  },
  "legend": {
    "data": [
      "最高溫度",
      "最低溫度"
    ]
  },
  "xAxis": [
    {
      "data": [
        "週一",
        "週二",
        "週三",
        "週四",
        "週五",
        "週六",
        "週日"
      ],
      "boundaryGap": false,
      "type": "category"
    }
  ],
  "yAxis": [
    {
      "type": "value",
      "axisLabel": {
        "formatter": "{value} ℃"
      }
    }
  ],
  "series": [
    {
      "data": [
        13,
        10,
        12,
        10,
        13,
        13,
        14
      ],
      "type": "line",
      "name": "最高溫度",
      "markPoint": {
        "data": [
          {
            "name": "最大值",
            "type": "max"
          },
          {
            "name": "最小值",
            "type": "min"
          }
        ]
      },
      "markLine": {
        "data": [
          {
            "name": "平均值",
            "type": "average"
          }
        ]
      }
    },
    {
      "data": [
        3,
        -1,
        1,
        -1,
        3,
        3,
        4
      ],
      "type": "line",
      "name": "最低溫度",
      "markPoint": {
        "data": [
          {
            "name": "周最低",
            "value": -1,
            "xAxis": 1,
            "yAxis": -0.5
          }
        ]
      },
      "markLine": {
        "data": [
          {
            "name": "平均值",
            "type": "average"
          }
        ]
      }
    }
  ]
}

  

 

對應的源碼:

   [AcceptVerbs("GET", "POST")]
        [ActionName("line1")]
        public string StdLine()
        {
            IList<string> weeks = ChartsUtil.Weeks();
 
            IList<int> datas1 = ChartsUtil.Datas(7, 10, 15);
 
            IList<int> datas2 = ChartsUtil.Datas(7, -2, 5);
 
            int min = datas2.Min();
            int index = datas2.IndexOf(min);
 
            ChartOption option = new ChartOption();
 
            option.title = new Title()
            {
                show = true,
                text = "將來一週天氣變化",
                subtext = "純虛構數據"
            };
 
 
            option.tooltip = new ToolTip()
            {
                trigger = TriggerType.axis
            };
 
            option.legend = new Legend()
            {
                data = new List<object>(){
                   "最高溫度",
                   "最低溫度"
                 }
            };
 
            option.calculable = true;
 
            option.xAxis = new List<Axis>()
            {
                new CategoryAxis()
                {                    
                    type = AxisType.category,                    
                    boundaryGap= false,
                    data = new List<object>(weeks)
                }
            };
 
            option.yAxis = new List<Axis>()
            {
                new ValueAxis()
                {
                    type = AxisType.value,
                    axisLabel = new AxisLabel(){
                     formatter=new JRaw("{value} ℃").ToString()
                    }
                }
            };
            option.series = new List<object>()
            {
                    new Line()
                    {
                        name = "最高溫度",
                        type =  ChartType.line,
                        data =  datas1,
                        markPoint =  new MarkPoint()
                        {
                                data = new List<object>()
                                {
                                    new MarkData()
                                    {
                                         name = "最大值",
                                         type= MarkType.max,                                                                                                                           
                                    },
                                    new MarkData()
                                    {
                                         name = "最小值",
                                         type= MarkType.min,
                                    }
                                }
                        },
                        markLine = new MarkLine()
                        {
                                data = new List<object>()
                                {
                                     new MarkData()
                                     {
                                          name = "平均值",
                                          type = MarkType.average
                                     }
                                }
                       }
              },
              new Line(){
                name="最低溫度",
                type = ChartType.line,
                data = datas2,
                markPoint= new MarkPoint(){
                 data = new List<object>(){
                    new MarkData(){
                     name="周最低",
                     value = min,
                     xAxis = index,
                     yAxis = min+0.5,
                    }        
                 }
                },
               markLine = new MarkLine(){
                data = new List<object>(){
                   new MarkData(){
                    type = MarkType.average,
                    name = "平均值"
                   }
                }
               }
              }
            };
            var result = JsonTools.ObjectToJson2(option);
            return result;
        }

  

 

2.使用function的bar示例.

演示地址: http://echarts.idoku.cn/home/example?api=bar10#              

 

給出的json代碼:

{
  "title": {
    "text": "溫度計式圖表",
    "subtext": "Form ExcelHome",
    "sublink": "http://e.weibo.com/1341556070/AizJXrAEa"
  },
  "toolbox": {
    "feature": {
      "mark": {
        "show": true
      },
      "dataView": {
        "show": true,
        "readOnly": false
      },
      "restore": {
        "show": true
      },
      "saveAsImage": {
        "show": true
      }
    },
    "show": true
  },
  "tooltip": {
    "trigger": "axis",
    "formatter": function (params){
            return params[0].name + '<br/>'
                   + params[0].seriesName + ' : ' + params[0].value + '<br/>'
                   + params[1].seriesName + ' : ' + (params[1].value + params[0].value);
            },
    "axisPointer": {
      "type": "shadow"
    }
  },
  "legend": {
    "data": [
      "Acutal",
      "Forecast"
    ]
  },
  "grid": {
    "y2": 30,
    "y": 80
  },
  "xAxis": [
    {
      "data": [
        "Cosco",
        "CMA",
        "APL",
        "OOCL",
        "Wanhai",
        "Zim"
      ],
      "type": "category"
    }
  ],
  "yAxis": [
    {
      "boundaryGap": [
        0.0,
        0.1
      ],
      "type": "value"
    }
  ],
  "series": [
    {
      "stack": "sum",
      "data": [
        260,
        200,
        220,
        120,
        100,
        80
      ],
      "type": "bar",
      "name": "Acutal",
      "itemStyle": {
        "normal": {
          "color": "tomato",
          "barBorderColor": "tomato",
          "barBorderRadius": 0,
          "barBorderWidth": 6,
          "label": {
            "show": true,
            "position": "insideTop"
          }
        }
      }
    },
    {
      "stack": "sum",
      "data": [
        40,
        80,
        50,
        80,
        80,
        70
      ],
      "type": "bar",
      "name": "Forecast",
      "itemStyle": {
        "normal": {
          "color": "#fff",
          "barBorderColor": "tomato",
          "barBorderRadius": 0,
          "barBorderWidth": 6,
          "label": {
            "show": true,
            "position": "top",
            "formatter": function (params) {
                            for (var i = 0, l = option.xAxis[0].data.length; i < l; i++) {
                                if (option.xAxis[0].data[i] == params.name) {
                                    return option.series[0].data[i] + params.value;
                                }
                            }
                        },
            "textStyle": {
              "color": "tomato"
            }
          }
        }
      }
    }
  ]
}

  

 

對應的源碼:

[AcceptVerbs("GET", "POST")]
        [ActionName("bar10")]
        public string TemperatureBar()
        {
            ChartOption option = new ChartOption();
            option.Title().Text("溫度計式圖表").Subtext("Form ExcelHome").
                Sublink("http://e.weibo.com/1341556070/AizJXrAEa");
            option.ToolTip().Trigger(TriggerType.axis)
             .Formatter(new JRaw(@"function (params){
            return params[0].name + '<br/>'
                   + params[0].seriesName + ' : ' + params[0].value + '<br/>'
                   + params[1].seriesName + ' : ' + (params[1].value + params[0].value);
            }"))
             .AxisPointer().Type(AxisPointType.shadow);
            option.Legend().Data("Acutal","Forecast");
            Feature feature = new Feature();
            feature.Mark().Show(true);
            feature.DataView().Show(true).ReadOnly(false);
            feature.Restore().Show(true);
            feature.SaveAsImage().Show(true);
            option.ToolBox().Show(true).SetFeature(feature);
            option.Grid().Y(80).Y2(30);
            CategoryAxis x = new CategoryAxis();
            x.Data("Cosco", "CMA", "APL", "OOCL", "Wanhai", "Zim");
            option.XAxis(x);
            ValueAxis y = new ValueAxis();
            y.BoundaryGap(new List<double>() { 0,0.1 });           
            option.YAxis(y);
 
            var tomatoStyle = new ItemStyle();
            tomatoStyle.Normal().Color("tomato").BarBorderRadius(0)
                .BarBorderColor("tomato").BarBorderWidth(6)
                .Label().Show(true).Position(StyleLabelTyle.insideTop);
            Bar b1 = new Bar("Acutal");
            b1.Stack("sum");
            b1.SetItemStyle(tomatoStyle);            
            b1.Data(260, 200, 220, 120, 100, 80);
 
            var forecastStyle = new ItemStyle();
            forecastStyle.Normal().Color("#fff").BarBorderRadius(0)
                .BarBorderColor("tomato").BarBorderWidth(6)
                .Label().Show(true).Position(StyleLabelTyle.top)
                .Formatter(new JRaw(@"function (params) {
                            for (var i = 0, l = option.xAxis[0].data.length; i < l; i++) {
                                if (option.xAxis[0].data[i] == params.name) {
                                    return option.series[0].data[i] + params.value;
                                }
                            }
                        }"))
                        .TextStyle().Color("tomato");
 
            Bar b2 = new Bar("Forecast");
            b2.Stack("sum");
            b2.SetItemStyle(forecastStyle);
            b2.Data(40, 80, 50, 80, 80, 70);
 
            option.Series(b1, b2);
 
            var result = JsonTools.ObjectToJson2(option);
            return result;
        }
 

  

博客總結:

  排版真是硬傷~~~由於在項目期間,百度將echarts版本升級到了3.0,可是我已經實現了一半,因此就沒有使用新的3.0來實現.並且上面說到的項目沒有作下去,因此我是參考了@abel533的寫法,實際中使用會碰到什麼問題暫時不清楚,若是有園友使用中碰到什麼問題,歡迎與我交流.第一次作開源項目,歡迎你們批評指正.

相關文章
相關標籤/搜索