Files
sf-app-platform/packages/sf_shared/lib/src/widgets/line_graph.dart
aitorarana 8201bff0a7 - created snackbar, step indicator, money text, text field and progress bar components.
- created wallet balance block, wallet item and kid line chart widgets.
- restructured onboarding, signup and device signup screens into layouts and main screens.
- updated signup and kid wallet screens to 17/11 design.
2025-11-21 15:28:46 +01:00

174 lines
6.3 KiB
Dart

import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class LineGraph extends ConsumerStatefulWidget {
final lines = [[0,1,0,1,0,1,0],[1,0,1,0,1,0,1]];
LineGraph({super.key});
@override
ConsumerState<LineGraph> createState() => LineGraphState();
}
class LineGraphState extends ConsumerState<LineGraph> {
final weekDays = ["L", "M", "X", "J", "V", "S", "D"];
String? timeSpan;
late var days = weekDays;
@override
void initState() {
timeSpan = "week";
super.initState();
}
@override
Widget build(BuildContext context) {
final theme = ref.watch(themePortProvider);
return Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
border: BoxBorder.fromLTRB(left: BorderSide(color: Colors.cyan, width: 5)),
borderRadius: BorderRadius.all(Radius.circular(13)),
color: theme.getColorFor(ThemeCode.backgroundPrimary)
),
child: Column(
spacing: 32,
children: [
Row(children: [
Text("Gastos", style: TextStyle(fontWeight: FontWeight.w500, fontSize: 18)),
Spacer(),
Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8)),
color: theme.getColorFor(ThemeCode.backgroundSecondary),
),
child: DropdownButton(
underline: Container(),
value: timeSpan,
onChanged: (String? value) {
setState(() {
timeSpan = value;
});
},
dropdownColor: theme.getColorFor(ThemeCode.backgroundPrimary),
items: [
DropdownMenuItem(value: "day", child: Text("Hoy", style: TextStyle(fontSize: 14, letterSpacing: 0))),
DropdownMenuItem(value: "week", child: Text("Esta semana", style: TextStyle(fontSize: 14, letterSpacing: 0))),
DropdownMenuItem(value: "month", child: Text("Este mes", style: TextStyle(fontSize: 14, letterSpacing: 0))),
]
),
)
]),
SizedBox(
height: 160,
child: LineChart(LineChartData(
gridData: FlGridData(
show: true,
drawHorizontalLine: false,
drawVerticalLine: true,
verticalInterval: 1,
getDrawingVerticalLine: (value)=>FlLine(strokeWidth: 43, color: theme.getColorFor(ThemeCode.backgroundSecondary))
),
titlesData: FlTitlesData(
bottomTitles: AxisTitles(
sideTitles: SideTitles(
interval: 1,
showTitles: true,
reservedSize: 40,
getTitlesWidget: (double value, TitleMeta meta){
String text = weekDays[value.toInt()];
return SideTitleWidget(
space: 4,
meta: meta,
child: Expanded(child: Center(child: Text(text, style: TextStyle(fontSize: 12)))),
);
},
),
),
leftTitles: AxisTitles(),
topTitles: AxisTitles(),
rightTitles: AxisTitles()
),
lineTouchData: LineTouchData(
touchTooltipData: LineTouchTooltipData(
tooltipBorderRadius: BorderRadius.all(Radius.circular(7)),
getTooltipColor: (spot) => theme.getColorFor(ThemeCode.buttonSecondary),
getTooltipItems: (List<LineBarSpot> touchedSpots) {
return touchedSpots.map((LineBarSpot touchedSpot) {
return LineTooltipItem(
"${touchedSpot.y}",
TextStyle(fontWeight: FontWeight.w500, fontSize: 14, color: theme.getColorFor(ThemeCode.textSecondary)),
);
}).toList();
},
),
getTouchedSpotIndicator: (
_,
indicators,
) {
return indicators
.map((int index) => const TouchedSpotIndicatorData(
FlLine(color: Colors.transparent),
FlDotData(show: false),
))
.toList();
},
touchSpotThreshold: 25,
distanceCalculator:
(Offset touchPoint, Offset spotPixelCoordinates) =>
(touchPoint - spotPixelCoordinates).distance,
),
borderData: FlBorderData(
show: true,
border: Border(
bottom: BorderSide(
color: Colors.lightBlue.withValues(alpha: 0.2),
width: 4
),
left: const BorderSide(color: Colors.transparent),
right: const BorderSide(color: Colors.transparent),
top: const BorderSide(color: Colors.transparent),
),
),
lineBarsData: [
LineChartBarData(
isCurved: true,
color: Colors.pink,
barWidth: 5,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(show: false),
spots: List<FlSpot>.generate(days.length, (int index){
return FlSpot(index.toDouble(), (index+1)%2);
})
),
LineChartBarData(
isCurved: true,
color: Colors.cyan,
barWidth: 5,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(show: false),
spots: List<FlSpot>.generate(days.length, (int index){
return FlSpot(index.toDouble(), index%2);
})
),
],
minX: 0,
maxX: days.length-1,
maxY: 1,
minY: 0,
))
)
],
),
);
}
}