Taro Echarts封装内外环形饼图

环形图是一种特殊的饼图,它由一个内圆和一个外圆组成,中间的部分是空的,形成一个环形。这种图表非常适合用来展示占比关系,同时保持视觉上的吸引力

封装组件

tsx 复制代码
import { StandardProps, View } from "@tarojs/components";
import { useMemoizedFn } from "ahooks";
import { useEffect, useState } from "react";
import { EchartsRef } from "src/components/ec-canvas/typings";
//@ts-ignore ts-nocheck
import * as echarts from "src/components/ec-canvas/echarts";

interface Props extends StandardProps {
  data: any[],
  total?: number,
}
const CircularPieChart: React.FC<Props> = ({ data, total }) => {

  const [chartRef, setChartRef] = useState<EchartsRef>();

  const onInit = useMemoizedFn((canvas, width, height, dpr) => {
    const chart = echarts.init(canvas, null, {
      width: width,
      height: height,
      devicePixelRatio: dpr, // 像素
    });
    canvas.setChart(chart);
    setChartRef(chart);
    return chart;
  });

  const setOption = useMemoizedFn(() => {
    const option = {
      // backgroundColor: '#1d2239',
      // tooltip: {
      //   trigger: 'item',
      //   formatter: "{a} <br/>{b}: {c} ({d}%)"
      // },
      title: {
        text: '总好友数',
        subtext: total,
        x: 'center',
        y: 'center',
        textStyle: {
          fontWeight: 'normal',
          fontSize: 16
        }
      },
      color: data.map((item) => item.color),
      legend: { //图例组件,颜色和名字
        left: '0',
        top: '50',
        orient: 'vertical',
        itemGap: 12, //图例每项之间的间隔
        itemWidth: 10,
        itemHeight: 10,
        icon: 'rect',
        textStyle: {
          color: [],
          fontStyle: 'normal',
          fontFamily: '微软雅黑',
          fontSize: 12,
        }
      },
      series: [{
        name: '违规次数',
        type: 'pie',
        select: false,
        hoverAnimation: false,
        // selectedMode: 'single',
        silent: true,
        clockwise: false,
        minAngle: 25, //最小的扇区角度(0 ~ 360)
        center: ['50%', '50%'], //饼图的中心(圆心)坐标
        radius: [54, 96], //饼图的半径
        avoidLabelOverlap: true, //是否启用防止标签重叠F
        legendHoverLink: false,
        // itemStyle: { //图形样式
        //   normal: {
        //     borderColor: '#1e2239',
        //     borderWidth: 1.5,
        //   },
        // },
        label: { //标签的位置
          normal: {
            show: true,
            position: 'inside', //标签的位置
            formatter: "{d}%",
            textStyle: {
              color: '#fff',
              fontSize: 12,
            }
          },
          emphasis: {
            show: true,
            disable: false,  //是否关闭扇区高亮效果
            scale: false,    //扇区是否缩放
            textStyle: {
              fontWeight: 'bold'
            }
          }
        },
        data: data
      },
      {
        name: '',
        type: 'pie',
        clockwise: false,
        // selectedMode: 'single',
        hoverAnimation: false,
        silent: true,
        legendHoverLink: false,
        minAngle: 25, //最小的扇区角度(0 ~ 360)
        center: ['50%', '50%'], //饼图的中心(圆心)坐标
        radius: [54, 96], //饼图的半径
        itemStyle: { //图形样式
          normal: {
            borderColor: '#fff',
            borderWidth: 1.5,
          }
        },
        select: false,
        label: { //标签的位置
          normal: {
            position: 'outer', //标签的位置
            formatter: '{a|{b}}\n{hr|}\n{per|{c}}',
            rich: {
              a: {
                color: '#999999',
                fontSize: 11,
                lineHeight: 20,
                align: 'center'
              },
              hr: {
                width: '100%',
                height: 0,
                alien: 'center'
              },
              per: {
                color: '#000000',
                align: 'center',
                fontSize: 15,
              }
            },
            // formatter: function (params) {
            //   console.log('ss', params)
            //   return `${params.value}\n${params.name}`
            // },
            textStyle: {
              color: '#000',
              fontSize: 12,
              textAlign: 'center',
            },
          }
        },
        labelLine: { length: 4 },
        data: data
      }

      ]
    }
    chartRef?.setOption?.(option);
  });

  useEffect(() => {
    if (!chartRef || !data.length) return;
    if (chartRef) {
      setOption();
    }
    return () => {
      chartRef?.destroy?.();
    };
  }, [chartRef, data]);
  return (
    <>
      <View className="w-750 h-700 absolute -left-10">
        {/* @ts-ignore */}
        <ec-canvas
          class="circular-pie-chart"
          id={`circular-pie-chart${Math.random() * 10000}`}
          canvas-id={`circular-pie-chart${Math.random() * 10000}`}
          ec={{ onInit }}
        />
      </View>
    </>
  )
}

export default CircularPieChart;

使用

tsx 复制代码
import { View } from "@tarojs/components";
import Taro from "@tarojs/taro";
import CircularPieChart from "src/components/CircularPieChart";

const app: App.GlobalData = Taro.getApp();
const Demo = () => {

  let data = [
    { value: 0, name: 'AL注册客人', color: '#7C74BC' },
    { value: 76, name: 'AU注册会员', color: '#554C99' },
    { value: 13, name: '非会员客人', color: '#554C99' },
    { value: 46, name: '注册会员客人', color: '#E6E4F7' },
  ];

  return (
    <>
      <View className="page mt-300">
        <CircularPieChart data={data} ></CircularPieChart>

      </View>
    </>
  );
};

export default Demo;
相关推荐
小白变怪兽1 小时前
一、react18+项目初始化(vite)
前端·react.js
ai小鬼头1 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github
墨菲安全2 小时前
NPM组件 betsson 等窃取主机敏感信息
前端·npm·node.js·软件供应链安全·主机信息窃取·npm组件投毒
GISer_Jing2 小时前
Monorepo+Pnpm+Turborepo
前端·javascript·ecmascript
天涯学馆2 小时前
前端开发也能用 WebAssembly?这些场景超实用!
前端·javascript·面试
我在北京coding3 小时前
TypeError: Cannot read properties of undefined (reading ‘queryComponents‘)
前端·javascript·vue.js
前端开发与ui设计的老司机4 小时前
UI前端与数字孪生结合实践探索:智慧物流的货物追踪与配送优化
前端·ui
全能打工人4 小时前
前端查询条件加密传输方案(SM2加解密)
前端·sm2前端加密
翻滚吧键盘4 小时前
vue绑定一个返回对象的计算属性
前端·javascript·vue.js
秃了也弱了。5 小时前
Chrome谷歌浏览器插件ModHeader,修改请求头,开发神器
前端·chrome