网上动态的例子并不多,都是各种的复制copy,个人正好用到就做了一些简单并常见的(当然json数据的格式写法每一个并不一样,所以并不是唯一的表示方式)具体参考文档详见
主要使用MyEclipse(Maven)+HBuilder 写前后代码,基本的目录如下:
1.柱形图,饼图,雷达图以及折线图
数据库字段都是基础字段(方便起见都引用同一个sql)
<div id="echarts" style="width: 400px;height:400px;float:left;"></div>
<div id="echarts2" style="width: 400px;height:400px;float: left;"></div>
<div id="echarts3" style="width: 400px;height:400px;float: left;"></div>
<div id="echarts4" style="width: 400px;height:400px;float: left;"></div>
<script>
var myChart = echarts.init(document.getElementById('echarts'));
// 显示标题,图例和空的坐标轴
myChart.setOption({
title: {
text: '柱状图'
},
tooltip: {},
legend: {
data:['数量']
},
xAxis: {
data: []
},
yAxis: {},
series: [{
name: '数量',
type: 'bar',
data: []
}]
});
//饼状图
var myChart2 = echarts.init(document.getElementById('echarts2'));
//雷达图
var myChart3 = echarts.init(document.getElementById('echarts3'));
//折线图
var myChart4 = echarts.init(document.getElementById('echarts4'));
//path引用后端url
var path="http://127.0.0.1:8080/echarts/";
$.ajax({
type:'post',
url:path+'zhu',
dataType: 'json',
async:true,
xhrFields: {
withCredentials: true
},
crossDomain: true,
success:function(data){
// console.log(data)
var name=new Array();
var num=new Array();
for(var i=0;i<data.length;i++){
name.push(data[i].name);
num.push(data[i].number);
}
myChart.setOption({
xAxis: {
data: name
},
series: [{
// 根据名字对应到相应的系列
name: '测试',
data: num
}]
});
var pie=new Array();
for(var i=0;i<data.length;i++){
var obj=new Object();
obj.name=data[i].name;
obj.value=data[i].number;
pie.push(obj);
}
myChart2.setOption({
title:{
text:'饼图(南丁格尔)'
},
series : [
{
name: '饼图',
type: 'pie',
radius : '45%',
center: ['50%', '60%'],
label:{ //饼图图形上的文本标签
normal:{
show:true,
// position:'inner', //标签的位置
textStyle : {
fontWeight : 200 ,
fontSize : 12 //文字的字体大小
},
formatter:'{b}({d}%)'
}
},
roseType: 'angle',
data:pie
}
]
});
var tri=new Array();
var radar=new Array();
for(var i=0;i<data.length;i++){
var obj=new Object();
obj.text=data[i].name;
obj.max=120;
tri.push(obj);
}
myChart3.setOption({
title : {
text: '雷达图',
},
tooltip : {
trigger: 'axis'
},
legend: {
orient : 'vertical',
x : 'right',
y : 'bottom',
data:['测试(Test)']
},
/*toolbox: {
show : true,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
restore : {show: true},
saveAsImage : {show: true}
}
},*/
polar : [
{
indicator : tri
}
],
calculable : true,
series : [
{
name: 'Test',
type: 'radar',
label:{ //饼图图形上的文本标签
normal:{
show:true,
textStyle : {
fontWeight : 200 ,
fontSize : 12 //文字的字体大小
},
formatter:'{c}'
}
},
itemStyle: {
normal: {
areaStyle: {
type: 'default'
}
}
},
data : [
{
value :num,
name : '测试'
},
]
}
]
});
var line=new Array();
for(var i=0;i<data.length;i++){
}
myChart4.setOption({
title:{
text:'折线图'
},
tooltip : {
trigger: 'axis'
},
legend: {
data:['选项1']
},
/*toolbox: {
show : true,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
magicType : {show: true, type: ['line', 'bar', 'stack', 'tiled']},
restore : {show: true},
saveAsImage : {show: true}
}
},*/
calculable : true,
xAxis : [
{
type : 'category',
boundaryGap : false,
data : name
}
],
yAxis : [
{
type : 'value'
}
],
series :[
{
name:'选项1',
type:'line',
data:num
}
]
});
}
});
</script>
饼图,折线,雷达图具体效果如下:
2.旭日图(只做了3级)
旭日图(Sunburst)由多层的环形图组成,在数据结构上,内圈是外圈的父节点。因此,它既能像饼图一样表现局部和整体的占比,又能像矩形树图一样表现层级关系。(官方介绍)
ps:旭日图与其他基本图表的区别还是对json格式的要求,创建旭日图需要在 series 配置项中声明类型为 ‘sunburst’ 的系列,并且以树形结构声明其 data
标准的json:
[{
name: 'parent1',
value: 10, // 可以不写父元素的 value,则为子元素之和;
// 如果写了,并且大于子元素之和,可以用来表示还有其他子元素未显示
children: [{
value: 5,
name: 'child1',
children: [{
value: 2,
name: 'grandchild1',
itemStyle: {
// 每个数据可以有自己的样式,覆盖 series.itemStyle 和 level.itemStyle
},
label: {
// 标签样式,同上
}
}]
}, {
value: 3,
name: 'child2'
}],
itemStyle: {
// parent1 的图形样式,不会被后代继承
},
label: {
// parent1 的标签样式,不会被后代继承
}
}, {
name: 'parent2',
value: 4
}]
由于只设计了3级,所以当时直接一步步分级写了(多级需同时考虑数据库字段设计)
只贴主体代码:
@Service
public class showsunServiceImpl implements showsunService{
@Autowired
private firstMapper firstMapper;
@Autowired
private secMapper secMapper;
@Autowired
private lastMapper lastMapper;
@Override
public List<Map<String,Object>> showSunthings() {
//查询第一级的省信息
List<First> firstList=firstMapper.getFirsts();
List<Map<String,Object>> list=new ArrayList<>();
//遍历获取省的分信息id,name
for (int i = 0; i < firstList.size(); i++) {
Map<String,Object> map=new HashMap<String, Object>();
int fid=firstList.get(i).getId(); //fid用于查询二级信息
String fname=firstList.get(i).getFirstname();
//判断是否有2级信息chlidren子菜单
List<Second> list2=secMapper.getSecondsByFid(fid);
if (list2==null || list2.size()==0) {
//不存在2级
map.put("name",fname);
list.add(map);
}else{
List<Map<String,Object>> list_sec=new ArrayList<>();
for (int j = 0; j < list2.size(); j++) {
int sid=list2.get(j).getId(); //用于三级信息查询
String sname=list2.get(j).getSecname();
Map<String,Object> secmap=new HashMap<String, Object>();
//旭日多级菜单要求时需要的多次判断
List<Last> list3=lastMapper.getLastsBySid(sid);
if (list3==null||list3.size()==0) {
//不存在三级列表项
secmap.put("name",sname);
secmap.put("value",Math.floor(Math.random()*10));
list_sec.add(secmap); //只包含了二级的内容信息
}else {
List<Map<String,Object>> list_last=new ArrayList<>();
for (int k = 0; k < list3.size(); k++) {
String lastname=list3.get(k).getLastname();
Map<String,Object> lastmap=new HashMap<String, Object>();
lastmap.put("name", lastname);
lastmap.put("value", Math.floor(Math.random()*10));
list_last.add(lastmap);
}
// System.out.println(list_last);
secmap.put("name",sname);
// secmap.put("value",Math.floor(Math.random()*10));
secmap.put("children", list_last);
list_sec.add(secmap);
}
}
map.put("name",fname);
map.put("children", list_sec);
list.add(map);
}
}
return list;
}
}
js部分:
$.ajax({
type:'post',
url:path+'showsun',
dataType: 'json',
async:true,
xhrFields: {
withCredentials: true
},
crossDomain: true,
success:function(data){
console.log(data)
myChart5.setOption({
title:{
text:'旭日图'
},
series: {
type: 'sunburst',
data: data
}
});
}
});
当然,对于json格式的处理也可以在js中去体现,具体api参数:
3.定时2秒更新的折线图
主要代码:
<div id="echarts6" style="width: 500px;height:500px;float: left;"></div>
//实时更新图
var myChart6= echarts.init(document.getElementById('echarts6'));
$.ajax({
type:'post',
url:path+'showtime',
dataType: 'json',
async:true,
xhrFields: {
withCredentials: true
},
crossDomain: true,
success:function(data){
// console.log(data)
var ctime=new Array();
var ctime_date=new Array();
for(var i=0;i<data.length;i++){
var obj=new Object();
obj.name=data[i].times;
obj.value=data[i].number;
ctime_date.push(data[i].times);
ctime.push(obj);
}
myChart6.setOption({
title: {
text: '动态数据 + 时间坐标轴'
},
tooltip: {
trigger: 'axis',
formatter:'{b}:{c}',
axisPointer: {
animation: false
}
},
xAxis: {
type: 'category',
splitLine: {
show: false
},
data:ctime_date
},
yAxis: {
type: 'value',
boundaryGap: [0, '100%'],
splitLine: {
show: false
}
},
series: [{
name: '数据库数据',
type: 'line',
showSymbol: false,
hoverAnimation: false,
data: ctime
}]
});
//用于测试动态添加的实时数据
var k=1;
setInterval(function () {
var date = new Date();//获取当前时间
date.setDate(date.getDate()+k);
var updatetime = date.Format("yyyy-MM-dd");
ctime.shift();
ctime.push(Math.floor(Math.random()*50));
ctime_date.shift();
ctime_date.push(updatetime);
myChart6.setOption({
xAxis: {
data:ctime_date
},
series: [{
data: ctime
}]
});
k++;
}, 2000);
}
});
ps:由于数据库没有进行实时的保存数据,所以在测试方面“懒惰”性数组push了随机+1的时间跟数值。
ps:附上SessionFilter登录过滤(包含了ajax跨域的一些头文件)
public class SessionFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest request1, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException
{
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest request=(HttpServletRequest)request1;
res.setContentType("textml;charset=UTF-8");
res.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
res.setHeader("Access-Control-Max-Age", "0");
res.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("XDomainRequestAllowed","1");
request.getSession();
String[] notFilter = new String[] { "/zhu","/showsun","/showtime"};
String uri = request.getRequestURI();
boolean doFilter = true;
for (String s : notFilter) {
if (uri.indexOf(s) != -1) {
doFilter = false;
break;
}
}
boolean isAjaxRequest = isAjaxRequest(request);
if (doFilter) {
// Object obj1 = request.getSession().getAttribute("teacher");
// System.out.println(obj1);
if(obj1!=null){
response.setCharacterEncoding("UTF-8");
filterChain.doFilter(request, response);
// System.out.println("可进入。。。");
}else{
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
// System.out.println("不可进入。。。");
}
}else{
response.setCharacterEncoding("UTF-8");
filterChain.doFilter(request, response);
return;
}
}
public static boolean isAjaxRequest(HttpServletRequest request)
{
String header = request.getHeader("X-Requested-With");
if (header != null && "XMLHttpRequest".equals(header))
return true;
else
return false;
}
}
文件下载: