nhance_partner/lib/presentation/screens/dashboard/tabs/chart.dart
2026-01-08 16:01:06 +05:30

244 lines
7.9 KiB
Dart

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<BarChartSample7> createState() => _BarChartSample7State();
}
class _BarChartSample7State extends State<BarChartSample7> {
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<ImplicitlyAnimatedWidget> createState() =>
_IconWidgetState();
}
class _IconWidgetState extends AnimatedWidgetBaseState<_IconWidget> {
Tween<double>? _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<dynamic> visitor) {
_rotationTween =
visitor(
_rotationTween,
widget.isSelected ? 1.0 : 0.0,
(dynamic value) => Tween<double>(
begin: value as double,
end: widget.isSelected ? 1.0 : 0.0,
),
)
as Tween<double>?;
}
}