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

Flutter中fl_chart的BarChart占满宽度,如何限制其宽度?

Flutter fl_chart BarChart 宽度不生效问题

在使用fl_chart的BarChart组件时,设置的宽度被忽略,图表始终占满容器宽度。已尝试用SizedBox、ConstrainedBox包裹组件,均未解决问题。

现有代码

DailyUtilizationChart 组件

class DailyUtilizationChart extends ConsumerWidget {
  const DailyUtilizationChart({super.key});
  @override
  Widget build(context, ref) {
    final parkingId = GoRouterState.of(context).pathParameters["id"];
    
    final dailyUtilization = ref.watch(dailyUtilizationFutureProvider(parkingId));
    final metricInterval = ref.watch(metricsIntervalProvider);

    return dailyUtilization.when(
      data: (utilization) {
        final weeklyData = generateBarChartData(utilization);
        return SizedBox(
          height: 300,
          width: 500,
          child: BarChart(
            BarChartData(
              maxY: 100,
              barGroups: weeklyData,
              titlesData: FlTitlesData(
                leftTitles: const AxisTitles(
                  sideTitles: SideTitles(showTitles: true, reservedSize: 35),
                ),
                rightTitles: emptyAxisTitles,
                topTitles: emptyAxisTitles,
                bottomTitles: AxisTitles(
                  sideTitles: SideTitles(
                    showTitles: true,
                    getTitlesWidget: (value, _) {
                      if (metricInterval == MetricInterval.weekly) {
                        final date = utilization[value.toInt()].date;
                        final dayFormat = DateFormat.E();
                        return Text(dayFormat.format(date));
                      } else {
                        if (value % 2 != 0) return const SizedBox();
                        final date = utilization[value.toInt()].date;
                        final dayFormat = DateFormat('dd/MMM');
                        return Text(dayFormat.format(date));
                      }
                    },
                  ),
                ),
              ),
              borderData: FlBorderData(show: true),
              gridData: const FlGridData(show: false),
            ),
          ),
        );
      },
      error: (_, _) =>Text("Error getting utilization"),
      loading: () => const Center(child: CircularProgressIndicator()),
    );
  }
}

generateBarChartData 函数

List<BarChartGroupData> generateBarChartData(List<DailyUtilizationModel> data) {
  return List.generate(data.length, (index) {
    final dayData = data[index];

    return BarChartGroupData(
      x: index,
      groupVertically: true,
      barRods: [
        BarChartRodData(toY: dayData.maxUtilization, color: AppColors.success),
        BarChartRodData(toY: dayData.avgUtilization, color: AppColors.primary),
        BarChartRodData(toY: dayData.minUtilization, color: AppColors.alert),
      ],
    );
  });
}

解决方案

1. 检查父容器约束

如果DailyUtilizationChart的父组件是Expanded、Flex这类强制占满宽度的组件,SizedBox的宽度设置会被覆盖。需要将组件放在非强制占满宽度的容器中,比如Center或Align:

// 父容器示例
Center(
  child: DailyUtilizationChart(),
)

2. 配置BarChart的layoutConfig

通过BarChartLayoutConfig控制图表的布局规则,限制图表宽度:

BarChart(
  BarChartData(...),
  layoutConfig: const BarChartLayoutConfig(
    barGroupHorizontalPadding: 4,
    showBarGroupsSpace: true,
    // 固定每组的最大宽度,避免图表过度拉伸
    maxBarGroupWidth: 40,
  ),
)

3. 调整BarGroup和BarRod的尺寸

在generateBarChartData中设置组间距和单条Bar的宽度,避免图表自动拉伸:

List<BarChartGroupData> generateBarChartData(List<DailyUtilizationModel> data) {
  return List.generate(data.length, (index) {
    final dayData = data[index];

    return BarChartGroupData(
      x: index,
      groupVertically: true,
      barGroupSpacing: 12, // 设置组之间的间距
      barRods: [
        BarChartRodData(
          toY: dayData.maxUtilization, 
          color: AppColors.success,
          width: 8, // 设置单条Bar的宽度
        ),
        BarChartRodData(
          toY: dayData.avgUtilization, 
          color: AppColors.primary,
          width: 8,
        ),
        BarChartRodData(
          toY: dayData.minUtilization, 
          color: AppColors.alert,
          width: 8,
        ),
      ],
    );
  });
}

4. 用Align包裹SizedBox

通过Align明确约束图表的对齐方式,确保SizedBox的宽度生效:

return dailyUtilization.when(
  data: (utilization) {
    final weeklyData = generateBarChartData(utilization);
    return Align(
      alignment: Alignment.center,
      child: SizedBox(
        height: 300,
        width: 500,
        child: BarChart(...),
      ),
    );
  },
  // ... 其他状态处理
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:45:19