Echarts是一款百度的开源图表库,里面提供了非常多的图表样式,我们今天要讲的内容是利用这一款开源js图表,制作一个能够动态定制的图表平台。

1)Echarts API介绍

首先我们先来看一下Echarts中的一个简单柱状图的API:

  1. option = {
  2. color: ['#3398DB'],
  3. tooltip : {
  4. trigger: 'axis',
  5. axisPointer : { // 坐标轴指示器,坐标轴触发有效
  6. type : 'shadow' // 默认为直线,可选为:'line' | 'shadow'
  7. }
  8. },
  9. grid: {
  10. left: '3%',
  11. right: '4%',
  12. bottom: '3%',
  13. containLabel: true
  14. },
  15. xAxis : [
  16. {
  17. type : 'category',
  18. data : ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
  19. axisTick: {
  20. alignWithLabel: true
  21. }
  22. }
  23. ],
  24. yAxis : [
  25. {
  26. type : 'value'
  27. }
  28. ],
  29. series : [
  30. {
  31. name:'直接访问',
  32. type:'bar',
  33. barWidth: '60%',
  34. data:[10, 52, 200, 334, 390, 330, 220]
  35. }
  36. ]
  37. };

在这个option中包含了很多图表的属性,series是图表的基础属性,包含了图表的类型、数据的值等,xAxis包含了x轴上的数据列等。在其他的图表类型中,还会包含legend、title、tooltip、toolbox等属性,这些可以通过查看Echarts API查看,这里不一一叙述。

2)根据Echarts API建模

我们既然要实现一个报表平台,就需要对这些属性需要的数据进行建模:

  1. public class TuBiao : IAggregateRoot
  2. {
  3. public title title { get; set; } = new title();
  4. public legend legend { get; set; } = new legend();
  5.  
  6. public xAxis xAxis { get; set; } = new xAxis();
  7.  
  8. public yAxis yAxis { get; set; } = new yAxis();
  9.  
  10. public IList<series> serieList { get; set; } = new List<series>();
  11.  
  12. public TuBiao GetTuBiaoByID(string tuBiaoID)
  13. {
  14. ITuBiaoRepository repo = IoC.Resolve<ITuBiaoRepository>();
  15. return repo.GetByTuBiaoID(tuBiaoID);
  16. }
  17. }

其中title、legend、xAxis、series都是图表模型中的值对象,熟悉领域驱动的同学可能看起来很熟悉,每一个都对应着Echarts API中的js属性,随便贴出一个两个代码示例:

  1. public class title
  2. {
  3. public string text { get; set; }
  4.  
  5. public string subtext { get; set; }
  6. }
  1. public class series
  2. {
  3. public string name { get; set; }
  4.  
  5. public string type { get; set; }
  6.  
  7. public List<string> dataList { get; set; } = new List<string>();
  8. }
  1. public class yAxis
  2. {
  3. /// <summary>
  4. /// 单位
  5. /// </summary>
  6. public string danwei { get; set; }
  7. /// <summary>
  8. /// 最大值
  9. /// </summary>
  10. public string ZuiDaZhi { get; set; }
  11. /// <summary>
  12. /// 最小值
  13. /// </summary>
  14. public string ZuiXiaoZhi { get; set; }
  15. }

值对象的创建方式可以参考Echarts的API创建,最终我们的模型要满足一个完整Echarts所需要的所有属性。

3)根据Echarts模型加载Echarts的JavaScript脚本

