需求要求:坐标轴上有俩条markline,并且可以单独移动???
遇到这种需求我的第一反应就是上网百度,百度百度百度。
哦买噶,我多么希望有个一模一样的,但是结果还真是我想多了。
然后很头疼的自己去翻资料写。
思路:首先先画出俩条markline,分别为X0,X1;在markline俩线条中间,添加一个graphic矩形Area
其次在markline的X0,X1上各添加一个graphic矩形,确保X0,X1可移动,并且把矩形设置透明,并且这俩条Markline线条位置等于Area的矩形的位置
最后,将线条靠近边缘化Area,改变位置后重新SetOption。
前面部分是基本作图,把模板画出个大概样子就差不多了。(因为有注释所以写的并不是很详细,注释已经写的很明白了)
var myChart = echarts.init(document.getElementById(id));
var myOption = {
title: {
text: "",
textStyle: {
color: 'white',
fontWeight: 400,
fontSize: 16
},
left: 'center',
top: '0%'
},
tooltip: {
trigger: "axis",
axisPointer: {
lineStyle: {
color: "#dddc6b"
}
},
formatter: function (params) {
return params[0].seriesName + '<br>' + params[0].marker + ' ' + params[0].data[0] + ' : ' + params[0].data[1];
}
},
legend: {
x: "right",
textStyle: {
color: "white",
fontSize: 12
},
},
grid: {
top: '20%',
bottom: '5%',
left: '2%',
right: '4%',
containLabel: true
},
xAxis: [{
id: 'x0',
type: "category",
boundaryGap: true,
axisLabel: {
textStyle: {
color: "#FFF",
fontSize: 12
}
},
axisLine: {
lineStyle: {
color: "#0066CC"
}
},
axisTick: {
show: false
},
}, {
axisPointer: {
show: false
},
axisLine: {
show: false
},
position: "bottom",
offset: 20
}],
yAxis: [{
id: '2',
name: yName,
nameTextStyle: {
color: '#FFF',
fontSize: 12,
},
type: "value",
min: ymin,
max: ymax,
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: "#0066CC"
}
},
axisLabel: {
formatter: '{value}',
textStyle: {
color: "#FFF",
fontSize: 12
}
},
splitLine: {
show: false
}
}],
series: [{
type: 'line',
z: 1,
data: seriesData,
symbolSize: 1,
symbol: 'circle',
smooth: true,
itemStyle: {
normal: {
color: 'rgba(0,245,255,0.9)'
}
},
markLine: {
symbol: ['none', 'triangle'],
silent: true,
label: {
show: true,
distance: 10,
fontWeight: "lighter"
},
data: [{
type: 'max',
lineStyle: {
normal: {
type: "solid",
width: 1,
color: '#CCFF66'
}
}
}, {
type: 'average',
lineStyle: {
normal: {
type: "solid",
width: 1,
color: '#CCFF66'
}
}
}, {
type: 'min',
lineStyle: {
normal: {
type: "solid",
width: 1,
color: '#CCFF66'
}
}
}]
},
}, {
id: 'vline',
z: 2,
data: seriesData,
type: 'line',
// 隐藏series
symbolSize: 0,
showSymbol: false,
lineStyle: {
width: 0,
color: 'rgba(0, 0, 0, 0)'
}
}]
};
myChart.setOption(myOption);
下一步则是为图形添加markline
//绘制垂直markLine
myChart.setOption(getVlineOpt(2, 8));
function getMarkAxis() {
var result = new Object();
var option = myChart.getOption();
$.each(option.series, function (i, series) {
if (series.id == 'vline') {
var markLine = series.markLine;
result['L1'] = markLine.data[0].xAxis;
result['L2'] = markLine.data[1].xAxis;
return false;
}
});
return result;
}
var myHeight = myChart.getHeight();
var myWidth = myChart.getWidth();
添加移动graphic
//markLine拖动
// 绘制L值的graphic line
myChart.setOption({
graphic: {
elements: [
{
type: 'rect',
id: 'rect1',
name: 'rect1',
bottom: -myHeight,
z: 10,
invisible: true,
shape: {
width: 0,
height: myHeight * 3
},
style: {
fill: 'rgba(128,128,128,0.5)',
stroke: 'rgba(128,128,128,0.5)',
lineWidth: 6
},
// 转换坐标系上的点到像素坐标值
position: [myChart.convertToPixel({xAxisId: 'x0'}, getMarkAxis()['L1']), 0],
bouding: 'all',
cursor: 'move',
draggable: true,
ondragstart: onLineDragStart,
ondragend: onLineDragEnd
}, {
type: 'rect',
id: 'rect2',
name: 'rect2',
bottom: -myHeight,
z: 9,
invisible: true,
shape: {
width: 0,
height: myHeight * 3
},
style: {
fill: 'rgba(128,128,128,0.5)',
stroke: 'rgba(128,128,128,0.5)',
lineWidth: 6
},
//转换坐标系上的点到像素坐标值
position: [myChart.convertToPixel({xAxisId: 'x0'}, getMarkAxis()['L2']), 0],
bouding: 'all',
cursor: 'move',
draggable: true,
ondragstart: onLineDragStart,
ondragend: onLineDragEnd
},{
type: 'rect',
id: 'rectArea',
name: 'rectArea',
bottom: -myHeight,
z: 8,
invisible: true,
shape: {
width: Math.abs(myChart.convertToPixel({xAxisId: 'x0'}, getMarkAxis()['L2']) - myChart.convertToPixel({xAxisId: 'x0'}, getMarkAxis()['L1'])) - 10,
height: myHeight * 3
},
style: {
fill: 'rgba(183,81,5,0.1)',
stroke: 'rgba(128,128,128,0.2)'
},
//转换坐标系上的点到像素坐标值
position: [myChart.convertToPixel({xAxisId: 'x0'}, getMarkAxis()['L1'] < getMarkAxis()['L2'] ? getMarkAxis()['L1'] : getMarkAxis()['L2']) + 5, 0],
bouding: 'all',
cursor: 'move',
draggable: true,
onmouseover: onAreaMouseOver,
onmouseout: onAreaMouseOut,
ondragend: onAreaDragEnd,
},{
type: 'rect',
id: 'rectAll',
name: 'rectAll',
bottom: 0,
z: 7,
invisible: true,
shape: {
width: myWidth,
height: myHeight
},
style: {
fill: 'rgba(183,81,5,0.8)',
stroke: 'rgba(128,128,128,0.2)'
},
//转换坐标系上的点到像素坐标值
position: [0, 0],
bouding: 'all',
cursor: 'default',
draggable: false
}]
}
});
其他操作代码
//鼠标移入移出显示隐藏Area图形
var area_opt = {
graphic: {
elements: [
{
id: 'rectArea',
$action: 'merge',
invisible: true
}]
}
};
function onAreaMouseOver() {
area_opt.graphic.elements[0].invisible = false;
myChart.setOption(area_opt);
}
function onAreaMouseOut() {
area_opt.graphic.elements[0].invisible = true;
myChart.setOption(area_opt);
}
// 垂直线重新定位,markLine 和 graphic 定位于 Area 的边缘
function onAreaDragEnd() {
try {
var x_start = getXAxis(this.position[0] - 5);
var x_end = getXAxis(this.position[0] + this.shape.width + 5);
//markLine重新定位
var vline_opt = {};
var result = getMarkAxis();
if (result['L1'] < result['L2']) {
vline_opt = getVlineOpt(x_start, x_end);
} else {
vline_opt = getVlineOpt(x_end, x_start);
}
myChart.setOption(vline_opt);
//graphic重新定位
var graph_opt = getGraphicOpt();
myChart.setOption(graph_opt);
//当前页所有echarts修改垂直线
var opt = $.extend(true, vline_opt, graph_opt);
changeCharts(id, opt);
} catch (e) {
console.log('垂直线移动失败。');
console.log(e);
}
}
//拖拽开始markline变色
function onLineDragStart() {
var graphicId = this.__ecGraphicId;
if (graphicId == 'rect1') {
myChart.setOption(getVlineOpt(null, null, 'L1'));
} else if (graphicId == 'rect2') {
myChart.setOption(getVlineOpt(null, null, 'L2'));
}
}
//垂直线重新定位,拖拽结束markLine和graphic确定位置
function onLineDragEnd() {
//console.log(this.position);
try {
var x = getXAxis(this.position[0]);
//markLine重新定位
var vline_opt = {};
var graphicId = this.__ecGraphicId;
if (graphicId == 'rect1') {
vline_opt = getVlineOpt(x, null);
} else if (graphicId == 'rect2') {
vline_opt = getVlineOpt(null, x);
}
myChart.setOption(vline_opt);
//graphic重新定位
var graph_opt = getGraphicOpt();
myChart.setOption(graph_opt);
//当前页所有echarts修改垂直线
var opt = $.extend(true, vline_opt, graph_opt);
changeCharts(id, opt);
} catch (e) {
console.log('垂直线移动失败。');
console.log(e);
}
}
//转换像素坐标值到逻辑坐标系上的点,是convertToPixel的逆运算
function getXAxis(Xpx) {
var x = myChart.convertFromPixel({xAxisId: 'x0'}, Xpx);
if (x <= 0) {
x = 0;
} else if (x >= seriesData.length) {
x = seriesData.length - 1;
}
return x;
}
function getVlineOpt(x1, x2, select) {
if (x1 == null || x1 == undefined) {
x1 = getMarkAxis()['L1'];
}
if (x2 == null || x2 == undefined) {
x2 = getMarkAxis()['L2'];
}
var color1 = '#FFBE00';
var color2 = '#FFBE00';
if (select == 'L1') {
color1 = '#FFF';
}
if (select == 'L2') {
color2 = '#FFF';
}
var option = {
series: [{
id: 'vline',
markLine: {
symbol: 'none',
silent: true,
label: {
show: true,
formatter: function (param) {
return seriesData[param.value][0];
}
},
data: [{
xAxis: x1,
name: 'L1',
lineStyle: {
normal: {
type: "dashed",
width: 1,
color: color1
}
}
}, {
xAxis: x2,
name: 'L2',
lineStyle: {
normal: {
type: "dashed",
width: 1,
color: color2
}
}
}]
}
}]
};
return option;
}
function getGraphicOpt() {
var result = getMarkAxis();
var option = {
graphic: {
elements: [
{
id: 'rect1',
$action: 'merge',
position: [myChart.convertToPixel({xAxisId: 'x0'}, result['L1']), 0]
},
{
id: 'rect2',
$action: 'merge',
position: [myChart.convertToPixel({xAxisId: 'x0'}, result['L2']), 0]
}, {
id: 'rectArea',
$action: 'merge',
shape: {
width: Math.abs(myChart.convertToPixel({xAxisId: 'x0'}, result['L2']) - myChart.convertToPixel({xAxisId: 'x0'}, result['L1'])) - 10,
},
position: [myChart.convertToPixel({xAxisId: 'x0'}, result['L1'] < result['L2'] ? result['L1'] : result['L2']) + 5, 0],
}]
}
};
return option;
}
myChart.resize();
//多表联动
myChart.on('mousemove', function (params) {
changeTips(id, 'show', params.event);
});
myChart.on('mouseout', function (params) {
changeTips(id, 'hide', params.event);
});