一、引入插件

pub.dev:fl_chart package - All Versions

根据项目版本,安装可适配的 fl_chart 版本

二、官网柱状图示例

github参数配置:(x轴、y轴、边框、柱条数据、tooltip等)

https://github.com/imaNNeo/fl_chart/blob/master/repo_files/documentations/bar_chart.md

BarChart(

BarChartData(

// read about it in the BarChartData section

),

swapAnimationDuration: Duration(milliseconds: 150), // Optional

swapAnimationCurve: Curves.linear, // Optional

);

官方给的例子:(柱条数量多时,不能左右滚动)https://github.com/imaNNeo/fl_chart/blob/master/example/lib/presentation/samples/bar/bar_chart_sample1.dart

 三、自定义实现左右滑动 固定y轴

思路:

1、在 BarChart 外层添加一层 Container,Container外面包裹一层 SingleChildScrollView,scrollDirection 属性设置为 Axis.horizontal,即可实现水平滚动;

2、但是y轴也会跟着一起滚动,所以我们在 SingleChildScrollView 外手写一个y轴,用Row包裹;

 1、手写的y轴

        这里没什么技巧,主要是y轴数据的分配:此例中最大值大于5时,也是5等分,四舍五入;小于5则根据最大值分,间隔为1;

// 手写y轴

Column(

children: [

const Text('人数',

style: TextStyle(color: Color(0xFF999999), fontSize: 11)),

Row(

children: [

Column(

children: totalNum >= 5

? List.generate(5, (index) {

return Column(

children: [

Text('${(totalNum / 4 * (4 - index)).round()}',

style: const TextStyle(

color: Color(0xFF999999),

fontSize: 11)),

index < 4 ? const SizedBox(height: 25) : const SizedBox()

],

);

})

: List.generate(totalNum + 1, (index) {

return Column(

children: [

Text('${totalNum - index}',

style: const TextStyle(

color: Color(0xFF999999),

fontSize: 11)),

index < totalNum ? SizedBox(height: (100 / totalNum).toDouble()) : const SizedBox()

],

);

})

),

const SizedBox(width: 4),

//垂直分割线

const SizedBox(

width: 1,

height: 161,

child: DecoratedBox(

decoration: BoxDecoration(color: Color(0xFFEEEEEE)),

),

),

],

),

],

),

2、实现左右滑动

注意层级结构,Expanded — SingleChildScrollView — Container — BarChart

Expanded(

child: SingleChildScrollView(

scrollDirection: Axis.horizontal,

child: Container(

padding: const EdgeInsets.only(top: 10, bottom: 10),

width: barList.length * 35 + 220,

height: 220,

child: BarChart(

BarChartData(

alignment: BarChartAlignment.spaceEvenly,

titlesData: FlTitlesData(

show: true,

topTitles: AxisTitles(

sideTitles: SideTitles(

showTitles: false

),

),

bottomTitles: AxisTitles(

sideTitles: SideTitles(

showTitles: true,

reservedSize: 32,

// getTitlesWidget: bottomTitles, x轴配置

),

),

leftTitles: AxisTitles(

sideTitles: SideTitles(

showTitles: false,

),

),

rightTitles: AxisTitles(

sideTitles: SideTitles(

showTitles: false

),

),

),

gridData: FlGridData(show: false),

borderData: FlBorderData(

border: const Border(

bottom: BorderSide(color: AppColors.colorFFEEEEEE),

)

),

// barGroups: showingGroups() 柱条数据配置

),

),

)

),

),

完整代码结构(x轴、图表数据等需要自己去完善)

import 'package:fl_chart/fl_chart.dart';

import 'package:flutter/material.dart';

import 'package:oamic_project/common/values/colors.dart';

// 柱状图

class SubjectClassficationBarChart extends StatelessWidget {

const SubjectClassficationBarChart({super.key});

@override

Widget build(BuildContext context) {

List barList = [10,20,30,4,0,5,50,50,78,45,23,6,21,10]; // 数据列表

int totalNum = 0; // 总人数

return LayoutBuilder(builder: (context, constraints) {

final maxWidth = constraints.maxWidth;

return SizedBox(

width: maxWidth,

height: 220,

child: Row(

children: [

// 手绘y轴

Column(

children: [

const Text('人数',

style: TextStyle(color: Color(0xFF999999), fontSize: 11)),

Row(

children: [

Column(

children: totalNum >= 5

? List.generate(5, (index) {

return Column(

children: [

Text('${(totalNum / 4 * (4 - index)).round()}',

style: const TextStyle(

color: Color(0xFF999999),

fontSize: 11)),

index < 4 ? const SizedBox(height: 25) : const SizedBox()

],

);

})

: List.generate(totalNum + 1, (index) {

return Column(

children: [

Text('${totalNum - index}',

style: const TextStyle(

color: Color(0xFF999999),

fontSize: 11)),

index < totalNum ? SizedBox(height: (100 / totalNum).toDouble()) : const SizedBox()

],

);

})

),

const SizedBox(width: 4),

//垂直分割线

const SizedBox(

width: 1,

height: 161,

child: DecoratedBox(

decoration: BoxDecoration(color: Color(0xFFEEEEEE)),

),

),

],

),

],

),

Expanded(

child: SingleChildScrollView(

scrollDirection: Axis.horizontal,

child: Stack(

children: [

Container(

padding: const EdgeInsets.only(top: 10, bottom: 10),

width: barList.length * 35 + 220,

height: 220,

child: BarChart(

BarChartData(

alignment: BarChartAlignment.spaceEvenly,

titlesData: FlTitlesData(

show: true,

topTitles: AxisTitles(

sideTitles: SideTitles(

showTitles: false

),

),

bottomTitles: AxisTitles(

sideTitles: SideTitles(

showTitles: true,

reservedSize: 32,

// getTitlesWidget: bottomTitles, x轴配置

),

),

leftTitles: AxisTitles(

sideTitles: SideTitles(

showTitles: false,

),

),

rightTitles: AxisTitles(

sideTitles: SideTitles(

showTitles: false

),

),

),

gridData: FlGridData(show: false),

borderData: FlBorderData(

border: const Border(

bottom: BorderSide(color: AppColors.colorFFEEEEEE),

)

),

// barGroups: showingGroups() 柱条数据配置

),

),

)],

),

),

),

],

),

);

});

}

}

配置过程要注意层级结构,不然可能会报错

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: