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

如何将Rest API动态数据传入Victory-native饼图的y值

解决Victory-Native饼图动态数据适配问题

我来帮你搞定这个动态数据转成VictoryPie可用格式的问题!你的核心问题是拿到API返回的TotalSales后,没有把它转换成VictoryPie要求的包含x、y、i字段的对象数组,而是直接把原始数据塞给了state。下面一步步帮你修正:

1. 先明确API返回数据结构

先在axios的回调里打印res.data.data[0].TotalSales,确认它的格式:

  • 是纯数值数组(比如[15, 25, 30, 10])
  • 还是带业务字段的对象数组(比如[{oem: "A", sales:15}, {oem: "B", sales:25}])

这决定了我们后续的转换逻辑。

2. 转换数据为VictoryPie要求的格式

在axios的then回调中,把原始的TotalSales转换成符合要求的结构:

  • 如果是纯数值数组:
    const formattedData = TotalSales.map((value, index) => ({
      x: index + 1, // 也可以替换成对应分类名称(如果有)
      y: value,
      i: index
    }));
    
  • 如果是对象数组(假设每个元素的数值字段是sales):
    const formattedData = TotalSales.map((item, index) => ({
      x: item.oem, // 用OEM名称作为x轴标识,更直观
      y: item.sales,
      i: index
    }));
    

转换完成后再更新state的data字段。

3. 修改渲染逻辑,使用动态数据

删掉render里的静态data定义,直接引用this.state.data,同时新增加载状态避免空图表。

完整修改后的代码

import React, {Component} from "react";
import { StyleSheet, View, ActivityIndicator } from "react-native";
import axios from 'axios'
import { VictoryPie, VictoryGroup, VictoryTheme } from "victory-native";
import Svg from 'react-native-svg';

export default class Chart extends Component {
  state= {
    id: '********************',
    data: [],
    isLoading: true // 新增加载状态,优化体验
  }

  componentDidMount(){
    const headers = {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Access-Control-Allow-Headers': 'x-access-token',
      'x-access-token': this.state.id
    }
    axios.post('http://bi.servassure.net/api/SalesOverviewOEMLevel2', { oem:'all' }, {headers: headers})
    .then((res) => {
      const TotalSales = res.data.data[0].TotalSales;
      // 根据你的TotalSales实际结构修改转换逻辑
      const formattedData = TotalSales.map((value, index) => ({
        x: index + 1,
        y: value,
        i: index
      }));
      this.setState({ 
        data: formattedData,
        isLoading: false
      });
      console.log('格式化后的数据:', this.state.data);
    })
    .catch(err => {
      console.log(err);
      this.setState({ isLoading: false });
    });
  }

  render() {
    const { data, isLoading } = this.state;
    const myColorScale = ["#1b4f72", "#21618c", "#2e86c1","#3498db", "#76d7c4", "#d1f2eb"];

    // 数据加载中显示加载指示器
    if (isLoading) {
      return <View style={styles.container}><ActivityIndicator size="large" color="#3498db" /></View>;
    }

    return (
      <View style={styles.container}>
        <Svg height={200} width={200} viewBox={'0 0 300 300'} preserveAspectRatio='none' >
          <VictoryGroup width={300} theme={VictoryTheme.material}>
            <VictoryPie
              style={{ 
                data: { fill: (d) => myColorScale[d.i] },
                labels: { fill: "white", fontSize: 10, fontWeight: "bold" }
              }}
              radius={100}
              innerRadius={60}
              labelRadius={70}
              data={data} // 这里使用state中的动态数据
              labels={(d) => `${d.x}: ${d.y}`} // 如果x是分类名称,标签会更清晰
            />
          </VictoryGroup>
        </Svg>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
});

额外提示

如果你的TotalSales包含分类名称(比如OEM名称),一定要把x字段替换成这个名称,这样饼图的标签会更直观,用户能直接看到每个区块对应的业务含义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:51:16