利用Echarts设计一个图表平台(一)
Echarts是一款百度的开源图表库,里面提供了非常多的图表样式,我们今天要讲的内容是利用这一款开源js图表,制作一个能够动态定制的图表平台。
1)Echarts API介绍
首先我们先来看一下Echarts中的一个简单柱状图的API:
option = {
color: ['#3398DB'],
tooltip : {
trigger: 'axis',
axisPointer : { // 坐标轴指示器,坐标轴触发有效
type : 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis : [
{
type : 'category',
data : ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisTick: {
alignWithLabel: true
}
}
],
yAxis : [
{
type : 'value'
}
],
series : [
{
name:'直接访问',
type:'bar',
barWidth: '60%',
data:[10, 52, 200, 334, 390, 330, 220]
}
]
};
在这个option中包含了很多图表的属性,series是图表的基础属性,包含了图表的类型、数据的值等,xAxis包含了x轴上的数据列等。在其他的图表类型中,还会包含legend、title、tooltip、toolbox等属性,这些可以通过查看Echarts API查看,这里不一一叙述。
2)根据Echarts API建模
我们既然要实现一个报表平台,就需要对这些属性需要的数据进行建模:
public class TuBiao : IAggregateRoot
{
public title title { get; set; } = new title();
public legend legend { get; set; } = new legend();
public xAxis xAxis { get; set; } = new xAxis();
public yAxis yAxis { get; set; } = new yAxis();
public IList<series> serieList { get; set; } = new List<series>();
public TuBiao GetTuBiaoByID(string tuBiaoID)
{
ITuBiaoRepository repo = IoC.Resolve<ITuBiaoRepository>();
return repo.GetByTuBiaoID(tuBiaoID);
}
}
其中title、legend、xAxis、series都是图表模型中的值对象,熟悉领域驱动的同学可能看起来很熟悉,每一个都对应着Echarts API中的js属性,随便贴出一个两个代码示例:
public class title
{
public string text { get; set; }
public string subtext { get; set; }
}
public class series
{
public string name { get; set; }
public string type { get; set; }
public List<string> dataList { get; set; } = new List<string>();
}
public class yAxis
{
/// <summary>
/// 单位
/// </summary>
public string danwei { get; set; }
/// <summary>
/// 最大值
/// </summary>
public string ZuiDaZhi { get; set; }
/// <summary>
/// 最小值
/// </summary>
public string ZuiXiaoZhi { get; set; }
}
值对象的创建方式可以参考Echarts的API创建,最终我们的模型要满足一个完整Echarts所需要的所有属性。
3)根据Echarts模型加载Echarts的JavaScript脚本
在页面加载的时候,我们可以获取Echarts的模型,并加载到Echarts图表中。示例代码如下:
myChart.setOption({
title: {
text: '@ViewBag.TuBiao.title.text',
subtext: '@ViewBag.TuBiao.title.subtext'
},
tooltip: {
trigger: 'axis',
},
legend: {
data: [@for (;i<= ViewBag.TuBiao.legend.dataList.Count - ;i++ )
{
)
{
<text>'@ViewBag.TuBiao.legend.dataList[i]'</text>
}
else
{
<text>'@ViewBag.TuBiao.legend.dataList[i]',</text>
}
}]
},
@if(ViewBag.TuBiao.serieList.Count >= && ViewBag.TuBiao.serieList[].type != ].type != "funnel")
{ <text>
xAxis: [
{
data: [@for (; i <= ViewBag.TuBiao.xAxis.dataList.Count - ; i++)
{
)
{<text>'@ViewBag.TuBiao.xAxis.dataList[i]'</text>}
else
{<text>'@ViewBag.TuBiao.xAxis.dataList[i]',</text>}
}]
}
],
yAxis: [
{
type: 'value',
axisLabel: {
formatter: '{value}@ViewBag.TuBiao.yAxis.danwei'
},
@if(!string.IsNullOrEmpty(ViewBag.TuBiao.yAxis.ZuiXiaoZhi))
{
<text>min:@ViewBag.TuBiao.yAxis.ZuiXiaoZhi,</text>
}
@if(!string.IsNullOrEmpty(ViewBag.TuBiao.yAxis.ZuiDaZhi))
{
<text>max:@ViewBag.TuBiao.yAxis.ZuiDaZhi,</text>
}
boundaryGap:[, ]
}
],</text>}
toolbox: {
show: true,
feature: {
mark : {show: true},
dataView : {show: true, readOnly: true},
@if (ViewBag.TuBiao.serieList.Count >= && ViewBag.TuBiao.serieList[].type != ].type != "funnel")
{ <text>
magicType: { type: ['line', 'bar'] },</text>}
restore: {},
saveAsImage: {}
}
},
series: [@for (; serie <= ViewBag.TuBiao.serieList.Count - ; serie++)
{
)
{
<text>
{
name: '@ViewBag.TuBiao.serieList[serie].name',
type: '@ViewBag.TuBiao.serieList[serie].type',
data: [@for (;i<= ViewBag.TuBiao.serieList[serie].dataList.Count -;i++)
{
)
{
<text>{value:'@ViewBag.TuBiao.serieList[serie].dataList[i]',name:'@ViewBag.TuBiao.xAxis.dataList[i]'}</text>
}
else {
<text>{value:'@ViewBag.TuBiao.serieList[serie].dataList[i]',name:'@ViewBag.TuBiao.xAxis.dataList[i]'},</text>
}
}],
@if(ViewBag.TuBiao.serieList.Count >= && ViewBag.TuBiao.serieList[].type != ].type != "funnel")
{ <text>
markLine: {
data: [
{ type: 'average', name: '平均值' }
]
}</text>}
}
</text>
}
else
{
<text>
{
name: '@ViewBag.TuBiao.serieList[serie].name',
type: '@ViewBag.TuBiao.serieList[serie].type',
data: [@for (;i<= ViewBag.TuBiao.serieList[serie].dataList.Count -;i++)
{
)
{
<text>{value:'@ViewBag.TuBiao.serieList[serie].dataList[i]',name:'@ViewBag.TuBiao.xAxis.dataList[i]'}</text>
}
else {
<text>{value:'@ViewBag.TuBiao.serieList[serie].dataList[i]',name:'@ViewBag.TuBiao.xAxis.dataList[i]'},</text>
}
}],
@if(ViewBag.TuBiao.serieList.Count >= && ViewBag.TuBiao.serieList[].type != ].type != "funnel")
{ <text>
markLine: {
data: [
{ type: 'average', name: '平均值' }
]
}</text>}
},
</text>
}
}]
});
其中ViewBag.TuBiao就是我们从model层返回的报表模型,根据Echarts的API一一对应就可以了。
4)如何装载Echarts模型
前面所述的都是Echarts报表的展示部位,下面我们来看一下这个TuBiao的模型该如何生成,有心的同学可能已经注意到了TuBiao的模型中包含一个GetByTuBiaoID的方法,下面把该代码的实现分享一下:
public class TuBiaoRepository:Repository<TuBiao>,ITuBiaoRepository
{public TuBiaoRepository(RepositoryContext context) : base(context) { }
public TuBiao GetByTuBiaoID(string tuBiaoID)
{
TuBiaoShuJuYuan shujuyuan = TuBiaoShuJuYuan.GetByTuBiaoID(tuBiaoID);
TuBiao result = new TuBiao();
result.title.text = shujuyuan.BiaoTi;
result.title.subtext = shujuyuan.FuBiaoTi;
//设置Y轴的一些信息
result.yAxis.danwei = shujuyuan.DanWei;
result.yAxis.ZuiDaZhi = shujuyuan.ZuiDaZhi;
result.yAxis.ZuiXiaoZhi = shujuyuan.ZuiXiaoZhi;
//读取数据源
StreamReader srsjy = new StreamReader(HttpContext.Current.Request.MapPath("~/TubiaoData/") + shujuyuan.ShuJuYuan, System.Text.Encoding.UTF8);
try
{
shujuyuan.ShuJuYuan = srsjy.ReadToEnd();
}
catch (Exception ex)
{
throw ex;
}
finally
{
srsjy.Close();
}
foreach (var item in HttpContext.Current.Request.QueryString.AllKeys)
{
if (!string.IsNullOrEmpty(item))
shujuyuan.ShuJuYuan = shujuyuan.ShuJuYuan.Replace("[" + item + "]", HttpContext.Current.Request.QueryString[item]);
}
// \{([^\{^\}]*)\}
shujuyuan.ShuJuYuan = Regex.Replace(shujuyuan.ShuJuYuan, @"\[\S*\]", "", RegexOptions.Multiline);
DbHelper h = new DbHelper(ConnectionName.LocalDB);
DataTable dt = h.ExecuteDataTable(shujuyuan.ShuJuYuan).DataResult;
//检索图例
var tuli = (from i in dt.AsEnumerable()
select i.Field<string>(TuBiaoZiDuanStruct.TuLi)).Distinct().ToList<string>();
result.legend.dataList.AddRange(tuli);
//检索统计单元
var tongJiDy = (from i in dt.AsEnumerable()
select i.Field<string>(TuBiaoZiDuanStruct.TongJiDY)).ToList<string>();
result.xAxis.dataList.AddRange(tongJiDy);
//循环为每个图例赋值
foreach (string dqtl in tuli)
{
//查询当前图例的图表类型
var leiXing = (from i in dt.AsEnumerable()
where i.Field<string>(TuBiaoZiDuanStruct.TuLi) == dqtl
select i.Field<string>(TuBiaoZiDuanStruct.LeiXing)).ToList<string>().FirstOrDefault();
//添加数据
series srs = new series();
srs.name = dqtl;
srs.type = leiXing;
//检索对应图例下的图表数据
var tubiaosy = (from i in dt.AsEnumerable()
where i.Field<string>(TuBiaoZiDuanStruct.TuLi) == dqtl
select i.Field<dynamic>(TuBiaoZiDuanStruct.Zhi)).ToList<dynamic>();
foreach (dynamic zhi in tubiaosy)
{
srs.dataList.Add(Convert.ToString(zhi));
}
result.serieList.Add(srs);
}
return result;
}
struct TuBiaoZiDuanStruct
{
public static string TuLi { get { return "TULI"; } }
public static string LeiXing { get { return "LEIXING"; } }
public static string TongJiDY { get { return "TONGJIDY"; } }
public static string Zhi { get { return "ZHI"; } }
}
}
这个方法的作用主要是从数据库中查询图表的数据源定义,并执行该数据源,得到图表所需要的数据,并装载TuBiao模型,示例数据源的SQL语句如下:
5)Echarts模型的数据源定义
SELECT T.XINGMING AS TULI,'line' AS LEIXING,T.TIWEN AS ZHI,T.JILUSJ AS TONGJIDY FROM TIWEN T WHERE T.ID= '[ID]'
这个SQL语句是根据一个ID获取一个人的体温变化曲线图,在这里的ID涉及到了图表的参数化查询,包括报表的其他个性化的定制(如图表的曲线的范围、计量单位的定义等),下篇文章将会继续介绍该图表平台的其他实现。
利用Echarts设计一个图表平台(一)的更多相关文章
- 如何利用Excel设计一个唱票统计系统?
具体操作如下: 首先需要一个如下的数据结构. 唱票数G列区域,不能手动输入候选人票数,这样很不方便,所以我们需要一个窗体控件,用点击鼠标的方法来实现唱票.在“开发工具-插入-数值调节钮”下图3处,然后 ...
- UE4笔记:利用Widget设计一个切换材质功能
UE4引擎中的Widget蓝图是一个重要的工具,可用于场景中的页面叠加,镜头绑定,场景切换等多处地方,在这里笔者介绍一种利用控件蓝图和场景中物体进行信息交互的方法,直观的体现就是进行物体的材质切换. ...
- 如何利用GitHub设计一个炫酷的个人网站(含代码)
1.在开始制作之前我们先预览一下我的网站吧! 1.方式一: 由于是手机版的所以用手机访问下面的链接体验比较好一点: https://tom-shushu.github.io/MyWeb.github. ...
- 如何利用Visio设计一个系统的结构图
首先建立一个空的vison列表 添加图形和连接线 托选一个矩形块到操作台上,并进行底色填充 选择有向线段1拖到矩形模块上,此时有向线段1会自动吸附到矩形的中点处. 此时按下图操作即可取消,自动吸附 托 ...
- C语言中利用clock设计一个简单的定时器
time.h是C/C++中的日期和时间头文件,用于需要时间方面的函数,定义了四个变量类型.两个宏和各种操作日期和时间的函数. 其中计时函数是clock(),而与其相关的数据类型是clock_t.clo ...
- 利用ELK构建一个小型的日志收集平台
利用ELK构建一个小型日志收集平台 伴随着应用以及集群的扩展,查看日志的方式总是不方便,我们希望可以有一个便于我们查询及提醒功能的平台:那么首先需要剖析有几步呢? 格式定义 --> 日志收集 - ...
- 如何设计一个web容器
开发一个web容器涉及很多不同方面不同层面的技术,例如通信层的知识,程序语言层面的知识等等,且一个可用的web容器是一个比较庞大的系统,要说清楚需要很长的篇幅,本文旨在介绍如何设计一个web容器,只探 ...
- 如何设计一个可用的web容器
之前在另外一个平台(http://www.jointforce.com/jfperiodical/article/1035)发表的一篇文章,现在发布到自己的博客上. 开发一个web容器涉及很多不同方面 ...
- 利用 vue-cli 构建一个 Vue 项目
一.项目初始构建 现在如果要构建一个 Vue 的项目,最方便的方式,莫过于使用官方的 vue-cli . 首先,咱们先来全局安装 vue-cli ,打开命令行工具,输入以下命令: $ npm inst ...
随机推荐
- delphi Sender和Tag的用法
var Form1: TForm1; SelectedColor:TColor;//clBlack; //Defaultimplementation{$R *.dfm}procedure TFor ...
- cocos2d粒子效果
第9章 粒子效果 游戏开发者通常使用粒子系统来制作视觉特效.粒子系统能够发射大量细小的粒子并对他们进行渲染,而且效率要远高于渲染同样数目的精灵.粒子系统可以模拟下雨.火焰.雪.爆炸.蒸气拖尾以及其他多 ...
- 修复 MySQL 数据库结构错误 – mysql_upgrade升级
http://www.cnblogs.com/wjoyxt/p/5477072.html 不知道是不是每次更新 MySQL 软件之后都需要执行数据库升级指令?在我进行过的几次软件升级之后,总会在 My ...
- qt 获取系统磁盘空间大小
quint64 getDiskFreeSpace(QString driver) { LPCWSTR lpcwstrDriver=(LPCWSTR)driver.utf16(); ULARGE_INT ...
- Naive Bayes Algorithm
朴素贝叶斯的核心基础理论就是贝叶斯理论和条件独立性假设,在文本数据分析中应用比较成功.朴素贝叶斯分类器实现起来非常简单,虽然其性能经常会被支持向量机等技术超越,但有时也能发挥出惊人的效果.所以,在将朴 ...
- 结合源码看nginx-1.4.0之nginx事件驱动机制详解
目录 0. 摘要 1. nginx事件模块组织结构 2. nginx事件模块数据结构及类图 3. nginx事件模块运行机制 4. 练习:一个简单的事件驱动模块 5. 小结 6. 参考源码
- 根据url获取网页内容
PrintWriter out = null; out = response.getWriter(); try{ URL getUrl = new URL("http://www.kuaid ...
- [改善Java代码]适时选择不同的线程池来实现
Java的线程池实现从最根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系,但是Java为了简化并行计算,还提供 ...
- [改善Java代码]建议40:匿名类的构造函数很特殊
建议40: 匿名类的构造函数很特殊 在上一个建议中我们讲到匿名类虽然没有名字,但可以有一个初始化块来充当构造函数,那这个构造函数是否就和普通的构造函数完全一样呢?我们来看一个例子,设计一个计算器,进行 ...
- 关于hadoop2.4.1伪分布式系统的搭建
1.准备Linux环境 1.0点击VMware快捷方式,右键打开文件所在位置 -> 双击vmnetcfg.exe -> VMnet1 host-only ->修改subnet ip ...