You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
5.4 KiB
Dart
175 lines
5.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:fl_chart/fl_chart.dart';
|
|
|
|
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
|
import 'package:fluffychat/pangea/models/headwords.dart';
|
|
import 'package:fluffychat/pangea/pages/analytics/base_analytics_page.dart';
|
|
import 'package:fluffychat/widgets/matrix.dart';
|
|
import 'bar_chart_card.dart';
|
|
import 'messages_legend_widget.dart';
|
|
|
|
class VocabBarChart extends StatefulWidget {
|
|
final AnalyticsSelected? selected;
|
|
final AnalyticsSelected defaultSelected;
|
|
|
|
const VocabBarChart({
|
|
super.key,
|
|
required this.selected,
|
|
required this.defaultSelected,
|
|
});
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => VocabBarChartState();
|
|
}
|
|
|
|
class VocabBarChartState extends State<VocabBarChart> {
|
|
final double barSpace = 16;
|
|
|
|
final PangeaController _pangeaController = MatrixState.pangeaController;
|
|
|
|
@override
|
|
initState() {
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return FutureBuilder<VocabHeadwords>(
|
|
future: _pangeaController.analytics.vocabHeadsByAnalyticsSelected(
|
|
selected: widget.selected,
|
|
defaultSelected: widget.defaultSelected,
|
|
),
|
|
builder: ((context, snapshot) => BarChartCard(
|
|
barChartTitle: (widget.selected != null
|
|
? widget.selected!
|
|
: widget.defaultSelected)
|
|
.displayName,
|
|
barChart: snapshot.hasData
|
|
? buildBarChart(context, snapshot.data!)
|
|
: null,
|
|
loadingData: snapshot.connectionState != ConnectionState.done,
|
|
legend: const MessagesLegendsListWidget(),
|
|
)),
|
|
);
|
|
}
|
|
|
|
TextStyle titleTextStyle(BuildContext context) => TextStyle(
|
|
color: Theme.of(context).textTheme.bodyLarge!.color,
|
|
fontSize: 10,
|
|
);
|
|
|
|
BarChart buildBarChart(BuildContext context, VocabHeadwords vocabHeadwords) {
|
|
final flLine = FlLine(
|
|
color: Theme.of(context).dividerColor,
|
|
strokeWidth: 1,
|
|
);
|
|
|
|
return BarChart(
|
|
BarChartData(
|
|
alignment: BarChartAlignment.spaceEvenly,
|
|
barTouchData: BarTouchData(
|
|
enabled: false,
|
|
),
|
|
// barTouchData: barTouchData,
|
|
titlesData: FlTitlesData(
|
|
show: true,
|
|
bottomTitles: AxisTitles(
|
|
sideTitles: SideTitles(
|
|
showTitles: true,
|
|
reservedSize: 28,
|
|
getTitlesWidget: (double value, TitleMeta meta) =>
|
|
SideTitleWidget(
|
|
axisSide: meta.axisSide,
|
|
child: Text(
|
|
vocabHeadwords.lists[value.toInt()].name,
|
|
style: titleTextStyle(context),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
leftTitles: AxisTitles(
|
|
sideTitles: SideTitles(
|
|
showTitles: true,
|
|
reservedSize: 40,
|
|
getTitlesWidget: (double value, TitleMeta meta) {
|
|
Widget textWidget;
|
|
if (value != meta.max) {
|
|
textWidget =
|
|
Text(meta.formattedValue, style: titleTextStyle(context));
|
|
} else {
|
|
textWidget = const Icon(Icons.abc_outlined, size: 14);
|
|
}
|
|
return SideTitleWidget(
|
|
axisSide: meta.axisSide,
|
|
child: textWidget,
|
|
);
|
|
},
|
|
),
|
|
),
|
|
topTitles: AxisTitles(
|
|
sideTitles: SideTitles(showTitles: false),
|
|
),
|
|
rightTitles: AxisTitles(
|
|
sideTitles: SideTitles(showTitles: false),
|
|
),
|
|
),
|
|
gridData: FlGridData(
|
|
show: true,
|
|
// checkToShowHorizontalLine: (value) => value % 10 == 0,
|
|
checkToShowHorizontalLine: (value) => true,
|
|
getDrawingHorizontalLine: (value) => flLine,
|
|
checkToShowVerticalLine: (value) => false,
|
|
getDrawingVerticalLine: (value) => flLine,
|
|
),
|
|
borderData: FlBorderData(
|
|
show: false,
|
|
),
|
|
groupsSpace: barSpace,
|
|
barGroups: barChartGroupData(vocabHeadwords),
|
|
backgroundColor: Colors.transparent,
|
|
),
|
|
swapAnimationDuration: const Duration(milliseconds: 250),
|
|
);
|
|
}
|
|
|
|
List<BarChartGroupData> barChartGroupData(VocabHeadwords vocabHeadwords) {
|
|
// sort vocab into lists
|
|
// calculate levels based on vocab data
|
|
|
|
final List<BarChartGroupData> chartData = [];
|
|
|
|
vocabHeadwords.lists.asMap().forEach((index, intervalGroup) {
|
|
chartData.add(
|
|
BarChartGroupData(
|
|
x: index,
|
|
barsSpace: barSpace,
|
|
// barRods: intervalGroup.map(constructBarChartRodData).toList(),
|
|
barRods: constructBarChartRodData(intervalGroup),
|
|
),
|
|
);
|
|
});
|
|
return chartData;
|
|
}
|
|
|
|
List<BarChartRodData> constructBarChartRodData(VocabList vocabList) {
|
|
final ListTotals listTotals = vocabList.calculuateTotals();
|
|
final y1 = listTotals.low;
|
|
final y2 = y1 + listTotals.medium;
|
|
final y3 = y2 + listTotals.high;
|
|
|
|
return [
|
|
BarChartRodData(
|
|
toY: y3.toDouble(),
|
|
width: 10.toDouble(),
|
|
rodStackItems: [
|
|
BarChartRodStackItem(0, y1.toDouble(), Colors.red),
|
|
BarChartRodStackItem(y1.toDouble(), y2.toDouble(), Colors.grey),
|
|
BarChartRodStackItem(y2.toDouble(), y3.toDouble(), Colors.green),
|
|
],
|
|
borderRadius: BorderRadius.zero,
|
|
),
|
|
];
|
|
}
|
|
}
|