echarts pie h5端高亮显示

221 阅读2分钟

最近遇到了需要将web端图表迁移到h5端,遇到了echarts的交互问题

想要实现的效果

image.png

最终实现效果

image.png

PieChart组件

<template>
  <div class="my-chart" ref="chartRef"></div>
</template>
<script lang="ts" setup>
import * as echarts from 'echarts'
type IProps = {
  data: any
}
const props = defineProps<IProps>()
let myChart: ECharts
const chartRef = ref<HTMLDivElement>()
watch(
  () => props.data,
  () => {
    drawChart()
  },
)

const getOptions = () => {
  const { color, data } = props.data.reduce(
    (result, items) => {
      const { color, value, label: name, endColor } = items
      result.color.push(color)
      result.data.push({ value, name, endColor, color })
      return result
    },
    { color: [], data: [] },
  )

  const options: EChartsOption = {
    title: {
      text: '',
      left: 'center',
      top: 'center',
      itemGap: 5, // 设置标题和副标题的间距
    },
    color: color,
    series: [
      {
        type: 'pie',
        radius: ['65%', '90%'],
        data: data,
        labelLine: {
          show: false,
        },
        label: {
          show: false,
          position: 'center',
        },
        itemStyle: {
          borderRadius: 3,
          borderColor: '#fff',
          borderWidth: 1,
        },
        emptyCircleStyle: {
          borderCap: 'round',
        },
      },
    ],
  }
  return options
}
const drawChart = () => {
  if (myChart) myChart.dispose()
  myChart = echarts.init(chartRef.value)
  if (props.data.length <= 0) {
    myChart.showLoading({
      text: '-暂无数据-',
      showSpinner: false, // 隐藏加载中的转圈动图
      textColor: '#9d9d9d',
      maskColor: 'rgba(255, 255, 255, 0)',
      fontSize: '14px',
      fontWeight: '400',
    })
  } else {
    myChart.hideLoading()
  }
  myChart.setOption(getOptions())
}

defineExpose({
  highlightChart: (text: string, percent: string | number, index: number) => {
    myChart.dispatchAction({
      type: 'downplay',
      seriesIndex: null, // 如果只想取消特定系列的高亮,可设置系列索引
      dataIndex: null, // 如果只想取消特定数据项的高亮,可设置数据项索引
    })
    myChart.dispatchAction({
      type: 'highlight',
      seriesIndex: 0,
      dataIndex: index,
    })
    let option = myChart.getOption()
    option.title = {
      text: `${text}`,
      subtext: `${percent}%`,
      rich: {
        // 定义富文本样式
        mainTitle: {
          color: 'red',
          fontWeight: 'bold',
        },
        subTitle: {
          color: 'blue',
          fontStyle: 'italic',
        },
      },
    }
    myChart.setOption(option)
  },
})
</script>
<style lang="scss" scoped>
.my-chart {
  width: 100%;
  height: 400px;
}
</style>

页面调用

 <div class="chart-item-chart">
        <PieChart :data="nodeHealthList" ref="nodeHealthChartRef" />
        <div class="chart-item-chart_legend">
          <div
            class="legend-item"
            :class="{ 'legend-item-active': item.active }"
            v-for="(item, index) in nodeHealthList"
            :key="index"
            @click="highlightNodeHealth(item, index)"
          >
            <div class="legend-item-wrapper">
              <div class="icon" :style="{ background: item.color }"></div>
              <div class="label">{{ item.label }}</div>
              <div class="value">{{ item.value }}</div>
            </div>
          </div>
        </div>
      </div>

主要实现方法 highlightNodeHealth

  /**节点健康诊断  PieChart实例对象*/
  const nodeHealthChartRef = ref<InstanceType<typeof import('./components/pieChart/index.vue')['default']>>()
  type INodeHealthList = (typeof NodeHealthList)[number] & { active?: boolean }
  /**节点健康选择的节点或企业数据 */
  const nodeHealthList = ref<INodeHealthList[]>()

  /**高亮节点健康诊断 */
  const highlightNodeHealth = (item: INodeHealthList, index: number) => {
    nodeHealthList.value?.forEach((i) => (i.active = false))
    item.active = true
    // 百分比
    let percent: string | number
    if (item.value == 0) {
      percent = 0
    } else {
      const total = (nodeHealthList.value?.reduce((total, item) => total + item.value, 0) as number) || 0
      percent = ((item.value / total) * 100).toFixed(2)
    }
    nodeHealthChartRef.value?.highlightChart(item.label, percent, index)
  }

echarts的高亮实现方法


defineExpose({
  highlightChart: (text: string, percent: string | number, index: number) => {
    myChart.dispatchAction({
      type: 'downplay',
      seriesIndex: null, // 如果只想取消特定系列的高亮,可设置系列索引
      dataIndex: null, // 如果只想取消特定数据项的高亮,可设置数据项索引
    })
    myChart.dispatchAction({
      type: 'highlight',
      seriesIndex: 0,
      dataIndex: index,
    })
    let option = myChart.getOption()
    option.title = {
      text: `${text}`,
      subtext: `${percent}%`,
      rich: {
        // 定义富文本样式
        mainTitle: {
          color: 'red',
          fontWeight: 'bold',
        },
        subTitle: {
          color: 'blue',
          fontStyle: 'italic',
        },
      },
    }
    myChart.setOption(option)
  },
})
ok! 在此记录一下,方便后期使用