Echarts灵活度封装,别被造轮子束缚了

1.下载echarts

下载 yarn add echarts vue-echarts 进行下载

2.进行ts+vue3类型封装

封装目的:

在每次使用echarts时不再需要每次进行引入,但是保留option的自主权,data按照echarts指定格式传参即可。

进行封装:

将echarts进行按需引入

import { ref, watchEffect, onMounted, onUnmounted } from 'vue';
import * as echarts from 'echarts/core';
import { EChartsOption } from 'echarts/types/dist/shared';
import {
  TooltipComponent,
  LegendComponent,
  TitleComponent,
  GridComponent
} from 'echarts/components';
import { PieChart, BarChart, LineChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';

echarts.use([
  PieChart,
  BarChart,
  LineChart,
  TooltipComponent,
  LegendComponent,
  CanvasRenderer,
  TitleComponent,
  GridComponent
]);

可以做成自动化引入,比如由父组件决定引入哪种图表,但是此项目仅仅是使用echarts的基本功能,不做此自动化引入

ts类型传参:

interface EchartProps {
  chartOptions: EChartsOption;
  chartType?: string;
  chartHeight?: string;
  chartWidth?: string;
  chartData?: any;
  xAxisData?: any;
  xAxisType?: any;
}
const props: EchartProps = defineProps({
  // 传递宽度
  chartWidth: {
    type: String,
    default: '100%'
  },
  // 传递高度
  chartHeight: {
    type: String,
    default: '400px'
  },
  // 传递数据
  chartData: {
    type: Array,
    default: []
  },
  // 传递配置
  chartOptions: {
    type: Object,
    default: () => ({})
  },
  // 传递图表类型
  chartType: {
    type: String,
    default: 'pie'
  },
  // 传递x轴数据
  xAxisData: {
    type: Array,
    default: () => []
  },
  xAxisType: {
    type: String,
    default: 'category'
  }
});

这里传入的类型都由 EchartsProps进行约束。

初始化实例:

const chart = ref<HTMLElement | null>(null);
const pieOption = ref();
// 初始化图表
const createChart = () => {
  // 如果没有传递数据则不渲染图表
  if (!chart.value) return;
  // 初始化图表
  const instance = echarts.init(chart.value);
  // 设置图表配置
  instance.setOption(generateOptions());

  // 监听窗口大小变化
  window.onresize = function () {
    instance.resize();
  };
};

这里需要注意的点是向Echarts推送父组件的值,此处不能直接将data和option一起使用setOption,如果出现没有data的情况,多半是这里出现问题。

销毁实例:

// 销毁图表
const destroyChart = () => {
  if (!chart.value) return;
  const instance = echarts.getInstanceByDom(chart.value);
  if (instance) {
    instance.dispose();
  }
};

每次关闭页面时进行销毁实例。释放内存

添加effectWatch,监听每次数据变化时,echarts进行变化

// 监听数据变化,重新渲染图表
watchEffect(() => {
  // 如果没有传递数据则不渲染图表
  if (!chart.value) return;
  // 获取图表实例
  const instance = echarts.getInstanceByDom(chart.value as HTMLElement);
  if (instance) {
    // 重新渲染图表
    instance.setOption(generateOptions());
  }
});

如果仔细看的话会发现在初始化和监听数据变化的时候会触发一个generateOptions的函数,此函数是针对数据进行配置

// 生成图表配置
const generateOptions = () => {
  // 默认配置
  let options: EChartsOption = {};
  // 根据图表类型生成配置
  switch (props.chartType) {
    case 'bar':
      // 合并配置
      options = {
        ...props.chartOptions,
        // 设置x轴数据
        xAxis: {
          type: props.xAxisType,
          data: props.xAxisData,
          ...(props.chartOptions.xAxis || {})
        },
        // 设置图表类型,数据展示
        series: [
          {
            type: 'bar',
            data: props.chartData,
            ...((props.chartOptions.series as object) || {})
          }
        ]
      };
      break;
    case 'line':
      options = {
        ...props.chartOptions,
        // 设置x轴数据
        xAxis: {
          type: 'category',
          data: props.xAxisData
        },
        // 设置图表类型,数据展示
        series: [
          {
            type: 'line',
            data: props.chartData,
            ...((props.chartOptions.series as object) || {})
          }
        ]
      };
      break;
    case 'pie':
    default:
      options = {
        ...props.chartOptions,
        series: [
          {
            type: 'pie',
            data: props.chartData,
            ...((props.chartOptions.series as object) || {})
          }
        ]
      };
      pieOption.value = options;
      break;
  }


  return options;
};

需要注意的是为了满足需求,在父组件传递配置的时候需要将series更改为

series: {
    name: 'Access From',
    type: 'pie',
    radius: '50%',
    avoidLabelOverlap: false,
    emphasis: {
      itemStyle: {
        shadowBlur: 10,
        shadowOffsetX: 0,
        shadowColor: 'rgba(0, 0, 0, 0.5)'
      }
    },
    labelLine: {
      show: false
    },
    label: {
      show: false,
      position: 'center'
    }
  }

在echarts中的格式是serise=[{}]的格式,但是我们进行了解构赋值,所以更改一下格式。如果有特殊需求可以视情况更改

调用的格式为

<echarts
      :chartData="chartBarData"
      :chartOptions="chartBarOptions"
      :chartWidth="'100%'"
      :xAxisData="xAxisBarData"
      :chartType="'bar'"
    ></echarts>

全部代码为:

<template>
  <div
    ref="chart"
    :style="{ width: props.chartWidth, height: props.chartHeight }"
    v-if="props.chartData"
  ></div>
</template>


<script setup lang="ts">
import { ref, watchEffect, onMounted, onUnmounted } from 'vue';
import * as echarts from 'echarts/core';
import { EChartsOption } from 'echarts/types/dist/shared';
import {
  TooltipComponent,
  LegendComponent,
  TitleComponent,
  GridComponent
} from 'echarts/components';
import { PieChart, BarChart, LineChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';


echarts.use([
  PieChart,
  BarChart,
  LineChart,
  TooltipComponent,
  LegendComponent,
  CanvasRenderer,
  TitleComponent,
  GridComponent
]);


interface EchartProps {
  chartOptions: EChartsOption;
  chartType?: string;
  chartHeight?: string;
  chartWidth?: string;
  chartData?: any;
  xAxisData?: any;
  xAxisType?: any;
}
const props: EchartProps = defineProps({
  // 传递宽度
  chartWidth: {
    type: String,
    default: '100%'
  },
  // 传递高度
  chartHeight: {
    type: String,
    default: '400px'
  },
  // 传递数据
  chartData: {
    type: Array,
    default: []
  },
  // 传递配置
  chartOptions: {
    type: Object,
    default: () => ({})
  },
  // 传递图表类型
  chartType: {
    type: String,
    default: 'pie'
  },
  // 传递x轴数据
  xAxisData: {
    type: Array,
    default: () => []
  },
  xAxisType: {
    type: String,
    default: 'category'
  }
});


const chart = ref<HTMLElement | null>(null);
const pieOption = ref();
// 初始化图表
const createChart = () => {
  // 如果没有传递数据则不渲染图表
  if (!chart.value) return;
  // 初始化图表
  const instance = echarts.init(chart.value);
  // 设置图表配置
  instance.setOption(generateOptions());


  // 监听窗口大小变化
  window.onresize = function () {
    instance.resize();
  };
};


// 销毁图表
const destroyChart = () => {
  if (!chart.value) return;
  const instance = echarts.getInstanceByDom(chart.value);
  if (instance) {
    instance.dispose();
  }
};


// 生成图表配置
const generateOptions = () => {
  // 默认配置
  let options: EChartsOption = {};
  // 根据图表类型生成配置
  switch (props.chartType) {
    case 'bar':
      // 合并配置
      options = {
        ...props.chartOptions,
        // 设置x轴数据
        xAxis: {
          type: props.xAxisType,
          data: props.xAxisData,
          ...(props.chartOptions.xAxis || {})
        },
        // 设置图表类型,数据展示
        series: [
          {
            type: 'bar',
            data: props.chartData,
            ...((props.chartOptions.series as object) || {})
          }
        ]
      };
      break;
    case 'line':
      options = {
        ...props.chartOptions,
        // 设置x轴数据
        xAxis: {
          type: 'category',
          data: props.xAxisData
        },
        // 设置图表类型,数据展示
        series: [
          {
            type: 'line',
            data: props.chartData,
            ...((props.chartOptions.series as object) || {})
          }
        ]
      };
      break;
    case 'pie':
    default:
      options = {
        ...props.chartOptions,
        series: [
          {
            type: 'pie',
            data: props.chartData,
            ...((props.chartOptions.series as object) || {})
          }
        ]
      };
      pieOption.value = options;
      break;
  }


  return options;
};


// 监听数据变化,重新渲染图表
watchEffect(() => {
  // 如果没有传递数据则不渲染图表
  if (!chart.value) return;
  // 获取图表实例
  const instance = echarts.getInstanceByDom(chart.value as HTMLElement);
  if (instance) {
    // 重新渲染图表
    instance.setOption(generateOptions());
  }
});


onMounted(() => {
  createChart();
});


onUnmounted(() => {
  destroyChart();
});
</script>


<style scoped>
.echarts-chart {
  width: 100%;
  height: 100%;
}
</style>

总结:此次封装仅仅为初步封装,暂时没有考虑更多的情况,但是针对基本情况是够用的。并且灵活度很高,并没有进行二次封装。针对折线图,柱状图和饼状图都可以直接调用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于echarts折线图的封装,可以参考以下步骤: 1. 引入echarts库和封装所需的数据 2. 创建一个div容器,设置宽高 3. 初始化echarts实例,并设置基本配置项 4. 封装数据,包括x轴数据、y轴数据、图例名称等 5. 设置折线图的配置项,包括颜色、线条样式、标记点等 6. 将封装好的数据和配置项传入echarts实例中 7. 渲染折线图 以下是一个简单的示例代码: ```javascript // 引入echarts库和封装所需的数据 import echarts from 'echarts' import data from './data' // 创建一个div容器,设置宽高 const container = document.getElementById('chart') container.style.width = '600px' container.style.height = '400px' // 初始化echarts实例,并设置基本配置项 const chart = echarts.init(container) const option = { title: { text: '折线图' }, tooltip: {}, legend: { data: [] }, xAxis: { data: [] }, yAxis: {}, series: [] } // 封装数据,包括x轴数据、y轴数据、图例名称等 option.legend.data = data.legend option.xAxis.data = data.xAxis for (let i = 0; i < data.series.length; i++) { option.series.push({ name: data.legend[i], type: 'line', data: data.series[i] }) } // 设置折线图的配置项,包括颜色、线条样式、标记点等 option.series.forEach(item => { item.lineStyle = { color: '#1890ff' } item.itemStyle = { color: '#1890ff' } item.label = { show: true } }) // 将封装好的数据和配置项传入echarts实例中 chart.setOption(option) // 渲染折线图 chart.render() ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值