在页面加载的时候,我们可以获取Echarts的模型,并加载到Echarts图表中。示例代码如下:

  1. myChart.setOption({
  2. title: {
  3. text: '@ViewBag.TuBiao.title.text',
  4. subtext: '@ViewBag.TuBiao.title.subtext'
  5. },
  6. tooltip: {
  7. trigger: 'axis',
  8. },
  9. legend: {
  10. data: [@for (;i<= ViewBag.TuBiao.legend.dataList.Count - ;i++ )
  11. {
  12. )
  13. {
  14. <text>'@ViewBag.TuBiao.legend.dataList[i]'</text>
  15. }
  16. else
  17. {
  18. <text>'@ViewBag.TuBiao.legend.dataList[i]',</text>
  19. }
  20. }]
  21. },
  22. @if(ViewBag.TuBiao.serieList.Count >= && ViewBag.TuBiao.serieList[].type != ].type != "funnel")
  23. { <text>
  24. xAxis: [
  25. {
  26. data: [@for (; i <= ViewBag.TuBiao.xAxis.dataList.Count - ; i++)
  27. {
  28. )
  29. {<text>'@ViewBag.TuBiao.xAxis.dataList[i]'</text>}
  30. else
  31. {<text>'@ViewBag.TuBiao.xAxis.dataList[i]',</text>}
  32.  
  33. }]
  34. }
  35. ],
  36. yAxis: [
  37. {
  38. type: 'value',
  39. axisLabel: {
  40. formatter: '{value}@ViewBag.TuBiao.yAxis.danwei'
  41. },
  42. @if(!string.IsNullOrEmpty(ViewBag.TuBiao.yAxis.ZuiXiaoZhi))
  43. {
  44. <text>min:@ViewBag.TuBiao.yAxis.ZuiXiaoZhi,</text>
  45. }
  46. @if(!string.IsNullOrEmpty(ViewBag.TuBiao.yAxis.ZuiDaZhi))
  47. {
  48. <text>max:@ViewBag.TuBiao.yAxis.ZuiDaZhi,</text>
  49. }
  50. boundaryGap:[, ]
  51.  
  52. }
  53. ],</text>}
  54. toolbox: {
  55. show: true,
  56. feature: {
  57. mark : {show: true},
  58. dataView : {show: true, readOnly: true},
  59. @if (ViewBag.TuBiao.serieList.Count >= && ViewBag.TuBiao.serieList[].type != ].type != "funnel")
  60. { <text>
  61. magicType: { type: ['line', 'bar'] },</text>}
  62. restore: {},
  63. saveAsImage: {}
  64. }
  65. },
  66. series: [@for (; serie <= ViewBag.TuBiao.serieList.Count - ; serie++)
  67. {
  68. )
  69. {
  70. <text>
  71. {
  72. name: '@ViewBag.TuBiao.serieList[serie].name',
  73. type: '@ViewBag.TuBiao.serieList[serie].type',
  74. data: [@for (;i<= ViewBag.TuBiao.serieList[serie].dataList.Count -;i++)
  75. {
  76. )
  77. {
  78. <text>{value:'@ViewBag.TuBiao.serieList[serie].dataList[i]',name:'@ViewBag.TuBiao.xAxis.dataList[i]'}</text>
  79. }
  80. else {
  81. <text>{value:'@ViewBag.TuBiao.serieList[serie].dataList[i]',name:'@ViewBag.TuBiao.xAxis.dataList[i]'},</text>
  82. }
  83.  
  84. }],
  85. @if(ViewBag.TuBiao.serieList.Count >= && ViewBag.TuBiao.serieList[].type != ].type != "funnel")
  86. { <text>
  87. markLine: {
  88. data: [
  89. { type: 'average', name: '平均值' }
  90. ]
  91. }</text>}
  92. }
  93. </text>
  94. }
  95. else
  96. {
  97. <text>
  98. {
  99. name: '@ViewBag.TuBiao.serieList[serie].name',
  100. type: '@ViewBag.TuBiao.serieList[serie].type',
  101. data: [@for (;i<= ViewBag.TuBiao.serieList[serie].dataList.Count -;i++)
  102. {
  103. )
  104. {
  105. <text>{value:'@ViewBag.TuBiao.serieList[serie].dataList[i]',name:'@ViewBag.TuBiao.xAxis.dataList[i]'}</text>
  106. }
  107. else {
  108. <text>{value:'@ViewBag.TuBiao.serieList[serie].dataList[i]',name:'@ViewBag.TuBiao.xAxis.dataList[i]'},</text>
  109. }
  110.  
  111. }],
  112. @if(ViewBag.TuBiao.serieList.Count >= && ViewBag.TuBiao.serieList[].type != ].type != "funnel")
  113. { <text>
  114. markLine: {
  115. data: [
  116. { type: 'average', name: '平均值' }
  117. ]
  118. }</text>}
  119. },
  120. </text>
  121. }
  122.  
  123. }]
  124. });

其中ViewBag.TuBiao就是我们从model层返回的报表模型,根据Echarts的API一一对应就可以了。

4)如何装载Echarts模型

