注:轮播库支持的
echarts
版本需大于5.0.0
,低于该版本的库,会出现异常,案例的echarts版本为5.2.1
核心类
/**
* 创建时间:2023-07-11 11:30:46
* 作者:Ayo
* !模块名:ecahrts轮播
* 描述:
*
* 参数说明
* @echartsDom {DOM} ecahrts挂载的dom节点
* @echartsTarget {Ecahrts Obj} ecahrts对象
* @chartOption {Object} ecahrts对象
* @timer {timer} 计时器对象
* @dataLength {number} 数据长度,用于判断数据轮播的最终位置
* @step {time} 计时器执行速度,默认3000
* @targetIndex {Number} 目标开始轮询的索引,默认0或者上次索引
*
*
* 返回值
* @ecahrtsTooltipPaly:{ecahrtsTooltipPaly} ecahrtsTooltipPaly的class对象
*/
(function (global, factory) {
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = factory();
} else if (typeof define === 'function' && define.amd) {
define(factory);
} else {
(global = global || self), (global.ecahrtsTooltipPaly = factory());
}
})(this, function () {
class ecahrtsTooltipPaly {
constructor(echartsDom, echartsTarget, chartOption, timer, dataLength, step, targetIndex) {
if (typeof echartsDom === 'undefined') {
throw new Error('必须传入echarts的DOM节点');
}
if (typeof echartsTarget === 'undefined') {
throw new Error('必须传入echarts对象');
}
if (typeof chartOption === 'undefined') {
throw new Error('必须传入echarts的option对象');
}
this.echartsDom = echartsDom;
this.echartsTarget = echartsTarget;
this.chartOption = chartOption;
this.dataLength = dataLength;
this.timer = timer;
this.step = step || 3000;
this.targetIndex = targetIndex || -1;
this.init();
}
/* 初始化 */
init() {
if (!this.echartsTarget) {
return;
}
this.play();
//dom的移入移出事件
this.openDomMonitor();
//ecahrts的移入
// this.openEchartsMonitor();
}
/* 开启ecahrts移入事件的监听 => 和开启dom事件不冲突,可能存在图例不是ecahrts绘制的,是通过div实现的 */
openEchartsMonitor() {
if (!this.echartsTarget) {
return;
}
let that = this;
this.echartsTarget.on('mouseover', function (params) {
that.setPlayIndex(params.dataIndex - 1);
});
}
/* 关闭ecahrts移入事件的监听 */
colseEchartsMonitor() {
if (!this.echartsTarget) {
return;
}
this.echartsTarget.off('mouseover');
}
/* 开启轮询 */
play() {
if (!this.echartsTarget) {
return;
}
this.timer && clearInterval(this.timer); //清除定时器,防止轮播出现混乱
this.dataLength =
this.dataLength ||
this.chartOption?.series?.data?.length ||
this.chartOption?.series[0]?.data?.length; //计算索引
let dataZoomExit = false;
var maxValueSpan = 5;
//验证dataZoom是否存在,如果存在则开启dataZoom滚动
if (this.chartOption.dataZoom) {
maxValueSpan = this.chartOption.dataZoom[0].maxValueSpan;
dataZoomExit = true;
}
let that = this;
this.timer = setInterval(function () {
that.echartsTarget.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: that.targetIndex,
});
that.targetIndex = (that.targetIndex + 1) % that.dataLength;
that.echartsTarget.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: that.targetIndex,
});
that.echartsTarget.dispatchAction({
//Echarts提供的方法
type: 'showTip',
seriesIndex: 0,
dataIndex: that.targetIndex,
});
if (dataZoomExit) {
that.echartsTarget.dispatchAction({
type: 'dataZoom',
startValue: that.targetIndex,
endValue: that.targetIndex + maxValueSpan,
});
// 监听 dataZoom 更新事件 => 开启轮播后,tooltip显示数据异常
that.echartsTarget.off('dataZoom'); // 先取消之前的监听,以免重复绑定
that.echartsTarget.on('dataZoom', function (params) {
// 使用 dispatchAction 方法手动刷新 tooltip
that.echartsTarget.dispatchAction({
type: 'showTip',
seriesIndex: 0,
// dataIndex: Math.floor(params.startValue), // 或者使用 endIndex
dataIndex: that.targetIndex,
});
});
}
}, this.step); //每隔3秒轮播一次
}
/* 暂停轮询 */
stop() {
if (!this.echartsTarget) {
return;
}
this.timer && clearInterval(this.timer);
this.echartsTarget.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: this.targetIndex,
});
// this.setPlayIndex(this.targetIndex);
}
/* 验证dom是否存在鼠标移入移出的监听 */
verifyDomMonitor() {
if (!this.echartsTarget) {
return;
}
if (typeof this.monitorOver == 'function' || typeof this.monitorOut == 'function') {
return true;
} else {
return false;
}
}
/* 开启鼠标移入移出的监听 */
openDomMonitor() {
if (!this.echartsTarget) {
return;
}
if (this.verifyDomMonitor()) {
console.error('已存在的dom监听事件,不可重复添加');
return;
}
//为了满足移出监听事件的要求,必须保证堆栈信息一致
this.monitorOver = () => {
this.stop();
};
this.monitorOut = () => {
this.play();
};
//开启鼠标移入移出事件
this.echartsDom.addEventListener('mouseover', this.monitorOver);
this.echartsDom.addEventListener('mouseout', this.monitorOut);
}
closeDomMonitor() {
if (!this.echartsTarget) {
return;
}
if (!this.verifyDomMonitor()) {
console.warn('将要的移出dom监听事件不存在');
return;
}
this.echartsDom.removeEventListener('mouseover', this.monitorOver);
this.monitorOver = null;
this.echartsDom.removeEventListener('mouseout', this.monitorOut);
this.monitorOut = null;
}
/* 设置轮询开始位置 */
setPlayIndex(index) {
if (!this.echartsTarget) {
return;
}
this.echartsTarget.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: this.targetIndex,
});
this.targetIndex = index;
}
/* 更新数据 */
updateData(chartOption, dataLength) {
this.chartOption = chartOption;
this.dataLength = dataLength;
this.play();
}
/* 销毁,释放资源 */
destroy() {
if (!this.echartsTarget) {
return;
}
this.timer && clearInterval(this.timer);
this.echartsDom = null;
this.echartsTarget = null;
this.chartOption = null;
this.timer = null;
this.step = null;
this.targetIndex = null;
//监听事件
this.monitorOver && (this.monitorOver = null);
this.monitorOut && (this.monitorOut = null);
}
}
return ecahrtsTooltipPaly;
});
类的使用
this palyEchars = new ecahrtsTooltipPaly(echartsDom, echartsTarget, chartOption [,timer | ,dataLength | ,step | ,targetIndex ] )
注:
中括号
表示该参数可传
可不传
入参说明
参数 | 说明 | 是否为必传项 |
---|---|---|
echartsDom | echars的div节点 | 是 |
echartsTarget | 使用ecahrts.init()生成的echars对象 | 是 |
chartOption | ecahrts的options对象 | 是 |
timer | 计时器对象,如果当前页面只有一个计时器对象,可不传,有多个依照情况判断 | 用户自行判断 |
dataLength | 数据长度 | 否 |
step | ecahrt轮播的速度 | 否 |
targetIndex | ecahrts开始轮播的位置,默认0 | 否 |
API
API | 说明 | 是否默认开启 |
---|---|---|
init() | 轮播初始化,默认new的时候自动加载,执行其他函数 | 是 |
openEchartsMonitor() | 开启ecahrts 的移入监听 ,目前只实现鼠标选中数据对象,则下次轮播位置从当前选择对象开始(可能会有问题) | 否 |
colseEchartsMonitor() | 关闭ecahrts的移入监听 | 否 |
play() | ecahrts开始轮询 ,默认在init()内执行 | 是 |
stop() | ecahrts停止轮询 | 否 |
verifyDomMonitor() | 验证是否存在dom节点的监听事件 | 否 |
openDomMonitor() | 开启dom 节点的监听 ,即鼠标移入dom停止轮询,移出开始轮询,默认在init()内执行 | 是 |
closeDomMonitor() | 移出dom 节点的监听 ,鼠标移入dom,将不再存在任何作用 | 否 |
setPlayIndex(index) | 更新轮播起始位置下标 | 否 |
updateData(option, dataLength) | 更新数据,当ecahrts发送更新时调用该api即可,dataLength可传可不传 | 否 |
destroy() | 释放资源,慎重使用 | 否 |
其他
/* 调用轮播以及数据更新 */
if (this.ecahrtsPlay) {
//更新数据 => updateData的第二个参数可传可不传
this.ecahrtsPlay.updateData(echartsConf.options, echartsConf.data.length);
} else {
//开启轮播
that.ecahrtsPlay = new ecahrtsTooltipPaly(
document.getElementById('echartsShowBox1'),
echartsConf.instantiation,
echartsConf.options,
that.timer,
echartsConf.data.length
);
}
项目演示地址:code.juejin.cn/pen/7273382…