You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中饼图与环形图绘制及填充动画解决方案咨询

在React Native中实现饼图/环形图及填充动画的方案

一、基于你用过的react-native-gifted-charts实现填充动画

这个库本身内置了动画支持,只需配置对应参数即可开启填充动画,环形图也可通过简单参数切换:

  • animate={true}:启用填充动画
  • animationDuration:自定义动画时长(单位:毫秒)
  • donut:开启环形图模式,donutWidth调整环的宽度

示例代码:

import { PieChart } from 'react-native-gifted-charts';

const chartData = [
  {value: 30, color: '#FF6384'},
  {value: 50, color: '#36A2EB'},
  {value: 20, color: '#FFCE56'},
];

const AnimatedDonut = () => {
  return (
    <PieChart
      data={chartData}
      donut
      donutWidth={30}
      animate={true}
      animationDuration={1500}
      showValuesAsLabels={true}
    />
  );
};

export default AnimatedDonut;

二、备选库:react-native-chart-kit

该库支持多种图表类型,环形图的填充动画可通过animate参数快速实现,配置灵活:

示例代码:

import { PieChart } from 'react-native-chart-kit';
import { Dimensions } from 'react-native';

const screenWidth = Dimensions.get('window').width;

const chartConfig = {
  color: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`,
};

const chartData = [
  {name: '分组A', population: 30, color: '#FF6384', legendFontColor: '#333'},
  {name: '分组B', population: 50, color: '#36A2EB', legendFontColor: '#333'},
  {name: '分组C', population: 20, color: '#FFCE56', legendFontColor: '#333'},
];

const AnimatedPieChart = () => {
  return (
    <PieChart
      data={chartData}
      width={screenWidth}
      height={220}
      chartConfig={chartConfig}
      accessor="population"
      backgroundColor="transparent"
      paddingLeft="15"
      center={[10, 10]}
      absolute
      animate
      animationDuration={1000}
      donut
      donutRadius={40}
    />
  );
};

export default AnimatedPieChart;

三、自定义精细动画(基于react-native-svg + Reanimated)

如果需要完全自定义动画节奏或样式,可以用react-native-svg绘制图形,配合react-native-reanimated实现精准的填充动画:

  1. 先安装依赖:
npm install react-native-svg react-native-reanimated
  1. 示例代码:
import React, { useEffect } from 'react';
import { View } from 'react-native';
import Svg, { Path } from 'react-native-svg';
import Animated, { useSharedValue, withTiming } from 'react-native-reanimated';

const AnimatedPath = Animated.createAnimatedComponent(Path);

const CustomAnimatedDonut = () => {
  const progress = useSharedValue(0);
  const totalValue = 100;
  const data = [30, 50, 20];
  const colors = ['#FF6384', '#36A2EB', '#FFCE56'];
  const radius = 80;
  const donutWidth = 25;
  const centerX = radius + donutWidth;
  const centerY = radius + donutWidth;

  // 计算扇形路径
  const getArcPath = (startAngle, endAngle) => {
    const startRadians = (startAngle * Math.PI) / 180;
    const endRadians = (endAngle * Math.PI) / 180;
    const largeArcFlag = endAngle - startAngle > 180 ? 1 : 0;

    const x1 = centerX + radius * Math.cos(startRadians);
    const y1 = centerY + radius * Math.sin(startRadians);
    const x2 = centerX + radius * Math.cos(endRadians);
    const y2 = centerY + radius * Math.sin(endRadians);

    const innerRadius = radius - donutWidth;
    const x1Inner = centerX + innerRadius * Math.cos(startRadians);
    const y1Inner = centerY + innerRadius * Math.sin(startRadians);
    const x2Inner = centerX + innerRadius * Math.cos(endRadians);
    const y2Inner = centerY + innerRadius * Math.sin(endRadians);

    return `M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2} L ${x2Inner} ${y2Inner} A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 0 ${x1Inner} ${y1Inner} Z`;
  };

  useEffect(() => {
    // 启动填充动画
    progress.value = withTiming(1, { duration: 1500 });
  }, []);

  let currentAngle = 0;
  return (
    <View>
      <Svg width={centerX * 2} height={centerY * 2}>
        {data.map((value, index) => {
          const animatedAngle = (value / totalValue) * 360 * progress.value;
          const path = getArcPath(currentAngle, currentAngle + animatedAngle);
          currentAngle += (value / totalValue) * 360;
          return (
            <AnimatedPath
              key={index}
              d={path}
              fill={colors[index]}
            />
          );
        })}
      </Svg>
    </View>
  );
};

export default CustomAnimatedDonut;

内容的提问来源于stack exchange,提问作者Yuva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 19:37:25