前面所述的都是Echarts报表的展示部位,下面我们来看一下这个TuBiao的模型该如何生成,有心的同学可能已经注意到了TuBiao的模型中包含一个GetByTuBiaoID的方法,下面把该代码的实现分享一下:

  1. public class TuBiaoRepository:Repository<TuBiao>,ITuBiaoRepository
  2. {public TuBiaoRepository(RepositoryContext context) : base(context) { }
  3.  
  4. public TuBiao GetByTuBiaoID(string tuBiaoID)
  5. {
  6. TuBiaoShuJuYuan shujuyuan = TuBiaoShuJuYuan.GetByTuBiaoID(tuBiaoID);
  7.  
  8. TuBiao result = new TuBiao();
  9. result.title.text = shujuyuan.BiaoTi;
  10. result.title.subtext = shujuyuan.FuBiaoTi;
  11. //设置Y轴的一些信息
  12. result.yAxis.danwei = shujuyuan.DanWei;
  13. result.yAxis.ZuiDaZhi = shujuyuan.ZuiDaZhi;
  14. result.yAxis.ZuiXiaoZhi = shujuyuan.ZuiXiaoZhi;
  15.  
  16. //读取数据源
  17. StreamReader srsjy = new StreamReader(HttpContext.Current.Request.MapPath("~/TubiaoData/") + shujuyuan.ShuJuYuan, System.Text.Encoding.UTF8);
  18. try
  19. {
  20. shujuyuan.ShuJuYuan = srsjy.ReadToEnd();
  21. }
  22. catch (Exception ex)
  23. {
  24. throw ex;
  25. }
  26. finally
  27. {
  28. srsjy.Close();
  29. }
  30.  
  31. foreach (var item in HttpContext.Current.Request.QueryString.AllKeys)
  32. {
  33. if (!string.IsNullOrEmpty(item))
  34. shujuyuan.ShuJuYuan = shujuyuan.ShuJuYuan.Replace("[" + item + "]", HttpContext.Current.Request.QueryString[item]);
  35. }
  36. // \{([^\{^\}]*)\}
  37. shujuyuan.ShuJuYuan = Regex.Replace(shujuyuan.ShuJuYuan, @"\[\S*\]", "", RegexOptions.Multiline);
  38.  
  39. DbHelper h = new DbHelper(ConnectionName.LocalDB);
  40. DataTable dt = h.ExecuteDataTable(shujuyuan.ShuJuYuan).DataResult;
  41. //检索图例
  42. var tuli = (from i in dt.AsEnumerable()
  43. select i.Field<string>(TuBiaoZiDuanStruct.TuLi)).Distinct().ToList<string>();
  44. result.legend.dataList.AddRange(tuli);
  45. //检索统计单元
  46. var tongJiDy = (from i in dt.AsEnumerable()
  47. select i.Field<string>(TuBiaoZiDuanStruct.TongJiDY)).ToList<string>();
  48. result.xAxis.dataList.AddRange(tongJiDy);
  49.  
  50. //循环为每个图例赋值
  51. foreach (string dqtl in tuli)
  52. {
  53. //查询当前图例的图表类型
  54. var leiXing = (from i in dt.AsEnumerable()
  55. where i.Field<string>(TuBiaoZiDuanStruct.TuLi) == dqtl
  56. select i.Field<string>(TuBiaoZiDuanStruct.LeiXing)).ToList<string>().FirstOrDefault();
  57. //添加数据
  58. series srs = new series();
  59. srs.name = dqtl;
  60. srs.type = leiXing;
  61.  
  62. //检索对应图例下的图表数据
  63. var tubiaosy = (from i in dt.AsEnumerable()
  64. where i.Field<string>(TuBiaoZiDuanStruct.TuLi) == dqtl
  65. select i.Field<dynamic>(TuBiaoZiDuanStruct.Zhi)).ToList<dynamic>();
  66.  
  67. foreach (dynamic zhi in tubiaosy)
  68. {
  69. srs.dataList.Add(Convert.ToString(zhi));
  70. }
  71.  
  72. result.serieList.Add(srs);
  73. }
  74.  
  75. return result;
  76. }
  77. struct TuBiaoZiDuanStruct
  78. {
  79. public static string TuLi { get { return "TULI"; } }
  80. public static string LeiXing { get { return "LEIXING"; } }
  81. public static string TongJiDY { get { return "TONGJIDY"; } }
  82. public static string Zhi { get { return "ZHI"; } }
  83. }
  84. }

这个方法的作用主要是从数据库中查询图表的数据源定义,并执行该数据源,得到图表所需要的数据,并装载TuBiao模型,示例数据源的SQL语句如下:

5)Echarts模型的数据源定义

  1. SELECT T.XINGMING AS TULI,'line' AS LEIXING,T.TIWEN AS ZHI,T.JILUSJ AS TONGJIDY
  2.  
  3. FROM TIWEN T WHERE T.ID= '[ID]'

这个SQL语句是根据一个ID获取一个人的体温变化曲线图,在这里的ID涉及到了图表的参数化查询,包括报表的其他个性化的定制(如图表的曲线的范围、计量单位的定义等),下篇文章将会继续介绍该图表平台的其他实现。

