在 Echarts + layer 图表放大实现方案一文中,简述了图表放大实现的思路。今天贴上方案三的相关代码。
文件结构如下图:
echarts.html代码:
demo
条形图
仪表盘
柱状图
放大弹窗expandChart.html 代码:
这里没有引入任何js文件,全部在父页面js中完成。
下面依次开始js的代码:
common.js:
定义了:路径、ajax请求数据、图表提示tootip等公共方法,
actionFun 用来做方法映射。
//取请求路径
var basePath = window.document.location.pathname.substring(0, window.document.location.pathname.substr(1).indexOf('/') + 1);
//提示内容
function tooltipFormatter(params){
var tips = "";
if (Array.isArray(params)){
tips = params[0].axisValue + "
";
for (var i = 0; i < params.length; i++) {
//格式:(名称):(值)(单位)
tips = tips + params[i].seriesName + ":" + params[i].value;
if (params[i].seriesName.indexOf("收入")>=0){
tips = tips +" (元)";
}else if(params[i].seriesName.indexOf("利润")>=0){
tips = tips +" (元)";
}else if (params[i].seriesName.indexOf("支出")>=0){
tips = tips +" (元)";
}
if(i != params.length-1){
tips = tips + "
";
}
}
}
return tips;
}
/*@定义方法映射@ 重要 */
var actionFun = {};
/**
* 封装AJAX 异步方法
* @param url
* @param type
* @param sucFun success映射方法名称
* @param comFun complete映射方法名称
*/
function baseAjax(url, type, comFun, sucFun){
var resData = {};
$.ajax({
url: url,
type: type,
dataType: "json",
success: function (data, textStatus, xhr) {
if(xhr.status == 200 && data != null && data != undefined){
resData = data;
}
if(sucFun !='' && sucFun != null && sucFun != undefined){
actionFun[sucFun](resData);
}
},
complete:function(){
actionFun[comFun](resData);
}
});
}
generalAttr.js定义图表公共属性,特殊图表单独处理:
这里有两个很重要的对象:
chartOption——图表放大专用 option对象,请在echarts初始化js方法最后追加属性、建立映射关系,最后在generalExpand.js 中 attrAssign() 方法调用。
chartObj ——数组,图表resize()专用 echarts对象,请在echarts初始化js方法最后追加echarts对象元素,最后在generalExpand.js 中 window.onresize() 方法调用。
/**
* echart 通用属性定义
* 若需要修改属性值,请在js方法中,option之前,对相应属性重新赋值
*
* 注意js引入顺序:
* 1、generalAttr.js
* 2、个人js文件
* 3、generalExpand.js
*/
var gridtop=40;
var gridright="3%";
var gridleft="3%";
var gridbottom="3%";
var legendtop="0%";
var legendwidth="100%";
var legenditemWidth=10;
var legenditemHeight=10;
var legenditemGap=4;
//全局title样式:
var globalTitleTextStyle = {
color: '#FFFFFF',
fontSize: 12
};
//全局文本样式:颜色白色
var globalTextStyle = {
color: '#FFFFFF',
fontSize: 11
};
//全局坐标标注文字样式:颜色白色
var globalAxisLabelTextStyle = {
color: '#FFFFFF',
fontSize: 10
}
//全局分割线的类型和颜色:实线,灰白
var globalSplitLineStyle = {
show: true,
lineStyle: {
type: 'dotted',
color: '#234A85'
}
};
//全局坐标线样式:颜色蓝色
var globalAxisLine = {
lineStyle: {
color: '#0000FF',//边线的颜色
width: 1
}
};
var globalBarWidth ="60%";
var globalBarWidth4 ="17%";//有4个柱子的bar的宽度
var globalbarBorderRadius =3;
//全局提示框样式
var globalToolTipTextStyle={
color: '#FFFFFF',
fontSize: 10
}
//定义图表大小,
// 若要改变,js方法中,重新赋值即可
var grid ={
left: gridleft,
right: gridright,
top: gridtop,
bottom: gridbottom,
containLabel: true //包含坐标轴文字在内的边距,不建议去掉
};
//定义图例
// 若要改变,js方法中,重新赋值即可
var legend = {
data: [], //请在js方法中提前赋值
textStyle: globalTextStyle,
icon:'roundRect',
top: legendtop,
width: legendwidth,
itemWidth: legenditemWidth,
itemHeight: legenditemHeight,
itemGap: legenditemGap
};
//定义X轴
// 若要改变,js方法中,重新赋值即可
var xAxis = {
type: 'category', //请重新赋值
data: [], //请重新赋值
name: '', //单位 请重新赋值(亿元)
nameGap: 8, //坐标轴名称与轴线之间的距离。
nameTextStyle: globalTextStyle,
axisLabel: globalAxisLabelTextStyle,
axisLine: globalAxisLine,
splitLine: globalSplitLineStyle
};
//定义y轴
// 若要改变,js方法中,重新赋值即可
var yAxis = {
align: 'left',
type: 'value', //类型 请重新赋值
name: '', //单位 请重新赋值 (亿元)
nameGap: 10, //坐标轴名称与轴线之间的距离。
nameLocation:'end',
minInterval: 1, //保证坐标轴分割刻度显示成整数
splitNumber:4,
nameTextStyle: globalTextStyle,
splitLine: globalSplitLineStyle,
axisLine: globalAxisLine,
axisLabel: globalAxisLabelTextStyle
};
//图表放大专用 option对象,请在echarts初始化js方法最后重新赋值
//最后在generalExpand.js 中 attrAssign() 方法调用
var chartOption = {};
//图表resize()专用 echarts对象,请在echarts初始化js方法最后重新赋值
//最后在generalExpand.js 中 window.onresize() 方法调用
var chartObj = new Array();
/**
* 传入一个 对象,返回新对象,用于一个页面有多个相同对象引用
* 一个页面有多个坐标轴时,可以使用 :如股票市场-stock_multiple.js
* @param obj 具有多个属性的对象
* @return 具有相同属性的,新的,对象
*/
function getSameAttrObj(obj){
var newObj = {};
for (var i in obj) {
newObj[i] = obj[i];
}
return newObj;
}
Instance.js:调用公共方法获取数据、处理数据、初始化图表方法;图表对象引用尽量引用公共属性;给公共对象(chartObj、chartOption)追加数据。
$(function(){
getData();
$(".scale").click(function(){
attrAssign(this);
})
})
/******条形图--开始**********************************/
/**
* 数据处理 【ajax 成功调用方法】
* @param res ajax 返回的数据
* {"incList":[],"proList":[],"payList":[]}
*/
var dataSucFun = function(res){
var monthList = [];
var incList = [];
var proList = [];
var payList = [];
if(res.monthList != undefined){
for (var i = 0; i < res.monthList.length; i++) {
monthList.push(res.monthList[i]);
}
}
if(res.incList != undefined){
for (var i = 0; i < res.incList.length; i++) {
incList.push(parseFloat(res.incList[i]).toFixed(2));
}
}
if(res.proList != undefined){
for (var i = 0; i < res.proList.length; i++) {
proList.push(parseFloat(res.proList[i]).toFixed(2));
}
}
if(res.payList != undefined){
for (var i = 0; i < res.payList.length; i++) {
payList.push(parseFloat(res.payList[i]).toFixed(2));
}
}
initLineChart(monthList, incList, proList, payList); //条形图
initBarChart(monthList, incList, proList); //柱状图
var resData = {"ajy":150,"bjy":160,"cjy":180}; //仪表盘
initDashboardChart(resData);
}
/*调用ajax 获取数据*/
function getData(){
actionFun.dataSucFun = dataSucFun; //success 方法 映射名称
var url = basePath+"/getData/line";
var type = 'get';
var comFun = "dataSucFun";
baseAjax(url, type, comFun);
}
/**
*条形图
*/
var lineChart={};
var lineOption={};
function initLineChart(monthList, incList, proList, payList){
lineChart = echarts.init(document.getElementById("Chart1"));
var invGrid = getSameAttrObj(grid);
invGrid.right = 50;
//定义图例
var invLegend = getSameAttrObj(legend);
invLegend.data = ['利润', '支出', '收入'];
invLegend.top = 10;
//定义X 轴
var invXAxis = getSameAttrObj(xAxis);
invXAxis.type = 'value';
invXAxis.name = '(元)';
//定义Y轴
var invYAxis = getSameAttrObj(yAxis);
invYAxis.type = 'category';
invYAxis.data = monthList;
lineOption = {
tooltip: {
trigger: 'axis',
confine:true,
formatter: tooltipFormatter
},
legend : invLegend,
grid : invGrid,
xAxis : [invXAxis],
yAxis : [invYAxis],
series : [
{
name:'利润',
type:'bar',
itemStyle: {
color: '#FFFF00',
fontSize:globalTextStyle.fontSize,
barBorderRadius: globalbarBorderRadius
},
data: proList //[200, 170, 240, 244, 200, 220, 210, 680, 990, 1200, 200, 120]
},
{
name:'收入',
type:'bar',
stack: '总量',
itemStyle: {
color: '#02B5F0',
fontSize:globalTextStyle.fontSize,
barBorderRadius: globalbarBorderRadius
},
data:incList //[320, 302, 341, 374, 390, 450, 420, 170, 240, 244, 200, 220]
},
{
name:'支出',
type:'bar',
itemStyle: {
color: 'white',
fontSize:globalTextStyle.fontSize,
barBorderRadius: globalbarBorderRadius
},
stack: '总量',
data: payList //[-120, -132, -101, -134, -190, -230, -210]
}
]
};
lineChart.setOption(lineOption, true);
chartOption.Chart1 = lineOption;
chartObj.push(lineChart);
}
/******条形图--结束**********************************/
/******仪表盘--开始**********************************/
var DashboardChart={};
var DashboardOption={};
function initDashboardChart(data){
DashboardChart = echarts.init(document.getElementById("Chart2"));
var maxValue = Math.max(data.ajy, data.bjy, data.cjy);
maxValue = Math.ceil(maxValue/10)*10 ; //仪表盘最大值
var name1 = "A交易额" ;
var center1 = ['17%', '55%'];
var value1 = parseFloat(data.ajy).toFixed(2);
var name2 = "B交易额" ;
var center2 = ['50%', '55%'];
var value2 = parseFloat(data.bjy).toFixed(2);
var name3 = "C交易额" ;
var center3 = ['83%', '55%'];
var value3 = parseFloat(data.cjy).toFixed(2);
var dashTooltip = {
confine:true,
formatter: "{b} : {c}(元)"
};
var serTitle = {color:'white', fontSize:'12px', offsetCenter:[0,'83%']};
var serDetail = {
formatter:function(params){
return parseFloat(params).toFixed(2) + " (元)";
},
color:'white',
fontSize:globalTextStyle.fontSize,
offsetCenter:[0,'65%']
};
var serRadius = '90%';
var serEndAngle = -45;
var serSplitNumber = 5;
var serAxisLine = { // 坐标轴线
lineStyle: { // 属性lineStyle控制线条样式
width: 6
}
};
var serAxisTick = { // 坐标轴小标记
length:10, // 属性length控制线长
lineStyle: { // 属性lineStyle控制线条样式
color: 'auto'
}
};
var serSplitLine = { // 分隔线
length:13, // 属性length控制线长
lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
color: 'auto'
}
};
var serPointer = {
width:5
};
DashboardOption = {
tooltip : dashTooltip,
grid:grid,
series: [
{
name: name1,
title:serTitle,
detail:serDetail,
type: 'gauge',
radius: serRadius,
min:0,
max:maxValue,
endAngle:serEndAngle,
splitNumber:serSplitNumber,
axisLine:serAxisLine,
axisTick: serAxisTick,
splitLine: serSplitLine,
pointer: serPointer,
center: center1, // 默认全局居中
data:[{value: value1, name: name1}]
},
{
name: name2,
title:serTitle,
detail:serDetail,
type: 'gauge',
radius: serRadius,
min:0,
max:maxValue,
endAngle:serEndAngle,
splitNumber:serSplitNumber,
axisLine:serAxisLine,
axisTick: serAxisTick,
splitLine: serSplitLine,
pointer: serPointer,
center: center2, // 默认全局居中
data:[{value: value2, name: name2}]
},
{
name: name3,
title:serTitle,
detail:serDetail,
type: 'gauge',
radius: serRadius,
min:0,
max:maxValue,
endAngle:serEndAngle,
splitNumber:serSplitNumber,
axisLine:serAxisLine,
axisTick: serAxisTick,
splitLine: serSplitLine,
pointer: serPointer,
center: center3, // 默认全局居中
data:[{value: value3, name: name3}]
}]
};
DashboardChart.setOption(DashboardOption, true);
chartOption.Chart2 = DashboardOption;
chartObj.push(DashboardChart);
}
/******仪表盘--结束**********************************/
/******柱状图--开始**********************************/
var BarChart = {};
var BarOption={};
function initBarChart(monthList, buyList, sellList){
BarChart = echarts.init(document.getElementById('Chart3'));
var xAxisData = monthList;//['2019-01','2019-02','2019-03','2019-04','2019-05','2019-06','2019-07','2019-08','2019-09','2019-10','2019-11','2019-12'];
var seriesDatazgb = buyList;//[ 900, 800, 400, 1250, 400, 1550, 1300, 1550, 400, 400, 400, 200 ]
var seriesDataltgb = sellList;//[ 600, 600, 600, 1450, 1300, 300, 1800, 620, 620,620, 620, 1300 ]
//定义图例
var mtLegend = getSameAttrObj(legend);
mtLegend.data = ['收入', '支出'];
mtLegend.top = 10;
//定义X 轴
var mtXAxis = getSameAttrObj(xAxis);
mtXAxis.data = xAxisData;
//定义Y轴
var mtYAxis = getSameAttrObj(yAxis);
mtYAxis.name = '(元)';
BarOption = {
tooltip: {
trigger: 'axis',
confine:true,
formatter:tooltipFormatter
},
legend : mtLegend,
grid: grid,
xAxis: mtXAxis,
yAxis: mtYAxis,
series: [
{
name: '收入',
type: 'bar',
barGap: 0,
barWidth: 15,
//roundCap: true,
itemStyle: {
color: '#0068BE',
fontSize: globalTextStyle.fontSize,
barBorderRadius: globalbarBorderRadius
},
markPoint: {
data: [
{type: 'max', name: '最大值'},
{type: 'min', name: '最小值'}
]
},
data: seriesDatazgb
},
{
name: '支出',
type: 'bar',
barWidth: 15,
//roundCap: true,
itemStyle: {
color: '#FEBA01',
fontSize: globalTextStyle.fontSize,
barBorderRadius: globalbarBorderRadius
},
markPoint: {
data: [
{type: 'max', name: '最大值'},
{type: 'min', name: '最小值'}
]
},
data: seriesDataltgb
}]
}
BarChart.setOption(BarOption);
chartOption.Chart3 = BarOption;
chartObj.push(BarChart);
}
/******柱状图--结束**********************************/
generalExpand.js:处理图表resize(随着窗口一起改变大小,自适应),定义弹窗(放大)图表属性,弹出窗口方法。
/**
* 通用放大js文件
*包含放大图表的属性处理、弹窗处理方法,以及图表尺寸重置 3个功能
*
* 注意js引入顺序:
* 1、generalAttr.js
* 2、个人js文件
* 3、generalExpand.js
*/
/*****************************************以下 窗口变化改变图表大小*********************************/
//chartObj 该变量已在 gerenalAttr.js 中声明;调用此方法前,需确保 变量chartObj已经声明并已赋值。
//案例:会计事务所
window.onresize = function () {
setTimeout(function (){
for(var i in chartObj){
chartObj[i].resize();
}
},100);
};
/*****************************************以下 放大弹窗 处理代码*********************************/
/**
*
* 案例:参考会计事务所
* 绑定触发元素、处理放大图表的属性
* 如有特殊,请重写类似方法,自行调用
* chartOption 该变量已在 gerenalAttr.js 中声明;调用此方法前,需确保 变量chartOption已经声明并已赋值。
* 调用方式:
1、$(".scale").click(function(){
attrAssign(this);
}
2、标签直接绑定:
* @param elem 触发事件的元素
* @constructor
*/
function attrAssign(elem){
var ChildGrid = { //子页面图表大小
left: "5%",
right: "5%",
bottom: "5%",
};
var title =$(elem).parent().text(); //标题
var optionKey = $(elem).attr("chartOption") ; //opton 对应的key
var childOption = chartOption[optionKey]; //获取opton
childOption.grid = ChildGrid;
openExpandChart(title,childOption,optionKey);
}
var expendChart = {};
/**
* 弹出放大图---统一方法
*/
function openExpandChart(title,childOption,optionKey) {
var url = basePath + "/expand";
layer.open({
type: 2,
title: [title, 'font-size:14px;'],
area: ['85%', '90%'],
maxmin: false,
move: false,
anim: 2,
zIndex:9999,
content: [url, 'no'], //no:禁止iframe出现滚动条
success: function (layero, index) {
var body = layer.getChildFrame('body', index);
expendChart = echarts.init(body.find('#expandChart').get(0));
expendChart.setOption(childOption);
},
resizing: function(){
setTimeout(function (){
expendChart.resize();
},10);
}
});
}
点此下载完整案例
欢迎大咖交流,指点,有问题欢迎留言。