From 3b99f4feeb5ee744e757d906f31556ce5c90ae48 Mon Sep 17 00:00:00 2001 From: Yegor Vialov Date: Sat, 3 Nov 2018 22:50:21 +0200 Subject: [PATCH] Resolves #120 --- .../history_chart/combined_history_chart.dart | 158 +++++------------- .../history_chart/entity_history_moment.dart | 25 +++ .../history_chart/history_control_widget.dart | 86 ++++++++++ .../numeric_state_history_chart.dart | 53 +++--- .../simple_state_history_chart.dart | 130 ++++---------- lib/main.dart | 2 + 6 files changed, 215 insertions(+), 239 deletions(-) create mode 100644 lib/entity_widgets/history_chart/entity_history_moment.dart create mode 100644 lib/entity_widgets/history_chart/history_control_widget.dart diff --git a/lib/entity_widgets/history_chart/combined_history_chart.dart b/lib/entity_widgets/history_chart/combined_history_chart.dart index 42d3b78..a6855da 100644 --- a/lib/entity_widgets/history_chart/combined_history_chart.dart +++ b/lib/entity_widgets/history_chart/combined_history_chart.dart @@ -17,7 +17,7 @@ class CombinedHistoryChartWidget extends StatefulWidget { class _CombinedHistoryChartWidgetState extends State { int _selectedId = -1; - List> _parsedHistory; + List> _parsedHistory; @override void initState() { @@ -46,7 +46,7 @@ class _CombinedHistoryChartWidgetState extends State mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ - CombinedHistoryControlWidget( + HistoryControlWidget( selectedTimeStart: selectedTime, selectedStates: selectedStates, onPrevTap: () => _selectPrev(), @@ -93,13 +93,13 @@ class _CombinedHistoryChartWidgetState extends State } } - List> _parseHistory() { + List> _parseHistory() { TheLogger.debug(" parsing history..."); - Map> numericDataLists = {}; + Map> numericDataLists = {}; int colorIdCounter = 0; widget.config.numericAttributesToShow.forEach((String attrName) { TheLogger.debug(" parsing attribute $attrName"); - List data = []; + List data = []; DateTime now = DateTime.now(); for (var i = 0; i < widget.rawHistory.length; i++) { var stateData = widget.rawHistory[i]; @@ -121,9 +121,28 @@ class _CombinedHistoryChartWidgetState extends State hiddenLine = hiddenDot; endTime = now; } - data.add(CombinedEntityStateHistoryMoment(value, previousValue, hiddenDot, hiddenLine, stateData["state"], startTime, endTime, i, colorIdCounter)); + data.add(EntityHistoryMoment( + value: value, + previousValue: previousValue, + hiddenDot: hiddenDot, + hiddenLine: hiddenLine, + state: stateData["state"], + startTime: startTime, + endTime: endTime, + id: i, + colorId: colorIdCounter + )); } - data.add(CombinedEntityStateHistoryMoment(data.last.value, data.last.previousValue, data.last.hiddenDot, data.last.hiddenLine, data.last.state, now, null, widget.rawHistory.length, colorIdCounter)); + data.add(EntityHistoryMoment( + value: data.last.value, + previousValue: data.last.previousValue, + hiddenDot: data.last.hiddenDot, + hiddenLine: data.last.hiddenLine, + state: data.last.state, + startTime: now, + id: widget.rawHistory.length, + colorId: colorIdCounter + )); numericDataLists.addAll({attrName: data}); colorIdCounter += 1; }); @@ -131,14 +150,14 @@ class _CombinedHistoryChartWidgetState extends State if ((_selectedId == -1) && (numericDataLists.isNotEmpty)) { _selectedId = 0; } - List> result = []; + List> result = []; numericDataLists.forEach((attrName, dataList) { TheLogger.debug(" adding ${dataList.length} data values"); result.add( - new charts.Series( + new charts.Series( id: "value", - colorFn: (CombinedEntityStateHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor("_", historyMoment.colorId), - radiusPxFn: (CombinedEntityStateHistoryMoment historyMoment, __) { + colorFn: (EntityHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor("_", historyMoment.colorId), + radiusPxFn: (EntityHistoryMoment historyMoment, __) { if (historyMoment.hiddenDot) { return 0.0; } else if (historyMoment.id == _selectedId) { @@ -147,9 +166,9 @@ class _CombinedHistoryChartWidgetState extends State return 1.0; } }, - strokeWidthPxFn: (CombinedEntityStateHistoryMoment historyMoment, __) => historyMoment.hiddenLine ? 0.0 : 2.0, - domainFn: (CombinedEntityStateHistoryMoment historyMoment, _) => historyMoment.startTime, - measureFn: (CombinedEntityStateHistoryMoment historyMoment, _) => historyMoment.value ?? historyMoment.previousValue, + strokeWidthPxFn: (EntityHistoryMoment historyMoment, __) => historyMoment.hiddenLine ? 0.0 : 2.0, + domainFn: (EntityHistoryMoment historyMoment, _) => historyMoment.startTime, + measureFn: (EntityHistoryMoment historyMoment, _) => historyMoment.value ?? historyMoment.previousValue, data: dataList, /*domainLowerBoundFn: (CombinedEntityStateHistoryMoment historyMoment, _) => historyMoment.time.subtract(Duration(hours: 1)), domainUpperBoundFn: (CombinedEntityStateHistoryMoment historyMoment, _) => historyMoment.time.add(Duration(hours: 1)),*/ @@ -157,13 +176,13 @@ class _CombinedHistoryChartWidgetState extends State ); }); result.add( - new charts.Series( + new charts.Series( id: 'state', - radiusPxFn: (CombinedEntityStateHistoryMoment historyMoment, __) => (historyMoment.id == _selectedId) ? 5.0 : 4.0, - colorFn: (CombinedEntityStateHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor(historyMoment.state, historyMoment.colorId), - domainFn: (CombinedEntityStateHistoryMoment historyMoment, _) => historyMoment.startTime, - domainLowerBoundFn: (CombinedEntityStateHistoryMoment historyMoment, _) => historyMoment.startTime, - domainUpperBoundFn: (CombinedEntityStateHistoryMoment historyMoment, _) => historyMoment.endTime ?? DateTime.now(), + radiusPxFn: (EntityHistoryMoment historyMoment, __) => (historyMoment.id == _selectedId) ? 5.0 : 4.0, + colorFn: (EntityHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor(historyMoment.state, historyMoment.colorId), + domainFn: (EntityHistoryMoment historyMoment, _) => historyMoment.startTime, + domainLowerBoundFn: (EntityHistoryMoment historyMoment, _) => historyMoment.startTime, + domainUpperBoundFn: (EntityHistoryMoment historyMoment, _) => historyMoment.endTime ?? DateTime.now(), // No measure values are needed for symbol annotations. measureFn: (_, __) => null, data: numericDataLists[numericDataLists.keys.first], @@ -209,102 +228,3 @@ class _CombinedHistoryChartWidgetState extends State } } } - -class CombinedHistoryControlWidget extends StatelessWidget { - - final Function onPrevTap; - final Function onNextTap; - final DateTime selectedTimeStart; - final DateTime selectedTimeEnd; - final List selectedStates; - final List colorIndexes; - - const CombinedHistoryControlWidget({Key key, this.onPrevTap, this.onNextTap, this.selectedTimeStart, this.selectedTimeEnd, this.selectedStates, @ required this.colorIndexes}) : super(key: key); - - @override - Widget build(BuildContext context) { - if (selectedTimeStart != null) { - return - Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - IconButton( - icon: Icon(Icons.chevron_left), - padding: EdgeInsets.all(0.0), - iconSize: 40.0, - onPressed: onPrevTap, - ), - Expanded( - child: Padding( - padding: EdgeInsets.only(right: 10.0), - child: _buildStates(), - ), - ), - _buildTime(), - IconButton( - icon: Icon(Icons.chevron_right), - padding: EdgeInsets.all(0.0), - iconSize: 40.0, - onPressed: onNextTap, - ), - ], - ); - - } else { - return Container(height: 48.0); - } - } - - Widget _buildStates() { - List children = []; - for (int i = 0; i < selectedStates.length; i++) { - children.add( - Text( - "${selectedStates[i] ?? '-'}", - textAlign: TextAlign.right, - style: TextStyle( - fontWeight: FontWeight.bold, - color: EntityColors.historyStateColor(selectedStates[i], colorIndexes[i]), - fontSize: 22.0 - ), - ) - ); - } - return Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: children, - ); - } - - Widget _buildTime() { - List children = []; - children.add( - Text("${formatDate(selectedTimeStart, [M, ' ', d, ', ', HH, ':', nn, ':', ss])}", textAlign: TextAlign.left,) - ); - if (selectedTimeEnd != null) { - children.add( - Text("${formatDate(selectedTimeEnd, [M, ' ', d, ', ', HH, ':', nn, ':', ss])}", textAlign: TextAlign.left,) - ); - } - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: children, - ); - } - -} - -class CombinedEntityStateHistoryMoment { - final DateTime startTime; - final DateTime endTime; - final double value; - final double previousValue; - final int id; - final int colorId; - final String state; - final bool hiddenDot; - final bool hiddenLine; - - CombinedEntityStateHistoryMoment(this.value, this.previousValue, this.hiddenDot, this.hiddenLine, this.state, this.startTime, this.endTime, this.id, this.colorId); -} diff --git a/lib/entity_widgets/history_chart/entity_history_moment.dart b/lib/entity_widgets/history_chart/entity_history_moment.dart new file mode 100644 index 0000000..14f1ac0 --- /dev/null +++ b/lib/entity_widgets/history_chart/entity_history_moment.dart @@ -0,0 +1,25 @@ +part of '../../main.dart'; + +class EntityHistoryMoment { + final DateTime startTime; + final DateTime endTime; + final double value; + final double previousValue; + final int id; + final int colorId; + final String state; + final bool hiddenDot; + final bool hiddenLine; + + EntityHistoryMoment({ + this.value, + this.previousValue, + this.hiddenDot, + this.hiddenLine, + this.state, + @required this.startTime, + this.endTime, + @required this.id, + this.colorId + }); +} \ No newline at end of file diff --git a/lib/entity_widgets/history_chart/history_control_widget.dart b/lib/entity_widgets/history_chart/history_control_widget.dart new file mode 100644 index 0000000..e79984d --- /dev/null +++ b/lib/entity_widgets/history_chart/history_control_widget.dart @@ -0,0 +1,86 @@ +part of '../../main.dart'; + +class HistoryControlWidget extends StatelessWidget { + + final Function onPrevTap; + final Function onNextTap; + final DateTime selectedTimeStart; + final DateTime selectedTimeEnd; + final List selectedStates; + final List colorIndexes; + + const HistoryControlWidget({Key key, this.onPrevTap, this.onNextTap, this.selectedTimeStart, this.selectedTimeEnd, this.selectedStates, @ required this.colorIndexes}) : super(key: key); + + @override + Widget build(BuildContext context) { + if (selectedTimeStart != null) { + return + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + IconButton( + icon: Icon(Icons.chevron_left), + padding: EdgeInsets.all(0.0), + iconSize: 40.0, + onPressed: onPrevTap, + ), + Expanded( + child: Padding( + padding: EdgeInsets.only(right: 10.0), + child: _buildStates(), + ), + ), + _buildTime(), + IconButton( + icon: Icon(Icons.chevron_right), + padding: EdgeInsets.all(0.0), + iconSize: 40.0, + onPressed: onNextTap, + ), + ], + ); + + } else { + return Container(height: 48.0); + } + } + + Widget _buildStates() { + List children = []; + for (int i = 0; i < selectedStates.length; i++) { + children.add( + Text( + "${selectedStates[i] ?? '-'}", + textAlign: TextAlign.right, + style: TextStyle( + fontWeight: FontWeight.bold, + color: EntityColors.historyStateColor(selectedStates[i], colorIndexes[i]), + fontSize: 22.0 + ), + ) + ); + } + return Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: children, + ); + } + + Widget _buildTime() { + List children = []; + children.add( + Text("${formatDate(selectedTimeStart, [M, ' ', d, ', ', HH, ':', nn, ':', ss])}", textAlign: TextAlign.left,) + ); + if (selectedTimeEnd != null) { + children.add( + Text("${formatDate(selectedTimeEnd, [M, ' ', d, ', ', HH, ':', nn, ':', ss])}", textAlign: TextAlign.left,) + ); + } + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: children, + ); + } + +} \ No newline at end of file diff --git a/lib/entity_widgets/history_chart/numeric_state_history_chart.dart b/lib/entity_widgets/history_chart/numeric_state_history_chart.dart index 25f096f..887de56 100644 --- a/lib/entity_widgets/history_chart/numeric_state_history_chart.dart +++ b/lib/entity_widgets/history_chart/numeric_state_history_chart.dart @@ -17,7 +17,7 @@ class NumericStateHistoryChartWidget extends StatefulWidget { class _NumericStateHistoryChartWidgetState extends State { int _selectedId = -1; - List> _parsedHistory; + List> _parsedHistory; @override Widget build(BuildContext context) { @@ -25,7 +25,7 @@ class _NumericStateHistoryChartWidgetState extends State -1) && (_parsedHistory != null) && (_parsedHistory.first.data.length >= (_selectedId + 1))) { - selectedTime = _parsedHistory.first.data[_selectedId].time; + selectedTime = _parsedHistory.first.data[_selectedId].startTime; selectedState = _parsedHistory.first.data[_selectedId].value; } return Column( @@ -34,10 +34,10 @@ class _NumericStateHistoryChartWidgetState extends State[ HistoryControlWidget( selectedTimeStart: selectedTime, - selectedState: "${selectedState ?? '-'}", + selectedStates: ["${selectedState ?? '-'}"], onPrevTap: () => _selectPrev(), onNextTap: () => _selectNext(), - colorIndex: -1, + colorIndexes: [-1], ), SizedBox( height: 150.0, @@ -66,8 +66,8 @@ class _NumericStateHistoryChartWidgetState extends State> _parseHistory() { - List data = []; + List> _parseHistory() { + List data = []; DateTime now = DateTime.now(); for (var i = 0; i < widget.rawHistory.length; i++) { var stateData = widget.rawHistory[i]; @@ -85,21 +85,35 @@ class _NumericStateHistoryChartWidgetState extends State( + new charts.Series( id: 'State', - colorFn: (NumericEntityStateHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor("on", -1), - domainFn: (NumericEntityStateHistoryMoment historyMoment, _) => historyMoment.time, - measureFn: (NumericEntityStateHistoryMoment historyMoment, _) => historyMoment.value ?? historyMoment.previousValue, + colorFn: (EntityHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor("on", -1), + domainFn: (EntityHistoryMoment historyMoment, _) => historyMoment.startTime, + measureFn: (EntityHistoryMoment historyMoment, _) => historyMoment.value ?? historyMoment.previousValue, data: data, - strokeWidthPxFn: (NumericEntityStateHistoryMoment historyMoment, __) => historyMoment.hiddenLine ? 0.0 : 2.0, - radiusPxFn: (NumericEntityStateHistoryMoment historyMoment, __) { + strokeWidthPxFn: (EntityHistoryMoment historyMoment, __) => historyMoment.hiddenLine ? 0.0 : 2.0, + radiusPxFn: (EntityHistoryMoment historyMoment, __) { if (historyMoment.hiddenDot) { return 0.0; } else if (historyMoment.id == _selectedId) { @@ -144,14 +158,3 @@ class _NumericStateHistoryChartWidgetState extends State { int _selectedId = -1; - List> _parsedHistory; + List> _parsedHistory; @override Widget build(BuildContext context) { @@ -36,10 +36,10 @@ class _SimpleStateHistoryChartWidgetState extends State _selectPrev(), onNextTap: () => _selectNext(), - colorIndex: _parsedHistory.first.data[_selectedId].colorId, + colorIndexes: [_parsedHistory.first.data[_selectedId].colorId], ), SizedBox( height: 70.0, @@ -70,8 +70,8 @@ class _SimpleStateHistoryChartWidgetState extends State> _parseHistory() { - List data = []; + List> _parseHistory() { + List data = []; DateTime now = DateTime.now(); Map cachedStates = {}; for (var i = 0; i < widget.rawHistory.length; i++) { @@ -86,35 +86,46 @@ class _SimpleStateHistoryChartWidgetState extends State( + new charts.Series( id: 'State', - strokeWidthPxFn: (SimpleEntityStateHistoryMoment historyMoment, __) => (historyMoment.id == _selectedId) ? 6.0 : 3.0, - colorFn: (SimpleEntityStateHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor(historyMoment.state, historyMoment.colorId), - domainFn: (SimpleEntityStateHistoryMoment historyMoment, _) => historyMoment.startTime, - measureFn: (SimpleEntityStateHistoryMoment historyMoment, _) => 10, + strokeWidthPxFn: (EntityHistoryMoment historyMoment, __) => (historyMoment.id == _selectedId) ? 6.0 : 3.0, + colorFn: (EntityHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor(historyMoment.state, historyMoment.colorId), + domainFn: (EntityHistoryMoment historyMoment, _) => historyMoment.startTime, + measureFn: (EntityHistoryMoment historyMoment, _) => 10, data: data, ), - new charts.Series( + new charts.Series( id: 'State', - radiusPxFn: (SimpleEntityStateHistoryMoment historyMoment, __) => (historyMoment.id == _selectedId) ? 5.0 : 3.0, - colorFn: (SimpleEntityStateHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor(historyMoment.state, historyMoment.colorId), - domainFn: (SimpleEntityStateHistoryMoment historyMoment, _) => historyMoment.startTime, - measureFn: (SimpleEntityStateHistoryMoment historyMoment, _) => 10, + radiusPxFn: (EntityHistoryMoment historyMoment, __) => (historyMoment.id == _selectedId) ? 5.0 : 3.0, + colorFn: (EntityHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor(historyMoment.state, historyMoment.colorId), + domainFn: (EntityHistoryMoment historyMoment, _) => historyMoment.startTime, + measureFn: (EntityHistoryMoment historyMoment, _) => 10, data: data, )..setAttribute(charts.rendererIdKey, 'startValuePoints'), - new charts.Series( + new charts.Series( id: 'State', - radiusPxFn: (SimpleEntityStateHistoryMoment historyMoment, __) => (historyMoment.id == _selectedId) ? 5.0 : 3.0, - colorFn: (SimpleEntityStateHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor(historyMoment.state, historyMoment.colorId), - domainFn: (SimpleEntityStateHistoryMoment historyMoment, _) => historyMoment.endTime ?? DateTime.now(), - measureFn: (SimpleEntityStateHistoryMoment historyMoment, _) => 10, + radiusPxFn: (EntityHistoryMoment historyMoment, __) => (historyMoment.id == _selectedId) ? 5.0 : 3.0, + colorFn: (EntityHistoryMoment historyMoment, __) => EntityColors.chartHistoryStateColor(historyMoment.state, historyMoment.colorId), + domainFn: (EntityHistoryMoment historyMoment, _) => historyMoment.endTime ?? DateTime.now(), + measureFn: (EntityHistoryMoment historyMoment, _) => 10, data: data, )..setAttribute(charts.rendererIdKey, 'endValuePoints') ]; @@ -153,78 +164,7 @@ class _SimpleStateHistoryChartWidgetState extends State[ - IconButton( - icon: Icon(Icons.chevron_left), - padding: EdgeInsets.all(0.0), - iconSize: 40.0, - onPressed: onPrevTap, - ), - Expanded( - child: Padding( - padding: EdgeInsets.only(right: 10.0), - child: Text( - "${selectedState ?? '-'}", - textAlign: TextAlign.right, - style: TextStyle( - fontWeight: FontWeight.bold, - color: EntityColors.historyStateColor(selectedState, colorIndex), - fontSize: 22.0 - ), - ), - ), - ), - _buildTime(), - IconButton( - icon: Icon(Icons.chevron_right), - padding: EdgeInsets.all(0.0), - iconSize: 40.0, - onPressed: onNextTap, - ), - ], - ); - - } else { - return Container(height: 48.0); - } - } - - Widget _buildTime() { - List children = []; - children.add( - Text("${formatDate(selectedTimeStart, [M, ' ', d, ', ', HH, ':', nn, ':', ss])}", textAlign: TextAlign.left,) - ); - if (selectedTimeEnd != null) { - children.add( - Text("${formatDate(selectedTimeEnd, [M, ' ', d, ', ', HH, ':', nn, ':', ss])}", textAlign: TextAlign.left,) - ); - } - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: children, - ); - } - -} - +/* class SimpleEntityStateHistoryMoment { final DateTime startTime; final DateTime endTime; @@ -233,4 +173,4 @@ class SimpleEntityStateHistoryMoment { final int colorId; SimpleEntityStateHistoryMoment(this.state, this.startTime, this.endTime, this.id, this.colorId); -} \ No newline at end of file +}*/ diff --git a/lib/main.dart b/lib/main.dart index de41d98..a30d068 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -42,6 +42,8 @@ part 'entity_widgets/history_chart/entity_history.dart'; part 'entity_widgets/history_chart/simple_state_history_chart.dart'; part 'entity_widgets/history_chart/numeric_state_history_chart.dart'; part 'entity_widgets/history_chart/combined_history_chart.dart'; +part 'entity_widgets/history_chart/history_control_widget.dart'; +part 'entity_widgets/history_chart/entity_history_moment.dart'; part 'entity_widgets/state/switch_state.dart'; part 'entity_widgets/state/slider_state.dart'; part 'entity_widgets/state/text_input_state.dart';