这几天接触的一个项目需要使用到百度的echart,所以简单查找并实验了几款比较简单且适用性较广的例子,做了几个简单的Demo,一来是对echart有所了解,二来也是记录一下,方便以后进一步的优化。

首先,是echart的js文件,一般情况下,这一个文件基本就可以了,但是由于本文还需要涉及到地图类型的处理,所以还需要一个地图包,,这个echart官网已经下架了,说是因为部分矢量数据不正确,建议用百度地图,但是在相关的实例中还是可以找到的,也挺好找的,就先拿这个练手,为了不暴露,代码中涉及到的url都用urlurlrul替代。

然后就是把相关的包导入项目,并且做引入

其实对于每一个实例而言,其过程都是类似的,先初始化相关参数,然后通过ajax动态加载需要更新的数据,

比如第一个柱图,首先初始化

 option = {title: {      //标题组件text: '消费金额统计图',x: 'center',y: 'top',textAlign: 'left'},tooltip: {    //提示框组件trigger: 'axis',showDelay: 5},legend: {     //图例组件left: 'left',data: ['消费金额(元)', '周环比(100%)']},grid: {       //直角坐标系内绘图网格x: 40,x2: 100,y2: 150,containLabel: true},toolbox: {     //工具栏feature: {magicType: {type: ['line', 'bar', 'tiled']},dataView: {readOnly: false},saveAsImage: {}}},xAxis: {       //直角坐标系 grid 中的 x 轴type: 'category',boundaryGap: true,axisLabel: {interval: 0,rotate: 40,},textStyle: '#333',name: "时间",axisTick: {show: false},data: []},yAxis: {       //直角坐标系 grid 中的 y 轴
//          min: 0,
//          max: 4000,
//          interval:500,name: "值",type: 'value'},series: [      //系列列表{name: '消费金额(元)',type: 'line',stack: '总量',itemStyle: {normal: {label: {show: true}}},data: [133, 21, 321, 2]},{name: '周环比(100%)',type: 'line',itemStyle: {normal: {label: {show: true}}},stack: '总量',data: [12, 32, 11, 45]}]};myChart.setOption(option);  

然后ajax动态加载数据:

function getChartData() {//获得图表的options对象var options = myChart.getOption();//通过Ajax获取数据$.ajax({type: "post",async: false, //同步执行url: "urlurlrul/getEchartData",data: {},dataType: "json", //返回数据形式为jsonsuccess: function (result) {if (result) {options.title[0].text=result.title;options.legend[0].data = result.legend;options.xAxis[0].data = result.category;for (var i = 0; i < result.series.length; i++) {options.series[i].name = result.series[i].name;options.series[i].type = result.series[i].type;options.series[i].data = result.series[i].data;}myChart.hideLoading();myChart.setOption(options);}},error: function (errorMsg) {alert("图表请求数据失败!");myChart.hideLoading();}});}

其实这部分最关键,也是整个项目最关键的部分,就是ajax动态加载之后的数据接收处理,由于都是自己的练手代码,所以我都在后台把数据处理好再发送。后端主要有三个主要的方法,EchartData(),Series(),和echartGetData()。EchartData()用于处理图表Option的主要参数,Series()处理series中data和其他相关参数,echartGetData()则是用于处理数据和传输数据的方法。

 @PostMapping(value = "/getEchartData",produces = "application/json;charset=utf-8")public EchartData echartGetData() {String title = "折线图和柱图";List<Object> seriesList = new ArrayList<>();//动态数据集List<String> legend = new ArrayList<>();//图例legend.add("销量");legend.add("售价");List<String> category = new ArrayList<>();//坐标轴category.add("一月份");category.add("二月份");category.add("三月份");category.add("四月份");List<Integer> xList = new ArrayList<>();xList.add(11);xList.add(24);xList.add(31);xList.add(14);seriesList.add(new Series("销量","line",xList));List<Integer> xList2 = new ArrayList<>();xList2.add(31);xList2.add(44);xList2.add(51);xList2.add(36);seriesList.add(new Series("售价","bar",xList2));EchartData echartData = new EchartData(title,category,legend,seriesList);return echartData;}public class EchartData {public String title;public List<String> category = new ArrayList<>();public List<String> legend = new ArrayList<>();public List<Object> series = new ArrayList<>();public EchartData(String title,List<String> categoryList,List<String> legendList,List<Object> seriesList) {// TODO Auto-generated constructor stubthis.title=title;this.legend = legendList;this.category = categoryList;this.series = seriesList;}}public class Series {public String name;public String type;public List<Integer> data;public Series(String name,String type,List<Integer> data) {// TODO Auto-generated constructor stubthis.name = name;this.type = type;this.data = data;}}

由于主要是为了看echart的动态加载过程,所以没有从数据库中直接取数,而是直接赋值进行操作的,如果是在实际项目中,用一个java bean,一个mabitis的mapper和一个service就可以直接获取到相关的数据集,再利用for循环进行循环导入就可以了。

echartGetData()传出的json数据为:

{"title": "折线图和柱图","category": ["一月份", "二月份", "三月份", "四月份"],"legend": ["销量", "售价"],"series": [{"name": "销量","type": "line","data": [11, 24, 31, 14]}, {"name": "售价","type": "bar","data": [31, 44, 51, 36]}]
}

实际加载数据后的echart图

由于折线图和柱图都比较简单,其data直接传一个数组就可以了,而在pie图以及一些其他复杂的一些echart图往往比较复杂,需要在数组中嵌套map,然后主要就是在哪里取数和处理,比如我这次pie图就是在后端直接处理好,然后传给前端一个封装好的Json,这样处理起来相对更加方便,话不多说,首先看pie图的前端处理

<script>var myChart = echarts.init(document.getElementById("pieChart"));option = {title: {text: '某站点用户访问来源',subtext: '纯属虚构',x: 'center'},tooltip: {trigger: 'item',formatter: "{a} <br/>{b} : {c} ({d}%)"},toolbox: {     //工具栏feature: {dataView: {readOnly: false},restore: {},saveAsImage: {}}},legend: {orient: 'vertical',left: 'left',data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']},series: [{name: '访问来源',type: 'pie',// radius: ['55%','70%'],radius: '55%',center: ['50%', '60%'],data: [{value: 335, name: '直接访问'},{value: 310, name: '邮件营销'},{value: 234, name: '联盟广告'},{value: 135, name: '视频广告'},{value: 1548, name: '搜索引擎'}]}]};myChart.setOption(option);myChart.hideLoading();getChartData();function getChartData() {var options = myChart.getOption();$.ajax({type: "post",sync: false,url: "urlurlrul/getPieChartData",data: {},dataType: "json",success: function (result) {options.title[0].text=result.title;options.legend[0].data = result.legend;options.series[0].name = result.series[0].name;options.series[0].data = result.series[0].data;myChart.hideLoading();myChart.setOption(options);}})}
</script>

可以看出我的data直接接收的就是可以直接使用的json,不需要再重新循环导入,当然如果在这里循环导入也是可以的,只是后端的处理方式不同而已。然后后端的处理是这样的

@PostMapping(value="/getPieChartData",produces="application/json;charset=utf-8")public EchartData getPieChartData() {String title = "Pie图和Doughnut图";List<String> category = new ArrayList<>();List<String> legend = new ArrayList<>();legend.add("Cola");legend.add("Wine");legend.add("Tea");legend.add("GreenTea");List<Object> dataList = new ArrayList<>();Map<String,Object> data0= new HashMap<>();data0.put("name","Cola");data0.put("value",32);dataList.add(JSONObject.fromObject(data0));data0.put("name","Wine");data0.put("value",23);dataList.add(JSONObject.fromObject(data0));data0.put("name","Tea");data0.put("value",12);dataList.add(JSONObject.fromObject(data0));data0.put("name","GreenTea");data0.put("value",35);dataList.add(JSONObject.fromObject(data0));List<Object> pieSeries = new ArrayList<>();pieSeries.add(new PieSeries("饮料分布",dataList));EchartData echartData = new EchartData(title,category,legend,pieSeries);return echartData;}public class PieSeries {public String name;
//  public Map<String,Integer> data;public List<Object> data;public PieSeries(String name,List<Object> obj) {// TODO Auto-generated constructor stubthis.name= name;this.data=obj;}}

getPieChartData传出的json文件为:

{"title": "Pie图和Doughnut图","legend": ["Cola", "Wine", "Tea", "GreenTea"],"series": [{"name": "饮料分布","data": [{"name": "Cola","value": 32}, {"name": "Wine","value": 23}, {"name": "Tea","value": 12}, {"name": "GreenTea","value": 35}]}]
}

加载之后的echart图表为:

这种后端处理后,直接向前端传处理好的json数据,实际用起来是非常方便的。另外对于饼图而言,其数据结构与Douhnut图和南丁格尔玫瑰图其实格式都是非常类似的,基本上一种就可以覆盖好几种的写法。其实这里最主要的麻烦是数据的格式问题,后端怎么传以及前端怎么处理,如果没有很好的需求文档,配合起来是非常痛苦的,所以最好的办法就是自己都会,自己都干了就行了(~.~)
有了这么一个练习基础,可以进行一个比较复杂的练习,其实也不复杂,只是看起来内容更加丰富而已。就是下面这个图

这是echart社区的一个例子,把它应用在项目中试试。这个图有两个比较重要的点,其一就是map图的处理,这种格式一般都会在输入端有所限制,只允许导入省份之类的信息,而且由于矢量信息存在问题,目前已经不支持省级以下比如市级甚至更低的缩放。其二就是这个例子给了我们一个非常好的思路,就是他将两种数据展示图用于展示同一组数据,这个功能的实现关键就在于echart 每个功能块强大的功能,如果仔细观察,我们发现上面无论是Legend,series等功能块其实都是数组形式的,而我们对于series这部分就可以定义不同的数据展现形式,比如bar、pie之类的,剩余的就是一些美化工作了。

当然,如果对于map这个图进一步进行仔细研究就会发现,还有很多需要进行进一步优化的,比如颜色范围的调节如何与实际的输入契合,避免局部大数导致整体没有区分。然后还有就是数据的排序,我们可以看出右边本意是为了进行排序,将前十列出来,但是这个一般是在后端数据有意义的情况下才会进行的,所以后续的工作还有很多。

首先,先看一下其js代码

<!DICTYPE html>
<html lang="en">
<head><meta charset="utf-8"/><title>ECharts图</title><script src="js/echarts.min.js" type="text/javascript"></script><script src="js/china.js" type="text/javascript"></script><!--    <script src="http://echarts.baidu.com/build/dist/echarts.js">--><script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
</head>
<body><div id="MapChart" style="height: 800px;width:1000px;border: 6px solid #ccc9cb; padding: 100px;"></div><script>var myChart = echarts.init(document.getElementById('MapChart'));var data = [{name: '江苏省',value: 5.3},{name: '北京市',value: 3.8},{name: '上海',value: 4.6},{name: '重庆',value: 3.6},{name: '河北',value: 3.4},{name: '河南',value: 3.2},{name: '云南',value: 1.6},{name: '辽宁',value: 4.3},{name: '黑龙江',value: 4.1},{name: '湖南',value: 2.4},{name: '安徽',value: 3.3},{name: '山东',value: 3.0},{name: '新疆',value: 1},{name: '江苏',value: 3.9},{name: '浙江',value: 3.5},{name: '江西',value: 2.0},{name: '湖北',value: 2.1},{name: '广西',value: 3.0},{name: '甘肃',value: 1.2},{name: '山西',value: 3.2},{name: '内蒙古',value: 3.5},{name: '陕西',value: 2.5},{name: '吉林',value: 4.5},{name: '福建',value: 2.8},{name: '贵州',value: 1.8},{name: '广东',value: 3.7},{name: '青海',value: 0.6},{name: '西藏',value: 0.4},{name: '四川',value: 3.3},{name: '宁夏',value: 0.8},{name: '海南',value: 1.9},{name: '台湾',value: 0.1},{name: '香港',value: 0.1},{name: '澳门',value: 0.1}];var yData = [];var barData = [];for (var i = 0; i < 5; i++) {barData.push(data[i]);yData.push(i + data[i].name);}var option = {title: [{show: true,text: '排名情况',textStyle: {color: '#2D3E53',fontSize: 18},right: 180,top: 100}],tooltip: {show: true,formatter: function(params) {return params.name + ':' + params.data['value'] + '%'},},visualMap: {type: 'continuous',orient: 'horizontal',itemWidth: 10,itemHeight: 80,text: ['高', '低'],showLabel: true,seriesIndex: [0],min: 0,max: 2,inRange: {color: ['#6FCF6A', '#FFFD64', '#FF5000']},textStyle: {color: '#7B93A7'},bottom: 30,left: 'left',},grid: {right: 10,top: 135,bottom: 100,width: '20%'},xAxis: {show: false},yAxis: {type: 'category',inverse: true,nameGap: 16,axisLine: {show: false,lineStyle: {color: '#ddd'}},axisTick: {show: false,lineStyle: {color: '#ddd'}},axisLabel: {interval: 0,margin: 85,textStyle: {color: '#455A74',align: 'left',fontSize: 14},rich: {a: {color: '#fff',backgroundColor: '#FAAA39',width: 20,height: 20,align: 'center',borderRadius: 2},b: {color: '#fff',backgroundColor: '#4197FD',width: 20,height: 20,align: 'center',borderRadius: 2}},formatter: function(params) {if (parseInt(params.slice(0, 1)) < 3) {return ['{a|' + (parseInt(params.slice(0, 1)) + 1) + '}' + '  ' + params.slice(1)].join('\n')} else {return ['{b|' + (parseInt(params.slice(0, 1)) + 1) + '}' + '  ' + params.slice(1)].join('\n')}}},data: yData},geo: {// roam: true,map: 'china',left: 'left',right: '300',// layoutSize: '80%',label: {emphasis: {show: false}},itemStyle: {emphasis: {areaColor: '#fff464'}}},series: [{name: 'mapSer',type: 'map',roam: false,geoIndex: 0,label: {show: false,},data: data}, {name: 'barSer',type: 'bar',roam: false,visualMap: false,zlevel: 2,barMaxWidth: 8,barGap: 0,itemStyle: {normal: {color: function(params) {// build a color map as your need.var colorList = [{colorStops: [{offset: 0,color: '#FFD119' // 0% 处的颜色}, {offset: 1,color: '#FFAC4C' // 100% 处的颜色}]},{colorStops: [{offset: 0,color: '#00C0FA' // 0% 处的颜色}, {offset: 1,color: '#2F95FA' // 100% 处的颜色}]}];if (params.dataIndex < 3) {return colorList[0]} else {return colorList[1]}},barBorderRadius: 15}},data: barData}]};myChart.setOption(option)myChart.hideLoading();getChartData();function getChartData(){var options = myChart.getOption();$.ajax({type: "post",async: false, //同步执行url: "urlurlrul/getMapChartData",data: {},dataType: "json", //返回数据形式为jsonsuccess: function (result) {if (result) {options.series[0].data = result.series;var tempData = result.series;var yData = [];var barData = [];for (var i = 0; i < result.series.length; i++) {barData.push(result.series[i]);yData.push(i + result.series[i].name);}options.yAxis[0].data=yData;options.series[1].data = barData;myChart.hideLoading();myChart.setOption(options);}},error: function (errorMsg) {alert("图表请求数据失败!");myChart.hideLoading();}});}</script><script type="text/javascript"></script>
</body>
</html>

其实这两部分的数据来源都是相同的,所以可以使用同一个数据元,然后进行进一步的处理就可以了。

后端的controller 为:

@PostMapping(value="/getMapChartData",produces="application/json;charset=utf-8")public EchartData getMapChartData() {String title ="MapChartData";List<String> category = new ArrayList<>();List<String> Legend = new ArrayList<>();List<Object> mapDataList = new ArrayList();Map<String,Object> map = new HashMap<>();map.put("name", "山西");map.put("value", 1.3);mapDataList.add(JSONObject.fromObject(map));map.put("name","北京");map.put("value",7.8);mapDataList.add(JSONObject.fromObject(map));map.put("name","浙江");map.put("value",3.2);mapDataList.add(JSONObject.fromObject(map));map.put("name","上海");map.put("value",6.3);mapDataList.add(JSONObject.fromObject(map));map.put("name","西藏");map.put("value",0.6);      mapDataList.add(JSONObject.fromObject(map));map.put("name","天津");map.put("value",0.1);mapDataList.add(JSONObject.fromObject(map));        EchartData echartData = new EchartData(title,category,Legend,mapDataList);return echartData;}

这个处理是非常简单的,当然也很粗糙,需要进一步的优化,我们先看一下传出的json:

{"title": "MapChartData","series": [{"name": "山西","value": 1.3}, {"name": "北京","value": 7.8}, {"name": "浙江","value": 3.2}, {"name": "上海","value": 6.3}, {"name": "西藏","value": 0.6}, {"name": "天津","value": 0.1}]
}

其最终显示效果:

基本功能算是实现了,后续的工作就是在实际的项目中实际的优化了。

这三个图例加上最后的整理总结,大概花了一天的时间,其实最主要的问题还是数据格式的问题,但是多看一些例子之后,自己也慢慢学会了到底该如何处理类似的数据。除了对echart图有了一丝的了解,也对前后端的交互有了更深层次的理解,同时,我觉得自己收获最大的应该是似乎在与echart的开发者对话,理解了某些巧妙的设计,的确佩服,自己不是做前端的,写js对于我来说算是一个挑战,虽然简单的可以读懂,写起来还是没那么容易。如果有想进一步交流的,欢迎评论(~.~)

百度echart柱图、折线图、饼图、Map类型等类似视图的动态加载数据相关推荐

  1. ECharts动态加载数据绘制折线图

    Echarts动态加载数据绘制折线图 ECharts 引入ECharts 步骤 连接数据接口,动态加载图表 动态加载数据,整体代码 折线图绘制 总结 绘制多个图表的方法 ECharts 纯Javasc ...

  2. echarts动态加载数据生成饼状图

    本文简单介绍使用ajax从JSON文件加载数据,动态生产并状态,第一次写,供大家参考.欢迎大家提出优化意见和建议. 一下是前端的代码: <!DOCTYPE html> <html l ...

  3. 饼图、柱形图、堆积柱、折线图、散点图,到底应该怎么选?

    "随着数字经济的发展,各行业的数据都出现了爆炸式的增长,如何快速从海量数据中提取出有效信息,最大化地挖掘数据价值,是所有转型的企业都在面临的问题." 想要快速直观地以易于理解.内容 ...

  4. 柱状折线图2-双柱状重合堆积折线-重写图例点击事件

    本例子: 使用了formatter方法重写了提示层的展示数据 使用了双x轴实现重合 使用了stack实现堆积 使用了legendselectchanged和dispatchAction重写了图例点击事 ...

  5. echart自定义动画_ECharts使用—折线图动态加载

    最近需求中用到折线图,单线条,多线交错,之前是散点图,用的是另一个 amcharts.js,这个文档也能找的到,回归早本次重点:ECharts 一.首先引入echarts.common.min.js文 ...

  6. Echarts使用及动态加载图表数据 折线图X轴数据动态加载

    Echarts简介 echarts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,来自百度...我想应该够简洁了 使用Echarts 目前,就官网的文 ...

  7. 【Excel】绘图案例_常见复合图:簇状图+堆积图+折线图

    [Excel]绘图案例_常见复合图:簇状图+堆积图+折线图 前言 最近有朋友让我帮忙用excel画图,老实说我很讨厌用excel画图,点来点去,复杂一些还不能复用,非常繁琐.当然,入门也很简单.需求时 ...

  8. Echarts动态加载多条折线图

    背景:动态加载多条折线图,折线图条数不确定 页面效果: 页面代码 //气象数据function serchQx(beginTime, endTime, str, parameter) {$(" ...

  9. flutter 轮播图动态加载网络图片

    Swiper,网上很多列子只是加载固定的几张图,并且页面只有一个轮播图,在实际应用中,可能会遇到类似ins这种,加载列表,并且都是多图模式的情况. 需要添加依赖包flukit: ^1.0.0引用 im ...

最新文章

  1. nginx报http400错误解决方法
  2. php使用redis内存不足,PHP开发:Redis 内存满了怎么办?
  3. 第三节 计算机体系结构,计算机系统结构 第三节 输入输出系统.pdf
  4. 指定的服务已经标记为删除_你的电话号码被标记过吗?你知道这件事情还能赚钱吗?...
  5. emc存储java打开后报错_连接EMC存储系统 - osc_mk8rqvg4的个人空间 - OSCHINA - 中文开源技术交流社区...
  6. Cocos2d-3.x目录介绍分析
  7. 微信小程序中form 表单提交和取值实例详解
  8. 永恒之蓝漏洞原理 445_不死的EternalBlue(永恒之蓝)
  9. Javascript 判断 object 的特定类
  10. jdbcUrl is required with driverClassName错误解决
  11. 通信基础 8 —— MIMO / 3GPP / UMI
  12. 好用又好玩的PC端特效
  13. linux透明桥,linux透明防墙(网桥模式).doc
  14. Scapy:send函数剖析(参数、返回值、应用)
  15. wps linux版公式编辑器,linux下的公式编辑器
  16. 如何验证JDK已安装好,环境变量已配置成功
  17. 关于linux的读写锁
  18. java中GRID_size的作用_Grid布局简介
  19. springboot实现网上宠物医院管理系统毕业设计
  20. OpenStack“女王”驾到,开源云中文社区粉丝炸锅了!

热门文章

  1. 单内存16g和双8g差别大吗_电脑内存条单16G和双8G哪个好,单条是不是稳定
  2. centos7.0查看IP,Linux基本命令
  3. 切换Outlook左边栏英文显示至中文
  4. mysql存入订单号不重复_MSSQL高并发下生成连续不重复的订单号
  5. Java项目Json字符串转对象,去斜杠
  6. Linux——进程间通信的常见方法(管道、信号、共享映射区、本地套接字)、管道的了解与简单用法
  7. GET和POST协议详解
  8. 敲出简易代码的秘密 — 开发人员如何产生10倍的价值
  9. 【python安装xlrd模块】
  10. web前端开发学习网站大全