将水球图写成固定组件

书接上文,把水球图写成固定组件,以下是文件格式结构:
结构如下:

src/
├── components/
│   └── LiquidFillChart.vue
├── views/
│   └── demo/
│       └── plugins/
│           └── import/
│               └── index.vue

以下是添加了详细注释的代码,帮助你更好地理解每一部分的作用:

<template>
  <!-- 卡片容器,用于包裹标题和图表 -->
  <div class="chart-card" ref="chartCard">
    <!-- 标题部分,如果传入了 title 则显示 -->
    <div v-if="title" class="chart-title">{{ title }}</div>
    <!-- 图表容器,用于渲染水球图 -->
    <div ref="chart" class="chart-container"></div>
  </div>
</template>

<script>
// 引入 echarts 和 echarts-liquidfill 插件
import * as echarts from 'echarts';
import 'echarts-liquidfill';

export default {
  name: 'LiquidFillChart', // 组件名称
  props: {
    // 标题属性,默认值为 '水球图标题'
    title: {
      type: String,
      default: '水球图标题'
    },
    // 数据属性,默认值为 [0.6, 0.5, 0.4, 0.3]
    data: {
      type: Array,
      default: () => [0.6, 0.5, 0.4, 0.3]
    },
    // 水球图半径属性,默认值为 '80%'
    radius: {
      type: String,
      default: '80%'
    }
  },
  data() {
    return {
      myChart: null // 用于存储 echarts 实例
    };
  },
  mounted() {
    // 在 DOM 更新后初始化图表,并监听窗口大小变化
    this.$nextTick(() => {
      this.initChart();
      this.adjustContainerSize();
      window.addEventListener('resize', this.resizeChart);
    });
  },
  beforeDestroy() {
    // 组件销毁前移除事件监听器并销毁图表实例
    window.removeEventListener('resize', this.resizeChart);
    if (this.myChart) {
      this.myChart.dispose();
    }
  },
  methods: {
    // 初始化图表
    initChart() {
      const chartDom = this.$refs.chart; // 获取图表容器的 DOM 元素
      this.myChart = echarts.init(chartDom); // 初始化 echarts 实例

      // 配置项
      const option = {
        series: [{
          type: 'liquidFill', // 使用水球图类型
          data: this.data, // 使用 props 中的数据
          radius: this.radius, // 使用 props 中的半径
          outline: { show: false }, // 不显示外边框
          label: {
            show: true, // 显示标签
            formatter: param => `${(param.value * 100).toFixed(0)}%`, // 格式化标签内容为百分比
            fontSize: 28, // 字体大小
            color: '#fff', // 字体颜色
            fontWeight: 'bold', // 字体加粗
            textShadow: '2px 2px 4px rgba(0, 0, 0, 0.5)' // 文字阴影
          },
          backgroundStyle: {
            color: '#E6F7FF', // 背景颜色
            borderWidth: 10, // 背景边框宽度
            borderColor: '#1890FF', // 背景边框颜色
            shadowBlur: 10, // 背景阴影模糊度
            shadowColor: 'rgba(0, 0, 0, 0.3)' // 背景阴影颜色
          },
          itemStyle: {
            color: {
              type: 'linear', // 使用线性渐变
              x: 0, // 渐变起始点 x 坐标
              y: 0, // 渐变起始点 y 坐标
              x2: 0, // 渐变结束点 x 坐标
              y2: 1, // 渐变结束点 y 坐标
              colorStops: [
                { offset: 0, color: '#1890FF' }, // 渐变起始颜色
                { offset: 1, color: '#0050B3' } // 渐变结束颜色
              ]
            },
            shadowBlur: 10, // 水球阴影模糊度
            shadowColor: 'rgba(0, 0, 0, 0.5)' // 水球阴影颜色
          }
        }]
      };

      this.myChart.setOption(option); // 设置图表配置项
    },
    // 调整图表容器大小
    resizeChart() {
      if (this.myChart) {
        this.myChart.resize(); // 调整图表大小
        this.adjustContainerSize(); // 调整容器大小
      }
    },
    // 动态调整容器大小
    adjustContainerSize() {
      this.$nextTick(() => {
        const chartCard = this.$refs.chartCard; // 获取卡片容器的 DOM 元素
        const chartDom = this.$refs.chart; // 获取图表容器的 DOM 元素
        if (chartCard && chartDom) {
          // 设置图表容器的高度等于卡片的宽度,确保水球图是正方形
          chartDom.style.height = `${chartCard.clientWidth}px`;
          this.myChart.resize(); // 重新调整图表大小
        }
      });
    }
  }
};
</script>

<style scoped>
/* 卡片容器样式 */
.chart-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: #ffffff;
  border-radius: 15px;
  box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.2);
  padding: 10px;
  width: fit-content; /* 宽度适应内容 */
}

/* 标题样式 */
.chart-title {
  font-size: 26px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  margin-top: 30px;
  text-align: center;
}

/* 图表容器样式 */
.chart-container {
  width: 400px; /* 固定宽度 */
  height: 400px; /* 固定高度 */
}
</style>

注释说明:

  1. 模板部分 (<template>)

    • chart-card:卡片容器,用于包裹标题和图表。
    • chart-title:标题部分,如果传入了 title 则显示。
    • chart-container:图表容器,用于渲染水球图。
  2. 脚本部分 (<script>)

    • props:定义了组件的属性,包括 titledataradius
    • data:定义了组件的内部状态,myChart 用于存储 echarts 实例。
    • mounted:在组件挂载后初始化图表,并监听窗口大小变化。
    • beforeDestroy:在组件销毁前移除事件监听器并销毁图表实例。
    • initChart:初始化图表并设置配置项。
    • resizeChart:调整图表大小。
    • adjustContainerSize:动态调整容器大小,确保水球图是正方形。
  3. 样式部分 (<style>)

    • .chart-card:卡片容器的样式。
    • .chart-title:标题的样式。
    • .chart-container:图表容器的样式。

使用示例:

<template>
  <div>
    <LiquidFillChart
      title="水球图示例"
      :data="[0.6, 0.5, 0.4, 0.3]"
      radius="85%"
    />
  </div>
</template>

<script>
import LiquidFillChart from '@/components/LiquidFillChart.vue';

export default {
  components: {
    LiquidFillChart
  }
};
</script>

效果:

  • 卡片宽度和高度自适应内容。
  • 水球图大小固定为 400px * 400px
  • 标题和图表布局合理,样式美观。
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值