优雅在vue3中使用echarts

step.1 按需引入

// plugins/echarts
import * as echarts from "echarts/core";
import { BarChart, PieChart, LineChart } from "echarts/charts";
import { TooltipComponent, GridComponent, LegendComponent, TitleComponent } from "echarts/components";
import { CanvasRenderer, SVGRenderer } from "echarts/renderers";
import echartsTheme from "./echartsTheme";
// import eventBus from "@/libs/eventBus";
// let echartsThemeKey = 1;
// 注入自定义主题
echarts.registerTheme("customed", echartsTheme);
// 注册必须的组件
echarts.use([BarChart, PieChart, TooltipComponent, GridComponent, LegendComponent, TitleComponent, CanvasRenderer, SVGRenderer, LineChart]);

export default echarts;

step.2 配置全局自定义样式

// plugins/echartsTheme
const echartsTheme = {
  color: ["#07C3FF", "#FFB821", "#FF6A98", "#F2877F", "#958EED", "#FFA5D6", "#fc8452", "#9a60b4", "#ea7ccc"],
  backgroundColor: "rgba(0, 0, 0, 0)",
  textStyle: {},
  title: {
    textStyle: {
      color: "#D9E7FF",
    },
    subtextStyle: {
      color: "#6E7079",
    },
  },
  bar: {
    ..
  },
  pie: {
    ...
  },
  // 类目轴
  categoryAxis: {
    ...
  },
  // 数值轴
  valueAxis: {
   .....
  },
  toolbox: {
    ...
  },
  // 图例
  legend: {
    ...
  },
  // 提示框
  tooltip: {
    axisPointer: {
      lineStyle: {
        color: "#ccc",
        width: px1,
      },
      crossStyle: {
        color: "#ccc",
        width: px1,
      },
    },
    textStyle: {
      color: "#D9E7FF",
      fontSize: px12,
    },

    backgroundColor: "rgba(3, 41, 55, 0.8)",
    borderColor: "#4ba9f5",
    padding: [px10, px10],
    borderWidth: px1,
    extraCssText: `border-radius:${px8}px;`,
  },
  dataZoom: {
   ...
  },
  markPoint: {
    ...
  },
};
export default echartsTheme;

step.3 基础渲染&卸载钩子

// useEcharts.js
// 可以在此钩子中添加eventBus~

import echarts from "@/plugins/echarts";
import { onBeforeUnmount, onMounted, ref, shallowRef } from "vue";
export default () => {
  let tempOption = null;
  const chartRef = ref(null),
    chartObj = shallowRef(null);
  /**
   * @description: 载入echarts
   */
  function init(themeName = "customed") {
    if (chartRef.value) {
      chartObj.value = echarts.init(chartRef.value, themeName, { renderer: "svg" });
      // console.log(chartObj);
    }
  }
  /**
   * @description: 销毁echarts
   * @return {*}
   */
  function dispose() {
    if (chartObj.value) chartObj.value?.dispose();
  }
  function setOption(option) {
    tempOption = option;
    chartObj.value?.setOption(option, true);
  }
  onMounted(() => {
    init();
  });
  onBeforeUnmount(() => {
    dispose();
  });
  return {
    chartRef, // ref
    setOption,// 传入option配置来渲染chart
    chartObj, // 实例对象
  };
};

step.4 自动播放钩子

// useChartAutoplay.js
/*
 * @Desc:自动播放通用hook 在获取数据后使用
 */
import { computed, onBeforeUnmount, ref } from "vue";

