Echart是百度开发的一个javascript图表库,可以流程运行于pc和移动端,底层依赖轻量级的 Canvas 类库 ZRender。
ECharts 提供了常规的折线图,柱状图,散点图,饼图,K线图,用于统计的盒形图,用于地理数据可视化的地图,热力图,线图,用于关系数据可视化的关系图,treemap,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。
支持:
多个坐标系:直角坐标系,极坐标系,地理坐标系;
移动端的优化:可以按需打包,支持移动端手指缩放;
数据的深度交互;
大量数据的展现:基于微博签到的100K条数据展现;
多维数据以及丰富的视觉效果;
动态数据和绚丽特效;
上手Echart(官网案例):
国际惯例,引入js文件,这里还是要先引入jquery。
<!DOCTYPE html> <html> <header> <meta charset="utf-8"> <!-- 引入 ECharts 文件 --> <script src="echarts.min.js"></script> </header> </html>
准备一个容器作为画布:
<body> <!-- 为 ECharts 准备一个具备大小(宽高)的 DOM --> <div id="main" style="width: 600px;height:400px;"></div> </body>
写js代码(这里的部分写法与highchart的写法很类似,以至于我曾经一直在highchart的api里面找echart的效果...):
<script type="text/javascript"> // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById(‘main‘)); // 指定图表的配置项和数据 var option = { //标题 title: { text: ‘ECharts 入门示例‘ }, tooltip: {}, //图例 legend: { data:[‘销量‘] }, //横坐标 xAxis: { data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"] }, //纵坐标 yAxis: {}, //数据列 series: [{ name: ‘销量‘, type: ‘bar‘, data: [5, 20, 36, 10, 10, 20] }] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); </script>
下面还是通过自己的一个例子来简单说明一下:写法可能不止一种。
数据是之前通过jsoup解析中通网页,将地址存到数据库里,然后根据地址查询百度地图api,获得经纬度信息再update到数据库里。(过程这里贴不下,以后整理一下再贴出来)
数据获取.......
List<Loc2> dat = testChartService.selectLoc(); Map all=new HashMap(); for(Loc2 loc2:dat){ List list = new ArrayList(); list.add(loc2.getLongitude()); list.add(loc2.getLatitude()); all.put(loc2.getAddress(),list); } System.out.println(all.toString()); writeJson(response, all); // 以json格式输出 public void writeJson(HttpServletResponse response, Object obj) { PrintWriter writer = null; try { response.setContentType("application/json" + ";charset=utf-8"); writer = response.getWriter(); Object jsonObject = null; if (obj instanceof List) { jsonObject = JSONArray.toJSON(obj); } else { jsonObject = JSONObject.toJSON(obj); } writer.print(jsonObject.toString()); } catch (Exception e) { e.printStackTrace(); } finally { if (writer != null) { writer.close(); } } }
//这是数据格式: loc:{ 白玉路346号=[121.423744, 31.23829], 新民路城南工商所对面巷子( 南苑菜市旁边 )=[106.577573, 31.082472], 长江路26号,苏展工业坊b栋1层=[118.328064, 33.949859] } //数据是之前做的,此处只是给个例子,可参考例子,写自己的地址和经纬度。
<html lang="en"> <head> <meta charset="UTF-8"> <title>散点图</title> <!-- 先引入jquery,再引入echart --> <script src="../js/jquery-2.1.4.min.js"></script> <script src="../js/bootstrap.js"></script> <script src="../js/echart/echarts.min.js"></script> <script type="text/javascript"> $(function () { //通过ajax请求来获取后台数据 $.ajax({ type: ‘post‘, //bashPath是jsp里面,获取的项目路径 url: ‘<%=basePath%>loc‘, async: true, cache: false, dataType: ‘json‘, success: function (data) { //把数据转化一下 data=eval(data); //res是数据,要传到api里面的 var res = []; //官方案例中,每个点还有一个value值,这里不需要,所以要改造一下。这里参考案例生成的数据格式,自己重新封装了一下 for(var key in data) { console.log(key+""); res.push({ name: key+"", value: data[key].concat(1) //这里concat后面的值就是value,这里统一设置成1。 }); } //这里需要下载中国地图的json文件,因为要创建地图需要初始化地图,至于怎么初始化的,json里面的数据也看不懂。 $.get(‘../js/echart/china.json‘, function (chinaJson) { echarts.registerMap(‘china‘, chinaJson); //注册地图名 var chart = echarts.init(document.getElementById(‘main‘)); //这里是主体的初始化echart方法,与上面的简单demo类似。 chart.setOption({ backgroundColor: ‘#404a59‘, title: { text: ‘中通快递全国网点分布‘, subtext: ‘data from 中通快递‘, sublink: ‘http://www.zto.com/‘, x: ‘center‘, textStyle: { color: ‘#fff‘ } }, legend: { orient: ‘vertical‘, y: ‘bottom‘, x: ‘right‘, data: [‘服务网点‘], textStyle: { color: ‘#fff‘ } }, //地图坐标系必备的配置,具体的含义可以参考api,索性都是中文的,没有什么阅读障碍。 geo: { silent:false, map: ‘china‘, label: { emphasis: { show: false } }, itemStyle: { hoverAnimation:false, normal: { areaColor: ‘#323c48‘, borderColor: ‘#000‘ }, emphasis: { areaColor: ‘#2a333d‘, opacity:0 } } }, series: [ { name: ‘服务网点‘, type: ‘scatter‘, coordinateSystem: ‘geo‘, //参照系:之前设置的geo。 //这里是api数据接受的的地方 data:res, symbolSize: 3, //散点半径 label: { normal: { show: false }, emphasis: { show: false } }, hoverAnimation:false, silent:false, animation:false, z:3 } ] }); }); } }); }); </script> </head> <body> <!-- 长宽必须指定,否则可能无法显示图像 --> <div id="main" class="main" style="width: 1000px;height:800px;"> </div> </body> </html>
echart内部是高度封装的了,配置起来非常简单,地图这样看起来很复杂的东西配置也不是很困难。
遇到过一个小问题,就是底图和数据点都有鼠标hover效果,导致图上常常闪烁有时是地图的hover有时是点的hover,尤其是比较密集的地区。
后来通过opacity 属性为0,使hover不显示任何特效解决。(其实我配置了许多的内容,包括禁用鼠标事件/禁用动画/设置z值等,不知道具体是哪个生效了,但是问题确实解决了。)
本案例参考了官网中的散点图案例,但是去掉了许多内容,图没有美化过,只是作为一个demo案例而已。
附上官网例子,对比看看api接受的是什么格式的数据,我们就拼什么格式的数据。
var geoCoordMap = { "海门":[121.15,31.89], "鄂尔多斯":[109.781327,39.608266], "招远":[120.38,37.35], "舟山":[122.207216,29.985295], "齐齐哈尔":[123.97,47.33], "盐城":[120.13,33.38], "赤峰":[118.87,42.28], "青岛":[120.33,36.07], "乳山":[121.52,36.89], "金昌":[102.188043,38.520089], "泉州":[118.58,24.93], "莱西":[120.53,36.86], "日照":[119.46,35.42], "胶南":[119.97,35.88], "南通":[121.05,32.08], "拉萨":[91.11,29.97] }; //这里是生成series的数据,将经纬度和value值映射起来,我根据这个方法,最后自己写了一个方法,生成同样格式的数据,实现了对value的屏蔽。 var convertData = function (data) { var res = []; for (var i = 0; i < data.length; i++) { var geoCoord = geoCoordMap[data[i].name]; if (geoCoord) { res.push({ name: data[i].name, value: geoCoord.concat(data[i].value) }); } } return res; }; option = { backgroundColor: ‘#404a59‘, title: { text: ‘全国主要城市空气质量‘, subtext: ‘data from PM25.in‘, sublink: ‘http://www.pm25.in‘, x:‘center‘, textStyle: { color: ‘#fff‘ } }, tooltip: { trigger: ‘item‘, formatter: function (params) { return params.name + ‘ : ‘ + params.value[2]; } }, legend: { orient: ‘vertical‘, y: ‘bottom‘, x:‘right‘, data:[‘pm2.5‘], textStyle: { color: ‘#fff‘ } }, visualMap: { min: 0, max: 200, calculable: true, inRange: { color: [‘#50a3ba‘, ‘#eac736‘, ‘#d94e5d‘] }, textStyle: { color: ‘#fff‘ } }, geo: { map: ‘china‘, label: { emphasis: { show: false } }, itemStyle: { normal: { areaColor: ‘#323c48‘, borderColor: ‘#111‘ }, emphasis: { areaColor: ‘#2a333d‘ } } }, series: [ { name: ‘pm2.5‘, type: ‘scatter‘, coordinateSystem: ‘geo‘, data: convertData([ {name: "海门", value: 9}, {name: "鄂尔多斯", value: 12}, {name: "招远", value: 12}, {name: "舟山", value: 12}, {name: "齐齐哈尔", value: 14}, {name: "盐城", value: 15}, {name: "赤峰", value: 16}, {name: "青岛", value: 18}, {name: "乳山", value: 18}, {name: "金昌", value: 19}, {name: "泉州", value: 21}, {name: "莱西", value: 21}, {name: "日照", value: 21}, {name: "胶南", value: 22}, {name: "南通", value: 23}, {name: "拉萨", value: 24} ]), symbolSize: 12, label: { normal: { show: false }, emphasis: { show: false } }, itemStyle: { emphasis: { borderColor: ‘#fff‘, borderWidth: 1 } } } ] }
参考资料:
http://echarts.baidu.com/option.html#polar
http://echarts.baidu.com/api.html#echarts