1、目前各大券商的基金股票商城很多都是用的H5实现,而谈到基金就离不开基金股票的走势图,那么首先想到的就是用echarts来实现,走势图内容展示用echarts的折线统计图再合适不过了,数据一套就出来了。
2、但是问题也来了,基金最重要的十字坐标怎么展示,即要根据手指滑动的位置实时显示基金的十字坐标点,而echarts只提供了y轴的也就是竖轴的指示线显示功能,下面图就是用echarts配置实现的y轴指示线功能。
![](https://i-blog.csdnimg.cn/blog_migrate/6e8d86206573139571e13156f8448865.png)
3、下面是具体实现的echarts配置项,其中主要的是axisPointer配置项,里面的label配置用于显示y轴指示线底部的日期,而lineStyle用于配置指示线颜色等基本属性:
const option = {
animation: false,
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
snap: true
},
formatter(params) {
props.handleTooltipClick && props.handleTooltipClick(params); // 点击使用
}
},
color: ['#F3402F', '#4C7CF1'],
grid: {
top: gridTop,
left: '1',
right: '1',
bottom: '30px',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: 'rgba(153, 153, 153, 0.2)',
type: 'dashed'
}
},
axisLabel: {
fontSize,
color: '#999',
margin: 16,
showMaxLabel: true,
showMinLabel: true,
interval: index => index === 0 || index === chartData.xData.length - 1 || index === Math.floor(chartData.xData.length / 2),
formatter(value, index) {
if (index === 0) {
return `${space}${dayjs(value).format('YYYY-MM-DD')}`;
} else if (index === chartData.xData.length - 1) {
return `${dayjs(value).format('YYYY-MM-DD')}${space}`;
}
return dayjs(value).format('YYYY-MM-DD');
},
...axisLabel
},
axisPointer: {
label: {
formatter(obj) {
return `${obj.value.substring(4, 6)}-${obj.value.substring(6, 8)}`;
},
show: true,
padding: [2, 4, 2, 4],
fontSize,
borderRadius: 0,
backgroundColor: '#F24957'
},
lineStyle: {
color: '#FF5800', // 指示线颜色
type: 'dashed',
height: 0.4
}
},
data: chartData.xData
},
yAxis: {
type: 'value',
axisLabel: {
fontSize,
formatter(value) {
return parseFloat(value).toFixed(toFixed) + sign;
},
color: '#999'
},
splitLine: {
lineStyle: {
color: 'rgba(153, 153, 153, 0.2)',
type: 'dashed'
}
},
axisPointer: {
show: false // 隐藏y轴指示线
},
splitNumber: 5,
axisTick: {
show: false
},
axisLine: {
show: false
},
scale: true
},
series: [
{
type: 'line',
lineStyle: {
normal: {
width: lineWidth
}
},
symbol: 'none',
data: chartData.yData,
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 1,
x2: 0,
y2: 0,
colorStops: [{ offset: 0, color: '#fff' }, { offset: 1, color: 'rgba(242, 73, 87, 0.1)' }],
global: false // 缺省为 false
},
origin: 'start'
}
},
{
type: 'line',
lineStyle: {
normal: {
width: lineWidth
}
},
symbol: 'none',
data: chartData.yData1 || []
}
]
};
4、那还剩下x轴的指示线怎么显示呢?echarts没有提供可以配置,且能根据手指滑动自动变换坐标的x轴的指示线;唯一显示的只有markLine配置项可以配置x轴的指示线,但是是静态的,并不能实时变动,因此要加上监听事件,而监听事件可以使用echarts的getZr()方法监听鼠标移动'mousemove',然后获取坐标实时更新markLine配置项,这样就能实现走势图十字坐标了。
(1)首先是markLine配置静态的x轴的指示线样式,下面是markLine配置代码
markLine: {
data: [],
animation: false,
label: {
formatter(obj) {
const plus = parseFloat(obj.value) > 0 ? '+' : '';
return plus + parseFloat(obj.value).toFixed(toFixed) + sign;
},
position: 'start',
padding: [2, 4, 2, 4],
fontSize,
borderRadius: 0,
backgroundColor: '#F24957',
color: '#fff'
},
lineStyle: {
color: '#FF5800', // 指示线颜色
type: 'dashed',
height: 0.4
},
symbol: 'none' // 去掉箭头
},
![](https://i-blog.csdnimg.cn/blog_migrate/f2179dc9f8044eab21444b3110de8481.png)
(2)在echarts的setOption下方加上getZr()方法监听鼠标(手指)移动'mousemove',最后实时获取x轴坐标并更新markLine配置,下面是具体实现的代码:
const myChart = echarts.init(document.getElementById('lineChart'));
const option = setLineOption();
myChart.setOption(option);
// 模拟十字轴的横轴
myChart.getZr().on('mousemove', (params) => {
// 获取点击位置的坐标
const pointInPixel = [params.offsetX, params.offsetY];
// containPixel为true则点击位置在坐标轴内
if (myChart.containPixel('grid', pointInPixel)) {
// 传入鼠标位置坐标进行转化
// convertFromPixel返回[x, y],x对应鼠标点击处数据的下标,y对应鼠标点击处的数值
const x = myChart.convertFromPixel({ seriesIndex: 0 }, pointInPixel)[0];
if (!data.yData.length) {
return;
}
const markLineValue = data.yData[x];
if (markLineValue) {
const series = option.series;
// 修改markLine的值
series[0].markLine.data = [{ yAxis: markLineValue }];
// 重新setOption
// console.log(series);
myChart.setOption({ series }, { lazyUpdate: true });
// 设置选中的内容
// props.handleTooltipClick({ axisValue: data.xData[x], value: data.yData[x], compRate: data.yData1 ? data.yData1[x] : '' });
}
} else {
// 不在坐标轴内不展示markLine
const series = option.series;
series[0].markLine.data = [];
myChart.setOption({ series }, { lazyUpdate: true });
}
});
myChart.getZr().on('mouseup', () => {
myChart.dispatchAction({
type: 'hideTip'
});
myChart.dispatchAction({
type: 'updateAxisPointer',
currTrigger: 'leave'
});
myChart.setOption({ series: [{ markLine: { data: [] } }] }, { lazyUpdate: true });
// 设置选中的内容
// props.handleTooltipClick({ axisValue: data.xData[data.xData.length - 1], value: data.yData[data.yData.length - 1], compRate: data.yData1 ? data.yData1[data.yData1.length - 1] : '' });
});