echarts 二次封装 本期 echarts折线图, 使用起来很方便

273 阅读2分钟

大概是这样 image.png

从后端返回的数据讲起。

下一期 双轴,左右坐标轴轴线对齐

image.png

如果你们后端返回的数据是这样的 这里只是模拟的,根据实际情况修改

  let data = {
    code: '200',
    message: '',
    data: [
      {
        mincellvoltage: '3.33',
        maxcellvoltage: '3.42',
        ts: '2024-12-03 06:50:14',
      },
      {
        mincellvoltage: '3.33',
        maxcellvoltage: '3.42',
        ts: '2024-12-03 06:50:24',
      },
      {
        mincellvoltage: '3.33',
        maxcellvoltage: '3.42',
        ts: '2024-12-03 06:50:34',
      },
    ],
    ext: {},
    success: true,
  };

页面中可以这样用

<LineCharts :datas="chartDetialList.VoltageData" />

// 自己定义接收的对象
const chartDetialList = reactive({
  VoltageData: {},
});

async function getVoltage() {
// 接口拿到数据
  let data = {
    code: '200',
    message: '',
    data: [
      {
        mincellvoltage: '3.33',
        maxcellvoltage: '3.42',
        ts: '2024-12-03 06:50:14',
      },
      {
        mincellvoltage: '3.33',
        maxcellvoltage: '3.42',
        ts: '2024-12-03 06:50:24',
      },
    ],
    ext: {},
    success: true,
  };
  // 折线图的点位
  let keys = [
    {
      label: 'maxcellvoltage',
      name: '预测',
      colors: [239, 189, 12],   // 这里是 rgba 格式的颜色前三个, 因为折线是100%颜色,面积是10% 的颜色,如有需要用原本的可以到子组件修改
      unit: 'MW',
      legend: true,
    },
    {
      label: 'mincellvoltage',
      name: '计划',
      colors: [172, 227, 147],
      unit: 'MW',
      legend: true,
    },
  ];
  chartDetialList.VoltageData = handleChartData(data.data, keys, 'ts');
}

// 这里可以放到项目中公共函数的地方  单轴 图表数据组装处理  data 第一个值是后端返回的数据 / keys 上面定义的数据格式 / xkeys 这是横坐标的 key '我上面的是 ts'
 const handleChartData = (data, keys, xkeys) => {
  let xData = [];
  let seriesData = {};

  keys.forEach((x) => {
    seriesData[x.label] = {
      name: x.name,
      data: [],
      unit: x.unit,
      colors: x.colors,
      legend: x.legend || null,
    };
  });

  data.forEach((item) => {
    xData.push(item[xkeys]);
    keys.forEach((x) => {
      seriesData[x.label].data.push(item[x.label]);
    });
  });
  return {
    xData,
    seriesData,
  };
};


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

子组件这样用 注意有 import dayjs from 'dayjs';

<template>
  <div class="w-100% h-100%" ref="myChart"></div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts';
import dayjs from 'dayjs';
const props = defineProps({
  // 传入的参数
  datas: {
    type: Object,
    default: () => {},
  },
});
watch(
  () => props.datas,
  (newVal) => {
    initChart();
  },
  { deep: true }
);
const myChart = ref(null);

function initChart() {
  let legendData = [];
  let seriesData = [];
  for (const key in props.datas.seriesData) {
    if (props.datas.seriesData[key].legend) {
      legendData.push({
        name: props.datas.seriesData[key].name,
        icon: 'circle',
        itemStyle: {
          color: `rgba(${props.datas.seriesData[key].colors.join(',')},1)`,
        },
      });
    }
    seriesData.push({
      name: props.datas.seriesData[key].name,
      type: 'line',
      //需要面积的可以把下面放开
      //   areaStyle: {
      //     color: {
      //       type: 'linear',
      //       x: 0,
      //       y: 0,
      //       x2: 0,
      //       y2: 1,
      //       colorStops: [
      //         {
      //           offset: 0,
      //           color: `rgba(${props.datas.seriesData[key].colors.join(
      //             ','
      //           )},0.1)`,
      //         },
      //         {
      //           offset: 1,
      //           color: `rgba(${props.datas.seriesData[key].colors.join(',')},0)`,
      //         },
      //       ],
      //     },
      //   },
      lineStyle: {
       // 这里是线的样式,我业务有个基线内容
        type: props.datas.seriesData[key].name == '基线' ? 'dashed' : 'solid',
       
        color: `rgba(${props.datas.seriesData[key].colors.join(',')},1)`,
      },
      itemStyle: {
        color: `rgba(${props.datas.seriesData[key].colors.join(',')},1)`,
      },
      smooth: true,
      unit: props.datas.seriesData[key].unit,
      data: props.datas.seriesData[key].data,
    });
  }
  let chartDom = myChart.value;
  let myCharts = echarts.init(chartDom);
  let option = {
  // 这里可以修改echarts 在div 中占位的左右上下编辑
    grid: {
      left: '3%',
      right: '3%',
      bottom: '15%',
      top: '13%',
      containLabel: true,
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        label: {
          backgroundColor: '#6a7985',
        },
      },
    },
    legend: {
      show: legendData.length > 0,
      data: legendData,
      top: 0,
      itemHeight: 10,
      itemWidth: 10,
      left: 'center',
      width: '100%',
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      axisLine: {
        lineStyle: {
          color: '#86909C',
        },
      },
      axisLabel: {
        formatter: function (value, index) {
        // 这里有时间格式 
          return dayjs(value).format('HH:mm');
        },
      },
      data: props.datas?.xData,
    },
    yAxis: {
      name: seriesData.length > 0 ? seriesData[0].unit : '',
      type: 'value',
    },
    series: seriesData,
  };

  option && myCharts.setOption(option);
  
  // 动态页面变大变小
  const observer = new ResizeObserver(() => {
    myCharts.resize();
  });
  observer.observe(chartDom);
}

onMounted(() => {
  initChart();
});
</script>