import 'dart:math' as math; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import '../../../themes/charts/appChartColors.dart'; class BarChartSample7 extends StatefulWidget { BarChartSample7({super.key}); final shadowColor = const Color(0xFFCCCCCC); final dataList = [ _BarData(AppColors.contentColorYellow, 18, 18), _BarData(AppColors.contentColorGreen, 17, 8), _BarData(AppColors.contentColorOrange, 10, 15), _BarData(AppColors.contentColorPink, 2.5, 5), _BarData(AppColors.contentColorBlue, 2, 2.5), _BarData(AppColors.contentColorRed, 2, 2), ]; @override State createState() => _BarChartSample7State(); } class _BarChartSample7State extends State { BarChartGroupData generateBarGroup( int x, Color color, double value, double shadowValue, ) { return BarChartGroupData( x: x, barRods: [ BarChartRodData(toY: value, color: color, width: 6), BarChartRodData(toY: shadowValue, color: widget.shadowColor, width: 6), ], showingTooltipIndicators: touchedGroupIndex == x ? [0] : [], ); } int touchedGroupIndex = -1; int rotationTurns = 1; @override Widget build(BuildContext context) { return SelectionArea( child: Padding( padding: const EdgeInsets.all(24), child: Column( children: [ Row( children: [ Expanded(child: Container()), const Text( 'Horizontal Bar Chart', style: TextStyle(color: AppColors.mainTextColor1, fontSize: 20), ), Expanded( child: Align( alignment: Alignment.centerRight, child: Tooltip( message: 'Rotate the chart 90 degrees (cw)', child: IconButton( onPressed: () { setState(() { rotationTurns += 1; }); }, icon: RotatedBox( quarterTurns: rotationTurns - 1, child: const Icon(Icons.rotate_90_degrees_cw), ), ), ), ), ), ], ), const SizedBox(height: 18), AspectRatio( aspectRatio: 1.4, child: BarChart( BarChartData( alignment: BarChartAlignment.spaceBetween, rotationQuarterTurns: rotationTurns, borderData: FlBorderData( show: true, border: Border.symmetric( horizontal: BorderSide( color: AppColors.borderColor.withValues(alpha: 0.2), ), ), ), titlesData: FlTitlesData( show: true, leftTitles: const AxisTitles( drawBelowEverything: true, sideTitles: SideTitles(showTitles: true, reservedSize: 30), ), bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, reservedSize: 50, getTitlesWidget: (value, meta) { final index = value.toInt(); return SideTitleWidget( meta: meta, child: Text('data'), // child: _IconWidget( // color: widget.dataList[index].color, // isSelected: touchedGroupIndex == index, // ), ); }, ), ), // rightTitles: const AxisTitles(), // topTitles: const AxisTitles(), ), gridData: FlGridData( show: true, drawVerticalLine: false, getDrawingHorizontalLine: (value) => FlLine( color: AppColors.borderColor.withValues(alpha: 0.2), strokeWidth: 1, ), ), barGroups: widget.dataList.asMap().entries.map((e) { final index = e.key; final data = e.value; return generateBarGroup( index, data.color, data.value, data.shadowValue, ); }).toList(), maxY: 20, barTouchData: BarTouchData( enabled: true, handleBuiltInTouches: false, touchTooltipData: BarTouchTooltipData( getTooltipColor: (group) => Colors.transparent, tooltipMargin: 0, getTooltipItem: ( BarChartGroupData group, int groupIndex, BarChartRodData rod, int rodIndex, ) { return BarTooltipItem( rod.toY.toString(), TextStyle( fontWeight: FontWeight.bold, color: rod.color, fontSize: 18, shadows: const [ Shadow(color: Colors.black26, blurRadius: 12), ], ), ); }, ), touchCallback: (event, response) { if (event.isInterestedForInteractions && response != null && response.spot != null) { setState(() { touchedGroupIndex = response.spot!.touchedBarGroupIndex; }); } else { setState(() { touchedGroupIndex = -1; }); } }, ), ), ), ), ], ), ) ); } } class _BarData { const _BarData(this.color, this.value, this.shadowValue); final Color color; final double value; final double shadowValue; } class _IconWidget extends ImplicitlyAnimatedWidget { const _IconWidget({required this.color, required this.isSelected}) : super(duration: const Duration(milliseconds: 300)); final Color color; final bool isSelected; @override ImplicitlyAnimatedWidgetState createState() => _IconWidgetState(); } class _IconWidgetState extends AnimatedWidgetBaseState<_IconWidget> { Tween? _rotationTween; @override Widget build(BuildContext context) { final rotation = math.pi * 4 * _rotationTween!.evaluate(animation); final scale = 1 + _rotationTween!.evaluate(animation) * 0.5; return Transform( transform: Matrix4.identity()..scale(0.8), // transform: Matrix4.rotationZ(rotation)..scaled(scale, scale, scale), // transform: Matrix4.rotationZ(rotation)..scale(scale, scale, scale), origin: const Offset(14, 14), child: Icon( widget.isSelected ? Icons.face_retouching_natural : Icons.face, color: widget.color, size: 28, ), ); } @override void forEachTween(TweenVisitor visitor) { _rotationTween = visitor( _rotationTween, widget.isSelected ? 1.0 : 0.0, (dynamic value) => Tween( begin: value as double, end: widget.isSelected ? 1.0 : 0.0, ), ) as Tween?; } }