遇到一个需求:折线图上最后一个点做成一个动态水波纹的点。。。
一开始想让 UI小哥做一个 gif动态图,直接加到 echarts折线图的拐点上,但是小哥说 gif的画质太差,不给用,切成了一系列的静态图,让自己组装成动态变换的。。。
要组装的话,那必然要自己写一个 html元素来设置 css样式,但是搞了半天,不知道怎么用自定义的 html元素,想直接使用 gif,然而 symbol属性不支持展示 gif,不过偶然发现 markPoint是支持 gif的哦!!!
但是回到 gif本身画质的问题上,当然还是能用自定义的元素最好了,而且,折线图的颜色不固定,总不能有几种颜色就让 UI小哥做几种颜色的图。。。
后来!!!终于在公司的 highcharts讨论群中获得了一些提示,是的,没错,以为 echarts做不了,跑去问 highcharts了 -_-|||
convertToPixel(finder, value): echarts实例有这么一个方法可以将图中的点转换成像素坐标,那只要将自定义的 html元素定位到这个坐标上就可以了!
- 页面效果
(因为是做的 Vue的项目,所以按照 Vue的语法写的,参考方法即可) - HTML代码
<template>
<div class="chart-wrapper">
<div id="myChart" :style="chartStyle"></div>
<!-- 自定义的动态点 -->
<div id="markPoint" class="mark-point">
<div class="water water1"></div>
<div class="water water2"></div>
</div>
</div>
</template>
- Javascript代码
this.chartsDom.setOption(this.option); // chartsDom: 定义过的 echarts实例
// 注意!!!添加动态点——在setOption之后!!!!
this.seriesData.forEach((item, index) => { // seriesData: 自己组装的series值,如果有多条折线的话,html中自己定义的 markPoint需要遍历成多个的
if (item.lastPoint) { // lastPoint: 每条折线找出的最后一个点的坐标[x, y]
// 定位点的位置
let position = this.chartsDom.convertToPixel({
xAxisIndex: 0, // 第一个参数:需要转换的坐标系的信息,
yAxisIndex: 0,
}, [item.lastPoint.x, item.lastPoint.y]); // 第二个参数:点的坐标值
const markPoint = document.getElementById('markPoint');
const waters = markPoint.getElementsByClassName('water');
markPoint.style.left = `${position[0] - 3}px`;
markPoint.style.top = `${position[1] - 3}px`;
const curColor = this.colors[index]; // colors:自定义的一组颜色值,取当前折线对应的 color
markPoint.style.background = curColor;
waters[0].style.background = curColor;
waters[1].style.background = curColor;
markPoint.style.display = 'block';
// 绑定缩放事件 => 由于数据比较多,还使用了 dataZoom,需要监听缩放事件,不断设置 markPoint的位置
this.chartsDom.on('dataZoom', () => {
if (item.lastPoint) {
position = this.chartsDom.convertToPixel({
xAxisIndex: 0,
yAxisIndex: 0,
}, [item.lastPoint.x, item.lastPoint.y]);
markPoint.style.left = `${position[0] - 3}px`;
markPoint.style.top = `${position[1] - 3}px`;
}
});
// 绑定legend切换事件 => legend切换时,也要让 markPoint随之显示/隐藏
this.chartsDom.on('legendselectchanged', (params) => {
// 判断当前是否被选中
const { name, selected } = params;
if (item.lastPoint) {
markPoint.style.display = selected[name] ? 'block' : 'none';
}
});
}
});
- CSS代码
.chart-wrapper {
/* 注意!!!转换成的像素坐标是以当前容器为基础的,所以不要忘记给容器设置 relative定位 */
position: relative;
overflow: hidden;
}
.mark-point {
display: none;
.water1 {
animation: markPointAnim 2s infinite;
}
.water2 {
animation: markPointAnim1 2s infinite;
}
}
.mark-point,
.mark-point .water {
position: absolute;
width: 6px;
height: 6px;
border-radius: 50%;
}
@keyframes markPointAnim {
0% {
transform: scale(1);
opacity: 0.9;
}
100% {
transform: scale(3);
opacity: 0;
}
}
@keyframes markPointAnim1 {
0% {
transform: scale(1);
opacity: 0.9;
}
100% {
transform: scale(6);
opacity: 0;
}
}