// showTip 自动播放是否显示提示框
// showHighlight 自动播放是否显示高亮
// customPlayFn 自动播放时的自定义fn
export default ({ chartObj, delay = 3000, showTip = false, showHighlight = false, customPlayFn = null }) => {
  let timer = null,
    maxIndex = 0;
  const activeIndex = ref(0),
    isSuspend = ref(false),
    preIndex = computed(() => {
      return activeIndex.value - 1 < 0 ? maxIndex : activeIndex.value - 1;
    });
  function createAutoPlay(dataLength) {
    if (timer) {
      clearAutoplay();
    }
    maxIndex = dataLength - 1;
    setMouseoverEvent();
    autoplayFn();
    timer = setInterval(() => {
      //   console.log("12312321");
      if (!isSuspend.value) {
        activeNext();
        autoplayFn();
      }
    }, delay);
  }
  /**
   * @description: 播放处理
   */
  function autoplayFn() {
    if (customPlayFn) {
      customPlayFn();
    }
    if (showTip) {
      handleShowTip(activeIndex.value);
    }
    if (showHighlight) {
      handleHideHighlight(preIndex.value);
      handleShowHighlight(activeIndex.value);
    }
  }
  /**
   * @description: 显示提示框
   * @param {*} dataIndex
   * @param {*} seriesIndex
   */
  function handleShowTip(dataIndex = 0, seriesIndex = 0) {
    chartObj.value?.dispatchAction({
      type: "showTip",
      seriesIndex: seriesIndex,
      playState: true,
      dataIndex: dataIndex,
    });
  }
  /**
   * @description: 显示高亮
   * @param {*} dataIndex
   * @param {*} seriesIndex
   */
  function handleShowHighlight(dataIndex = 0, seriesIndex = 0) {
    chartObj.value?.dispatchAction({
      type: "highlight",
      playState: true,
      seriesIndex: seriesIndex,
      dataIndex: dataIndex,
    });
  }
  /**
   * @description: 关闭高亮
   * @param {*} dataIndex
   * @param {*} seriesIndex
   */
  function handleHideHighlight(dataIndex = 0, seriesIndex = 0) {
    chartObj.value?.dispatchAction({
      type: "downplay",
      playState: true,
      seriesIndex: seriesIndex,
      dataIndex: dataIndex,
    });
  }
  /**
   * @description: 设置当前激活index
   * @param {number} index
   */
  function setActiveIndex(index) {
    activeIndex.value = index;
  }
  /**
   * @description: 激活下一个
   */
  function activeNext() {
    // console.log(maxIndex);
    activeIndex.value = activeIndex.value + 1 > maxIndex ? 0 : activeIndex.value + 1;
  }
  function setMouseoverEvent() {
    // 鼠标移入 暂停
    chartObj.value?.on("mouseover", () => {
      isSuspend.value = true;
    });
    // 鼠标移除 不暂停
    chartObj.value?.on("globalout", () => {
      isSuspend.value = false;
    });
  }
  /**
   * @description: 清除自动播放
   */
  function clearAutoplay() {
    activeIndex.value = 0;
    clearInterval(timer);
  }
  onBeforeUnmount(() => {
    if (timer) clearInterval(timer);
  });
  return {
    activeIndex,
    isSuspend,
    createAutoPlay, // 创建自动播放,入参为数据长度
  };
};

step.5 使用

/*
 * @Desc:
 */
import useBarChart from "@/libs/use/useEcharts";
import useChartAutoPlay from "@/libs/use/useChartAutoPlay";
import { getVerticalGradient } from "@/utils/echarts";
export default () => {
  const { chartRef, setOption, chartObj } = useBarChart();
  const { createAutoPlay } = useChartAutoPlay({
    chartObj: chartObj,
    showTip: true,
  });
  const option = {
    从echarts复制的option配置
  };
  function setCategory(arr) {
    option.xAxis.data = arr;
  }
  function createData(arr) {
    ...数据处理部分
    setOption(option);
    createAutoPlay(dataLength);
  }
  return {
    chartRef,
    setCategory,
    createData,
  };
};

step.6 在组件中使用

// some component hook
import useAreaLineChart from "@/libs/echarts/useXxxxChart";
import { onMounted } from "vue";
export default () => {
  const { chartRef, setCategory, createData } = useXxxxChart();
  function setData() {
    setTimeout(() => {
      setCategory(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]);
      createData([
        {
          name: "总数",
          data: [11, 22, 33, 44, 55, 55, 55, 55, 55, 55, 55, 55],
        },
        {
          name: "完成数",
          data: [4, 3, 5, 5, 6, 7, 8, 9, 10, 11, 12, 2],
        },
      ]);
    });
  }
  onMounted(() => {
    setData();
  });
  return {
    chartRef,
  };
};

// template
 <div  ref="chartRef"></div>

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值