echarts-tooltip-carousel.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /**
  2. * Created by chengwb on 2016/9/3.
  3. */
  4. (function (global) {
  5. global.tools = global.tools || {};
  6. /**
  7. * echarts tooltip轮播
  8. * @param chart ECharts实例
  9. * @param chartOption echarts的配置信息
  10. * @param options object 选项
  11. * {
  12. * interval 轮播时间间隔,单位毫秒,默认为2000
  13. * loopSeries boolean类型,默认为false。
  14. * true表示循环所有series的tooltip,false则显示指定seriesIndex的tooltip
  15. * seriesIndex 默认为0,指定某个系列(option中的series索引)循环显示tooltip,
  16. * 当loopSeries为true时,从seriesIndex系列开始执行。
  17. * updateData 自定义更新数据的函数,默认为null;
  18. * 用于类似于分页的效果,比如总数据有20条,chart一次只显示5条,全部数据可以分4次显示。
  19. * }
  20. * @returns {{clearLoop: clearLoop}}
  21. */
  22. tools.loopShowTooltip = function (chart, chartOption, options) {
  23. let defaultOptions = {
  24. interval: 2000,
  25. loopSeries: false,
  26. seriesIndex: 0,
  27. updateData: null
  28. };
  29. if (!chart || !chartOption) {
  30. return;
  31. }
  32. let dataIndex = 0; // 数据索引,初始化为-1,是为了判断是否是第一次执行
  33. let seriesIndex = 0; // 系列索引
  34. let timeTicket = 0;
  35. let seriesLen = chartOption.series.length; // 系列个数
  36. let dataLen = 0; // 某个系列数据个数
  37. let chartType; // 系列类型
  38. let first = true;
  39. let lastShowSeriesIndex = 0;
  40. let lastShowDataIndex = 0;
  41. if (seriesLen === 0) {
  42. return;
  43. }
  44. //待处理列表
  45. //不循环series时seriesIndex指定显示tooltip的系列,不指定默认为0,指定多个则默认为第一个
  46. //循环series时seriesIndex指定循环的series,不指定则从0开始循环所有series,指定单个则相当于不循环,指定多个
  47. //要不要添加开始series索引和开始的data索引?
  48. if (options) {
  49. options.interval = options.interval || defaultOptions.interval;
  50. options.loopSeries = options.loopSeries || defaultOptions.loopSeries;
  51. options.seriesIndex = options.seriesIndex || defaultOptions.seriesIndex;
  52. options.updateData = options.updateData || defaultOptions.updateData;
  53. } else {
  54. options = defaultOptions;
  55. }
  56. //如果设置的seriesIndex无效,则默认为0
  57. if (options.seriesIndex < 0 || options.seriesIndex >= seriesLen) {
  58. seriesIndex = 0;
  59. } else {
  60. seriesIndex = options.seriesIndex;
  61. }
  62. /**
  63. * 清除定时器
  64. */
  65. function clearLoop() {
  66. if (timeTicket) {
  67. clearInterval(timeTicket);
  68. timeTicket = 0;
  69. }
  70. chart.off('mousemove', stopAutoShow);
  71. zRender.off('mousemove', zRenderMouseMove);
  72. zRender.off('globalout', zRenderGlobalOut);
  73. }
  74. /**
  75. * 取消高亮
  76. */
  77. function cancelHighlight() {
  78. /**
  79. * 如果dataIndex为0表示上次系列完成显示,如果是循环系列,且系列索引为0则上次是seriesLen-1,否则为seriesIndex-1;
  80. * 如果不是循环系列,则就是当前系列;
  81. * 如果dataIndex>0则就是当前系列。
  82. */
  83. let tempSeriesIndex = dataIndex === 0 ?
  84. (options.loopSeries ?
  85. (seriesIndex === 0 ? seriesLen - 1 : seriesIndex - 1)
  86. : seriesIndex)
  87. : seriesIndex;
  88. let tempType = chartOption.series[tempSeriesIndex].type;
  89. if (tempType === 'pie' || tempType === 'radar') {
  90. chart.dispatchAction({
  91. type: 'downplay',
  92. seriesIndex: lastShowSeriesIndex,
  93. dataIndex: lastShowDataIndex
  94. });//wait 系列序号为0且循环系列,则要判断上次的系列类型是否是pie、radar
  95. }
  96. }
  97. /**
  98. * 自动轮播tooltip
  99. */
  100. function autoShowTip() {
  101. let invalidSeries = 0;
  102. let invalidData = 0;
  103. function showTip() {
  104. //判断是否更新数据
  105. if (dataIndex === 0 && !first && typeof options.updateData === "function") {
  106. options.updateData();
  107. chart.setOption(chartOption);
  108. }
  109. let series = chartOption.series;
  110. let currSeries = series[seriesIndex];
  111. if (!series || series.length === 0 ||
  112. !currSeries || !currSeries.type || !currSeries.data ||
  113. !currSeries.data.length) {
  114. return;
  115. }
  116. chartType = currSeries.type; // 系列类型
  117. dataLen = currSeries.data.length; // 某个系列的数据个数
  118. let tipParams = {seriesIndex: seriesIndex};
  119. switch (chartType) {
  120. case 'pie':
  121. case 'map':
  122. case 'chord':
  123. tipParams.name = currSeries.data[dataIndex].name;
  124. break;
  125. case 'radar': // 雷达图
  126. tipParams.seriesIndex = seriesIndex;
  127. tipParams.dataIndex = dataIndex;
  128. break;
  129. default:
  130. tipParams.dataIndex = dataIndex;
  131. break;
  132. }
  133. if (chartType === 'pie' || chartType === 'radar') {
  134. if (!first) {
  135. cancelHighlight();
  136. }
  137. // 高亮当前图形
  138. chart.dispatchAction({
  139. type: 'highlight',
  140. seriesIndex: seriesIndex,
  141. dataIndex: dataIndex
  142. });
  143. }
  144. // 显示 tooltip
  145. tipParams.type = 'showTip';
  146. // 防止updateData时先处理tooltip后刷新数据导出tooltip显示不正确
  147. setTimeout(() => {
  148. chart.dispatchAction(tipParams);
  149. }, 0);
  150. lastShowSeriesIndex = seriesIndex;
  151. lastShowDataIndex = dataIndex;
  152. dataIndex = (dataIndex + 1) % dataLen;
  153. if (options.loopSeries && dataIndex === 0) { // 数据索引归0表示当前系列数据已经循环完
  154. invalidData = 0;
  155. seriesIndex = (seriesIndex + 1) % seriesLen;
  156. if (seriesIndex === options.seriesIndex) {
  157. invalidSeries = 0;
  158. }
  159. }
  160. first = false;
  161. }
  162. showTip();
  163. timeTicket = setInterval(showTip, options.interval);
  164. }
  165. // 关闭轮播
  166. function stopAutoShow() {
  167. if (timeTicket) {
  168. clearInterval(timeTicket);
  169. timeTicket = 0;
  170. if (chartType === 'pie' || chartType === 'radar') {
  171. cancelHighlight();
  172. }
  173. }
  174. }
  175. let zRender = chart.getZr();
  176. function zRenderMouseMove(param) {
  177. if (param.event) {
  178. //阻止canvas上的鼠标移动事件冒泡
  179. param.event.cancelBubble = true;
  180. }
  181. stopAutoShow();
  182. }
  183. // 离开echarts图时恢复自动轮播
  184. function zRenderGlobalOut() {
  185. if (!timeTicket) {
  186. autoShowTip();
  187. }
  188. }
  189. // 鼠标在echarts图上时停止轮播
  190. chart.on('mousemove', stopAutoShow);
  191. zRender.on('mousemove', zRenderMouseMove);
  192. zRender.on('globalout', zRenderGlobalOut);
  193. autoShowTip();
  194. return {
  195. clearLoop: clearLoop
  196. };
  197. };
  198. })(window);