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

如何在React Native中实现每月含预订、营收的双柱状图表?

React Native 双柱状图表实现方案

针对每个月份展示「预订(booking)」和「营收(earning)」双柱状条的需求,提供两种可行实现方式:

一、基于现有图表库改造

1. 使用 react-native-chart-kit

该库的BarChart原生支持多系列数据,只需配置对应结构即可实现双柱子效果:

import { BarChart } from 'react-native-chart-kit';
import { View } from 'react-native';

const chartData = {
  labels: ['1月', '2月', '3月', '4月'], // 月份数组
  datasets: [
    {
      data: [20, 45, 28, 60], // 预订数据
      color: (opacity = 1) => `rgba(54, 162, 235, ${opacity})`, // 预订柱子颜色
      label: '预订'
    },
    {
      data: [1500, 3200, 2100, 4800], // 营收数据
      color: (opacity = 1) => `rgba(75, 192, 192, ${opacity})`, // 营收柱子颜色
      label: '营收'
    }
  ]
};

const chartConfig = {
  backgroundColor: '#ffffff',
  decimalPlaces: 0,
  color: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`,
  labelColor: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`,
  style: { borderRadius: 16 },
  propsForDots: { r: '0' } // 隐藏点标记
};

export default function DoubleBarChart() {
  return (
    <View>
      <BarChart
        data={chartData}
        width={350}
        height={250}
        chartConfig={chartConfig}
        showValuesOnTopOfBars
        fromZero
        barRadius={4}
        barPercentage={0.6} // 控制柱子宽度,留出双柱子间距
      />
    </View>
  );
}

2. 使用 victory-native

victory-native的VictoryBar支持分组柱状图,通过参数控制双柱子布局:

import { VictoryChart, VictoryBar, VictoryAxis, VictoryTheme } from 'victory-native';
import { View } from 'react-native';

const chartData = [
  { month: '1月', booking: 20, earning: 1500 },
  { month: '2月', booking: 45, earning: 3200 },
  { month: '3月', booking: 28, earning: 2100 },
  { month: '4月', booking: 60, earning: 4800 },
];

export default function GroupedBarChart() {
  return (
    <View>
      <VictoryChart
        theme={VictoryTheme.material}
        domainPadding={{ x: 20 }}
        categorySpacing={50} // 月份组之间的间距
      >
        <VictoryAxis
          tickValues={['1月', '2月', '3月', '4月']}
          tickFormat={(month) => month}
        />
        <VictoryAxis dependentAxis />
        <VictoryBar
          data={chartData}
          x="month"
          y="booking"
          barWidth={20}
          style={{ data: { fill: '#36a2eb' } }}
        />
        <VictoryBar
          data={chartData}
          x="month"
          y="earning"
          barWidth={20}
          style={{ data: { fill: '#4bc0c0' } }}
        />
      </VictoryChart>
    </View>
  );
}

二、自定义双柱状组件(高度定制场景)

如果现有库无法满足UI细节需求,可使用React Native基础组件手动实现:

import { View, Text, StyleSheet } from 'react-native';

// 模拟数据
const monthData = [
  { month: '1月', booking: 20, earning: 1500 },
  { month: '2月', booking: 45, earning: 3200 },
  { month: '3月', booking: 28, earning: 2100 },
  { month: '4月', booking: 60, earning: 4800 },
];

// 计算最大值用于归一化柱子高度
const maxBooking = Math.max(...monthData.map(item => item.booking));
const maxEarning = Math.max(...monthData.map(item => item.earning));

export default function CustomDoubleBarChart() {
  return (
    <View style={styles.container}>
      {monthData.map((item, index) => (
        <View key={index} style={styles.monthGroup}>
          <Text style={styles.monthText}>{item.month}</Text>
          <View style={styles.barsContainer}>
            {/* 预订柱子 */}
            <View style={[
              styles.bar,
              { 
                height: (item.booking / maxBooking) * 180,
                backgroundColor: '#36a2eb'
              }
            ]}>
              <Text style={styles.barValue}>{item.booking}</Text>
            </View>
            {/* 营收柱子 */}
            <View style={[
              styles.bar,
              { 
                height: (item.earning / maxEarning) * 180,
                backgroundColor: '#4bc0c0'
              }
            ]}>
              <Text style={styles.barValue}>{item.earning}</Text>
            </View>
          </View>
        </View>
      ))}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    paddingHorizontal: 10,
    paddingVertical: 20,
    alignItems: 'flex-end',
    height: 300,
  },
  monthGroup: {
    alignItems: 'center',
    flex: 1,
  },
  monthText: {
    fontSize: 12,
    marginBottom: 8,
  },
  barsContainer: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    width: '80%',
    alignItems: 'flex-end',
  },
  bar: {
    width: 25,
    borderRadius: 4,
    justifyContent: 'flex-end',
    paddingBottom: 4,
    alignItems: 'center',
  },
  barValue: {
    fontSize: 10,
    color: '#fff',
    fontWeight: 'bold',
  },
});

注意事项

  • 数据归一化:自定义实现时需将不同量级的数据(如预订数和营收额)分别归一化,避免柱子高度差异过大
  • 适配:可通过Dimensions获取屏幕宽度,动态调整容器和柱子尺寸
  • 交互:如需点击效果,可给柱子添加TouchableOpacity组件扩展交互逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:27:24