echarts柱状图、折线图自动滚动

定义一些option

// 滑动条,一个页面展示5条数据
const sliderDataZoom = [
  {
    type: 'slider',
    height: 8,
    bottom: 0,
    zoomLock: true,
    borderColor: '#fff',
    fillerColor: '#e4e4e4',
    showDataShadow: false,
    textStyle: false,
    startValue: 0,
    endValue: 4,
  },
];
// 不用滑动条
const noDataZoom = [
  {
    show: false,
  },
];

// 重新渲染时,不改变的部分
const invariantOption = {
  grid: {
    left: 0,
    right: 0,
    top: 40,
    bottom: 18,
    containLabel: true,
  },
  tooltip: {
    trigger: 'axis',
  },
  color: ['#3388FF', '#FF9900', '#11C79B', '#FF9900', '#11C79B'],
  legend: {
    show: true,
    textStyle: {
      fontSize: '.14rem',
      color: '#223355',
    },
    data: ['指标1', '指标2', '指标3', '指标4', '指标5'],
  },
  yAxis: [
    {
      type: 'value',
      position: 'left', // 左边的比例尺
      axisLabel: {
        textStyle: {
          color: '#223254',
          fontSize: '.14rem',
        },
      },
      axisTick: {
        show: false,
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: '#EEE',
          type: 'dashed',
        },
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: '#EEE',
          type: 'dashed',
        },
      },
    },
    {
      type: 'value',
      position: 'right', // 右边的比例尺
      axisLabel: {
        textStyle: {
          color: '#223254',
          fontSize: '.14rem',
        },
        formatter: '{value}%',
      },
      axisTick: {
        show: false,
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: '#EEE',
          type: 'dashed',
        },
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: '#EEE',
          type: 'dashed',
        },
      },
      min: 0,
      max: 100,
    },
  ],
};

得到Option的函数

const [option, setOption] = useState({});

const getOption = (list) => {
  let xAxisData = [];
  let lineData1 = [];
  let lineData2 = [];
  let lineData3 = [];
  let lineData4 = [];
  let lineData5 = [];
  list.forEach((element) => {
    xAxisData.push(element.xLabelName);
    lineData1.push(element.xxxx1);
    lineData2.push(element.xxxx2);
    lineData3.push(element.xxxx3);
    lineData4.push(parseFloat(element.xxxxRate1.split('%')[0])); // 字符串转为数字,才能正确展示折线图
    lineData5.push(parseFloat(element.xxxxRate2.split('%')[0]));
  });
  const newOption = {
    ...invariantOption,
    dataZoom: list.length > 5 ? sliderDataZoom : noDataZoom,
    xAxis: [
      {
        axisLabel: {
          interval: 0,
          textStyle: {
            color: '#223254',
            fontSize: '.14rem',
          },
          formatter: (value) => {
            value = value || '';
            return value.length > 5 ? value.slice(0, 5) + '\n' + value.slice(5) : value; // xLabelName换行
          },
        },
        axisTick: {
          show: false,
        },
        axisLine: {
          show: false,
        },
        data: xAxisData,
      },
    ],
    series: [
      {
        name: 'xxxx1',
        type: 'bar', // 柱状图
        data: lineData1,
        barWidth: '10',
        yAxisIndex: 0,
      },
      {
        name: 'xxxx2',
        type: 'bar',
        data: lineData2,
        barWidth: '10',
      },
      {
        name: 'xxxx3',
        type: 'bar',
        data: lineData3,
        barWidth: '10',
      },
      {
        name: 'xxxx4',
        type: 'line', // 折线图
        data: lineData4,
        yAxisIndex: 1,
      },
      {
        name: 'xxxx5',
        type: 'line',
        data: lineData5,
      },
    ],
  };
  setOption(newOption);
  return new Promise((resolve) => {
  	// 确保option已经更新(主要为了更新滑动条是否展示)
    resolve();
  });
};

获取展示数据,然后调用上诉函数

const getRegionStatisticsData = () => {
  const params = {};
  // 调用封装的接口
  api()
    .getRegionStatistics(params)
    .then((res) => {
      const list = res?.data?.list || [];
      getOption(list).then(() => {
      	// 更新完option再更新数据
        setRegionStatistics(list);
      });
    });
};

自动滚动

const timerRef = useRef(); // 用ref实例,注销时可确保清除

useEffect(() => {
  if (timerRef.current) {
     clearInterval(timerRef.current);
     timerRef.current = null;
   }
  if (regionStatistics?.length > 0 && option?.dataZoom?.length > 0 && option.dataZoom[0].endValue) {
  	// 有数据,且展示滑动条
    setTimeout(() => {
      // 等待页面其他模块加载,按需选择是否需要setTimeout
      const intervalTimer = setInterval(() => {
      	// 间隔一段时间自动滚动一项
        let transOption = { ...option };
        const position = option.dataZoom[0];
        if (position.endValue === regionStatistics.length - 1) {
          transOption.dataZoom[0].endValue = 4;
          transOption.dataZoom[0].startValue = 0;
          setOption(transOption);
        } else {
          transOption.dataZoom[0].endValue = position.endValue + 1;
          transOption.dataZoom[0].startValue = position.startValue + 1;
          setOption(transOption);
        }
      }, 3500);
      timerRef.current = intervalTimer;
    }, 3000);
  }
}, [regionStatistics]);

useEffect(() => {
  return () => {
  	// 注销组件时清除定时器
    if (timerRef.current) {
      clearInterval(timerRef.current);
      timerRef.current = null;
    }
  };
}, []);

const onClearTimer = () => {
  if (timerRef.current) {
     clearInterval(timerRef.current);
     timerRef.current = null;
   }
};

Echarts组件

  1. 点击每一项,跳转至详情页面
  2. 鼠标点击滑动条后,停止自动滚动
<ReactEcharts
   style={{ width: '100%', height: '100%' }}
   option={option}
   onEvents={{
     click: onGotoRegionStatistics,
     dataZoom: onClearTimer,
   }}
 />

你可能感兴趣的:(前端,javascript,前端,开发语言)