【echarts】堆叠柱形图

发布于:2025-06-05 ⋅ 阅读:(26) ⋅ 点赞:(0)

主要功能

  1. 数据可视化:以堆叠柱形图形式展示两组数据(销售和技术)的月度分布情况。
  2. 响应式设计:图表会根据窗口大小自动调整。
  3. 数据交互:鼠标悬停时显示详细数据(包括每项的具体数值和总计)。
  4. 数据更新:当传入的 props 数据变化时,图表会自动更新。

 组件代码

<template>
  <div class="chart-container" ref="chartRef"></div>
</template>
  
  <script setup>
import { ref, onMounted, watch } from "vue";
import * as echarts from "echarts";

const props = defineProps({
  // 接收秘密和机密数据
  secretData: {
    type: Array,
    default: () => [],
  },
  confidentialData: {
    type: Array,
    default: () => [],
  },
  // 可选:自定义标题
  title: {
    type: String,
    default: "堆叠柱形图",
  },
  // 可选:自定义x轴标签
  xAxisLabels: {
    type: Array,
    default: () => [
      "一月",
      "二月",
      "三月",
      "四月",
      "五月",
      "六月",
      "七月",
      "八月",
      "九月",
      "十月",
      "十一月",
      "十二月",
    ],
  },
});

const chartRef = ref(null);
let chartInstance = null;

// 初始化图表
const initChart = () => {
  if (!chartRef.value) return;

  chartInstance = echarts.init(chartRef.value);

  const option = {
    backgroundColor: "#fff",
    title: {
      text: props.title,
      left: "center",
      textStyle: {
        color: "#333",
        fontSize: 16,
      },
    },
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "cross",
        crossStyle: {
          color: "#999",
        },
      },
      formatter: (params) => {
        let result = `<div class="font-bold">${params[0].name}</div>`;
        let total = 0;

        params.forEach((param) => {
          total += param.value;
          result += `<div class="flex items-center">
              <span class="inline-block w-3 h-3 rounded-full mr-2" style="background-color: ${param.color}"></span>
              ${param.seriesName}: ${param.value}
            </div>`;
        });

        result += `<div class="font-bold mt-1">总计: ${total}</div>`;
        return result;
      },
    },
    legend: {
      data: ["销售", "技术"],
      top: "5%",
      right: "0",
      itemWidth: 10,
      itemHeight: 10,
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      data: props.xAxisLabels,
      axisTick: false,
      axisLabel: {
        color: "#999999",
      },
      axisLine: {
        show: true, // 显示轴线
        lineStyle: {
          color: "#DDDDDD", // 轴线颜色
          width: 1, // 轴线宽度
          type: "solid", // 轴线样式:solid, dashed, dotted
        },
      },
    },
    yAxis: {
      type: "value",
      min: 0,
      axisLabel: {
        formatter: "{value}",
        color: "#999999",
      },
      splitLine: {
        show: false, // 隐藏y轴横线(网格线)
      },
    },
    series: [
      {
        name: "销售",
        type: "bar",
        stack: "总量",
        data: props.secretData,
        color: "#FC1705",
        barWidth: "30%",
      },
      {
        name: "技术",
        type: "bar",
        stack: "总量",
        data: props.confidentialData,
        color: "#970E02",
        barWidth: "30%",
      },
    ],
  };

  chartInstance.setOption(option);

  // 监听窗口大小变化,调整图表
  window.addEventListener("resize", () => {
    if (chartInstance) chartInstance.resize();
  });
};

// 初始化和更新图表
onMounted(() => {
  initChart();
});

// 监听props变化,更新图表
watch([() => props.secretData, () => props.confidentialData], () => {
  if (chartInstance) {
    chartInstance.setOption({
      series: [
        {
          data: props.secretData,
        },
        {
          data: props.confidentialData,
        },
      ],
    });
  }
});

// 组件卸载时销毁图表
onUnmounted(() => {
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
});
</script>
  
  <style scoped>
.chart-container {
  width: 100%;
  height: 360px;
  margin: 0 auto;
}
</style>

组件引用

<StackedBarChart
    :secretData="[0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0]"
    :confidentialData="[0, 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 0]"
/>


网站公告

今日签到

点亮在社区的每一天
去签到