需求

大屏项目需要让元素动起来才好看,因此条形需要自动轮播,鼠标移入后停止轮播,移除后再次开始轮播。

效果

echarts 自动轮播.gif

代码

  1. import React, { useEffect, useRef, useState } from 'react';
  2. import { useInterval, useUpdateEffect, useHover } from 'ahooks';
  3. import * as echarts from 'echarts';
  4. const timing = 1500;
  5. const yDataSource = ['Mon', 'Tue', 'Wed', 'Thu'];
  6. const xDataSource = [
  7. {
  8. name: 'Affiliate Ad',
  9. data: [220, 182, 191, 234],
  10. },
  11. {
  12. name: 'Video Ad',
  13. data: [150, 212, 201, 154],
  14. },
  15. {
  16. name: 'Search Engine',
  17. data: [820, 832, 901, 934],
  18. },
  19. ];
  20. const option: echarts.EChartsOption = {
  21. title: {
  22. text: '堆叠条形图',
  23. },
  24. tooltip: {
  25. trigger: 'axis',
  26. axisPointer: {
  27. type: 'shadow',
  28. },
  29. },
  30. legend: {
  31. // data: ['Affiliate Ad', 'Video Ad', 'Search Engine'],
  32. show: true,
  33. top: 30,
  34. },
  35. grid: {
  36. left: '3%',
  37. right: '5%',
  38. bottom: '3%',
  39. containLabel: true,
  40. },
  41. xAxis: {
  42. type: 'value',
  43. },
  44. yAxis: {
  45. type: 'category',
  46. data: yDataSource,
  47. },
  48. series: xDataSource.map((item) => ({
  49. name: item.name,
  50. data: item.data,
  51. type: 'bar',
  52. stack: 'total',
  53. barWidth: '50%',
  54. label: {
  55. show: true,
  56. },
  57. emphasis: {
  58. focus: 'series',
  59. blurScope: 'coordinateSystem',
  60. },
  61. })),
  62. };
  63. export default () => {
  64. const chartRef = useRef<any>();
  65. const myChart = useRef<echarts.ECharts>();
  66. const [interval, setInterval] = useState<number | undefined>(undefined);
  67. const [count, setCount] = useState(0);
  68. const setTooltip = (index: number) => {
  69. if (myChart.current) {
  70. myChart.current.dispatchAction({
  71. type: 'hideTip',
  72. });
  73. myChart.current.dispatchAction({
  74. type: 'showTip',
  75. seriesIndex: 0,
  76. dataIndex: index,
  77. });
  78. }
  79. };
  80. // 移入时取消轮播
  81. const isHovering = useHover(() => chartRef.current);
  82. useUpdateEffect(() => {
  83. setInterval(isHovering ? undefined : timing);
  84. }, [isHovering]);
  85. // 自动轮播
  86. useInterval(() => {
  87. setCount((prev) => (prev >= yDataSource?.length - 1 ? 0 : prev + 1));
  88. }, interval);
  89. useUpdateEffect(() => {
  90. setTooltip(count);
  91. }, [count]);
  92. useEffect(() => {
  93. if (!myChart.current && chartRef?.current) {
  94. myChart.current = echarts.init(chartRef.current);
  95. if (myChart?.current) {
  96. myChart.current.setOption(option);
  97. setTooltip(0);
  98. setInterval(timing);
  99. }
  100. }
  101. }, []);
  102. return <div style={{ width: '100%', height: '100%' }} ref={chartRef} />;
  103. };

出现的问题

echarts 自带 mouseover 在鼠标移入画布时不生效,即使使用了 getZr() 依然不生效。事件只会在鼠标移入某个具体区域才生效,移入画布空白区域不生效。(click、mouseout 等其他事件有效)
因此不用自带的鼠标事件,而是用 ahooks 中的 useHover 事件进行监听。