利用Echarts设计一个图表平台(一)的更多相关文章

  1. 如何利用Excel设计一个唱票统计系统?

    具体操作如下: 首先需要一个如下的数据结构. 唱票数G列区域,不能手动输入候选人票数,这样很不方便,所以我们需要一个窗体控件,用点击鼠标的方法来实现唱票.在“开发工具-插入-数值调节钮”下图3处,然后 ...

  2. UE4笔记:利用Widget设计一个切换材质功能

    UE4引擎中的Widget蓝图是一个重要的工具,可用于场景中的页面叠加,镜头绑定,场景切换等多处地方,在这里笔者介绍一种利用控件蓝图和场景中物体进行信息交互的方法,直观的体现就是进行物体的材质切换. ...

  3. 如何利用GitHub设计一个炫酷的个人网站(含代码)

    1.在开始制作之前我们先预览一下我的网站吧! 1.方式一: 由于是手机版的所以用手机访问下面的链接体验比较好一点: https://tom-shushu.github.io/MyWeb.github. ...

  4. 如何利用Visio设计一个系统的结构图

    首先建立一个空的vison列表 添加图形和连接线 托选一个矩形块到操作台上,并进行底色填充 选择有向线段1拖到矩形模块上,此时有向线段1会自动吸附到矩形的中点处. 此时按下图操作即可取消,自动吸附 托 ...

  5. C语言中利用clock设计一个简单的定时器

    time.h是C/C++中的日期和时间头文件,用于需要时间方面的函数,定义了四个变量类型.两个宏和各种操作日期和时间的函数. 其中计时函数是clock(),而与其相关的数据类型是clock_t.clo ...

  6. 利用ELK构建一个小型的日志收集平台

    利用ELK构建一个小型日志收集平台 伴随着应用以及集群的扩展,查看日志的方式总是不方便,我们希望可以有一个便于我们查询及提醒功能的平台:那么首先需要剖析有几步呢? 格式定义 --> 日志收集 - ...

  7. 如何设计一个web容器

    开发一个web容器涉及很多不同方面不同层面的技术,例如通信层的知识,程序语言层面的知识等等,且一个可用的web容器是一个比较庞大的系统,要说清楚需要很长的篇幅,本文旨在介绍如何设计一个web容器,只探 ...

  8. 如何设计一个可用的web容器

    之前在另外一个平台(http://www.jointforce.com/jfperiodical/article/1035)发表的一篇文章,现在发布到自己的博客上. 开发一个web容器涉及很多不同方面 ...

  9. 利用 vue-cli 构建一个 Vue 项目

    一.项目初始构建 现在如果要构建一个 Vue 的项目,最方便的方式,莫过于使用官方的 vue-cli . 首先,咱们先来全局安装 vue-cli ,打开命令行工具,输入以下命令: $ npm inst ...

随机推荐

  1. MS509Team----------------Cknife

    http://www.ms509.com/ http://www.freebuf.com/sectool/98681.html 中国蚁剑

  2. Asp.Net 之 使用Form认证实现用户登录 (LoginView的使用)

    1. 创建一个WebSite,新建一个页面命名为SignIn.aspx,然后在页面中添加如下的代码 <div class="div_logView"> <asp: ...

  3. spring+hibernate+struts整合(2)

    spring和struts2的整合 1:配置Web.xml文件 <filter> <filter-name>struts2</filter-name> <fi ...

  4. ArcGIS Server 10.2 实战(五)spatial etl tool 格式转换服务

    上不同的地图服务平台对地图文件格式的要求多种多样,arcgis使用的文件很难应用于其他平台上,因此需要有格式转换的服务来克服这种使用不同平台带来的麻烦,下面以TIFF格式转GEOTIFF格式为例. 首 ...

  5. vsftp安装与配置

    配置参考:https://help.aliyun.com/knowledge_detail/5973912.html?spm=5176.776701992.0.0.3X2PB8 553 Could n ...

  6. Kali+Win7双系统

    ----------------------------------------------------------前言---------------------------------------- ...

  7. logstash jdbc 各种数据库配置

    MySQL数据库 Driver ="path/to/jdbc-drivers/mysql-connector-java-5.1.35-bin.jar"   //驱动程序Class ...

  8. HDU 1978 How many ways (DP)

    How many ways Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  9. poj 3264 RMQ

    直接写个RMQ就能过. #include<iostream> #include<cstdio> #include<cstring> #include<algo ...

  10. c#语法笔记

    书写代码需要注意的地方: 1.代码中出现的所有标点都是英文半角 shift键快速切换中文半角和英文半角 shift+空格 切换全角/半角 2.在c#代码中,每行代码的结束,我们都以分号结束,注意:这个 ...