Skip to content

Commit

Permalink
Merge pull request RIP-Comm#134 from PietroChitto/linechart
Browse files Browse the repository at this point in the history
fix linechart
  • Loading branch information
theperu authored Feb 1, 2024
2 parents 3c7a2f1 + 29cbff0 commit c446b09
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 109 deletions.
4 changes: 2 additions & 2 deletions lib/custom_widgets/account_modal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class AccountDialog extends StatelessWidget with Functions {
const Padding(
padding: EdgeInsets.all(8.0),
),
const LineChartWidget(
LineChartWidget(
line1Data: [
FlSpot(0, 3),
FlSpot(1, 1.3),
Expand All @@ -80,7 +80,7 @@ class AccountDialog extends StatelessWidget with Functions {
line2Data: <FlSpot>[],
colorLine2Data: Color(0xffffffff),
colorBackground: Color(0xff356CA3),
maxDays: 30.0,
period: Period.month,
),
const Padding(
padding: EdgeInsets.only(bottom: 14.0),
Expand Down
261 changes: 161 additions & 100 deletions lib/custom_widgets/line_chart.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import 'dart:math';

import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

enum Period {
month,
year
}

//This class can be used when we need to draw a line chart with one or two lines
class LineChartWidget extends StatefulWidget {
Expand All @@ -9,22 +17,36 @@ class LineChartWidget extends StatefulWidget {
final List<FlSpot> line2Data; //this should be a list of Flspot(x,y), if you only need one just put an empty list
final Color colorLine2Data;

//Contains the number of days of the month
final double maxDays;

// Used to decide the bottom label
final Period period;
final int currentMonthDays = DateUtils.getDaysInMonth(DateTime.now().year, DateTime.now().month);
final int nXLabel = 10;
final double minY;

final Color colorBackground;
const LineChartWidget({
LineChartWidget({
super.key,
required this.line1Data,
required this.colorLine1Data,
required this.line2Data,
required this.colorLine2Data,
required this.colorBackground,
this.maxDays = 31,
});
this.period = Period.month,
int nXLabel = 10,
double? minY,
}) : minY = minY ?? calculateMinY(line1Data, line2Data);

static double calculateMinY(List<FlSpot> line1Data, List<FlSpot> line2Data){
if (line1Data.isEmpty && line2Data.isEmpty) {
return 0;
}

return [...line1Data, ...line2Data].map((e) => e.y).reduce(min);
}

@override
State<LineChartWidget> createState() => _LineChartSample2State();

}

class _LineChartSample2State extends State<LineChartWidget> {
Expand All @@ -45,8 +67,28 @@ class _LineChartSample2State extends State<LineChartWidget> {
),
child: Padding(
padding: const EdgeInsets.only(top: 24),
child: LineChart(
mainData(),
child: Builder(
builder: (context) {
if(widget.line1Data.length < 2 && widget.line2Data.length < 2){
return Center(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: DefaultTextStyle.of(context).style,
children: <TextSpan>[
TextSpan(
text: "We are sorry but there are not\nenough data to make the graph",
style: TextStyle(color: Theme.of(context).hintColor),
)
]
)
),
); }

return LineChart(
mainData(),
);
},
),
),
),
Expand All @@ -62,24 +104,36 @@ class _LineChartSample2State extends State<LineChartWidget> {
fontSize: 8,
);
Widget text;
switch (widget.maxDays) {
case 12:
switch (widget.period) {
case Period.year:
switch (value.toInt()) {
case 0:
text = Text('Jan', style: style);
case 1:
text = Text('Feb', style: style);
break;
case 2:
text = Text('Mar', style: style);
break;
case 3:
text = Text('Apr', style: style);
break;
case 4:
text = Text('May', style: style);
break;
case 5:
text = Text('Jun', style: style);
break;
case 6:
text = Text('Jul', style: style);
break;
case 7:
text = Text('Aug', style: style);
break;
case 8:
text = Text('Sep', style: style);
break;
case 9:
text = Text('Oct', style: style);
break;
case 10:
text = Text('Nov', style: style);
break;
Expand All @@ -88,94 +142,14 @@ class _LineChartSample2State extends State<LineChartWidget> {
break;
}
break;
case 28:
switch (value.toInt()) {
case 6:
text = Text('7', style: style);
break;
case 12:
text = Text('13', style: style);
break;
case 17:
text = Text('18', style: style);
break;
case 23:
text = Text('24', style: style);
break;
case 27:
text = Text('28', style: style);
break;
default:
text = Text('', style: style);
break;
}
break;
case 29:
switch (value.toInt()) {
case 6:
text = Text('7', style: style);
break;
case 12:
text = Text('13', style: style);
break;
case 17:
text = Text('18', style: style);
break;
case 23:
text = Text('24', style: style);
break;
case 27:
text = Text('28', style: style);
break;
default:
text = Text('', style: style);
break;
}
break;
case 30:
switch (value.toInt()) {
case 5:
text = Text('6', style: style);
break;
case 11:
text = Text('12', style: style);
break;
case 17:
text = Text('18', style: style);
break;
case 23:
text = Text('24', style: style);
break;
case 29:
text = Text('30', style: style);
break;
default:
text = Text('', style: style);
break;
case Period.month:
int step = (widget.currentMonthDays / widget.nXLabel).round();
if(value.toInt() % step == 1 && value.toInt() != widget.currentMonthDays){
text = Text((value + 1).toStringAsFixed(0), style: style,);
}else{
text = Text('', style: style);
}
break;
case 31:
switch (value.toInt()) {
case 3:
text = Text('4', style: style);
break;
case 10:
text = Text('11', style: style);
break;
case 17:
text = Text('18', style: style);
break;
case 24:
text = Text('25', style: style);
break;
case 30:
text = Text('31', style: style);
break;
default:
text = Text('', style: style);
break;
}
break;

default:
text = Text('', style: style);
break;
Expand Down Expand Up @@ -208,13 +182,100 @@ class _LineChartSample2State extends State<LineChartWidget> {
),
),
gridData: const FlGridData(show: false),
lineTouchData: LineTouchData(
getTouchedSpotIndicator:
(LineChartBarData barData, List<int> spotIndexes) {
bool allSameX = spotIndexes.toSet().length == 1;

if(!allSameX){
return [];
}
return spotIndexes.map((spotIndex) {
return TouchedSpotIndicatorData(
const FlLine(
color: Colors.blueGrey,
strokeWidth: 2,
),
FlDotData(
getDotPainter: (spot, percent, barData, index) {
return FlDotCirclePainter(
radius: 2,
color: Colors.grey,
strokeWidth: 2,
strokeColor: Colors.blueGrey
);
},
),
);
}).toList();
},
touchTooltipData: LineTouchTooltipData(
fitInsideHorizontally: true,
getTooltipItems: (List<LineBarSpot> touchedBarSpots) {
bool allSameX = touchedBarSpots.map((e) => e.x).toSet().length == 1;

if(!allSameX || touchedBarSpots.isEmpty){
return [];
}

double x = touchedBarSpots[0].x;
DateTime date = widget.period == Period.month ?
DateTime(DateTime.now().year, DateTime.now().month, (x+1).toInt()) :
DateTime(DateTime.now().year, (x+1).toInt(), 1);
String dateFormat = widget.period == Period.month ?
DateFormat(DateFormat.ABBR_MONTH_DAY).format(date) :
DateFormat(DateFormat.ABBR_MONTH).format(date);

LineTooltipItem first = LineTooltipItem(
'$dateFormat \n\n',
TextStyle(
color: Theme.of(context).colorScheme.onBackground,
fontWeight: FontWeight.bold,
),
children: [
TextSpan(
text: touchedBarSpots[0].y.toString(),
style: TextStyle(
color: widget.colorLine2Data,
fontWeight: FontWeight.w900,
),
),
],
);

var others = touchedBarSpots.sublist(1).map((barSpot) {
final flSpot = barSpot;

return LineTooltipItem(
'',
const TextStyle(
fontWeight: FontWeight.bold,
),
children: [
TextSpan(
text: flSpot.y.toString(),
style: TextStyle(
color: widget.colorLine1Data,
fontWeight: FontWeight.w900,
),
),
],
);
}).toList();

return [first, ...others];
},
),
),

borderData: FlBorderData(
border: const Border(
bottom: BorderSide(color: Colors.grey, width: 1.0, style: BorderStyle.solid),
),
),
minX: 0,
maxX: widget.maxDays - 1,
maxX: widget.period == Period.year ? 11 : widget.currentMonthDays - 1, // if year display 12 month, if mont display the number of days in the month
minY: widget.minY,
lineBarsData: [
LineChartBarData(
spots: widget.line1Data,
Expand Down
2 changes: 1 addition & 1 deletion lib/model/bank_account.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class BankAccountMethods extends SossoldiDatabase {
final db = await database;

final orderByASC = '${BankAccountFields.createdAt} ASC';
final where = '${BankAccountFields.active} = 1 AND ${TransactionFields.recurring} = 0';
final where = '${BankAccountFields.active} = 1 AND (t.${TransactionFields.recurring} = 0 OR t.${TransactionFields.recurring} is NULL)';

final result = await db.rawQuery('''
SELECT b.*, (b.${BankAccountFields.startingValue} +
Expand Down
3 changes: 2 additions & 1 deletion lib/pages/account_page/account_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ class _AccountPage extends ConsumerState<AccountPage> with Functions {
line2Data: const <FlSpot>[],
colorLine2Data: const Color(0xffffffff),
colorBackground: blue5,
maxDays: DateUtils.getDaysInMonth(DateTime.now().year, DateTime.now().month).toDouble(),
period: Period.month,
minY: 0,
),
),
],
Expand Down
2 changes: 1 addition & 1 deletion lib/pages/statistics_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class _StatsPageState extends ConsumerState<StatsPage> with Functions {
line2Data: <FlSpot>[],
colorLine2Data: Color(0xffB9BABC),
colorBackground: Color(0xffF1F5F9),
maxDays: 12.0,
period: Period.year,
),
);
},
Expand Down
Loading

0 comments on commit c446b09

Please sign in to comment.