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;
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端