步骤1:
(1)在java后台,使用MSQL分组函数,列出所有线在对应的点的值,
(2)组成的Map如图所示:
注意:
key为0的value表示X轴需要的数据;key为其他的值表示图表线条的名字,value为x轴的点对应的y轴的值,y轴的值和x轴是一一对应的,即使没有值,也要放入0
为了方便测试,这里在Aciton中放入测试数据,如:
public String searchChartData() {
Map<String, List<String>> valueMap = new HashMap<>();
List<String> list1 = new ArrayList<>();
valueMap.put("0", list1);
list1.add("2016年7月");
list1.add("2016年12月");
list1.add("2017年1月");
list1 = new ArrayList<>();
valueMap.put("A线条", list1);
list1.add("2016年7月:11");
list1.add("2016年12月:22");
list1.add("2017年1月:33");
list1 = new ArrayList<>();
valueMap.put("B线条", list1);
list1.add("2016年7月:66");
list1.add("2016年12月:0");
list1.add("2017年1月:77");
parseValueMapToImageData(valueMap,xDataStr,chartDataStr);
valueMap = new HashMap<>();
list1 = new ArrayList<>();
valueMap.put("0", list1);
list1.add("aaa");
list1.add("bbb");
list1.add("ccc");
list1 = new ArrayList<>();
valueMap.put("C线条", list1);
list1.add("aaa:1");
list1.add("bbb:0");
list1.add("ccc:3");
list1 = new ArrayList<>();
valueMap.put("D线条", list1);
list1.add("aaa:5");
list1.add("bbb:6");
list1.add("ccc:7");
parseValueMapToImageData(valueMap,xDataStr2,chartDataStr2);
return SUCCESS;
}
因为前台需要有两个线,所以这里放入了两个图表需要的数据,后台debugg的数值如下图:
SERVICE:
//根据SQL组装的map解析为echarts想要的数据
public void parseValueMapToImageData(Map<String, List<String>> valueMap,List<String> xDataStr,List<String> chartDataStr) {
if(valueMap.size()>0) {
//图表数据
for (String key : valueMap.keySet()) {
Map<String, String> map = new LinkedHashMap<String, String>();
List<String> valueList = valueMap.get(key);
if(key.equals("0")){
xDataStr.addAll(valueList);
// xDataStr = valueList;
continue;
}
String valueStr = "";
map.put("name", key);
int i = 0;
for (String value : valueList) {
String[] splitValue = value.split(":");
map.put(splitValue[0], splitValue[1]);
}
for (String keys : xDataStr) {
if(valueStr.length()>0){
valueStr+=";";
}
if(map.get(keys)==null) {
valueStr+="0";
}else {
valueStr+=map.get(keys);
}
}
chartDataStr.add(key+":"+valueStr);
}
}
}
前台使用easyui的layout布局:
jsp:
<script type="text/javascript" src="echarts.js>"></script>
<body>
<s:hidden name="chartDataStr" id="chartDataStr" cssClass="container chartDataStr"/>
<s:hidden name="xDataStr" id = "xDataStr" cssClass="container xDataStr"/>
<s:hidden name="chartDataStr2" id="chartDataStr2" cssClass="container2 chartDataStr"/>
<s:hidden name="xDataStr2" id = "xDataStr2" cssClass="container2 xDataStr"/>
<div class="easyui-layout" data-options="fit: true" id="topLayout">
<div data-options="region: 'center', border: true,fit: false,title: '',iconCls:''">
<div id="container" style="min-width:0px;height: 0px" class="containerDiv"></div>
</div>
<div data-options="region: 'south', border: true,split: true" >
<div id="container2" style="min-width:0px;height: 0px" class="containerDiv"></div>
</div>
</body>
JS:
var yearCount = undefined;
var fontSize = 15;
var nameData = [];
var valueData = [];
var rotateNumber = 0;
var maxLength = 5;//每项显示文字个数
$(function(){
initContainerHeightFun();
var $containers = $('.containerDiv');
//创建2个图表
$containers.each(function(){
$container = $(this);
var id = $container.attr("id");
$xDataStr = $('.xDataStr.'+id);
$chartDataStr = $('.chartDataStr.'+id);
initEcharsFun($container,$xDataStr,$chartDataStr);
});
});
//设置2个图表分别和对应的layout的高度一致(如果不动态设置,那么就要在jsp页面写好,否则会报错)
function initContainerHeightFun(){
var northHeight = getPanelHeight('#topLayout',"north");
$('#container2').css('min-width',northHeight);
$('#container2').css('height',northHeight);
var centerHeight = getPanelHeight('#topLayout',"center");
$('#container').css('min-width',centerHeight);
$('#container').css('height',centerHeight);
}
//获取layout指定面板的高度
function getPanelHeight(layoutId,p){
var layout = $(layoutId);
var panel = layout.layout('panel',p);
var height = panel.panel('panel').outerHeight();
return height;
}
//图表echarts初始化
function initEcharsFun($container,$xDataStr,$chartDataStr){
var myWidth = $container.css('width').slice(0,-2);
var height_frm = $(document.body).height();
chartDataStr = $chartDataStr.val();
//因为从后台传过来的是数组,这里把数组的中括号去除掉
xDataStr = $xDataStr.val();
xDataStr = xDataStr.replace("[","");
xDataStr = xDataStr.replace("]","");
xDataStr = xDataStr.replace(/ /g,"");
categories = xDataStr.split(",");//获取x轴数据
if(categories.length>20){
fontSize = 10;
}else if(categories.length>15){
fontSize = 12;
}
yearCount = [];//y轴数据
if(categories.length>20){
fontSize = 10;
}else if(categories.length>15){
fontSize = 12;
}
for(var i= 0;i< categories.length;i++){
if(categories[i]){
yearCount.push(categories[i]);
if(categories[i].length>5){
}else if(categories[i].length>10){
}
}else{
yearCount.push(0);
}
}
$container[0].style.width = myWidth-50;
$container[0].style.height = height_frm-50;
var myChart = echarts.init($container[0]);
var posList = [
'left', 'right', 'top', 'bottom',
'inside',
'insideTop', 'insideLeft', 'insideRight', 'insideBottom',
'insideTopLeft', 'insideTopRight', 'insideBottomLeft', 'insideBottomRight'
];
myChart.configParameters = {
rotate: {
min: -90,
max: 90
},
align: {
options: {
left: 'left',
center: 'center',
right: 'right'
}
},
verticalAlign: {
options: {
top: 'top',
middle: 'middle',
bottom: 'bottom'
}
},
position: {
options: echarts.util.reduce(posList, function (map, pos) {
map[pos] = pos;
return map;
}, {})
},
distance: {
min: 0,
max: 100
}
};
myChart.config = {
rotate:35,
align: 'left',
position: 'top',
distance: 10,
verticalAlign:'bottom',
onChange: function () {
labelOption = {
normal: {
rotate: myChart.config.rotate,
align: myChart.config.align,
verticalAlign: myChart.config.verticalAlign,
position: myChart.config.position,
distance: myChart.config.distance
}
};
myChart.setOption({
series: [{
label: labelOption
}, {
label: labelOption
}, {
label: labelOption
}, {
label: labelOption
}]
});
}
};
labelOption = {
normal: {
//show: true,
position: myChart.config.position,
distance: myChart.config.distance,
align: myChart.config.align,
verticalAlign: myChart.config.verticalAlign,
rotate: myChart.config.rotate,
formatter: '{c}',
fontSize: fontSize,
rich: {
name: {
textBorderColor: '#fff'
}
}
}
};
valueData = getSeriesData(chartDataStr,categories);
var option = {
color: ['#ff7f50','#87cefa','#da70d6','#32cd32','#6495ed',
'#ff69b4','#ba55d3','#cd5c5c','#ffa500','#40e0d0',
'#1e90ff','#ff6347','#7b68ee','#00fa9a','#ffd700',
'#6699FF','#ff6666','#3cb371','#b8860b','#30e0e0'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: nameData
},
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
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',
axisTick: {show: false},
data: yearCount,
axisLabel:{
interval:0,
rotate:rotateNumber,
formatter:function(value,index)
{
var ret = "";//拼接加\n返回的类目项
var valLength = value.length;//X轴类目项的文字个数
var rowN = Math.ceil(valLength / maxLength); //类目项需要换行的行数
if (rowN > 1)//如果类目项的文字大于3,
{
for (var i = 0; i < rowN; i++) {
var temp = "";//每次截取的字符串
var start = i * maxLength;//开始截取的位置
var end = start + maxLength;//结束截取的位置
//这里也可以加一个是否是最后一行的判断,但是不加也没有影响,那就不加吧
temp = value.substring(start, end) + "\n";
ret += temp; //凭借最终的字符串
}
return ret;
}else{
return value;
}
}
}
}
],
yAxis: [
{
type: 'value',
scale: true
}
],
series: valueData
};
myChart.setOption(option);
// 图形报表
}
//数据解析
function getSeriesData(param,param1){
var cType = "bar";//饼图
cType = "line"//这里默认为线图
var returnData = [];
actionData = param.replace("[","").replace("]","").replace(" ","");
if(actionData != null && actionData != ""){
var data = actionData.split(",");
for (var i = 0; i < data.length; i++) {
var obj = {};
var objct = data[i].split(":");
obj.name = objct[0];
nameData.push(objct[0]);
obj.type = cType;
obj.barGap = 0;
obj.label = labelOption;
var values = objct[1].split(";");
obj.data = values;
returnData.push(obj);
}
}
return returnData;
}
2个图表显示效果图: