stats: layout on small screens
This commit is contained in:
parent
b3fde095e9
commit
dad5f080c2
1 changed files with 71 additions and 47 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/model/collection_lens.dart';
|
import 'package:aves/model/collection_lens.dart';
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/model/filters/location.dart';
|
import 'package:aves/model/filters/location.dart';
|
||||||
|
@ -19,6 +21,10 @@ class StatsPage extends StatelessWidget {
|
||||||
final CollectionLens collection;
|
final CollectionLens collection;
|
||||||
final Map<String, int> entryCountPerCity = Map(), entryCountPerCountry = Map(), entryCountPerTag = Map();
|
final Map<String, int> entryCountPerCity = Map(), entryCountPerCountry = Map(), entryCountPerTag = Map();
|
||||||
|
|
||||||
|
List<ImageEntry> get entries => collection.sortedEntries;
|
||||||
|
|
||||||
|
static const mimeDonutMinWidth = 124.0;
|
||||||
|
|
||||||
StatsPage({this.collection}) {
|
StatsPage({this.collection}) {
|
||||||
entries.forEach((entry) {
|
entries.forEach((entry) {
|
||||||
if (entry.isLocated) {
|
if (entry.isLocated) {
|
||||||
|
@ -38,8 +44,6 @@ class StatsPage extends StatelessWidget {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ImageEntry> get entries => collection.sortedEntries;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final catalogued = entries.where((entry) => entry.isCatalogued);
|
final catalogued = entries.where((entry) => entry.isCatalogued);
|
||||||
|
@ -59,8 +63,8 @@ class StatsPage extends StatelessWidget {
|
||||||
Wrap(
|
Wrap(
|
||||||
alignment: WrapAlignment.center,
|
alignment: WrapAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_buildMimePie(context, (sum) => Intl.plural(sum, one: 'image', other: 'images'), imagesByMimeTypes),
|
_buildMimeDonut(context, (sum) => Intl.plural(sum, one: 'image', other: 'images'), imagesByMimeTypes),
|
||||||
_buildMimePie(context, (sum) => Intl.plural(sum, one: 'video', other: 'videos'), videoByMimeTypes),
|
_buildMimeDonut(context, (sum) => Intl.plural(sum, one: 'video', other: 'videos'), videoByMimeTypes),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
|
@ -93,7 +97,7 @@ class StatsPage extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMimePie(BuildContext context, String Function(num) label, Map<String, num> byMimeTypes) {
|
Widget _buildMimeDonut(BuildContext context, String Function(num) label, Map<String, num> byMimeTypes) {
|
||||||
if (byMimeTypes.isEmpty) return const SizedBox.shrink();
|
if (byMimeTypes.isEmpty) return const SizedBox.shrink();
|
||||||
|
|
||||||
final sum = byMimeTypes.values.fold(0, (prev, v) => prev + v);
|
final sum = byMimeTypes.values.fold(0, (prev, v) => prev + v);
|
||||||
|
@ -116,50 +120,70 @@ class StatsPage extends StatelessWidget {
|
||||||
];
|
];
|
||||||
|
|
||||||
return LayoutBuilder(builder: (context, constraints) {
|
return LayoutBuilder(builder: (context, constraints) {
|
||||||
var mq = MediaQuery.of(context);
|
final mq = MediaQuery.of(context);
|
||||||
final dim = constraints.maxWidth / (mq.orientation == Orientation.portrait ? 2 : 4);
|
final availableWidth = constraints.maxWidth;
|
||||||
return Row(
|
final double dim = max(mimeDonutMinWidth, availableWidth / (mq.orientation == Orientation.landscape && availableWidth > 4 * mimeDonutMinWidth ? 4 : 2));
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
final donut = Container(
|
||||||
Container(
|
width: dim,
|
||||||
width: dim,
|
height: dim,
|
||||||
height: dim,
|
child: Stack(
|
||||||
child: Stack(
|
children: [
|
||||||
children: [
|
charts.PieChart(
|
||||||
charts.PieChart(
|
series,
|
||||||
series,
|
defaultRenderer: charts.ArcRendererConfig(
|
||||||
defaultRenderer: charts.ArcRendererConfig(
|
arcWidth: 16,
|
||||||
arcWidth: 16,
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
Center(
|
|
||||||
child: Text(
|
|
||||||
'${sum}\n${label(sum)}',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
Center(
|
||||||
SizedBox(
|
child: Text(
|
||||||
width: dim,
|
'${sum}\n${label(sum)}',
|
||||||
child: Column(
|
textAlign: TextAlign.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
),
|
||||||
children: seriesData
|
],
|
||||||
.map((kv) => Row(
|
),
|
||||||
children: [
|
|
||||||
Icon(Icons.fiber_manual_record, color: stringToColor(kv.key)),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Text(kv.key),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Text('${kv.value}', style: const TextStyle(color: Colors.white70)),
|
|
||||||
],
|
|
||||||
))
|
|
||||||
.toList()),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
final legend = SizedBox(
|
||||||
|
width: dim,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: seriesData
|
||||||
|
.map((kv) => RichText(
|
||||||
|
overflow: TextOverflow.fade,
|
||||||
|
softWrap: false,
|
||||||
|
maxLines: 1,
|
||||||
|
text: TextSpan(
|
||||||
|
children: [
|
||||||
|
WidgetSpan(
|
||||||
|
alignment: PlaceholderAlignment.middle,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.only(end: 8),
|
||||||
|
child: Icon(Icons.fiber_manual_record, color: stringToColor(kv.key)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(text: '${kv.key} '),
|
||||||
|
TextSpan(text: '${kv.value}', style: const TextStyle(color: Colors.white70)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final children = [
|
||||||
|
donut,
|
||||||
|
legend,
|
||||||
|
];
|
||||||
|
return availableWidth > mimeDonutMinWidth * 2
|
||||||
|
? Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: children,
|
||||||
|
)
|
||||||
|
: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: children,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue