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;
相关推荐
VT.馒头3 分钟前
【力扣】2695. 包装数组
前端·javascript·算法·leetcode·职场和发展·typescript
css趣多多14 分钟前
一个UI内置组件el-scrollbar
前端·javascript·vue.js
C澒34 分钟前
前端整洁架构(Clean Architecture)实战解析:从理论到 Todo 项目落地
前端·架构·系统架构·前端框架
C澒41 分钟前
Remesh 框架详解:基于 CQRS 的前端领域驱动设计方案
前端·架构·前端框架·状态模式
Charlie_lll44 分钟前
学习Three.js–雪花
前端·three.js
onebyte8bits1 小时前
前端国际化(i18n)体系设计与工程化落地
前端·国际化·i18n·工程化
C澒1 小时前
前端分层架构实战:DDD 与 Clean Architecture 在大型业务系统中的落地路径与项目实践
前端·架构·系统架构·前端框架
BestSongC1 小时前
行人摔倒检测系统 - 前端文档(1)
前端·人工智能·目标检测
0思必得02 小时前
[Web自动化] Selenium处理滚动条
前端·爬虫·python·selenium·自动化
Misnice2 小时前
Webpack、Vite、Rsbuild区别
前端·webpack·node.js