新建loopShowTooltip.js并引入引入
import { loopShowTooltip } from "../../../utils/loopShowTooltip.js"
loopShowTooltip.js文件
/**
* echarts tooltip輪播
* @param chart ECharts實(shí)例
* @param chartOption echarts的配置信息
* @param options object 選項(xiàng)
* {
* interval 輪播時(shí)間間隔,單位毫秒逢勾,默認(rèn)為2000
* loopSeries boolean類型桅打,默認(rèn)為false剪撬。
* true表示循環(huán)所有series的tooltip炒瘸,false則顯示指定seriesIndex的tooltip
* seriesIndex 默認(rèn)為0达传,指定某個(gè)系列(option中的series索引)循環(huán)顯示tooltip碌更,
* 當(dāng)loopSeries為true時(shí)瓶籽,從seriesIndex系列開(kāi)始執(zhí)行恃鞋。
* updateData 自定義更新數(shù)據(jù)的函數(shù)崖媚,默認(rèn)為null;
* 用于類似于分頁(yè)的效果恤浪,比如總數(shù)據(jù)有20條畅哑,chart一次只顯示5條,全部數(shù)據(jù)可以分4次顯示水由。
* }
* @returns {{clearLoop: clearLoop}|undefined}
*/
export function loopShowTooltip(chart, chartOption, options) {
let defaultOptions = {
interval: 2000,
loopSeries: false,
seriesIndex: 0,
updateData: null,
shunXu: "zhengXu", //播放順序 默認(rèn)正序 zhengXu daoXu
};
if (!chart || !chartOption) {
return;
}
if (options) {
options.interval = options.interval || defaultOptions.interval;
options.loopSeries = options.loopSeries || defaultOptions.loopSeries;
options.seriesIndex = options.seriesIndex || defaultOptions.seriesIndex;
options.updateData = options.updateData || defaultOptions.updateData;
options.zhengXu = options.zhengXu || defaultOptions.zhengXu;
} else {
options = defaultOptions;
}
let dataIndex = -1; // 數(shù)據(jù)索引荠呐,初始化為-1,是為了判斷是否是第一次執(zhí)行
let seriesIndex = 0; // 系列索引
let timeTicket = 0;
let seriesLen = chartOption.series.length; // 系列個(gè)數(shù)
let dataLen = 0; // 某個(gè)系列數(shù)據(jù)個(gè)數(shù)
let chartType; // 系列類型
let first = true;
let lastShowSeriesIndex = 0;
let lastShowDataIndex = 0;
if (seriesLen === 0) {
return;
}
// 待處理列表
// 不循環(huán)series時(shí)seriesIndex指定顯示tooltip的系列砂客,不指定默認(rèn)為0直秆,指定多個(gè)則默認(rèn)為第一個(gè)
// 循環(huán)series時(shí)seriesIndex指定循環(huán)的series,不指定則從0開(kāi)始循環(huán)所有series鞭盟,指定單個(gè)則相當(dāng)于不循環(huán)圾结,指定多個(gè)
// 要不要添加開(kāi)始series索引和開(kāi)始的data索引?
// 如果設(shè)置的seriesIndex無(wú)效齿诉,則默認(rèn)為0
if (options.seriesIndex < 0 || options.seriesIndex >= seriesLen) {
seriesIndex = 0;
} else {
seriesIndex = options.seriesIndex;
}
/**
* 清除定時(shí)器
*/
function clearLoop() {
if (timeTicket) {
clearInterval(timeTicket);
timeTicket = 0;
}
chart.off('mousemove', stopAutoShow);
zRender.off('mousemove', zRenderMouseMove);
zRender.off('globalout', zRenderGlobalOut);
}
/**
* 取消高亮
*/
function cancelHighlight() {
/**
* 如果dataIndex為0表示上次系列完成顯示筝野,如果是循環(huán)系列,且系列索引為0則上次是seriesLen-1粤剧,否則為seriesIndex-1歇竟;
* 如果不是循環(huán)系列,則就是當(dāng)前系列抵恋;
* 如果dataIndex>0則就是當(dāng)前系列焕议。
*/
let tempSeriesIndex = dataIndex === 0 ? options.loopSeries ? seriesIndex === 0 ? seriesLen - 1 : seriesIndex -
1 : seriesIndex : seriesIndex;
let tempType = chartOption.series[tempSeriesIndex].type;
if (tempType === 'pie' || tempType === 'radar' || tempType === 'map') {
chart.dispatchAction({
type: 'downplay',
seriesIndex: lastShowSeriesIndex,
dataIndex: lastShowDataIndex,
}); // wait 系列序號(hào)為0且循環(huán)系列,則要判斷上次的系列類型是否是pie弧关、radar
}
}
/**
* 自動(dòng)輪播tooltip
*/
function autoShowTip() {
let invalidSeries = 0;
let invalidData = 0;
function showTip() {
// chart不在頁(yè)面中時(shí)盅安,銷毀定時(shí)器
let dom = chart.getDom();
if (document !== dom && !document.documentElement.contains(dom)) {
clearLoop();
return;
}
// 判斷是否更新數(shù)據(jù)
if (
dataIndex === 0 &&
!first &&
typeof options.updateData === 'function'
) {
options.updateData();
chart.setOption(chartOption);
}
let series = chartOption.series;
let currSeries = series[seriesIndex];
if (!series || series.length === 0 || !currSeries || !currSeries.type || !currSeries.data || !currSeries
.data.length) {
return;
}
chartType = currSeries.type; // 系列類型
dataLen = currSeries.data.length; // 某個(gè)系列的數(shù)據(jù)個(gè)數(shù)
let tipParams = {
seriesIndex: seriesIndex
};
switch (chartType) {
case 'pie':
// 處理餅圖中數(shù)據(jù)為0或系列名為空的不顯示tooltip
if (!currSeries.data[dataIndex].name || currSeries.data[dataIndex].name === '空' || !currSeries.data[
dataIndex].value) {
invalidData += 1;
dataIndex = (dataIndex + 1) % dataLen;
if (options.loopSeries && dataIndex === 0) {
// 數(shù)據(jù)索引歸0表示當(dāng)前系列數(shù)據(jù)已經(jīng)循環(huán)完
// 無(wú)效數(shù)據(jù)個(gè)數(shù)個(gè)總數(shù)據(jù)個(gè)數(shù)相等唤锉,則該系列無(wú)效
if (invalidData === dataLen) {
invalidSeries += 1;
}
// 新系列,重置無(wú)效數(shù)據(jù)個(gè)數(shù)
invalidData = 0;
// 系列循環(huán)遞增1
seriesIndex = (seriesIndex + 1) % seriesLen;
// 系列數(shù)循環(huán)至起始值時(shí)重置無(wú)效系列數(shù)
if (seriesIndex === options.seriesIndex) {
if (seriesLen !== invalidSeries) {
// 下一次系列輪回别瞭,重置無(wú)效系列數(shù)
invalidSeries = 0;
showTip();
} else {
// 下一次系列輪回窿祥,重置無(wú)效系列數(shù)
invalidSeries = 0;
clearLoop();
}
} else {
showTip();
}
} else if (!options.loopSeries && dataIndex === 0) {
if (dataLen !== invalidData) {
invalidData = 0;
showTip();
} else {
invalidData = 0;
clearLoop();
}
} else {
showTip();
}
return;
}
// eslint-disable-next-line no-fallthrough
case 'map':
case 'chord':
tipParams.name = currSeries.data[dataIndex].name;
break;
case 'radar': // 雷達(dá)圖
tipParams.seriesIndex = seriesIndex;
// tipParams.dataIndex = dataIndex;
break;
case 'lines': // 線圖地圖上的lines忽略
dataIndex = 0;
seriesIndex = (seriesIndex + 1) % seriesLen;
invalidSeries++; // 記錄無(wú)效系列數(shù),如果無(wú)效系列數(shù)和系列總數(shù)相等則取消循環(huán)顯示
if (seriesLen !== invalidSeries) {
showTip();
} else {
clearLoop();
}
return;
default:
tipParams.dataIndex = dataIndex;
break;
}
if (chartType === 'pie' || chartType === 'radar' || chartType === 'map') {
if (!first) {
cancelHighlight();
}
// 高亮當(dāng)前圖形
chart.dispatchAction({
type: 'highlight',
seriesIndex: seriesIndex,
dataIndex: dataIndex,
});
}
// 顯示 tooltip
tipParams.type = 'showTip';
chart.dispatchAction(tipParams);
lastShowSeriesIndex = seriesIndex;
lastShowDataIndex = dataIndex;
//如果是倒序
if (options.shunXu == "daoXu") {
if (first) {
dataIndex = dataLen - 1;
} else {
dataIndex--;
if (dataIndex < 0) {
dataIndex = dataLen - 1;
}
}
} else {
dataIndex = (dataIndex + 1) % dataLen;
if (options.loopSeries && dataIndex === 0) {
// 數(shù)據(jù)索引歸0表示當(dāng)前系列數(shù)據(jù)已經(jīng)循環(huán)完
invalidData = 0;
seriesIndex = (seriesIndex + 1) % seriesLen;
if (seriesIndex === options.seriesIndex) {
invalidSeries = 0;
}
}
}
if (options.loopSeries && dataIndex === 0) {
// 數(shù)據(jù)索引歸0表示當(dāng)前系列數(shù)據(jù)已經(jīng)循環(huán)完
invalidData = 0;
seriesIndex = (seriesIndex + 1) % seriesLen;
if (seriesIndex === options.seriesIndex) {
invalidSeries = 0;
}
}
first = false;
}
showTip();
timeTicket = setInterval(showTip, options.interval);
}
// 關(guān)閉輪播
function stopAutoShow() {
if (timeTicket) {
clearInterval(timeTicket);
timeTicket = 0;
if (chartType === 'pie' || chartType === 'radar' || chartType === 'map') {
cancelHighlight();
}
}
}
//從頭開(kāi)始
function Retart() {
first = true;
stopAutoShow()
autoShowTip();
}
let zRender = chart.getZr();
function zRenderMouseMove(param) {
if (param.event) {
// 阻止canvas上的鼠標(biāo)移動(dòng)事件冒泡
// param.event.cancelBubble = true;
}
stopAutoShow();
}
// 離開(kāi)echarts圖時(shí)恢復(fù)自動(dòng)輪播
function zRenderGlobalOut() {
// console.log("移出了")
// console.log(timeTicket)
if (!timeTicket) {
autoShowTip();
}
}
// 鼠標(biāo)在echarts圖上時(shí)停止輪播
chart.on('mousemove', stopAutoShow);
zRender.on('mousemove', zRenderMouseMove);
zRender.on('globalout', zRenderGlobalOut);
autoShowTip();
return {
Retart: Retart,
clearLoop: clearLoop
};
}
使用方法
showLoop() {
this.tootipTimer && this.tootipTimer.clearLoop();
this.tootipTimer = 0;
// 調(diào)用輪播的方法
// myChart為Echarts容器實(shí)例
this.tootipTimer = loopShowTooltip(this.chartMap, this.option, {
interval: 2000, // 輪播間隔時(shí)間
loopSeries: true, // 是否開(kāi)啟輪播循環(huán)
// shunXu: "daoXu", // 顯示順序
// loopSeries: boolean類型蝙寨,默認(rèn)為false晒衩。true表示循環(huán)所有series的tooltip;false則顯示指定seriesIndex的tooltip墙歪。
// seriesIndex: 默認(rèn)為0听系,指定某個(gè)系列(option中的series索引)循環(huán)顯示tooltip,當(dāng)loopSeries為true時(shí)虹菲,從seriesIndex系列開(kāi)始執(zhí)行跛锌。
})
},