Skip to content

Commit

Permalink
Add weekly chart
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiasn committed Jul 18, 2022
1 parent 0e347c1 commit a10e940
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 5 deletions.
21 changes: 21 additions & 0 deletions lib/blocs/charts/story_chart_info_cubit.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:lotti/logic/charts/story_data.dart';
import 'package:lotti/widgets/charts/utils.dart';

part 'story_chart_info_cubit.freezed.dart';
Expand All @@ -22,3 +23,23 @@ class StoryChartInfoState with _$StoryChartInfoState {
required MeasuredObservation? selected,
}) = _StoryChartInfoState;
}

class WeeklyStoryChartInfoCubit extends Cubit<WeeklyStoryChartInfoState> {
WeeklyStoryChartInfoCubit()
: super(WeeklyStoryChartInfoState(selected: null));

void setSelected(WeeklyAggregate? observation) {
emit(WeeklyStoryChartInfoState(selected: observation));
}

void clearSelected() {
emit(WeeklyStoryChartInfoState(selected: null));
}
}

@freezed
class WeeklyStoryChartInfoState with _$WeeklyStoryChartInfoState {
factory WeeklyStoryChartInfoState({
required WeeklyAggregate? selected,
}) = _WeeklyStoryChartInfoState;
}
17 changes: 13 additions & 4 deletions lib/pages/dashboards/dashboard_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,19 @@ class _DashboardPageState extends State<DashboardPage> {
},
wildcardStoryTimeChart:
(WildcardStoryTimeItem storyChart) {
return WildcardStoryChart(
chartConfig: storyChart,
rangeStart: rangeStart,
rangeEnd: rangeEnd,
return Column(
children: [
WildcardStoryChart(
chartConfig: storyChart,
rangeStart: rangeStart,
rangeEnd: rangeEnd,
),
WildcardStoryWeeklyChart(
chartConfig: storyChart,
rangeStart: rangeStart,
rangeEnd: rangeEnd,
),
],
);
},
surveyChart: (DashboardSurveyItem surveyChart) {
Expand Down
186 changes: 186 additions & 0 deletions lib/widgets/charts/stories/wildcard_story_chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,189 @@ class InfoWidget extends StatelessWidget {
);
}
}

class WildcardStoryWeeklyChart extends StatefulWidget {
const WildcardStoryWeeklyChart({
super.key,
required this.chartConfig,
required this.rangeStart,
required this.rangeEnd,
});

final WildcardStoryTimeItem chartConfig;
final DateTime rangeStart;
final DateTime rangeEnd;

@override
State<WildcardStoryWeeklyChart> createState() =>
_WildcardStoryWeeklyChartState();
}

class _WildcardStoryWeeklyChartState extends State<WildcardStoryWeeklyChart> {
final _chartState = charts.UserManagedState<String>();
final JournalDb _db = getIt<JournalDb>();
final TagsService tagsService = getIt<TagsService>();

@override
void initState() {
super.initState();
}

@override
Widget build(BuildContext context) {
final subString = widget.chartConfig.storySubstring;
final title = subString;

return BlocProvider<WeeklyStoryChartInfoCubit>(
create: (BuildContext context) => WeeklyStoryChartInfoCubit(),
child: StreamBuilder<List<JournalEntity?>>(
stream: _db.watchJournalByTagIds(
match: subString,
rangeStart: widget.rangeStart,
rangeEnd: widget.rangeEnd,
),
builder: (
BuildContext context,
AsyncSnapshot<List<JournalEntity?>> snapshot,
) {
final data = aggregateStoryWeeklyTimeSum(
snapshot.data ?? [],
rangeStart: widget.rangeStart,
rangeEnd: widget.rangeEnd,
);

final seriesList = [
charts.Series<WeeklyAggregate, String>(
id: widget.chartConfig.storySubstring,
domainFn: (WeeklyAggregate val, _) => val.isoWeek.substring(5),
measureFn: (WeeklyAggregate val, _) => val.value,
data: data,
labelAccessorFn: (byWeek, _) => minutesToHhMm(byWeek.value),
),
];

void _infoSelectionModelUpdated(
charts.SelectionModel<String> model,
) {
if (model.hasDatumSelection) {
final newSelection =
model.selectedDatum.first.datum as WeeklyAggregate;
context
.read<WeeklyStoryChartInfoCubit>()
.setSelected(newSelection);
_chartState.selectionModels[charts.SelectionModelType.info] =
charts.UserManagedSelectionModel(model: model);
} else {
context.read<WeeklyStoryChartInfoCubit>().clearSelected();
_chartState.selectionModels[charts.SelectionModelType.info] =
charts.UserManagedSelectionModel();
}
}

return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Container(
key: Key('${widget.chartConfig.hashCode}2'),
color: Colors.white,
height: 120,
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Stack(
children: [
charts.BarChart(
seriesList,
animate: false,
selectionModels: [
charts.SelectionModelConfig(
updatedListener: _infoSelectionModelUpdated,
)
],
barRendererDecorator: charts.BarLabelDecorator<String>(),
domainAxis: const charts.OrdinalAxisSpec(),
primaryMeasureAxis: const charts.NumericAxisSpec(
tickFormatterSpec: charts.BasicNumericTickFormatterSpec(
minutesToHhMm,
),
tickProviderSpec: charts.BasicNumericTickProviderSpec(
zeroBound: true,
dataIsInWholeNumbers: false,
desiredMinTickCount: 4,
desiredMaxTickCount: 5,
),
),
),
InfoWidget2(title),
],
),
),
),
);
},
),
);
}
}

class InfoWidget2 extends StatelessWidget {
const InfoWidget2(
this.title, {
super.key,
});

final String title;

@override
Widget build(BuildContext context) {
return BlocBuilder<WeeklyStoryChartInfoCubit, WeeklyStoryChartInfoState>(
builder: (BuildContext context, WeeklyStoryChartInfoState state) {
final selected = state.selected;
final duration = minutesToHhMmSs(selected?.value ?? 0);

return Positioned(
top: 0,
left: MediaQuery.of(context).size.width / 4,
child: SizedBox(
width: MediaQuery.of(context).size.width / 2,
child: IgnorePointer(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Spacer(),
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width / 2,
),
child: Text(
title,
style: chartTitleStyle(),
overflow: TextOverflow.ellipsis,
softWrap: false,
),
),
if (selected != null) ...[
const Spacer(),
Padding(
padding: AppTheme.chartDateHorizontalPadding,
child: Text(
selected.isoWeek,
style: chartTitleStyle(),
),
),
const Spacer(),
Text(
' $duration',
style: chartTitleStyle()
.copyWith(fontWeight: FontWeight.bold),
),
],
const Spacer(),
],
),
),
),
);
},
);
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: lotti
description: A Smart Journal.
publish_to: 'none'
version: 0.8.113+1169
version: 0.8.113+1170

msix_config:
display_name: Lotti
Expand Down

0 comments on commit a10e940

Please sign in to comment.