簡介
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:詞雲。詞雲是關鍵詞的視覺化描述,用於匯總用戶生成的標簽或一個網站的文字內容。
圖表庫標准包含單圖表類型的標准圖表以及多圖表類型混合的混搭圖表:
在這裡我就不用一一列舉了,還有很多,你們自己可以去搞搞,提升自己的技能。。。
現在我用一個簡單的例子,先不從數據庫裡面拿取數據,那就非常非常的簡單了。
效果圖如下:
只要建一個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="expires" content="0"> <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" ></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 : '年最高', value : 182.2, xAxis: 7, yAxis: 183, symbolSize:18}, {name : '年最低', value : 2.3, xAxis: 11, yAxis: 3} ] }, 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\:1521\: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> <!-- 01.配置數據源 --> <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" /> <!-- 02.配置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> <!-- 06.配置事務管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 07.配置開啟事務操作 --> <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" ></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 : 20 }, }, //圖例 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" ></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:300,name:'星期一'}, {value:300,name:'星期二'}, {value:2000,name:'星期三'}, {value:3000,name:'星期四'}, {value:700,name:'星期五'}, {value:1500,name:'星期六'}, {value:800,name:'星期日'}, ], itemStyle : { emphasis : { shadowBlur : 10, shadowOffsetX : 0, shadowColor : 'rgba(0, 0, 0, 0.5)' } } } ] }; //使用個剛指定的配置項和數據顯示圖表 myChart.setOption(option); </script> </html>
接下來我們繼續搞理論哈,但下面這些理論都是基於上面的解析的
如果你使用模塊化開發但並沒有自己的打包合並環境,或者說你不希望在你的項目裡引入第三方庫的源文件,我們建議你使用單文件引入,同模塊化包引入一樣,你需要熟悉模塊化開發。
自2.1.8起,我們為echarts開發了專門的合並壓縮工具echarts-optimizer。如你所發現的,build文件夾下已經包含了由echarts-optimizer生成的單文件:
通過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支持鏈式調用
圖表選項,包含圖表實例任何可配置選項: 公共選項 , 組件選項 , 數據選項
直角坐標系中橫軸數組,數組中每一項代表一條橫軸坐標軸,僅有一條時可省略數組。最多同時存在2條橫軸,單條橫軸時可指定安放於grid的底部(默認)或頂部,2條同時存在時位置互斥,默認第一條安放於底部,第二條安放於頂部。
坐標軸有三種類型,類目型、數值型和時間型(區別詳見axis),橫軸通常為類目型,但條形圖時則橫軸為數值型,散點圖時則橫縱均為數值型,具體參數詳見axis。
直角坐標系中縱軸數組,數組中每一項代表一條縱軸坐標軸,僅有一條時可省略數組。最多同時存在2條縱軸,單條縱軸時可指定安放於grid的左側(默認)或右側,2條同時存在時位置互斥,默認第一條安放於左側,第二條安放於右側。
坐標軸有三種類型,類目型、數值型和時間型(區別詳見axis),縱軸通常為數值型,但條形圖時則縱軸為類目型,具體參數詳見axis。
驅動圖表生成的數據內容數組,數組中每一項為一個系列的選項及數據,其中個別選項僅在部分圖表類型中有效,請注意適用類型:
驅動圖表生成的數據內容數組,數組中每一項為一個系列的選項及數據:
就寫這個算了,還有太多呢。。。。。。。。。