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
}
}
}
]
}
参考资料: