Skip to content
Snippets Groups Projects
Commit 4a42cc31 authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Stack global counts and eclecticism charts

parent 3159c8ca
No related branches found
No related tags found
1 merge request!18Resolve "Stack global counts and eclecticism charts"
Pipeline #4504 passed
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
app.versionName=0.0.16 app.versionName=0.0.17
app.versionCode=16 app.versionCode=17
Stack global counts and eclecticism charts.
Superposition des graphiques d'écoutes global et d'éclectisme.
...@@ -37,7 +37,7 @@ class CustomBarChart extends StatelessWidget { ...@@ -37,7 +37,7 @@ class CustomBarChart extends StatelessWidget {
} }
double getBarWidth(double containerWidth, int barsCount) { double getBarWidth(double containerWidth, int barsCount) {
return 0.7 * (containerWidth / barsCount); return 0.65 * (containerWidth / barsCount);
} }
List<BarChartGroupData> getDataCounts(double barWidth) { List<BarChartGroupData> getDataCounts(double barWidth) {
...@@ -118,11 +118,21 @@ class CustomBarChart extends StatelessWidget { ...@@ -118,11 +118,21 @@ class CustomBarChart extends StatelessWidget {
final AxisTitles verticalTitles = AxisTitles( final AxisTitles verticalTitles = AxisTitles(
sideTitles: SideTitles( sideTitles: SideTitles(
showTitles: true, showTitles: true,
reservedSize: 30, reservedSize: 35,
getTitlesWidget: getVerticalTitlesWidget, getTitlesWidget: getVerticalTitlesWidget,
interval: this.verticalTicksInterval, interval: this.verticalTicksInterval,
), ),
); );
final AxisTitles verticalSpacer = AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 35,
getTitlesWidget: getVerticalTitlesSpacerWidget,
interval: this.verticalTicksInterval,
),
);
final AxisTitles horizontalTitles = AxisTitles( final AxisTitles horizontalTitles = AxisTitles(
sideTitles: SideTitles( sideTitles: SideTitles(
showTitles: true, showTitles: true,
...@@ -136,13 +146,14 @@ class CustomBarChart extends StatelessWidget { ...@@ -136,13 +146,14 @@ class CustomBarChart extends StatelessWidget {
bottomTitles: horizontalTitles, bottomTitles: horizontalTitles,
leftTitles: verticalTitles, leftTitles: verticalTitles,
topTitles: none, topTitles: none,
rightTitles: verticalTitles, rightTitles: verticalSpacer,
); );
} }
Widget getVerticalTitlesWidget(double value, TitleMeta meta) { Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
String suffix = String suffix =
this.verticalAxisTitleSuffix != '' ? ' ' + this.verticalAxisTitleSuffix : ''; this.verticalAxisTitleSuffix != '' ? ' ' + this.verticalAxisTitleSuffix : '';
return SideTitleWidget( return SideTitleWidget(
axisSide: meta.axisSide, axisSide: meta.axisSide,
space: 4, space: 4,
...@@ -156,6 +167,14 @@ class CustomBarChart extends StatelessWidget { ...@@ -156,6 +167,14 @@ class CustomBarChart extends StatelessWidget {
); );
} }
Widget getVerticalTitlesSpacerWidget(double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
space: 4,
child: Text(''),
);
}
Widget getHorizontalTitlesWidget(double value, TitleMeta meta) { Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
final DateFormat formatter = DateFormat('dd/MM'); final DateFormat formatter = DateFormat('dd/MM');
...@@ -165,13 +184,16 @@ class CustomBarChart extends StatelessWidget { ...@@ -165,13 +184,16 @@ class CustomBarChart extends StatelessWidget {
return SideTitleWidget( return SideTitleWidget(
axisSide: meta.axisSide, axisSide: meta.axisSide,
space: 4, space: 4,
child: RotationTransition( child: Padding(
turns: new AlwaysStoppedAnimation(-30 / 360), padding: EdgeInsets.only(right: 10),
child: Text( child: RotationTransition(
text, turns: new AlwaysStoppedAnimation(-30 / 360),
style: TextStyle( child: Text(
color: AppColors.mainTextColor1, text,
fontSize: this.titleFontSize, style: TextStyle(
color: AppColors.mainTextColor1,
fontSize: this.titleFontSize,
),
), ),
), ),
), ),
......
import 'package:easy_localization/easy_localization.dart';
import 'package:fl_chart/fl_chart.dart'; import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../config/app_colors.dart'; import '../../../config/app_colors.dart';
import '../../../utils/color_extensions.dart';
class CustomLineChart extends StatelessWidget { class CustomLineChart extends StatelessWidget {
CustomLineChart({super.key}); CustomLineChart({super.key});
...@@ -20,34 +18,54 @@ class CustomLineChart extends StatelessWidget { ...@@ -20,34 +18,54 @@ class CustomLineChart extends StatelessWidget {
); );
} }
LinearGradient getGradient(Color baseColor) {
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: <Color>[
baseColor.lighten(30),
baseColor,
baseColor.darken(30),
],
tileMode: TileMode.mirror,
);
}
FlBorderData getBorderData() { FlBorderData getBorderData() {
return FlBorderData( return FlBorderData(
show: true, show: false,
border: Border.all(
color: AppColors.borderColor,
width: 2,
),
); );
} }
FlGridData getGridData() { FlGridData getGridData() {
return const FlGridData( return const FlGridData(
show: false,
);
}
FlTitlesData getTitlesData() {
const AxisTitles none = const AxisTitles(
sideTitles: SideTitles(showTitles: false),
);
final AxisTitles verticalTitles = AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 35,
getTitlesWidget: getVerticalTitlesWidget,
interval: 25,
),
);
final AxisTitles verticalSpacer = AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 35,
getTitlesWidget: getVerticalTitlesSpacerWidget,
),
);
final AxisTitles horizontalTitles = AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 20,
getTitlesWidget: getHorizontalTitlesWidget,
),
);
return FlTitlesData(
show: true, show: true,
drawHorizontalLine: true, bottomTitles: horizontalTitles,
drawVerticalLine: false, leftTitles: verticalSpacer,
topTitles: none,
rightTitles: verticalTitles,
); );
} }
...@@ -56,7 +74,7 @@ class CustomLineChart extends StatelessWidget { ...@@ -56,7 +74,7 @@ class CustomLineChart extends StatelessWidget {
axisSide: meta.axisSide, axisSide: meta.axisSide,
space: 4, space: 4,
child: Text( child: Text(
value.toInt().toString(), value.toInt().toString() + ' %',
style: TextStyle( style: TextStyle(
color: AppColors.mainTextColor1, color: AppColors.mainTextColor1,
fontSize: this.titleFontSize, fontSize: this.titleFontSize,
...@@ -65,28 +83,18 @@ class CustomLineChart extends StatelessWidget { ...@@ -65,28 +83,18 @@ class CustomLineChart extends StatelessWidget {
); );
} }
Widget getHorizontalTitlesWidget(double value, TitleMeta meta) { Widget getVerticalTitlesSpacerWidget(double value, TitleMeta meta) {
final DateFormat formatter = DateFormat('dd/MM');
final DateTime date = DateTime.fromMillisecondsSinceEpoch(value.toInt());
final String text = formatter.format(date);
return SideTitleWidget( return SideTitleWidget(
axisSide: meta.axisSide, axisSide: meta.axisSide,
space: 4, space: 4,
child: RotationTransition( child: Text(''),
turns: new AlwaysStoppedAnimation(-30 / 360),
child: Text(
text,
style: TextStyle(
color: AppColors.mainTextColor1,
fontSize: this.titleFontSize,
),
),
),
); );
} }
Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
return Text('');
}
LineTouchData getLineTouchDataEclecticism() { LineTouchData getLineTouchDataEclecticism() {
return LineTouchData( return LineTouchData(
handleBuiltInTouches: true, handleBuiltInTouches: true,
......
...@@ -10,7 +10,7 @@ class ChartTimelineCounts extends CustomBarChart { ...@@ -10,7 +10,7 @@ class ChartTimelineCounts extends CustomBarChart {
ChartTimelineCounts({super.key, required this.chartData}); ChartTimelineCounts({super.key, required this.chartData});
final double chartHeight = 150.0; final double chartHeight = 120.0;
final double verticalTicksInterval = 50; final double verticalTicksInterval = 50;
@override @override
......
...@@ -13,16 +13,19 @@ class ChartTimelineEclecticism extends CustomLineChart { ...@@ -13,16 +13,19 @@ class ChartTimelineEclecticism extends CustomLineChart {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final horizontalScale = getHorizontalScale();
return Container( return Container(
height: this.chartHeight, height: this.chartHeight,
child: LineChart( child: LineChart(
LineChartData( LineChartData(
lineBarsData: getDataEclecticism(), lineBarsData: getDataEclecticism(),
backgroundColor: Theme.of(context).colorScheme.onSurface,
borderData: getBorderData(), borderData: getBorderData(),
gridData: getGridData(), gridData: getGridData(),
titlesData: getTitlesData(), titlesData: getTitlesData(),
lineTouchData: getLineTouchDataEclecticism(), lineTouchData: getLineTouchDataEclecticism(),
minX: horizontalScale['min'],
maxX: horizontalScale['max'],
maxY: 100, maxY: 100,
minY: 0, minY: 0,
), ),
...@@ -31,6 +34,33 @@ class ChartTimelineEclecticism extends CustomLineChart { ...@@ -31,6 +34,33 @@ class ChartTimelineEclecticism extends CustomLineChart {
); );
} }
Map<String, double> getHorizontalScale() {
// Left/right margins: 12h, in milliseconds
int margin = 12 * 60 * 60 * 1000;
double minDateAsDouble = double.maxFinite;
double maxDateAsDouble = -double.maxFinite;
this.chartData.data.keys.forEach((element) {
TimelineDataValue? value = this.chartData.data[element];
if (value != null) {
final double date = DateTime.parse(element).millisecondsSinceEpoch.toDouble();
if (date < minDateAsDouble) {
minDateAsDouble = date;
}
if (date > maxDateAsDouble) {
maxDateAsDouble = date;
}
}
});
return {
'min': minDateAsDouble - margin,
'max': maxDateAsDouble + margin,
};
}
List<LineChartBarData> getDataEclecticism() { List<LineChartBarData> getDataEclecticism() {
List<FlSpot> spots = []; List<FlSpot> spots = [];
...@@ -45,53 +75,17 @@ class ChartTimelineEclecticism extends CustomLineChart { ...@@ -45,53 +75,17 @@ class ChartTimelineEclecticism extends CustomLineChart {
}); });
final baseColor = AppColors.contentColorCyan; final baseColor = AppColors.contentColorCyan;
final gradient = getGradient(baseColor);
final borderColor = baseColor.darken(20); final borderColor = baseColor.darken(20);
return [ return [
LineChartBarData( LineChartBarData(
isCurved: true, isCurved: true,
color: borderColor, color: borderColor,
barWidth: 3, barWidth: 2,
isStrokeCapRound: false, isStrokeCapRound: false,
dotData: const FlDotData(show: false), dotData: const FlDotData(show: false),
belowBarData: BarAreaData(
show: true,
color: baseColor,
gradient: gradient,
),
spots: spots, spots: spots,
), ),
]; ];
} }
FlTitlesData getTitlesData() {
const AxisTitles none = const AxisTitles(
sideTitles: SideTitles(showTitles: false),
);
final AxisTitles verticalTitles = AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 30,
getTitlesWidget: getVerticalTitlesWidget,
interval: 25,
),
);
final AxisTitles horizontalTitles = AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 20,
getTitlesWidget: getHorizontalTitlesWidget,
),
);
return FlTitlesData(
show: true,
bottomTitles: horizontalTitles,
leftTitles: verticalTitles,
topTitles: none,
rightTitles: verticalTitles,
);
}
} }
...@@ -35,14 +35,11 @@ class ChartTimelineCardContent extends StatelessWidget { ...@@ -35,14 +35,11 @@ class ChartTimelineCardContent extends StatelessWidget {
const SizedBox(height: 8), const SizedBox(height: 8),
this.isLoading this.isLoading
? Text(placeholder) ? Text(placeholder)
: Column( : Stack(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
ChartTimelineCounts( ChartTimelineCounts(
chartData: TimelineData.fromJson(jsonDecode(this.chartData.toString())), chartData: TimelineData.fromJson(jsonDecode(this.chartData.toString())),
), ),
const SizedBox(height: 8),
ChartTimelineEclecticism( ChartTimelineEclecticism(
chartData: TimelineData.fromJson(jsonDecode(this.chartData.toString())), chartData: TimelineData.fromJson(jsonDecode(this.chartData.toString())),
), ),
......
...@@ -3,7 +3,7 @@ description: Display scrobbles data and charts ...@@ -3,7 +3,7 @@ description: Display scrobbles data and charts
publish_to: 'none' publish_to: 'none'
version: 0.0.16+16 version: 0.0.17+17
environment: environment:
sdk: '^3.0.0' sdk: '^3.0.0'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment