zoukankan      html  css  js  c++  java
  • echarts .NET类库开源

    前言:

      2012年从长沙跑到深圳,2016年又从深圳回到长沙,兜兜转转一圈,又回到了原点.4年在深圳就呆了一家公司,回长沙也是因为深圳公司无力为继,长沙股东老板挽留,想想自己年纪也不小了.就回来了,在长沙工作几月,也没什么太多的不适应.不用赶着项目上线,不用加班,想想其实也不错. 

      从12年在长沙就想写点开源的东西,不过实在不敢献丑.这次机缘巧合,有个朋友一个项目需要用到大量报表,我找到百度的开源echarts项目(感谢开源,4年工作以来用到很多很好的开源项目,对工作助力颇多),看着就挺舒服的,又看到了@abel533写的java类库,萌生了想写一个.net类库的想法.项目后来没做下去了,但是echart类库倒是坚持写下来了.断断续续几个月的时间,终于有点样子了.之所以写这篇博客,是因为最近在园子里看到很多看衰.net的文章,我无法判断对错,也不想引起争论,不过我只是简单喜欢编程的人,能够做自己喜欢的事就好,其实好的环境需要大家一起营造,我也想为.net阵营做一些有意义的事情.

    源码:

    源码地址:https://github.com/idoku/EChartsSDK

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

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

    先放几张eharts的图感受一下:

                          折线图

                      柱状图

                    散点图

                饼图

    正文

    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的写法,实际中使用会碰到什么问题暂时不清楚,如果有园友使用中碰到什么问题,欢迎与我交流.第一次做开源项目,欢迎大家批评指正.

  • 相关阅读:
    大华解码器二次开发/C#调用C++DLL
    C# 获取网站页面的句柄
    C# 字节数组 字符数组 字符串 Byte[] Char[] String
    C# 结构体数组 C++ DLL
    Django
    Djano
    Django
    数据分析 02 -Pandas
    数据分析-01 Numpy
    02-正则和xpath
  • 原文地址:https://www.cnblogs.com/kulong995/p/5237796.html
Copyright © 2011-2022 走看看