From b3610d560d8925067a979e1caaa9e6d845e81735 Mon Sep 17 00:00:00 2001 From: Nicci Sylvester Date: Tue, 18 Feb 2025 20:01:08 -0700 Subject: [PATCH 1/2] multi-value filters and dashboard update --- lib/Analytics.dart | 16 ++++++++--- lib/dashboard.dart | 68 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/lib/Analytics.dart b/lib/Analytics.dart index 70c71d6..03be63f 100644 --- a/lib/Analytics.dart +++ b/lib/Analytics.dart @@ -71,12 +71,20 @@ class HomeAnalytics { // Submit the user filtered search Future submitFilterSearch(Set filter) { - Map submissionFilter = {}; - for (var filterItem in filter) { - submissionFilter[filterItem.category] = filterItem.value; + // gather all values in a list keyed by the category + Map submissionFilter = {}; + + for (var filterItem in filter) { + // if the map already has a key for this category, append to the list + if (submissionFilter.containsKey(filterItem.category)) { + (submissionFilter[filterItem.category] as List).add(filterItem.value); + } else { + // otherwise create a new list with the first value + submissionFilter[filterItem.category] = [filterItem.value]; } - return eventLog.uploadRecord("filter", submissionFilter); } + return eventLog.uploadRecord("filter", submissionFilter); +} // Submit the resource clicked event Future submitClickedResource(String resource) { diff --git a/lib/dashboard.dart b/lib/dashboard.dart index a6ac6c2..3b64ee1 100644 --- a/lib/dashboard.dart +++ b/lib/dashboard.dart @@ -229,7 +229,8 @@ class _DashboardState extends State try { // check if data source is type or age if (selectedData == 'Resource Type Searches' || - selectedData == 'Age Range Searches' || selectedData == 'Health Focus Searches') { + selectedData == 'Age Range Searches' || + selectedData == 'Health Focus Searches') { // get documents in event log collection where event is filter QuerySnapshot querySnapshot = await FirebaseFirestore.instance .collection('RRDBEventLog') @@ -250,11 +251,20 @@ class _DashboardState extends State // check if the document's payload contains the 'Type' key if (docData['payload'] != null && docData['payload'].containsKey('Type')) { - Map validDocData = { - 'timestamp': doc['timestamp'].toDate(), - 'Type': docData['payload']['Type'] - }; - data.add(validDocData); + var value = docData['payload']['Type']; + if (value is List) { + for (var item in value) { + data.add({ + 'timestamp': doc['timestamp'].toDate(), + 'Type': item, + }); + } + } else if (value is String) { + data.add({ + 'timestamp': doc['timestamp'].toDate(), + 'Type': value, + }); + } } } // if the selected data source is 'Age Range Searches' @@ -262,22 +272,40 @@ class _DashboardState extends State // check if the document's payload contains the 'Age Range' key if (docData['payload'] != null && docData['payload'].containsKey('Age Range')) { - Map validDocData = { - 'timestamp': doc['timestamp'].toDate(), - 'Age Range': docData['payload']['Age Range'] - }; - data.add(validDocData); + var value = docData['payload']['Age Range']; + if (value is List) { + for (var item in value) { + data.add({ + 'timestamp': doc['timestamp'].toDate(), + 'Age Range': item, + }); + } + } else if (value is String) { + data.add({ + 'timestamp': doc['timestamp'].toDate(), + 'Age Range': value, + }); + } } } - if (selectedData == 'Health Focus Searches' && - docData['payload'] != null && - docData['payload'].containsKey("Health Focus")) { - Map validDocData = { + if (selectedData == 'Health Focus Searches' && + docData['payload'] != null && + docData['payload'].containsKey("Health Focus")) { + var value = docData['payload']['Health Focus']; + if (value is List) { + for (var item in value) { + data.add({ + 'timestamp': doc['timestamp'].toDate(), + 'Health Focus': item, + }); + } + } else if (value is String) { + data.add({ 'timestamp': doc['timestamp'].toDate(), - 'Health Focus': docData['payload']['Health Focus'] - }; - data.add(validDocData); + 'Health Focus': value, + }); } + } }); return data; } @@ -374,8 +402,6 @@ class _DashboardState extends State final isSmallScreen = screenWidth < 600; // variables to manage selection and export type String? selectedOption = 'Graph'; - String? selectedExportType = exportTypes.isNotEmpty ? exportTypes - .first : null; return StatefulBuilder( builder: (BuildContext context, StateSetter setState) { @@ -434,7 +460,7 @@ class _DashboardState extends State value: selectedExportType, onChanged: (String? newValue) { setState(() { - selectedExportType = newValue; + selectedExportType = newValue!; }); }, items: exportTypes From 87e7f98769e3fc3403e9553ab20ce5177df06c73 Mon Sep 17 00:00:00 2001 From: Nicci Sylvester Date: Wed, 26 Feb 2025 12:55:52 -0700 Subject: [PATCH 2/2] cleaned up code --- lib/Analytics.dart | 9 ++----- lib/dashboard.dart | 65 +++++++++++++++------------------------------- 2 files changed, 23 insertions(+), 51 deletions(-) diff --git a/lib/Analytics.dart b/lib/Analytics.dart index 03be63f..318b758 100644 --- a/lib/Analytics.dart +++ b/lib/Analytics.dart @@ -72,16 +72,11 @@ class HomeAnalytics { // Submit the user filtered search Future submitFilterSearch(Set filter) { // gather all values in a list keyed by the category - Map submissionFilter = {}; + Map> submissionFilter = {}; for (var filterItem in filter) { // if the map already has a key for this category, append to the list - if (submissionFilter.containsKey(filterItem.category)) { - (submissionFilter[filterItem.category] as List).add(filterItem.value); - } else { - // otherwise create a new list with the first value - submissionFilter[filterItem.category] = [filterItem.value]; - } + submissionFilter.putIfAbsent(filterItem.category, () => []).add(filterItem.value); } return eventLog.uploadRecord("filter", submissionFilter); } diff --git a/lib/dashboard.dart b/lib/dashboard.dart index 3b64ee1..1507e1b 100644 --- a/lib/dashboard.dart +++ b/lib/dashboard.dart @@ -224,6 +224,21 @@ class _DashboardState extends State return csv.ListToCsvConverter().convert(rows); } + // normalize the payload value for a given key + List> normalizeAndAdd( + Map payload, String key, DateTime timestamp) { + final value = payload[key]; + // if it's not a list, wrap it in one + final normalizedValues = value is List ? value : [value]; + // create a map for each value + return normalizedValues.map((item) { + return { + 'timestamp': timestamp, + key: item, + }; + }).toList(); + } + // function to fetch data from RRDBFilters Future>> fetchData() async { try { @@ -251,20 +266,7 @@ class _DashboardState extends State // check if the document's payload contains the 'Type' key if (docData['payload'] != null && docData['payload'].containsKey('Type')) { - var value = docData['payload']['Type']; - if (value is List) { - for (var item in value) { - data.add({ - 'timestamp': doc['timestamp'].toDate(), - 'Type': item, - }); - } - } else if (value is String) { - data.add({ - 'timestamp': doc['timestamp'].toDate(), - 'Type': value, - }); - } + data.addAll(normalizeAndAdd( docData['payload'], 'Type', doc['timestamp'].toDate())); } } // if the selected data source is 'Age Range Searches' @@ -272,38 +274,13 @@ class _DashboardState extends State // check if the document's payload contains the 'Age Range' key if (docData['payload'] != null && docData['payload'].containsKey('Age Range')) { - var value = docData['payload']['Age Range']; - if (value is List) { - for (var item in value) { - data.add({ - 'timestamp': doc['timestamp'].toDate(), - 'Age Range': item, - }); - } - } else if (value is String) { - data.add({ - 'timestamp': doc['timestamp'].toDate(), - 'Age Range': value, - }); - } + data.addAll(normalizeAndAdd( docData['payload'], 'Age Range', doc['timestamp'].toDate())); } } - if (selectedData == 'Health Focus Searches' && - docData['payload'] != null && - docData['payload'].containsKey("Health Focus")) { - var value = docData['payload']['Health Focus']; - if (value is List) { - for (var item in value) { - data.add({ - 'timestamp': doc['timestamp'].toDate(), - 'Health Focus': item, - }); - } - } else if (value is String) { - data.add({ - 'timestamp': doc['timestamp'].toDate(), - 'Health Focus': value, - }); + if (selectedData == 'Health Focus Searches'){ + if(docData['payload'] != null && + docData['payload'].containsKey("Health Focus")) { + data.addAll(normalizeAndAdd( docData['payload'], 'Health Focus', doc['timestamp'].toDate())); } } });