简介
ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器(IE6/7/8/9/10/11,chrome,firefox,Safari等),底层依赖轻量级的Canvas类库ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。
支持折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)、雷达图(填充雷达图)、和弦图、力导向布局图、地图、仪表盘、漏斗图、事件河流图等12类图表,同时提供标题,详情气泡、图例、值域、数据区域、时间轴、工具箱等7个可交互组件,支持多图表、组件的联动和混搭展现。
名词解析
基本名词
chart:是指一个完整的图表,如折线图,饼图等“基本”图表类型或由基本图表组合而成的“混搭”图表,可能包括坐标轴、图例等
axis:直角坐标系中的一个坐标轴,坐标轴可分为类目型、数值型或时间型
xAxis:直角坐标系中的横轴,通常并默认为类目型
yAxis:直角坐标系中的纵轴,通常并默认为数值型
grid:直角坐标系中除坐标轴外的绘图网格,用于定义直角系整体布局
legend:图例,表述数据和图形的关联
dataRange:值域选择,常用于展现地域数据时选择值域范围
dataZoom:数据区域缩放,常用于展现大量数据时选择可视范围
roamController:缩放漫游组件,搭配地图使用
toolbox:辅助工具箱,辅助功能,如添加标线,框选缩放等
tooltip:气泡提示框,常用于展现更详细的数据
timeline:时间轴,常用于展现同一系列数据在时间维度上的多份数据
series:数据系列,一个图表可能包含多个系列,每一个系列可能包含多个数据
图表名词
line:折线图,堆积折线图,区域图,堆积区域图。
bar:柱形图(纵向),堆积柱形图,条形图(横向),堆积条形图。
scatter:散点图,气泡图。散点图至少需要横纵两个数据,更高维度数据加入时可以映射为颜色或大小,当映射到大小时则为气泡图
k:K线图,蜡烛图。常用于展现股票交易数据。
pie:饼图,圆环图。饼图支持两种(半径、面积)南丁格尔玫瑰图模式。
radar:雷达图,填充雷达图。高维度数据展现的常用图表。
chord:和弦图。常用于展现关系数据,外层为圆环图,可体现数据占比关系,内层为各个扇形间相互连接的弦,可体现关系数据
force:力导布局图。常用于展现复杂关系网络聚类布局。
map:地图。内置世界地图、中国及中国34个省市自治区地图数据、可通过标准GeoJson扩展地图类型。支持svg扩展类地图应用,如室内地图、运动场、物件构造等。
heatmap:热力图。用于展现密度分布信息,支持与地图、百度地图插件联合使用。
gauge:仪表盘。用于展现关键指标数据,常见于BI类系统。
funnel:漏斗图。用于展现数据经过筛选、过滤等流程处理后发生的数据变化,常见于BI类系统。
evnetRiver:事件河流图。常用于展示具有时间属性的多个事件,以及事件随时间的演化。
treemap:矩形式树状结构图,简称:矩形树图。用于展示树形数据结构,优势是能最大限度展示节点的尺寸特征。
venn:韦恩图。用于展示集合以及它们的交集。
tree:树图。用于展示树形数据结构各节点的层级关系。
wordCloud:词云。词云是关键词的视觉化描述,用于汇总用户生成的标签或一个网站的文字内容。
图表类型
图表库标准包含单图表类型的标准图表以及多图表类型混合的混搭图表:
单图表类型:line
单图表类型:bar
单图表类型:pie
在这里我就不用一一列举了,还有很多,你们自己可以去搞搞,提升自己的技能。。。
现在我用一个简单的例子,先不从数据库里面拿取数据,那就非常非常的简单了。
效果图如下:
只要建一个web项目,就可以了
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>ECharts</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script type="text/javascript" src="js/jquery-1.8.0.min.js"></script> <script type="text/javascript" src="js/echarts.js"></script></head> <body> <!-- 为ECharts准备一个具备大小(宽高)的Dom --> <div id="main" style="width: 900px;height: 600px"></div> </body> <!-- ECharts单文件引入 --> <script type="text/javascript"> // 基于准备好的dom,初始化echarts图表 var myChart = echarts.init(document.getElementById("main")); option = { title : { text: '某地区蒸发量和降水量', subtext: '纯属虚构' }, tooltip : { trigger: 'axis' }, legend: { data:['蒸发量','降水量'] }, toolbox: { show : true, feature : { mark : {show: true}, dataView : {show: true, readOnly: false}, magicType : {show: true, type: ['line', 'bar']}, restore : {show: true}, saveAsImage : {show: true} } }, calculable : true, xAxis : [ { type : 'category', data : ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'] } ], yAxis : [ { type : 'value' } ], series : [ { name:'蒸发量', type:'bar', data:[2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3], markPoint : { data : [ {type : 'max', name: '最大值'}, {type : 'min', name: '最小值'} ] }, markLine : { data : [ {type : 'average', name: '平均值'} ] } }, { name:'降水量', type:'bar', data:[2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3], markPoint : { data : [ {name : , yAxis: , symbolSize:}, {name : , yAxis: } ] }, markLine : { data : [ {type : 'average', name : '平均值'} ] } } ] }; // 为echarts对象加载数据 myChart.setOption(option); </script> </html>
启动服务运行就可以了
从数据库拿区数据填充到echarts上给大家展示一下:
图型效果:
项目架构
lib文件下的jar包
代码实现:
Company 实体类
//公司 @Entity @Table public class Company { @Id @GeneratedValue private Integer id;//公司编号 private Integer sales;//销量 private Integer yield;//产量 private String week;//星期 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getSales() { return sales; } public void setSales(Integer sales) { this.sales = sales; } public Integer getYield() { return yield; } public void setYield(Integer yield) { this.yield = yield; } public String getWeek() { return week; } public void setWeek(String week) { this.week = week; }
CompanyDao接口
public interface CompanyDao { /** * 查询所有 * @return */ public List<Company> alllist(); /** * 所有销量 * @return */ public List<Integer> allsales();
CompanyDaoImpl 实现类
@Repository public class CompanyDaoImpl implements CompanyDao { @Autowired private SessionFactory sessionFactory; @SuppressWarnings("unchecked") public List<Company> alllist() { List<Company> list = sessionFactory.getCurrentSession().createQuery("from Company").list(); return list; } public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public List<Integer> allsales() { // TODO Auto-generated method stub return null; }
CompanyService接口
/** * 查询所有 * @return */ public List<Company> alllist();
CompanyServiceImpl 实现类
@Service public class CompanyServiceImpl implements CompanyService { @Resource private CompanyDao companyDao; public List<Company> alllist() { // TODO Auto-generated method stub return companyDao.alllist(); } public CompanyDao getCompanyDao() { return companyDao; } public void setCompanyDao(CompanyDao companyDao) { this.companyDao = companyDao; }
CompanyAction 类
@Controller @Scope("prototype") public class CompanyAction extends ActionSupport { private static final long serialVersionUID = 1L; @Resource private CompanyService companyService; //返回的json值 private String result; /** * 柱状图跳转 * @return * @throws IOException */ public String alllist() throws IOException{ List<Company> list = companyService.alllist(); for (Company company : list) { System.out.println(company.getWeek()); } Gson gn=new Gson(); result=gn.toJson(list); System.out.println(result); return "alllist"; } /** * 饼图跳转 * @return * @throws IOException */ public String alllistpie() throws IOException{ List<Company> list = companyService.alllist(); for (Company company : list) { System.out.println(company.getWeek()); } Gson gn=new Gson(); result=gn.toJson(list); System.out.println(result); return "alllistpie"; } /** * ajax 异步 同页显示 * @return * @throws IOException */ public String alllistajax() throws IOException{ List<Company> list = companyService.alllist(); for (Company company : list) { System.out.println(company.getWeek()); } Gson gn=new Gson(); result=gn.toJson(list); System.out.println(result); return SUCCESS; } public CompanyService getCompanyService() { return companyService; } public void setCompanyService(CompanyService companyService) { this.companyService = companyService; } public String getResult() { return result; } public void setResult(String result) { this.result = result; }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name></display-name> <!--指定路径 applicationContext.xml --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- 监听器:在应用程序加载启动的时候,spring容器自动构建 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> <filter-name>openSessionInView</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>openSessionInView</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置Struts2 的 核心过滤器 --> <filter> <filter-name>struts</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>source/login.jsp</welcome-file> </welcome-file-list> </web-app>
jdbc.properties
driverClass=oracle.jdbc.driver.OracleDriver jdbcUrl=jdbc\:oracle\:thin\:@localhost\:\:orcl user=xxx password=xxx
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd "> <!-- 自动扫描与装配bean --> <context:component-scan base-package="cn"></context:component-scan> <!-- .配置数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> </bean> <!-- 1.1 关联jdbc.properties --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- .配置SessionFactory --> <!-- sessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- 添加Hibernate配置信息 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop> <prop key="hibernate.current_session_context_class"> org.springframework.orm.hibernate3.SpringSessionContext</prop> </props> </property> <!-- 配置关联的映射文件 --> <property name="packagesToScan" value="cn.entity"></property> </bean> <!-- .配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- .配置开启事务操作 --> <tx:annotation-driven transaction-manager="transactionManager" /> </beans>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 对配置文件做了修正后,不需要重启服务器 --> <constant name="struts.devMode" value="true" /> <!-- 开启了对象工厂的移交权 --> <!-- <constant name="struts.ojectFactory" value="spring"></constant> --> <!-- simmple主题的设定 。 让UI人员更好的把控前台的界面 --> <constant name="struts.ui.theme" value="simple"></constant> <package name="default" namespace="/" extends="json-default"> <action name="alllist" class="companyAction" method="alllist"> <result name="alllist">/bar_db.jsp</result> </action> <action name="alllistajax" class="companyAction" method="alllistajax"> <result type="json"> <param name="root">result</param><!-- 表示返回的json对象,程序会默认以为你要返回的json类型为该对象下的所有属性及对象,以及对象的对象,对象的属性 --> </result> </action> <action name="alllistpie" class="companyAction" method="alllistpie"> <result name="alllistpie">/pie_db.jsp</result> </action> </package> </struts>
页面 jsp
bar_db.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+ path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>多种图</title> <!-- 引入echarts.js --> <script type="text/javascript" src="<%=path%>/js/echarts.js"></script> </head> <body> <!--为ECharts准备一个具有大小的Dom--> <div id="main" style="width: 900px;height: 600px"></div> </body> <script type="text/javascript"> //总的json串 var list=${result}; //销量 var mysales=new Array(); //产量 var myyield=new Array(); //星期 var myweek=new Array(); for (var item in list) { mysales[item]=list[item].sales; myyield[item]=list[item].yield; myweek[item]=list[item].week } //基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById("main")); var option = { //标题 title : { text :'某公司的星期销量图', subtext : '纯属虚构', left : 'left', textStyle : { fontSize : }, }, //图例 legend : { data : [ '销量' ] }, //颜色 color : [ 'red' ], //提示框组件 tooltip : { trigger : 'axis', axisPointer : { // 坐标轴指示器,坐标轴触发有效 type : 'cross' // 默认为直线,可选为:'line' | 'shadow'|'cross' } }, //工具栏 toolbox : { show : true,//是否显示 feature : { //数据视图工具,可以展现当前图表所用的数据,编辑后可以动态更新。 dataView : { show : true, readOnly : false }, //动态类型切换 magicType : { show : true, type : [ 'line', 'bar' ] }, //数据区域缩放。目前只支持直角坐标系的缩放 dataZoom : { show : true }, //配置项还原 restore : { show : true }, //保存为图片 saveAsImage : { show : true } } }, //x轴 xAxis : [ { position:'bottom',//x 轴的位置。可选:'top','bottom' type : 'category', data : myweek, axisTick : { alignWithLabel : true } } ], //y轴 yAxis : [ { type : 'value' } ], //数据 series : [ { name : '销量', type : 'bar', barWidth : '60%', data : mysales, markPoint : { data : [ { type : 'max', name : '最大值' }, { type : 'min', name : '最小值' } ] }, markLine : { data : [ { type : 'average', name : '平均值' } ] } }, { name : '产量', type : 'line', data : myyield } ], }; //使用个刚指定的配置项和数据显示图表 myChart.setOption(option); </script> </html>
饼图
pie_db.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>饼图</title> <script type="text/javascript" src="<%=path%>/js/jquery-1.8.0.min.js"></script> <!-- 引入echarts.js --> <script type="text/javascript" src="<%=path%>/js/echarts.js"></script> </head> <body> <!--为ECharts准备一个具有大小的Dom--> <div id="main" style="width: 900px;height: 600px"></div> </body> <script type="text/javascript"> //总的json串 var list = ${result}; //alert(list); //星期 var myweek = new Array(); //饼图的数据源 var mydata =new Array(); $.each(list, function(i, dom) { myweek[i]=dom.week; mydata[i]="{value:" + dom.yield + ",name:"+ dom.week+"}"; }); //基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById("main")); var option = { title : { text : '某公司的星期产量', subtext : '纯属虚构', x : 'center' }, tooltip : { trigger : 'item', formatter : "{a} <br/>{b} : {c} ({d}%)" }, legend : { orient : 'vertical', left : 'left', data :myweek, //['星期一','星期二','星期三','星期四','星期五','星期六','星期日'] //星期 }, series : [ { name : '产量', type : 'pie', radius : '55%', center : [ '50%', '60%' ], data :[ {value:,name:'星期一'}, {value:,name:'星期二'}, {value:,name:'星期三'}, {value:,name:'星期四'}, {value:,name:'星期五'}, {value:,name:'星期六'}, {value:,name:'星期日'}, ], itemStyle : { emphasis : { shadowBlur : , shadowOffsetX : , shadowColor : 'rgba(0, 0, 0, 0.5)' } } } ] }; //使用个刚指定的配置项和数据显示图表 myChart.setOption(option); </script> </html>
例子就先这么多,不过其他的例子跟上面也差不多了,如果以后还有碰到更好的例子,会分享给大家
接下来我们继续搞理论哈,但下面这些理论都是基于上面的解析的
引入ECharts
模块化单文件引入(推荐)
如果你使用模块化开发但并没有自己的打包合并环境,或者说你不希望在你的项目里引入第三方库的源文件,我们建议你使用单文件引入,同模块化包引入一样,你需要熟悉模块化开发。
自2.1.8起,我们为echarts开发了专门的合并压缩工具echarts-optimizer。如你所发现的,build文件夹下已经包含了由echarts-optimizer生成的单文件:
- dist(文件夹) : 经过合并、压缩的单文件
- echarts.js : 这是包含AMD加载器的echarts主文件,需要通过script最先引入
- chart(文件夹) : echarts-optimizer通过依赖关系分析同时去除与echarts.js的重复模块后为echarts的每一个图表类型单独打包生成一个独立文件,根据应用需求可实现图表类型按需加载
- line.js : 折线图(如需折柱动态类型切换,require时还需要echarts/chart/bar)
- bar.js : 柱形图(如需折柱动态类型切换,require时还需要echarts/chart/line)
- scatter.js : 散点图
- k.js : K线图
- pie.js : 饼图(如需饼漏斗图动态类型切换,require时还需要echarts/chart/funnel)
- radar.js : 雷达图
- map.js : 地图
- force.js : 力导向布局图(如需力导和弦动态类型切换,require时还需要echarts/chart/chord)
- chord.js : 和弦图(如需力导和弦动态类型切换,require时还需要echarts/chart/force)
- funnel.js : 漏斗图(如需饼漏斗图动态类型切换,require时还需要echarts/chart/pie)
- gauge.js : 仪表盘
- eventRiver.js : 事件河流图
- treemap.js : 矩阵树图
- venn.js : 韦恩图
- source(文件夹) : 经过合并,但并没有压缩的单文件,内容同dist,可用于调试
初始化
通过require获得echarts接口(或者命名空间)后可实例化图表,echarts接口仅有一个方法init,执行init时传入一个具备大小的dom节点(width、height可被计算得到即可,不一定可见)后即可实例化出图表对象,图表库实现为多实例的,同一页面可在多个dom上init出多个图表,同一个dom上多次init将自动释放已有实例(1.4.0+)。init方法说明如下:
图表实例可用方法见方法
引入ECharts后的的初始化代码如下:
// 作为入口 require( [ 'echarts', 'echarts/chart/pie' ], function (ec) { var myChart = ec.init(document.getElementById('main')); myChart.setOption({...}); } ); // ----------------------------- // 非入口或再次使用,图表已被加载注册 require('echarts').init(dom).setOption({...}); // 如果需要再次使用ECharts的图表实例,建议你还是保存init返回的图表实例吧 var myChart = require('echarts').init(dom); myChart.setOption({...});
熟悉模块化的你可以跳过了下面代码了
// 不习惯模块化的你当然可以 var echarts; require(['echarts'], function (ec){ echarts = ec; }); // 是的,把echarts加载后保存起来作为命名空间使用
实例方法
实例指的就是接口init()返回的对象,即上述代码中的“myChart”,非get接口均返回自身self支持链式调用
option
图表选项,包含图表实例任何可配置选项: 公共选项 , 组件选项 , 数据选项
xAxis
直角坐标系中横轴数组,数组中每一项代表一条横轴坐标轴,仅有一条时可省略数组。最多同时存在2条横轴,单条横轴时可指定安放于grid的底部(默认)或顶部,2条同时存在时位置互斥,默认第一条安放于底部,第二条安放于顶部。
坐标轴有三种类型,类目型、数值型和时间型(区别详见axis),横轴通常为类目型,但条形图时则横轴为数值型,散点图时则横纵均为数值型,具体参数详见axis。
yAxis
直角坐标系中纵轴数组,数组中每一项代表一条纵轴坐标轴,仅有一条时可省略数组。最多同时存在2条纵轴,单条纵轴时可指定安放于grid的左侧(默认)或右侧,2条同时存在时位置互斥,默认第一条安放于左侧,第二条安放于右侧。
坐标轴有三种类型,类目型、数值型和时间型(区别详见axis),纵轴通常为数值型,但条形图时则纵轴为类目型,具体参数详见axis。
series(通用)
驱动图表生成的数据内容数组,数组中每一项为一个系列的选项及数据,其中个别选项仅在部分图表类型中有效,请注意适用类型:
series(饼图)
驱动图表生成的数据内容数组,数组中每一项为一个系列的选项及数据:
就写这个算了,还有太多呢。。。。。。。。。