vue3 + echarts 饼图 legend 显示在右侧 并且展示百分比

524 阅读1分钟

效果图

image.png

option配置

const option = {
  color: ['#007CF9','#29FFCD'],
  tooltip: {
    trigger: "item",
    axisPointer: {            // Use axis to trigger tooltip
      type: "shadow"        // 'shadow' as default; can also be 'line' or 'shadow'
    },
    formatter: function (params) {
      var res
      res = `<div><span>${params.data.name}:</span>  ${params.data.value}  亩</div>`
      return res
    }
  },
  legend: {
    orient: 'vertical',
    x:'right',      // 图例在左(left)、右(right)、居中(center)、100px
    y:'center',      // 图例在上(top)、下(bottom)、居中(center、100px)、100px
    padding:[90,10,0,0],   // 图例[距上右下左方距离
    top: '5%',
    itemGap:30,
    itemHeight: 14, //修改icon图形大小
    itemWidth: 14, //修改icon图形大小
    data:legendData,
    formatter:  function(name){
      var total = 0;
      var value;

      data.data.forEach((item)=>{
        total += Number(item.value);
        if (item.name == name) {
          value = item.value;
        }
      })
      var p = Math.round(((value / total) * 100)); //求出百分比
      // var arr = ['{a|'+name+':}{b|'+p+'%}']
      // return arr.join('\n')
      return `${name}:${p}%`
    },
    textStyle: {
      color: "#FFFFFF",
      fontSize: 14,
    },
  },
  series: [
    {
      name: 'Access From',
      type: 'pie',
      radius: ['50%', '65%'],
      avoidLabelOverlap: false,
      label: {
        show: false,
        position: 'center'
      },
      emphasis: {
        label: {
          show: true,
          fontSize: 40,
          fontWeight: 'bold'
        }
      },
      labelLine: {
        show: false
      },
      itemStyle: {
        shadowBlur: 40,
        shadowOffsetX: 22,
        shadowOffsetY: 22,
      },
      data: seriesData
    }
  ]
};

完整代码如下:

<template>
  <div class="card-jyxz">
    <CardTitle title="作物占比" />

    <div class="echarts-dis">
      <div id="zwzbEcharts" style="width: 100%; height: 100%;"></div>
    </div>

  </div>
</template>

<script setup lang="ts">

import { $message } from "@mars/components/mars-ui"
import { computed, onMounted, onUnmounted, reactive, ref } from "vue"
import { countCropAreaDistribution } from "@mars/common/api/jsyApi/scgl"
import { events } from "../../../pages/zhts/main"
import * as echarts from "echarts"

let myChart: any

const state = reactive({
  xm:"0",
  yc:"0"
})

const unit = ref("")

const dataList = ref([])

// // 计算属性
// const xmDoubleCount = computed(() => {
//   return (Number(state.xm)/(Number(state.xm)+Number(state.yc))*100).toFixed(2) || undefined
// })
// const ycDoubleCount = computed(() => {
//   return Number((state.yc)/(Number(state.xm)+Number(state.yc))*100).toFixed(2) || undefined
// })

onMounted(() => {
  events.on("sourceId-toolber", (val: any) => {
    getData(val)
  })
})

onUnmounted(() => {
  // 销毁操作
})

const getData = async (sourceId) => {
  const { code, data, message } = await countCropAreaDistribution({...sourceId})
  if (code === 200) {
    dataList.value = data.data
    unit.value = data.unit
    await getEcharts(data)
  } else {
    $message(message)
  }
}
// echarts
const getEcharts = (data) => {
  // 基于准备好的dom,初始化echarts实例
  myChart = echarts.init(document.getElementById("zwzbEcharts"), "dark")

  // 指定图表的配置项和数据
  const option = getOption(data)

  // 使用刚指定的配置项和数据显示图表。
  myChart.setOption(option)
}

function getOption(data) {
  let legendData = data.legend
  let seriesData = data.data

  const option = {
    color: ['#007CF9','#29FFCD'],
    tooltip: {
      trigger: "item",
      axisPointer: {            // Use axis to trigger tooltip
        type: "shadow"        // 'shadow' as default; can also be 'line' or 'shadow'
      },
      formatter: function (params) {
        var res
        res = `<div><span>${params.data.name}:</span>  ${params.data.value}  亩</div>`
        return res
      }
    },
    legend: {
      orient: 'vertical',
      x:'right',      // 图例在左(left)、右(right)、居中(center)、100px
      y:'center',      // 图例在上(top)、下(bottom)、居中(center、100px)、100px
      padding:[90,10,0,0],   // 图例[距上右下左方距离
      top: '5%',
      itemGap:30,
      itemHeight: 14, //修改icon图形大小
      itemWidth: 14, //修改icon图形大小
      data:legendData,
      formatter:  function(name){
        var total = 0;
        var value;

        data.data.forEach((item)=>{
          total += Number(item.value);
          if (item.name == name) {
            value = item.value;
          }
        })
        var p = Math.round(((value / total) * 100)); //求出百分比
        // var arr = ['{a|'+name+':}{b|'+p+'%}']
        // return arr.join('\n')
        return `${name}:${p}%`
      },
      textStyle: {
        color: "#FFFFFF",
        fontSize: 14,
      },
    },
    series: [
      {
        name: 'Access From',
        type: 'pie',
        radius: ['50%', '65%'],
        avoidLabelOverlap: false,
        label: {
          show: false,
          position: 'center'
        },
        emphasis: {
          label: {
            show: true,
            fontSize: 40,
            fontWeight: 'bold'
          }
        },
        labelLine: {
          show: false
        },
        itemStyle: {
          shadowBlur: 40,
          shadowOffsetX: 22,
          shadowOffsetY: 22,
        },
        data: seriesData
      }
    ]
  };
  return option
}


</script>

<style lang="less" scoped>
.card-jyxz {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 370px;
  height: 308px;
  z-index: 10000000;
  background: rgba(5, 28, 50, 0.5);

  .echarts-dis{
    width: 100%;
    height: 87%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    //padding-right: 80px;
    box-sizing: border-box;
    .dis-left{
      width: 50%;
      height: 100%;
    }
    .dis-right{
      flex: 1;
      .ri-box{
        margin-bottom: 14px;
        .box-dis{
          .fang{
            display: inline-block;
            width: 12px;
            height: 12px;
            //background: #007CF9;
            border-radius: 2px;
            margin-right: 12px;
          }
          .text-span{
            font-size: 18px;
            font-family: Source Han Sans CN;
            font-weight: 400;
            color: #FFFFFF;
            //margin-right: 18px;
          }
        }
        .text-p{
          text-align: center;
          font-size: 20px;
          font-family: Arial;
          font-weight: bold;
          //color: #60AFFF;
          .text-p-s{
            font-size: 14px;
            font-family: Source Han Sans CN;
            font-weight: 400;
          }
        }
      }
    }
  }

}
</style>