Echarts 饼状图 标签大小响应式 label大小

448 阅读2分钟

饼状图的样式和效果有了,但是中心的 label(标签) 大小没有响应式。

Echarts官方提供的方法好像没有能设置label响应式的,所以这里我自己写了方法来处理大小

当前样式

当窗口变小时

label没有缩小

image.png

解决方案

// total大小
const totalSize = ref(30)
// active大小
const activeSize = ref(16)

// 处理大小
const legendFontSizeinit = () => {
  const myHeight = container.value.clientHeight
  const myWidth = container.value.clientWidth
  console.log(myHeight, myWidth);
  // 最小边长
  const minSizeLength = Math.min(myHeight, myWidth)
  // 控制total大小
  totalSize.value = Math.floor(minSizeLength / 10) + 2 // 设置自己想要的比例
  // 控制total最小大小
  totalSize.value = totalSize.value <= 10 ? 10 : totalSize.value
  // 控制active大小
  activeSize.value = totalSize.value - 14 // 设置自己想要的大小
  // 控制active最小大小
  activeSize.value = activeSize.value <= 10 ? 10 : activeSize.value
  console.log(totalSize.value, activeSize.value);
}

const pieChart = () => {
  legendFontSizeinit()
  myChart = echarts.init(main.value);
  const option = {
    ...
    series: [
      {
       ...
        label: {
          show: true, // 是否显示标签
          position: 'center', // 标签的位置,'center' 表示在饼图的中心
          formatter: '{total|' + '{d}%' + '}' + '\n' + '{active|{b}率}', // 标签的格式化字符串
          rich: {
          // 绑定数据
            total: {
              fontSize: totalSize.value,
              fontFamily: '微软雅黑',
              color: '#454c5c',
              height: totalSize.value,
              backgroundColor: '#fff',
            },
            active: {
              fontSize: activeSize.value,
              fontFamily: '微软雅黑',
              color: '#6c7a89',
              height: activeSize.value + 2,
              backgroundColor: '#fff',
            }
          }
        },
        
        ...
      }
    ]
  };

  myChart.setOption(option);
}

最终效果

CPT2406181350-469x447.gif

完整代码

<template>
  <div class="container" ref="container">
    <div ref="main" class="main"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import * as echarts from 'echarts';

const main = ref(null);
const container = ref(null)
let myChart = null;

const totalSize = ref(30)
const activeSize = ref(16)

const legendFontSizeinit = () => {
  const myHeight = container.value.clientHeight
  const myWidth = container.value.clientWidth
  console.log(myHeight, myWidth);
  // 最小边长
  const minSizeLength = Math.min(myHeight, myWidth)
  // 控制total大小
  totalSize.value = Math.floor(minSizeLength / 10) + 2 // 设置自己想要的比例
  // 控制total最小大小
  totalSize.value = totalSize.value <= 10 ? 10 : totalSize.value
  // 控制active大小
  activeSize.value = totalSize.value - 14 // 设置自己想要的大小
  // 控制active最小大小
  activeSize.value = activeSize.value <= 10 ? 10 : activeSize.value
  console.log(totalSize.value, activeSize.value);
}

const pieChart = () => {
  legendFontSizeinit()
  myChart = echarts.init(main.value);
  const option = {
    tooltip: {
      // 提示框触发类型
      trigger: 'item' // 鼠标移到数据项上时触发提示框
    },
    // 图例
    legend: {
      bottom: '0%', // 图例组件离容器底部的距离
      data: [{ name: '回退' }], // 图例的数据数组,数组中每一项代表一个系列的名称
      selectedMode: false // 图例选择的模式,'false' 表示不可选择
    },
    avoidLabelOverlap: false, // 防止标签重叠
    series: [
      {
        type: 'pie',
        legendHoverLink: false, // 图例是否联动高亮
        radius: ['55%', '70%'],
        label: {
          show: true, // 是否显示标签
          position: 'center', // 标签的位置,'center' 表示在饼图的中心
          formatter: '{total|' + '{d}%' + '}' + '\n' + '{active|{b}率}', // 标签的格式化字符串
          rich: {
            total: {
              fontSize: totalSize.value,
              fontFamily: '微软雅黑',
              color: '#454c5c',
              height: totalSize.value,
              backgroundColor: '#fff',
            },
            active: {
              fontSize: activeSize.value,
              fontFamily: '微软雅黑',
              color: '#6c7a89',
              height: activeSize.value + 2,
              backgroundColor: '#fff',
            }
          }
        },
        emphasis: {
          label: {
            show: true // 高亮时显示标签
          }
        },
        data: [
          {
            value: 9,
            name: '完成',
            emphasis: {
              itemStyle: {
                color: '#e6e8ea' // 高亮时的数据项的颜色
              }
            }
          },
          {
            value: 2,
            name: '回退'
          }
        ],
        color: ['#e6e8ea', '#4183e6']
      }
    ]
  };

  myChart.setOption(option);
}

// 饼状图初始化
const pieChartInit = () => {
  myChart.dispatchAction({
    type: 'highlight',
    seriesIndex: 0,
    dataIndex: 1,
  })
  // 鼠标移入
  myChart.on('mouseover', (e) => {
    // 清除全部已有高亮
    myChart.dispatchAction({
      type: 'downplay',
      seriesIndex: 0,
      dataIndex: [0, 1],
    })
    // 高亮鼠标触发的数据
    myChart.dispatchAction({
      type: 'highlight',
      seriesIndex: 0,
      dataIndex: e.dataIndex,
    })
  })
  // 鼠标移出
  myChart.on('mouseout', () => {
    // 清除全部已有高亮
    myChart.dispatchAction({
      type: 'downplay',
      seriesIndex: 0,
      dataIndex: [0, 1],
    })
    // 高亮默认数据
    myChart.dispatchAction({
      type: 'highlight',
      seriesIndex: 0,
      dataIndex: 1,
    })
  })
}

const resizeChart = () => {

  if (myChart) {
    pieChart()
    myChart.resize();
  }
}

onMounted(() => {
  pieChart();
  pieChartInit();
  window.addEventListener('resize', resizeChart);
});

onUnmounted(() => {
  window.removeEventListener('resize', resizeChart);
  if (myChart) {
    myChart.dispose();
  }
});
</script>

<style scoped>
.container {
  width: 100vw;
  height: 100vh;
}

.main {
  width: 80%;
  height: 80%;
}
</style>