From 4f2643c59856a61b1742e621742dd2d04acb5a9e Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Tue, 26 Oct 2021 14:16:04 +0200
Subject: [PATCH 1/9] Create new modules for chart drawing

... based on selected drop-dowwn options
---
 public/js/appChart.js                         |  13 +-
 .../src_modules/dropDownListChartColumn.mjs   | 186 +++++++
 .../src_modules/dropDownListChartHeatmap.mjs  |  32 ++
 .../js/src_modules/dropDownListChartLine.mjs  | 186 +++++++
 .../dropDownListChartScatterPlot.mjs          |  33 ++
 .../js/src_modules/dropDownListProcessing.mjs | 466 +-----------------
 6 files changed, 469 insertions(+), 447 deletions(-)
 create mode 100644 public/js/src_modules/dropDownListChartColumn.mjs
 create mode 100644 public/js/src_modules/dropDownListChartHeatmap.mjs
 create mode 100644 public/js/src_modules/dropDownListChartLine.mjs
 create mode 100644 public/js/src_modules/dropDownListChartScatterPlot.mjs

diff --git a/public/js/appChart.js b/public/js/appChart.js
index fe5aade..16780a0 100644
--- a/public/js/appChart.js
+++ b/public/js/appChart.js
@@ -50,12 +50,13 @@ import {
   getAbbreviationsForSelectedOptionsFromAllDropDownLists,
 } from "./src_modules/dropDownListHelpers.mjs";
 
-import {
-  drawHeatmapBasedOnSelectedOptions,
-  drawScatterPlotFromChartSelection,
-  drawLineChartBasedOnSelectedAggregationOptions,
-  drawColumnChartBasedOnSelectedAggregationOptions,
-} from "./src_modules/dropDownListProcessing.mjs";
+import { drawColumnChartBasedOnSelectedAggregationOptions } from "./src_modules/dropDownListChartColumn.mjs";
+
+import { drawHeatmapBasedOnSelectedOptions } from "./src_modules/dropDownListChartHeatmap.mjs";
+
+import { drawLineChartBasedOnSelectedAggregationOptions } from "./src_modules/dropDownListChartLine.mjs";
+
+import { drawScatterPlotFromChartSelection } from "./src_modules/dropDownListChartScatterPlot.mjs";
 
 /**
  * Use the `vanillaDropDown` library to style the buildings & data points drop down list
diff --git a/public/js/src_modules/dropDownListChartColumn.mjs b/public/js/src_modules/dropDownListChartColumn.mjs
new file mode 100644
index 0000000..01c35b9
--- /dev/null
+++ b/public/js/src_modules/dropDownListChartColumn.mjs
@@ -0,0 +1,186 @@
+import { drawColumnChartHighcharts } from "./chartColumn.mjs";
+
+import {
+  calculateAndFormatDailySumObservations,
+  calculateAndFormatMonthlySumObservations,
+  calculateAndFormatDailyMaximumObservations,
+  calculateAndFormatMonthlyMaximumObservations,
+  calculateAndFormatDailyMinimumObservations,
+  calculateAndFormatMonthlyMinimumObservations,
+  calculateAndFormatDailyAverageObservations,
+  calculateAndFormatMonthlyAverageObservations,
+} from "./dropDownListProcessing.mjs";
+
+/**
+ * Draw a column chart based on the selected aggregation options from a drop-down list
+ *
+ * @param {String} selectedAggregationType A string representing the selected aggregation type. The currently supported strings include `Sum`, `Maximum`, `Minimum` and `Average`
+ * @param {String} selectedAggregationDuration A string representing the selected aggregation duration. The currently supported strings include `Daily` and `Monthly`
+ * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
+ * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
+ * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
+ * @returns {undefined} undefined
+ */
+export const drawColumnChartBasedOnSelectedAggregationOptions = function (
+  selectedAggregationTypeArr,
+  selectedAggregationDuration,
+  observationsAggregationNestedArr,
+  selectedSamplingRateAbbrev,
+  uniqueCalendarDatesNestedArr,
+  formattedMetadataNestedArr
+) {
+  if (
+    selectedAggregationTypeArr === "Sum" &&
+    selectedAggregationDuration === "Daily"
+  ) {
+    // Formatted observations and metadata for chart - daily / sum
+    const [
+      formattedObservationsSumDailyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatDailySumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawColumnChartHighcharts(
+      formattedObservationsSumDailyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationTypeArr === "Sum" &&
+    selectedAggregationDuration === "Monthly"
+  ) {
+    // Formatted observations and metadata for chart - monthly / sum
+    const [
+      formattedObservationsSumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatMonthlySumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawColumnChartHighcharts(
+      formattedObservationsSumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationTypeArr === "Maximum" &&
+    selectedAggregationDuration === "Daily"
+  ) {
+    // Formatted observations and metadata for chart - daily / maximum
+    const [
+      formattedObservationsMaximumDailyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatDailyMaximumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawColumnChartHighcharts(
+      formattedObservationsMaximumDailyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationTypeArr === "Maximum" &&
+    selectedAggregationDuration === "Monthly"
+  ) {
+    // Formatted observations and metadata for chart - monthly / maximum
+    const [
+      formattedObservationsMaximumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatMonthlyMaximumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawColumnChartHighcharts(
+      formattedObservationsMaximumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationTypeArr === "Minimum" &&
+    selectedAggregationDuration === "Daily"
+  ) {
+    // Formatted observations and metadata for chart - daily / minimum
+    const [
+      formattedObservationsMinimumDailyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatDailyMinimumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawColumnChartHighcharts(
+      formattedObservationsMinimumDailyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationTypeArr === "Minimum" &&
+    selectedAggregationDuration === "Monthly"
+  ) {
+    // Formatted observations and metadata for chart - monthly / minimum
+    const [
+      formattedObservationsMinimumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatMonthlyMinimumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawColumnChartHighcharts(
+      formattedObservationsMinimumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationTypeArr === "Average" &&
+    selectedAggregationDuration === "Daily"
+  ) {
+    // Formatted observations and metadata for chart - daily / average
+    const [
+      formattedObservationsAverageDailyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatDailyAverageObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawColumnChartHighcharts(
+      formattedObservationsAverageDailyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationTypeArr === "Average" &&
+    selectedAggregationDuration === "Monthly"
+  ) {
+    // Formatted observations and metadata for chart - monthly / average
+    const [
+      formattedObservationsAverageMonthlyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatMonthlyAverageObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawColumnChartHighcharts(
+      formattedObservationsAverageMonthlyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  }
+};
diff --git a/public/js/src_modules/dropDownListChartHeatmap.mjs b/public/js/src_modules/dropDownListChartHeatmap.mjs
new file mode 100644
index 0000000..d50ae63
--- /dev/null
+++ b/public/js/src_modules/dropDownListChartHeatmap.mjs
@@ -0,0 +1,32 @@
+import {
+  formatSensorThingsApiResponseForHeatMap,
+  drawHeatMapHighcharts,
+} from "./chartHeatmap.mjs";
+
+/**
+ * Draw a heatmap based on the selected options from a drop-down list
+ *
+ * @param {Array} observationsComboNestedArr An array that contains non-computed (raw) observations and computed (temperature difference, dT) observations
+ * @param {Object} extractedFormattedDatastreamProperties An object that contains array(s) of formatted Datastream properties
+ * @returns {undefined} undefined
+ */
+export const drawHeatmapBasedOnSelectedOptions = function (
+  observationsComboNestedArr,
+  extractedFormattedDatastreamProperties
+) {
+  // Create formatted array of observations
+  const formattedObservationsHeatMapNestedArr = observationsComboNestedArr.map(
+    (observationsArr) =>
+      formatSensorThingsApiResponseForHeatMap(observationsArr)
+  );
+
+  // Note: The resulting array is nested and is not suitable for heatmap,
+  // extract the nested array
+  const [formattedObservationsHeatMapArr] =
+    formattedObservationsHeatMapNestedArr;
+
+  drawHeatMapHighcharts(
+    formattedObservationsHeatMapArr,
+    extractedFormattedDatastreamProperties
+  );
+};
diff --git a/public/js/src_modules/dropDownListChartLine.mjs b/public/js/src_modules/dropDownListChartLine.mjs
new file mode 100644
index 0000000..37e22a8
--- /dev/null
+++ b/public/js/src_modules/dropDownListChartLine.mjs
@@ -0,0 +1,186 @@
+import { drawLineChartHighcharts } from "./chartLine.mjs";
+
+import {
+  calculateAndFormatDailySumObservations,
+  calculateAndFormatMonthlySumObservations,
+  calculateAndFormatDailyMaximumObservations,
+  calculateAndFormatMonthlyMaximumObservations,
+  calculateAndFormatDailyMinimumObservations,
+  calculateAndFormatMonthlyMinimumObservations,
+  calculateAndFormatDailyAverageObservations,
+  calculateAndFormatMonthlyAverageObservations,
+} from "./dropDownListProcessing.mjs";
+
+/**
+ * Draw a line chart based on the selected aggregation options from a drop-down list
+ *
+ * @param {String} selectedAggregationType A string representing the selected aggregation type. The currently supported strings include `Sum`, `Maximum`, `Minimum` and `Average`
+ * @param {String} selectedAggregationDuration A string representing the selected aggregation duration. The currently supported strings include `Daily` and `Monthly`
+ * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
+ * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
+ * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
+ * @returns {undefined} undefined
+ */
+export const drawLineChartBasedOnSelectedAggregationOptions = function (
+  selectedAggregationType,
+  selectedAggregationDuration,
+  observationsAggregationNestedArr,
+  selectedSamplingRateAbbrev,
+  uniqueCalendarDatesNestedArr,
+  formattedMetadataNestedArr
+) {
+  if (
+    selectedAggregationType === "Sum" &&
+    selectedAggregationDuration === "Daily"
+  ) {
+    // Formatted observations and metadata for chart - daily / sum
+    const [
+      formattedObservationsSumDailyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatDailySumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawLineChartHighcharts(
+      formattedObservationsSumDailyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationType === "Sum" &&
+    selectedAggregationDuration === "Monthly"
+  ) {
+    // Formatted observations and metadata for chart - monthly / sum
+    const [
+      formattedObservationsSumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatMonthlySumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawLineChartHighcharts(
+      formattedObservationsSumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationType === "Maximum" &&
+    selectedAggregationDuration === "Daily"
+  ) {
+    // Formatted observations and metadata for chart - daily / maximum
+    const [
+      formattedObservationsMaximumDailyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatDailyMaximumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawLineChartHighcharts(
+      formattedObservationsMaximumDailyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationType === "Maximum" &&
+    selectedAggregationDuration === "Monthly"
+  ) {
+    // Formatted observations and metadata for chart - monthly / maximum
+    const [
+      formattedObservationsMaximumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatMonthlyMaximumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawLineChartHighcharts(
+      formattedObservationsMaximumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationType === "Minimum" &&
+    selectedAggregationDuration === "Daily"
+  ) {
+    // Formatted observations and metadata for chart - daily / minimum
+    const [
+      formattedObservationsMinimumDailyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatDailyMinimumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawLineChartHighcharts(
+      formattedObservationsMinimumDailyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationType === "Minimum" &&
+    selectedAggregationDuration === "Monthly"
+  ) {
+    // Formatted observations and metadata for chart - monthly / minimum
+    const [
+      formattedObservationsMinimumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatMonthlyMinimumObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawLineChartHighcharts(
+      formattedObservationsMinimumMonthlyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationType === "Average" &&
+    selectedAggregationDuration === "Daily"
+  ) {
+    // Formatted observations and metadata for chart - daily / average
+    const [
+      formattedObservationsAverageDailyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatDailyAverageObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawLineChartHighcharts(
+      formattedObservationsAverageDailyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  } else if (
+    selectedAggregationType === "Average" &&
+    selectedAggregationDuration === "Monthly"
+  ) {
+    // Formatted observations and metadata for chart - monthly / average
+    const [
+      formattedObservationsAverageMonthlyNestedArr,
+      extractedFormattedDatastreamProperties,
+    ] = calculateAndFormatMonthlyAverageObservations(
+      uniqueCalendarDatesNestedArr,
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      formattedMetadataNestedArr
+    );
+
+    drawLineChartHighcharts(
+      formattedObservationsAverageMonthlyNestedArr,
+      extractedFormattedDatastreamProperties
+    );
+  }
+};
diff --git a/public/js/src_modules/dropDownListChartScatterPlot.mjs b/public/js/src_modules/dropDownListChartScatterPlot.mjs
new file mode 100644
index 0000000..6138881
--- /dev/null
+++ b/public/js/src_modules/dropDownListChartScatterPlot.mjs
@@ -0,0 +1,33 @@
+import {
+  formatSensorThingsApiResponseForScatterPlot,
+  drawScatterPlotHighcharts,
+} from "./chartScatterPlot.mjs";
+
+/**
+ * Draw a scatter plot based on the selected options from a drop-down list
+ *
+ * @param {Array} observationsComboNestedArr An array that contains non-computed (raw) observations and computed (temperature difference, dT) observations
+ * @param {Object} extractedFormattedDatastreamProperties An object that contains array(s) of formatted Datastream properties
+ * @returns {undefined} undefined
+ */
+export const drawScatterPlotFromChartSelection = function (
+  observationsComboNestedArr,
+  extractedFormattedDatastreamProperties
+) {
+  // Extract values for x-axis and y-axis
+  // x-axis values are first element of nested observations array
+  const [obsXAxisArr] = observationsComboNestedArr.slice(0, 1);
+  // y-axis values are rest of elements of nested observations array
+  const obsYAxisNestedArr = observationsComboNestedArr.slice(1);
+
+  // Create formatted array(s) of observations
+  const formattedObservationsScatterPlotArr = obsYAxisNestedArr.map(
+    (obsYAxisArr) =>
+      formatSensorThingsApiResponseForScatterPlot(obsXAxisArr, obsYAxisArr)
+  );
+
+  drawScatterPlotHighcharts(
+    formattedObservationsScatterPlotArr,
+    extractedFormattedDatastreamProperties
+  );
+};
diff --git a/public/js/src_modules/dropDownListProcessing.mjs b/public/js/src_modules/dropDownListProcessing.mjs
index 123db15..fc97b86 100644
--- a/public/js/src_modules/dropDownListProcessing.mjs
+++ b/public/js/src_modules/dropDownListProcessing.mjs
@@ -1,21 +1,6 @@
 "use strict";
 
-import { drawLineChartHighcharts } from "./chartLine.mjs";
-
-import {
-  formatSensorThingsApiResponseForHeatMap,
-  drawHeatMapHighcharts,
-} from "./chartHeatmap.mjs";
-
-import {
-  formatSensorThingsApiResponseForScatterPlot,
-  drawScatterPlotHighcharts,
-} from "./chartScatterPlot.mjs";
-
-import {
-  formatAggregationResultForColumnChart,
-  drawColumnChartHighcharts,
-} from "./chartColumn.mjs";
+import { formatAggregationResultForColumnChart } from "./chartColumn.mjs";
 
 import { extractUniqueCalendarMonthsFromCalendarDates } from "./aggregateHelpers.mjs";
 
@@ -28,63 +13,6 @@ import {
 
 import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataProcessing.mjs";
 
-/**
- * Draw a heatmap based on the selected options from a drop-down list
- *
- * @param {Array} observationsComboNestedArr An array that contains non-computed (raw) observations and computed (temperature difference, dT) observations
- * @param {Object} extractedFormattedDatastreamProperties An object that contains array(s) of formatted Datastream properties
- * @returns {undefined} undefined
- */
-const drawHeatmapBasedOnSelectedOptions = function (
-  observationsComboNestedArr,
-  extractedFormattedDatastreamProperties
-) {
-  // Create formatted array(s) for observations
-  const formattedObservationsHeatMapNestedArr = observationsComboNestedArr.map(
-    (observationsArr) =>
-      formatSensorThingsApiResponseForHeatMap(observationsArr)
-  );
-
-  // Note: The resulting array is nested and is not suitable for heatmap,
-  // extract the nested array
-  const [formattedObservationsHeatMapArr] =
-    formattedObservationsHeatMapNestedArr;
-
-  drawHeatMapHighcharts(
-    formattedObservationsHeatMapArr,
-    extractedFormattedDatastreamProperties
-  );
-};
-
-/**
- * Draw a scatter plot based on the selected options from a drop-down list
- *
- * @param {Array} observationsComboNestedArr An array that contains non-computed (raw) observations and computed (temperature difference, dT) observations
- * @param {Object} extractedFormattedDatastreamProperties An object that contains array(s) of formatted Datastream properties
- * @returns {undefined} undefined
- */
-const drawScatterPlotFromChartSelection = function (
-  observationsComboNestedArr,
-  extractedFormattedDatastreamProperties
-) {
-  // Extract values for x-axis and y-axis
-  // x-axis values are first element of nested observations array
-  const [obsXAxisArr] = observationsComboNestedArr.slice(0, 1);
-  // y-axis values are rest of elements of nested observations array
-  const obsYAxisNestedArr = observationsComboNestedArr.slice(1);
-
-  // Create formatted array(s) for observations
-  const formattedObservationsScatterPlotArr = obsYAxisNestedArr.map(
-    (obsYAxisArr) =>
-      formatSensorThingsApiResponseForScatterPlot(obsXAxisArr, obsYAxisArr)
-  );
-
-  drawScatterPlotHighcharts(
-    formattedObservationsScatterPlotArr,
-    extractedFormattedDatastreamProperties
-  );
-};
-
 /**
  * Calculate the daily sum of observations and format these aggregated observations
  *
@@ -100,7 +28,7 @@ const calculateAndFormatDailySumObservations = function (
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
-  // Calculate sum of values of observations - daily
+  // Calculate SUM / DAILY of values of observations
   const observationsSumDailyNestedArr =
     calculateSumOfObservationValuesWithinInterval(
       observationsAggregationNestedArr,
@@ -109,7 +37,7 @@ const calculateAndFormatDailySumObservations = function (
       "daily"
     );
 
-  // Format the observations - sum / daily
+  // Format the observations
   const formattedObservationsSumDailyNestedArr =
     observationsSumDailyNestedArr.map((obsSumDailyArr, i) =>
       formatAggregationResultForColumnChart(
@@ -154,7 +82,7 @@ const calculateAndFormatMonthlySumObservations = function (
       extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
   );
 
-  // Calculate sum of values of observations - monthly
+  // Calculate SUM / MONTHLY of values of observations
   const observationsSumMonthlyNestedArr =
     calculateSumOfObservationValuesWithinInterval(
       observationsAggregationNestedArr,
@@ -163,7 +91,7 @@ const calculateAndFormatMonthlySumObservations = function (
       "monthly"
     );
 
-  // Format the observations - sum / monthly
+  // Format the observations
   const formattedObservationsSumMonthlyNestedArr =
     observationsSumMonthlyNestedArr.map((obsSumMonthlyArr, i) =>
       formatAggregationResultForColumnChart(
@@ -202,7 +130,7 @@ const calculateAndFormatDailyMaximumObservations = function (
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
-  // Calculate minimum of values of observations - daily
+  // Calculate MAXIMUM / DAILY of values of observations
   const observationsMaximumDailyNestedArr =
     calculateMaximumObservationValuesWithinInterval(
       observationsAggregationNestedArr,
@@ -211,7 +139,7 @@ const calculateAndFormatDailyMaximumObservations = function (
       "daily"
     );
 
-  // Format the observations - min / daily
+  // Format the observations
   const formattedObservationsMaximumDailyNestedArr =
     observationsMaximumDailyNestedArr.map((obsMinDailyArr, i) =>
       formatAggregationResultForColumnChart(
@@ -256,7 +184,7 @@ const calculateAndFormatMonthlyMaximumObservations = function (
       extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
   );
 
-  // Calculate minimum of values of observations - monthly
+  // Calculate MAXIMUM / MONTHLY of values of observations
   const observationsMaximumMonthlyNestedArr =
     calculateMaximumObservationValuesWithinInterval(
       observationsAggregationNestedArr,
@@ -265,7 +193,7 @@ const calculateAndFormatMonthlyMaximumObservations = function (
       "monthly"
     );
 
-  // Format the observations - max / monthly
+  // Format the observations
   const formattedObservationsMaximumMonthlyNestedArr =
     observationsMaximumMonthlyNestedArr.map((obsMaxMonthlyArr, i) =>
       formatAggregationResultForColumnChart(
@@ -304,7 +232,7 @@ const calculateAndFormatDailyMinimumObservations = function (
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
-  // Calculate minimum of values of observations - daily
+  // Calculate MINIMUM / DAILY of values of observations
   const observationsMinimumDailyNestedArr =
     calculateMinimumObservationValuesWithinInterval(
       observationsAggregationNestedArr,
@@ -313,7 +241,7 @@ const calculateAndFormatDailyMinimumObservations = function (
       "daily"
     );
 
-  // Format the observations - min / daily
+  // Format the observations
   const formattedObservationsMinimumDailyNestedArr =
     observationsMinimumDailyNestedArr.map((obsMinDailyArr, i) =>
       formatAggregationResultForColumnChart(
@@ -358,7 +286,7 @@ const calculateAndFormatMonthlyMinimumObservations = function (
       extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
   );
 
-  // Calculate minimum of values of observations - monthly
+  // Calculate MINIMUM / MONTHLY of values of observations
   const observationsMinimumMonthlyNestedArr =
     calculateMinimumObservationValuesWithinInterval(
       observationsAggregationNestedArr,
@@ -367,7 +295,7 @@ const calculateAndFormatMonthlyMinimumObservations = function (
       "monthly"
     );
 
-  // Format the observations - min / monthly
+  // Format the observations
   const formattedObservationsMinimumMonthlyNestedArr =
     observationsMinimumMonthlyNestedArr.map((obsMinMonthlyArr, i) =>
       formatAggregationResultForColumnChart(
@@ -406,7 +334,7 @@ const calculateAndFormatDailyAverageObservations = function (
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
-  // Calculate average of values of observations - daily
+  // Calculate AVERAGE / DAILY of values of observations
   const observationsAverageDailyNestedArr =
     calculateAverageOfObservationValuesWithinInterval(
       observationsAggregationNestedArr,
@@ -415,7 +343,7 @@ const calculateAndFormatDailyAverageObservations = function (
       "daily"
     );
 
-  // Format the observations - average / daily
+  // Format the observations
   const formattedObservationsAverageDailyNestedArr =
     observationsAverageDailyNestedArr.map((obsAverageDailyArr, i) =>
       formatAggregationResultForColumnChart(
@@ -460,7 +388,7 @@ const calculateAndFormatMonthlyAverageObservations = function (
       extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
   );
 
-  // Calculate average of values of observations - monthly
+  // Calculate AVERAGE / MONTHLY of values of observations
   const observationsAverageMonthlyNestedArr =
     calculateAverageOfObservationValuesWithinInterval(
       observationsAggregationNestedArr,
@@ -469,7 +397,7 @@ const calculateAndFormatMonthlyAverageObservations = function (
       "monthly"
     );
 
-  // Format the observations - average / monthly
+  // Format the observations
   const formattedObservationsAverageMonthlyNestedArr =
     observationsAverageMonthlyNestedArr.map((obsAverageMonthlyArr, i) =>
       formatAggregationResultForColumnChart(
@@ -493,357 +421,13 @@ const calculateAndFormatMonthlyAverageObservations = function (
   ];
 };
 
-/**
- * Draw a line chart based on the selected aggregation options from a drop-down list
- *
- * @param {String} selectedAggregationType A string representing the selected aggregation type. The currently supported strings include `Sum`, `Maximum`, `Minimum` and `Average`
- * @param {String} selectedAggregationDuration A string representing the selected aggregation duration. The currently supported strings include `Daily` and `Monthly`
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
- * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
- * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
- * @returns {undefined} undefined
- */
-const drawLineChartBasedOnSelectedAggregationOptions = function (
-  selectedAggregationType,
-  selectedAggregationDuration,
-  observationsAggregationNestedArr,
-  selectedSamplingRateAbbrev,
-  uniqueCalendarDatesNestedArr,
-  formattedMetadataNestedArr
-) {
-  if (
-    selectedAggregationType === "Sum" &&
-    selectedAggregationDuration === "Daily"
-  ) {
-    // Formatted observations and metadata for chart - daily / sum
-    const [
-      formattedObservationsSumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailySumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawLineChartHighcharts(
-      formattedObservationsSumDailyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationType === "Sum" &&
-    selectedAggregationDuration === "Monthly"
-  ) {
-    // Formatted observations and metadata for chart - monthly / sum
-    const [
-      formattedObservationsSumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlySumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawLineChartHighcharts(
-      formattedObservationsSumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationType === "Maximum" &&
-    selectedAggregationDuration === "Daily"
-  ) {
-    // Formatted observations and metadata for chart - daily / maximum
-    const [
-      formattedObservationsMaximumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyMaximumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawLineChartHighcharts(
-      formattedObservationsMaximumDailyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationType === "Maximum" &&
-    selectedAggregationDuration === "Monthly"
-  ) {
-    // Formatted observations and metadata for chart - monthly / maximum
-    const [
-      formattedObservationsMaximumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyMaximumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawLineChartHighcharts(
-      formattedObservationsMaximumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationType === "Minimum" &&
-    selectedAggregationDuration === "Daily"
-  ) {
-    // Formatted observations and metadata for chart - daily / minimum
-    const [
-      formattedObservationsMinimumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyMinimumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawLineChartHighcharts(
-      formattedObservationsMinimumDailyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationType === "Minimum" &&
-    selectedAggregationDuration === "Monthly"
-  ) {
-    // Formatted observations and metadata for chart - monthly / minimum
-    const [
-      formattedObservationsMinimumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyMinimumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawLineChartHighcharts(
-      formattedObservationsMinimumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationType === "Average" &&
-    selectedAggregationDuration === "Daily"
-  ) {
-    // Formatted observations and metadata for chart - daily / average
-    const [
-      formattedObservationsAverageDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyAverageObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawLineChartHighcharts(
-      formattedObservationsAverageDailyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationType === "Average" &&
-    selectedAggregationDuration === "Monthly"
-  ) {
-    // Formatted observations and metadata for chart - monthly / average
-    const [
-      formattedObservationsAverageMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyAverageObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawLineChartHighcharts(
-      formattedObservationsAverageMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  }
-};
-
-/**
- * Draw a column chart based on the selected aggregation options from a drop-down list
- *
- * @param {String} selectedAggregationType A string representing the selected aggregation type. The currently supported strings include `Sum`, `Maximum`, `Minimum` and `Average`
- * @param {String} selectedAggregationDuration A string representing the selected aggregation duration. The currently supported strings include `Daily` and `Monthly`
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
- * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
- * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
- * @returns {undefined} undefined
- */
-const drawColumnChartBasedOnSelectedAggregationOptions = function (
-  selectedAggregationTypeArr,
-  selectedAggregationDuration,
-  observationsAggregationNestedArr,
-  selectedSamplingRateAbbrev,
-  uniqueCalendarDatesNestedArr,
-  formattedMetadataNestedArr
-) {
-  if (
-    selectedAggregationTypeArr === "Sum" &&
-    selectedAggregationDuration === "Daily"
-  ) {
-    // Formatted observations and metadata for chart - daily / sum
-    const [
-      formattedObservationsSumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailySumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawColumnChartHighcharts(
-      formattedObservationsSumDailyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationTypeArr === "Sum" &&
-    selectedAggregationDuration === "Monthly"
-  ) {
-    // Formatted observations and metadata for chart - monthly / sum
-    const [
-      formattedObservationsSumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlySumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawColumnChartHighcharts(
-      formattedObservationsSumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationTypeArr === "Maximum" &&
-    selectedAggregationDuration === "Daily"
-  ) {
-    // Formatted observations and metadata for chart - daily / maximum
-    const [
-      formattedObservationsMaximumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyMaximumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawColumnChartHighcharts(
-      formattedObservationsMaximumDailyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationTypeArr === "Maximum" &&
-    selectedAggregationDuration === "Monthly"
-  ) {
-    // Formatted observations and metadata for chart - monthly / maximum
-    const [
-      formattedObservationsMaximumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyMaximumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawColumnChartHighcharts(
-      formattedObservationsMaximumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationTypeArr === "Minimum" &&
-    selectedAggregationDuration === "Daily"
-  ) {
-    // Formatted observations and metadata for chart - daily / minimum
-    const [
-      formattedObservationsMinimumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyMinimumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawColumnChartHighcharts(
-      formattedObservationsMinimumDailyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationTypeArr === "Minimum" &&
-    selectedAggregationDuration === "Monthly"
-  ) {
-    // Formatted observations and metadata for chart - monthly / minimum
-    const [
-      formattedObservationsMinimumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyMinimumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawColumnChartHighcharts(
-      formattedObservationsMinimumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationTypeArr === "Average" &&
-    selectedAggregationDuration === "Daily"
-  ) {
-    // Formatted observations and metadata for chart - daily / average
-    const [
-      formattedObservationsAverageDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyAverageObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawColumnChartHighcharts(
-      formattedObservationsAverageDailyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  } else if (
-    selectedAggregationTypeArr === "Average" &&
-    selectedAggregationDuration === "Monthly"
-  ) {
-    // Formatted observations and metadata for chart - monthly / average
-    const [
-      formattedObservationsAverageMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyAverageObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
-    drawColumnChartHighcharts(
-      formattedObservationsAverageMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
-    );
-  }
-};
-
 export {
-  drawHeatmapBasedOnSelectedOptions,
-  drawScatterPlotFromChartSelection,
-  drawLineChartBasedOnSelectedAggregationOptions,
-  drawColumnChartBasedOnSelectedAggregationOptions,
+  calculateAndFormatDailySumObservations,
+  calculateAndFormatMonthlySumObservations,
+  calculateAndFormatDailyMaximumObservations,
+  calculateAndFormatMonthlyMaximumObservations,
+  calculateAndFormatDailyMinimumObservations,
+  calculateAndFormatMonthlyMinimumObservations,
+  calculateAndFormatDailyAverageObservations,
+  calculateAndFormatMonthlyAverageObservations,
 };
-- 
GitLab


From 57668697397097cee3b04467ba3d3c46514f09d2 Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Tue, 26 Oct 2021 14:29:38 +0200
Subject: [PATCH 2/9] Edit function: format aggregated values for chart

- Rename function since it supports both line and column charts

- Add logic for comparing the lengths of the timestamps and aggregated
values arrays

- Update the function documentation

- Move the function to a different module file
---
 public/js/src_modules/aggregateHelpers.mjs    | 32 ++++++++++++++++++
 public/js/src_modules/chartColumn.mjs         | 33 +++----------------
 public/js/src_modules/chartHeatmap.mjs        |  2 +-
 public/js/src_modules/chartLine.mjs           | 11 +------
 public/js/src_modules/chartScatterPlot.mjs    |  6 ++--
 .../src_modules/dropDownListChartColumn.mjs   |  2 ++
 .../src_modules/dropDownListChartHeatmap.mjs  |  2 ++
 .../js/src_modules/dropDownListChartLine.mjs  |  2 ++
 .../dropDownListChartScatterPlot.mjs          |  2 ++
 public/js/src_modules/dropDownListHelpers.mjs | 10 ++----
 .../js/src_modules/dropDownListProcessing.mjs | 23 ++++++-------
 11 files changed, 64 insertions(+), 61 deletions(-)

diff --git a/public/js/src_modules/aggregateHelpers.mjs b/public/js/src_modules/aggregateHelpers.mjs
index e81f0cb..4f9d780 100644
--- a/public/js/src_modules/aggregateHelpers.mjs
+++ b/public/js/src_modules/aggregateHelpers.mjs
@@ -354,10 +354,42 @@ const extractUniqueCalendarMonthsFromCalendarDates = function (
   return [...uniqueCalendarMonths];
 };
 
+/**
+ * Format a computed aggregation result to make it suitable for a chart. Currently, only line and column charts are supported
+ * @param {Array} calendarDatesMonthsStrArr An array of unique calendar dates strings (in "YYYY-MM-DD" fromat) or unique calendar months strings (in "YYYY-MM" format)
+ * @param {Array} aggregatedValuesArr An array of aggregated values
+ * @returns {Array} An array of formatted aggregation values suitable for use in a column chart
+ */
+const formatAggregationResultForChart = function (
+  calendarDatesMonthsStrArr,
+  aggregatedValuesArr
+) {
+  if (!calendarDatesMonthsStrArr || !aggregatedValuesArr) return;
+
+  // Create an array of Unix timestamp strings
+  const timestampsArr = calendarDatesMonthsStrArr.map((calendarStr) =>
+    new Date(calendarStr).getTime()
+  );
+
+  // Combine timestamp and value pairs
+  // The timestamps array and values array have same lengths, use one for looping
+  if (timestampsArr.length !== aggregatedValuesArr.length) {
+    throw new Error(
+      "The timestamps array and aggregated values array have different lengths"
+    );
+  } else {
+    return timestampsArr.map((timestamp, i) => [
+      timestamp,
+      aggregatedValuesArr[i],
+    ]);
+  }
+};
+
 export {
   extractObservationsWithinDatesInterval,
   extractObservationValuesWithinDatesInterval,
   extractObservationValuesWithinMonthInterval,
   extractUniqueCalendarDatesFromTimestamp,
   extractUniqueCalendarMonthsFromCalendarDates,
+  formatAggregationResultForChart,
 };
diff --git a/public/js/src_modules/chartColumn.mjs b/public/js/src_modules/chartColumn.mjs
index d971746..646efbc 100644
--- a/public/js/src_modules/chartColumn.mjs
+++ b/public/js/src_modules/chartColumn.mjs
@@ -9,31 +9,6 @@ import {
   createTooltipDateString,
 } from "./chartHelpers.mjs";
 
-/**
- * Format a computed aggregation result to make it suitable for a column chart
- * @param {Array} calendarDatesMonthsStrArr An array of unique calendar dates strings (in "YYYY-MM-DD" fromat) or unique calendar months strings (in "YYYY-MM" format)
- * @param {Array} aggregatedValuesArr An array of aggregated values
- * @returns {Array} An array of formatted aggregation values suitable for use in a column chart
- */
-const formatAggregationResultForColumnChart = function (
-  calendarDatesMonthsStrArr,
-  aggregatedValuesArr
-) {
-  if (!calendarDatesMonthsStrArr || !aggregatedValuesArr) return;
-
-  // Create an array of Unix timestamp strings
-  const timestampsArr = calendarDatesMonthsStrArr.map((calendarStr) =>
-    new Date(calendarStr).getTime()
-  );
-
-  // Combine timestamp and value pairs
-  // The timestamps array and values array have same lengths, use one for looping
-  return timestampsArr.map((timestamp, i) => [
-    timestamp,
-    aggregatedValuesArr[i],
-  ]);
-};
-
 /**
  * Creates an options object for each series drawn in a column chart
  * @param {Array} formattedAggregatedResultForColumnChart An array of formatted aggregated result array(s) from one or more datastreams
@@ -96,12 +71,12 @@ const createYAxisTitleTextColumnChart = function (
 
 /**
  * Draw a column chart using Highcharts library
- * @param {Array} formattedAggResultArraysForColumnChart An array made up of formatted aggregated result array(s) suitable for use in a column chart
+ * @param {Array} formattedObsArraysForColumnChart An array made up of formatted observation array(s) suitable for use in a column chart. The observations may either be raw or aggregated
  * @param {Object} extractedFormattedDatastreamProperties An object that contains arrays of formatted Datastream properties
  * @returns {undefined} undefined
  */
 const drawColumnChartHighcharts = function (
-  formattedAggResultArraysForColumnChart,
+  formattedObsArraysForColumnChart,
   extractedFormattedDatastreamProperties
 ) {
   // Formatted datastream properties
@@ -136,7 +111,7 @@ const drawColumnChartHighcharts = function (
 
   // Create the array of series options object(s)
   const seriesOptionsArr = createSeriesOptionsForColumnChart(
-    formattedAggResultArraysForColumnChart,
+    formattedObsArraysForColumnChart,
     buildingIdsPhenomenonNamesArr
   );
 
@@ -213,4 +188,4 @@ const drawColumnChartHighcharts = function (
   });
 };
 
-export { formatAggregationResultForColumnChart, drawColumnChartHighcharts };
+export { drawColumnChartHighcharts };
diff --git a/public/js/src_modules/chartHeatmap.mjs b/public/js/src_modules/chartHeatmap.mjs
index 87884e0..24e997c 100644
--- a/public/js/src_modules/chartHeatmap.mjs
+++ b/public/js/src_modules/chartHeatmap.mjs
@@ -57,7 +57,7 @@ const calculateMinMaxValuesForHeatmapColorAxis = function (
 
 /**
  * Draw a heatmap using Highcharts library
- * @param {Array} formattedObsArrayForHeatmap Response from SensorThings API formatted for use in a heatmap
+ * @param {Array} formattedObsArrayForHeatmap Response from SensorThings API formatted for use in a heatmap. Currently, only raw observations are supported, i.e. no aggregation
  * @param {Object} extractedFormattedDatastreamProperties An object that contains arrays of formatted Datastream properties
  * @returns {undefined} undefined
  */
diff --git a/public/js/src_modules/chartLine.mjs b/public/js/src_modules/chartLine.mjs
index f34b8a9..8a44bf1 100644
--- a/public/js/src_modules/chartLine.mjs
+++ b/public/js/src_modules/chartLine.mjs
@@ -22,15 +22,6 @@ const formatSensorThingsApiResponseForLineOrColumnChart = function (obsArray) {
   });
 };
 
-/**
- * Concatenates metadata properties to create a string for either the title or subtitle of a line chart
- * @param {Array} phenomenonNamesArr An array of phenomenon name strings
- * @returns {String} A string made up of combined phenomenon names
- */
-const createCombinedTextForLineChartTitles = function (phenomenonNamesArr) {
-  return phenomenonNamesArr.join(", ");
-};
-
 /**
  * Creates an options object for each series drawn in the line chart
  * @param {Array} formattedObsArraysForLineChart An array of formatted observation array(s) from one or more datastreams
@@ -71,7 +62,7 @@ const createSeriesOptionsForLineChart = function (
 
 /**
  * Draw a line chart using Highcharts library
- * @param {Array} formattedObsArraysForLineChart An array made up of formatted observation array(s) suitable for use in a line chart
+ * @param {Array} formattedObsArraysForLineChart An array made up of formatted observation array(s) suitable for use in a line chart. The observations may either be raw or aggregated
  * @param {Object} extractedFormattedDatastreamPropertiesArr An object that contains arrays of formatted Datastream properties
  * @returns {undefined} undefined
  */
diff --git a/public/js/src_modules/chartScatterPlot.mjs b/public/js/src_modules/chartScatterPlot.mjs
index 0c3cf1e..ff11192 100644
--- a/public/js/src_modules/chartScatterPlot.mjs
+++ b/public/js/src_modules/chartScatterPlot.mjs
@@ -209,12 +209,12 @@ const getYAxisUnitOfMeasurementSymbol = function (seriesName) {
 
 /**
  * Draw a scatter plot using Highcharts library
- * @param {Array} formattedObsArrayForSeriesOnePlusSeriesTwo Response from SensorThings API formatted for use in a scatter plot
+ * @param {Array} formattedObsArraysForScatterPlot Response from SensorThings API formatted for use in a scatter plot. Currently, only raw observations are supported, i.e. no aggregation
  * @param {Object} extractedFormattedDatastreamProperties An object that contains arrays of formatted Datastream properties
  * @returns {undefined} undefined
  */
 const drawScatterPlotHighcharts = function (
-  formattedObsArrayForSeriesOnePlusSeriesTwo,
+  formattedObsArraysForScatterPlot,
   extractedFormattedDatastreamProperties
 ) {
   // Arrays of datastream properties
@@ -227,7 +227,7 @@ const drawScatterPlotHighcharts = function (
 
   // Create the array of series options object(s)
   const seriesOptionsArr = createSeriesOptionsForScatterPlot(
-    formattedObsArrayForSeriesOnePlusSeriesTwo,
+    formattedObsArraysForScatterPlot,
     phenomenonNamesArr
   );
 
diff --git a/public/js/src_modules/dropDownListChartColumn.mjs b/public/js/src_modules/dropDownListChartColumn.mjs
index 01c35b9..eda51d7 100644
--- a/public/js/src_modules/dropDownListChartColumn.mjs
+++ b/public/js/src_modules/dropDownListChartColumn.mjs
@@ -1,3 +1,5 @@
+"use strict";
+
 import { drawColumnChartHighcharts } from "./chartColumn.mjs";
 
 import {
diff --git a/public/js/src_modules/dropDownListChartHeatmap.mjs b/public/js/src_modules/dropDownListChartHeatmap.mjs
index d50ae63..cad7760 100644
--- a/public/js/src_modules/dropDownListChartHeatmap.mjs
+++ b/public/js/src_modules/dropDownListChartHeatmap.mjs
@@ -1,3 +1,5 @@
+"use strict";
+
 import {
   formatSensorThingsApiResponseForHeatMap,
   drawHeatMapHighcharts,
diff --git a/public/js/src_modules/dropDownListChartLine.mjs b/public/js/src_modules/dropDownListChartLine.mjs
index 37e22a8..7d10a0d 100644
--- a/public/js/src_modules/dropDownListChartLine.mjs
+++ b/public/js/src_modules/dropDownListChartLine.mjs
@@ -1,3 +1,5 @@
+"use strict";
+
 import { drawLineChartHighcharts } from "./chartLine.mjs";
 
 import {
diff --git a/public/js/src_modules/dropDownListChartScatterPlot.mjs b/public/js/src_modules/dropDownListChartScatterPlot.mjs
index 6138881..9307a48 100644
--- a/public/js/src_modules/dropDownListChartScatterPlot.mjs
+++ b/public/js/src_modules/dropDownListChartScatterPlot.mjs
@@ -1,3 +1,5 @@
+"use strict";
+
 import {
   formatSensorThingsApiResponseForScatterPlot,
   drawScatterPlotHighcharts,
diff --git a/public/js/src_modules/dropDownListHelpers.mjs b/public/js/src_modules/dropDownListHelpers.mjs
index 50ffbb8..bb37a61 100644
--- a/public/js/src_modules/dropDownListHelpers.mjs
+++ b/public/js/src_modules/dropDownListHelpers.mjs
@@ -279,14 +279,10 @@ const checkIfChartRequiresRawObservations = function (
   selectedAggregationType,
   selectedAggregationDuration
 ) {
-  if (
-    selectedAggregationType === "None (raw data)" &&
+  return selectedAggregationType === "None (raw data)" &&
     selectedAggregationDuration === undefined
-  ) {
-    return true;
-  } else {
-    return false;
-  }
+    ? true
+    : false;
 };
 
 /**
diff --git a/public/js/src_modules/dropDownListProcessing.mjs b/public/js/src_modules/dropDownListProcessing.mjs
index fc97b86..508a73d 100644
--- a/public/js/src_modules/dropDownListProcessing.mjs
+++ b/public/js/src_modules/dropDownListProcessing.mjs
@@ -1,8 +1,9 @@
 "use strict";
 
-import { formatAggregationResultForColumnChart } from "./chartColumn.mjs";
-
-import { extractUniqueCalendarMonthsFromCalendarDates } from "./aggregateHelpers.mjs";
+import {
+  extractUniqueCalendarMonthsFromCalendarDates,
+  formatAggregationResultForChart,
+} from "./aggregateHelpers.mjs";
 
 import {
   calculateMinimumObservationValuesWithinInterval,
@@ -40,7 +41,7 @@ const calculateAndFormatDailySumObservations = function (
   // Format the observations
   const formattedObservationsSumDailyNestedArr =
     observationsSumDailyNestedArr.map((obsSumDailyArr, i) =>
-      formatAggregationResultForColumnChart(
+      formatAggregationResultForChart(
         uniqueCalendarDatesNestedArr[i],
         obsSumDailyArr
       )
@@ -94,7 +95,7 @@ const calculateAndFormatMonthlySumObservations = function (
   // Format the observations
   const formattedObservationsSumMonthlyNestedArr =
     observationsSumMonthlyNestedArr.map((obsSumMonthlyArr, i) =>
-      formatAggregationResultForColumnChart(
+      formatAggregationResultForChart(
         uniqueCalendarMonthsNestedArr[i],
         obsSumMonthlyArr
       )
@@ -142,7 +143,7 @@ const calculateAndFormatDailyMaximumObservations = function (
   // Format the observations
   const formattedObservationsMaximumDailyNestedArr =
     observationsMaximumDailyNestedArr.map((obsMinDailyArr, i) =>
-      formatAggregationResultForColumnChart(
+      formatAggregationResultForChart(
         uniqueCalendarDatesNestedArr[i],
         obsMinDailyArr
       )
@@ -196,7 +197,7 @@ const calculateAndFormatMonthlyMaximumObservations = function (
   // Format the observations
   const formattedObservationsMaximumMonthlyNestedArr =
     observationsMaximumMonthlyNestedArr.map((obsMaxMonthlyArr, i) =>
-      formatAggregationResultForColumnChart(
+      formatAggregationResultForChart(
         uniqueCalendarMonthsNestedArr[i],
         obsMaxMonthlyArr
       )
@@ -244,7 +245,7 @@ const calculateAndFormatDailyMinimumObservations = function (
   // Format the observations
   const formattedObservationsMinimumDailyNestedArr =
     observationsMinimumDailyNestedArr.map((obsMinDailyArr, i) =>
-      formatAggregationResultForColumnChart(
+      formatAggregationResultForChart(
         uniqueCalendarDatesNestedArr[i],
         obsMinDailyArr
       )
@@ -298,7 +299,7 @@ const calculateAndFormatMonthlyMinimumObservations = function (
   // Format the observations
   const formattedObservationsMinimumMonthlyNestedArr =
     observationsMinimumMonthlyNestedArr.map((obsMinMonthlyArr, i) =>
-      formatAggregationResultForColumnChart(
+      formatAggregationResultForChart(
         uniqueCalendarMonthsNestedArr[i],
         obsMinMonthlyArr
       )
@@ -346,7 +347,7 @@ const calculateAndFormatDailyAverageObservations = function (
   // Format the observations
   const formattedObservationsAverageDailyNestedArr =
     observationsAverageDailyNestedArr.map((obsAverageDailyArr, i) =>
-      formatAggregationResultForColumnChart(
+      formatAggregationResultForChart(
         uniqueCalendarDatesNestedArr[i],
         obsAverageDailyArr
       )
@@ -400,7 +401,7 @@ const calculateAndFormatMonthlyAverageObservations = function (
   // Format the observations
   const formattedObservationsAverageMonthlyNestedArr =
     observationsAverageMonthlyNestedArr.map((obsAverageMonthlyArr, i) =>
-      formatAggregationResultForColumnChart(
+      formatAggregationResultForChart(
         uniqueCalendarMonthsNestedArr[i],
         obsAverageMonthlyArr
       )
-- 
GitLab


From dacc18440f2c13bb9c2b726613a4a5f3977d9669 Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Tue, 26 Oct 2021 14:34:53 +0200
Subject: [PATCH 3/9] Edit function: format observations scatter plot

Replace if/else block with ternary operator
---
 public/js/src_modules/chartScatterPlot.mjs | 26 ++++++++++------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/public/js/src_modules/chartScatterPlot.mjs b/public/js/src_modules/chartScatterPlot.mjs
index ff11192..71a32d9 100644
--- a/public/js/src_modules/chartScatterPlot.mjs
+++ b/public/js/src_modules/chartScatterPlot.mjs
@@ -36,20 +36,18 @@ const formatSensorThingsApiResponseForScatterPlot = function (
   obsArrayOne,
   obsArrayTwo
 ) {
-  // When our observation arrays have DIFFERENT lengths
-  if (obsArrayOne.length !== obsArrayTwo.length) {
-    const [obsArrayOneFinal, obsArrayTwoFinal] =
-      checkForAndDeleteUniqueObservationsFromLargerArray(
-        obsArrayOne,
-        obsArrayTwo
-      );
-
-    return createCombinedObservationValues(obsArrayOneFinal, obsArrayTwoFinal);
-  }
-  // When our observation arrays already have SAME lengths
-  else {
-    return createCombinedObservationValues(obsArrayOne, obsArrayTwo);
-  }
+  // Check if our observation arrays have equal lengths,
+  // remove the unique observations, if necessary
+  const [obsArrayOneFinal, obsArrayTwoFinal] =
+    obsArrayOne.length !== obsArrayTwo.length
+      ? checkForAndDeleteUniqueObservationsFromLargerArray(
+          obsArrayOne,
+          obsArrayTwo
+        )
+      : [obsArrayOne, obsArrayTwo];
+
+  // Create the combined observations array
+  return createCombinedObservationValues(obsArrayOneFinal, obsArrayTwoFinal);
 };
 
 /**
-- 
GitLab


From 8628915f557c9d577a4afc63d55f85e78d66d78b Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Tue, 26 Oct 2021 14:36:56 +0200
Subject: [PATCH 4/9] Edit function: create series options line chart

Rename references
---
 public/js/src_modules/chartLine.mjs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/public/js/src_modules/chartLine.mjs b/public/js/src_modules/chartLine.mjs
index 8a44bf1..cd698f9 100644
--- a/public/js/src_modules/chartLine.mjs
+++ b/public/js/src_modules/chartLine.mjs
@@ -33,10 +33,10 @@ const createSeriesOptionsForLineChart = function (
   buildingIdsPhenomenonNamesArr
 ) {
   // An array of colors, in hexadecimal format, provided by the global Highcharts object
-  const seriesColors = Highcharts.getOptions().colors;
+  const seriesColorsArr = Highcharts.getOptions().colors;
 
-  // Create a copy of the colors array
-  const seriesColorsArr = [...seriesColors];
+  // Create a local copy of the colors array
+  const seriesColorsForLineChartArr = [...seriesColorsArr];
 
   // Create an array of seriesOptions objects
   // Assumes that the observation array of arrays and building IDs + phenomenon names array are of equal length
@@ -53,7 +53,7 @@ const createSeriesOptionsForLineChart = function (
       return {
         name: `${buildingIdsPhenomenonNamesArr[i]}`,
         data: formattedObsArray,
-        color: seriesColorsArr[i],
+        color: seriesColorsForLineChartArr[i],
         turboThreshold: Number.MAX_VALUE, // #3404, remove after 4.0.5 release
       };
     });
-- 
GitLab


From 483897462f7adbec370e9481ac06308244479fca Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Tue, 26 Oct 2021 14:38:55 +0200
Subject: [PATCH 5/9] Edit function: create series options scatter plot

- Rename references

- Do not reverse the array of colors
---
 public/js/src_modules/chartScatterPlot.mjs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/public/js/src_modules/chartScatterPlot.mjs b/public/js/src_modules/chartScatterPlot.mjs
index 71a32d9..345465c 100644
--- a/public/js/src_modules/chartScatterPlot.mjs
+++ b/public/js/src_modules/chartScatterPlot.mjs
@@ -136,14 +136,14 @@ const createSeriesOptionsForScatterPlot = function (
   // An array of colors, in hexadecimal format, provided by the global Highcharts object
   const highchartsColorsArr = Highcharts.getOptions().colors;
 
-  // Create a reversed copy of the colors array
-  const highchartsColorsReversedArr = [...highchartsColorsArr].reverse();
+  // Create a local copy of the colors array
+  const highchartsColorsForScatterPlotArr = [...highchartsColorsArr];
 
   // Opacity value for symbol
   const SERIES_SYMBOL_COLOR_OPACITY = ".3";
 
   // Create array of colors in RGBA format
-  const seriesColors = highchartsColorsReversedArr.map(
+  const seriesColorsArr = highchartsColorsForScatterPlotArr.map(
     (hexColorCode) =>
       `rgba(${convertHexColorToRGBColor(
         hexColorCode
@@ -169,7 +169,7 @@ const createSeriesOptionsForScatterPlot = function (
       return {
         name: `${phenomenonNamesYAxisArr[i]}, ${phenomenonNameXAxis}`,
         data: formattedObsArray,
-        color: seriesColors[i],
+        color: seriesColorsArr[i],
       };
     });
   }
-- 
GitLab


From 1501726b141e36c0f17bce0bb3612cb0b76f7be0 Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Tue, 26 Oct 2021 14:41:32 +0200
Subject: [PATCH 6/9] Move function to a different module file

Function that formats observations for line chart or column chart
---
 public/js/appChart.js                  |  7 +++----
 public/js/src_modules/chartHelpers.mjs | 16 ++++++++++++++++
 public/js/src_modules/chartLine.mjs    | 20 +-------------------
 3 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/public/js/appChart.js b/public/js/appChart.js
index 16780a0..bb1f8d3 100644
--- a/public/js/appChart.js
+++ b/public/js/appChart.js
@@ -17,10 +17,9 @@ import {
   extractPropertiesFromFormattedDatastreamMetadata,
 } from "./src_modules/fetchedDataProcessing.mjs";
 
-import {
-  formatSensorThingsApiResponseForLineOrColumnChart,
-  drawLineChartHighcharts,
-} from "./src_modules/chartLine.mjs";
+import { formatSensorThingsApiResponseForLineOrColumnChart } from "./src_modules/chartHelpers.mjs";
+
+import { drawLineChartHighcharts } from "./src_modules/chartLine.mjs";
 
 import { drawColumnChartHighcharts } from "./src_modules/chartColumn.mjs";
 
diff --git a/public/js/src_modules/chartHelpers.mjs b/public/js/src_modules/chartHelpers.mjs
index 0c633b3..432b043 100644
--- a/public/js/src_modules/chartHelpers.mjs
+++ b/public/js/src_modules/chartHelpers.mjs
@@ -177,6 +177,21 @@ const checkForAndDeleteUniqueObservationsFromLargerArray = function (
   }
 };
 
+/**
+ * Format the response from SensorThings API to make it suitable for use in a line chart or column chart
+ * @param {Array} obsArray Array of observations (timestamp + value) that is response from SensorThings API
+ * @returns {Array} Array of formatted observations suitable for use in a line chart
+ */
+const formatSensorThingsApiResponseForLineOrColumnChart = function (obsArray) {
+  if (!obsArray) return;
+
+  return obsArray.map((result) => {
+    const timestampObs = new Date(result[0].slice(0, -1)).getTime(); // slice() removes trailing "Z" character in timestamp
+    const valueObs = result[1];
+    return [timestampObs, valueObs];
+  });
+};
+
 /**
  * Convert a hexadecimal color code obtained from the Highcharts object (`Highcharts.getOptions().colors`) to its equivalent RGB color code
  * @param {String} hexCode Input hex color code
@@ -406,6 +421,7 @@ const removeTransparencyFromColor = function (rgbaColor) {
 export {
   chartExportOptions,
   checkForAndDeleteUniqueObservationsFromLargerArray,
+  formatSensorThingsApiResponseForLineOrColumnChart,
   createCombinedTextDelimitedByAmpersand,
   createCombinedTextDelimitedByComma,
   extractSamplingRateFromDatastreamName,
diff --git a/public/js/src_modules/chartLine.mjs b/public/js/src_modules/chartLine.mjs
index cd698f9..6754a96 100644
--- a/public/js/src_modules/chartLine.mjs
+++ b/public/js/src_modules/chartLine.mjs
@@ -7,21 +7,6 @@ import {
   createTooltipDateString,
 } from "./chartHelpers.mjs";
 
-/**
- * Format the response from SensorThings API to make it suitable for use in a line chart or column chart
- * @param {Array} obsArray Array of observations (timestamp + value) that is response from SensorThings API
- * @returns {Array} Array of formatted observations suitable for use in a line chart
- */
-const formatSensorThingsApiResponseForLineOrColumnChart = function (obsArray) {
-  if (!obsArray) return;
-
-  return obsArray.map((result) => {
-    const timestampObs = new Date(result[0].slice(0, -1)).getTime(); // slice() removes trailing "Z" character in timestamp
-    const valueObs = result[1];
-    return [timestampObs, valueObs];
-  });
-};
-
 /**
  * Creates an options object for each series drawn in the line chart
  * @param {Array} formattedObsArraysForLineChart An array of formatted observation array(s) from one or more datastreams
@@ -162,7 +147,4 @@ const drawLineChartHighcharts = function (
   });
 };
 
-export {
-  formatSensorThingsApiResponseForLineOrColumnChart,
-  drawLineChartHighcharts,
-};
+export { drawLineChartHighcharts };
-- 
GitLab


From 2c77d957d25c2e0d79a3c4a1fbea695c2d3b9344 Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Tue, 26 Oct 2021 14:50:06 +0200
Subject: [PATCH 7/9] Create new modules for aggregation calculation

... and formatting
---
 .../dropDownListAggregationAverage.mjs        | 117 +++++
 .../dropDownListAggregationMaximum.mjs        | 117 +++++
 .../dropDownListAggregationMinimum.mjs        | 117 +++++
 .../dropDownListAggregationSum.mjs            | 117 +++++
 .../src_modules/dropDownListChartColumn.mjs   |  11 +-
 .../js/src_modules/dropDownListChartLine.mjs  |  11 +-
 .../js/src_modules/dropDownListProcessing.mjs | 434 ------------------
 7 files changed, 488 insertions(+), 436 deletions(-)
 create mode 100644 public/js/src_modules/dropDownListAggregationAverage.mjs
 create mode 100644 public/js/src_modules/dropDownListAggregationMaximum.mjs
 create mode 100644 public/js/src_modules/dropDownListAggregationMinimum.mjs
 create mode 100644 public/js/src_modules/dropDownListAggregationSum.mjs
 delete mode 100644 public/js/src_modules/dropDownListProcessing.mjs

diff --git a/public/js/src_modules/dropDownListAggregationAverage.mjs b/public/js/src_modules/dropDownListAggregationAverage.mjs
new file mode 100644
index 0000000..98098af
--- /dev/null
+++ b/public/js/src_modules/dropDownListAggregationAverage.mjs
@@ -0,0 +1,117 @@
+"use strict";
+
+import {
+  extractUniqueCalendarMonthsFromCalendarDates,
+  formatAggregationResultForChart,
+} from "./aggregateHelpers.mjs";
+
+import { calculateAverageOfObservationValuesWithinInterval } from "./aggregate.mjs";
+
+import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataProcessing.mjs";
+
+/**
+ * Calculate the daily average of observations and format these aggregated observations
+ *
+ * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
+ * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
+ * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
+ * @returns {Array} An array whose first element is the formatted aggregated (daily average) observations. The second element is an object made up of extracted & formatted datastream properties
+ */
+const calculateAndFormatDailyAverageObservations = function (
+  uniqueCalendarDatesNestedArr,
+  observationsAggregationNestedArr,
+  selectedSamplingRateAbbrev,
+  formattedMetadataNestedArr
+) {
+  // Calculate AVERAGE / DAILY of values of observations
+  const observationsAverageDailyNestedArr =
+    calculateAverageOfObservationValuesWithinInterval(
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      uniqueCalendarDatesNestedArr,
+      "daily"
+    );
+
+  // Format the observations
+  const formattedObservationsAverageDailyNestedArr =
+    observationsAverageDailyNestedArr.map((obsAverageDailyArr, i) =>
+      formatAggregationResultForChart(
+        uniqueCalendarDatesNestedArr[i],
+        obsAverageDailyArr
+      )
+    );
+
+  // Extract the formatted metadata properties
+  const extractedFormattedDatastreamProperties =
+    extractPropertiesFromFormattedDatastreamMetadata(
+      formattedMetadataNestedArr,
+      true,
+      "daily",
+      "average"
+    );
+
+  return [
+    formattedObservationsAverageDailyNestedArr,
+    extractedFormattedDatastreamProperties,
+  ];
+};
+
+/**
+ * Calculate the monthly average of observations and format these aggregated observations
+ *
+ * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
+ * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
+ * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
+ * @returns {Array} An array whose first element is the formatted aggregated (monthly average) observations. The second element is an object made up of extracted & formatted datastream properties
+ */
+const calculateAndFormatMonthlyAverageObservations = function (
+  uniqueCalendarDatesNestedArr,
+  observationsAggregationNestedArr,
+  selectedSamplingRateAbbrev,
+  formattedMetadataNestedArr
+) {
+  // Unique calendar months
+  const uniqueCalendarMonthsNestedArr = uniqueCalendarDatesNestedArr.map(
+    (uniqueCalendarDatesArr) =>
+      extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
+  );
+
+  // Calculate AVERAGE / MONTHLY of values of observations
+  const observationsAverageMonthlyNestedArr =
+    calculateAverageOfObservationValuesWithinInterval(
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      uniqueCalendarMonthsNestedArr,
+      "monthly"
+    );
+
+  // Format the observations
+  const formattedObservationsAverageMonthlyNestedArr =
+    observationsAverageMonthlyNestedArr.map((obsAverageMonthlyArr, i) =>
+      formatAggregationResultForChart(
+        uniqueCalendarMonthsNestedArr[i],
+        obsAverageMonthlyArr
+      )
+    );
+
+  // Extract the formatted metadata properties
+  const extractedFormattedDatastreamProperties =
+    extractPropertiesFromFormattedDatastreamMetadata(
+      formattedMetadataNestedArr,
+      true,
+      "monthly",
+      "average"
+    );
+
+  return [
+    formattedObservationsAverageMonthlyNestedArr,
+    extractedFormattedDatastreamProperties,
+  ];
+};
+
+export {
+  calculateAndFormatDailyAverageObservations,
+  calculateAndFormatMonthlyAverageObservations,
+};
diff --git a/public/js/src_modules/dropDownListAggregationMaximum.mjs b/public/js/src_modules/dropDownListAggregationMaximum.mjs
new file mode 100644
index 0000000..3ef25d3
--- /dev/null
+++ b/public/js/src_modules/dropDownListAggregationMaximum.mjs
@@ -0,0 +1,117 @@
+"use strict";
+
+import {
+  extractUniqueCalendarMonthsFromCalendarDates,
+  formatAggregationResultForChart,
+} from "./aggregateHelpers.mjs";
+
+import { calculateMaximumObservationValuesWithinInterval } from "./aggregate.mjs";
+
+import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataProcessing.mjs";
+
+/**
+ * Calculate the daily maximum of observations and format these aggregated observations
+ *
+ * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
+ * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
+ * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
+ * @returns {Array} An array whose first element is the formatted aggregated (daily maximum) observations. The second element is an object made up of extracted & formatted datastream properties
+ */
+const calculateAndFormatDailyMaximumObservations = function (
+  uniqueCalendarDatesNestedArr,
+  observationsAggregationNestedArr,
+  selectedSamplingRateAbbrev,
+  formattedMetadataNestedArr
+) {
+  // Calculate MAXIMUM / DAILY of values of observations
+  const observationsMaximumDailyNestedArr =
+    calculateMaximumObservationValuesWithinInterval(
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      uniqueCalendarDatesNestedArr,
+      "daily"
+    );
+
+  // Format the observations
+  const formattedObservationsMaximumDailyNestedArr =
+    observationsMaximumDailyNestedArr.map((obsMinDailyArr, i) =>
+      formatAggregationResultForChart(
+        uniqueCalendarDatesNestedArr[i],
+        obsMinDailyArr
+      )
+    );
+
+  // Extract the formatted metadata properties
+  const extractedFormattedDatastreamProperties =
+    extractPropertiesFromFormattedDatastreamMetadata(
+      formattedMetadataNestedArr,
+      true,
+      "daily",
+      "maximum"
+    );
+
+  return [
+    formattedObservationsMaximumDailyNestedArr,
+    extractedFormattedDatastreamProperties,
+  ];
+};
+
+/**
+ * Calculate the monthly maximum of observations and format these aggregated observations
+ *
+ * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
+ * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
+ * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
+ * @returns {Array} An array whose first element is the formatted aggregated (monthly maximum) observations. The second element is an object made up of extracted & formatted datastream properties
+ */
+const calculateAndFormatMonthlyMaximumObservations = function (
+  uniqueCalendarDatesNestedArr,
+  observationsAggregationNestedArr,
+  selectedSamplingRateAbbrev,
+  formattedMetadataNestedArr
+) {
+  // Unique calendar months
+  const uniqueCalendarMonthsNestedArr = uniqueCalendarDatesNestedArr.map(
+    (uniqueCalendarDatesArr) =>
+      extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
+  );
+
+  // Calculate MAXIMUM / MONTHLY of values of observations
+  const observationsMaximumMonthlyNestedArr =
+    calculateMaximumObservationValuesWithinInterval(
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      uniqueCalendarMonthsNestedArr,
+      "monthly"
+    );
+
+  // Format the observations
+  const formattedObservationsMaximumMonthlyNestedArr =
+    observationsMaximumMonthlyNestedArr.map((obsMaxMonthlyArr, i) =>
+      formatAggregationResultForChart(
+        uniqueCalendarMonthsNestedArr[i],
+        obsMaxMonthlyArr
+      )
+    );
+
+  // Extract the formatted metadata properties
+  const extractedFormattedDatastreamProperties =
+    extractPropertiesFromFormattedDatastreamMetadata(
+      formattedMetadataNestedArr,
+      true,
+      "monthly",
+      "maximum"
+    );
+
+  return [
+    formattedObservationsMaximumMonthlyNestedArr,
+    extractedFormattedDatastreamProperties,
+  ];
+};
+
+export {
+  calculateAndFormatDailyMaximumObservations,
+  calculateAndFormatMonthlyMaximumObservations,
+};
diff --git a/public/js/src_modules/dropDownListAggregationMinimum.mjs b/public/js/src_modules/dropDownListAggregationMinimum.mjs
new file mode 100644
index 0000000..2fec44e
--- /dev/null
+++ b/public/js/src_modules/dropDownListAggregationMinimum.mjs
@@ -0,0 +1,117 @@
+"use strict";
+
+import {
+  extractUniqueCalendarMonthsFromCalendarDates,
+  formatAggregationResultForChart,
+} from "./aggregateHelpers.mjs";
+
+import { calculateMinimumObservationValuesWithinInterval } from "./aggregate.mjs";
+
+import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataProcessing.mjs";
+
+/**
+ * Calculate the daily minimum of observations and format these aggregated observations
+ *
+ * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
+ * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
+ * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
+ * @returns {Array} An array whose first element is the formatted aggregated (daily minimum) observations. The second element is an object made up of extracted & formatted datastream properties
+ */
+const calculateAndFormatDailyMinimumObservations = function (
+  uniqueCalendarDatesNestedArr,
+  observationsAggregationNestedArr,
+  selectedSamplingRateAbbrev,
+  formattedMetadataNestedArr
+) {
+  // Calculate MINIMUM / DAILY of values of observations
+  const observationsMinimumDailyNestedArr =
+    calculateMinimumObservationValuesWithinInterval(
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      uniqueCalendarDatesNestedArr,
+      "daily"
+    );
+
+  // Format the observations
+  const formattedObservationsMinimumDailyNestedArr =
+    observationsMinimumDailyNestedArr.map((obsMinDailyArr, i) =>
+      formatAggregationResultForChart(
+        uniqueCalendarDatesNestedArr[i],
+        obsMinDailyArr
+      )
+    );
+
+  // Extract the formatted metadata properties
+  const extractedFormattedDatastreamProperties =
+    extractPropertiesFromFormattedDatastreamMetadata(
+      formattedMetadataNestedArr,
+      true,
+      "daily",
+      "minimum"
+    );
+
+  return [
+    formattedObservationsMinimumDailyNestedArr,
+    extractedFormattedDatastreamProperties,
+  ];
+};
+
+/**
+ * Calculate the monthly minimum of observations and format these aggregated observations
+ *
+ * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
+ * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
+ * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
+ * @returns {Array} An array whose first element is the formatted aggregated (monthly minimum) observations. The second element is an object made up of extracted & formatted datastream properties
+ */
+const calculateAndFormatMonthlyMinimumObservations = function (
+  uniqueCalendarDatesNestedArr,
+  observationsAggregationNestedArr,
+  selectedSamplingRateAbbrev,
+  formattedMetadataNestedArr
+) {
+  // Unique calendar months
+  const uniqueCalendarMonthsNestedArr = uniqueCalendarDatesNestedArr.map(
+    (uniqueCalendarDatesArr) =>
+      extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
+  );
+
+  // Calculate MINIMUM / MONTHLY of values of observations
+  const observationsMinimumMonthlyNestedArr =
+    calculateMinimumObservationValuesWithinInterval(
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      uniqueCalendarMonthsNestedArr,
+      "monthly"
+    );
+
+  // Format the observations
+  const formattedObservationsMinimumMonthlyNestedArr =
+    observationsMinimumMonthlyNestedArr.map((obsMinMonthlyArr, i) =>
+      formatAggregationResultForChart(
+        uniqueCalendarMonthsNestedArr[i],
+        obsMinMonthlyArr
+      )
+    );
+
+  // Extract the formatted metadata properties
+  const extractedFormattedDatastreamProperties =
+    extractPropertiesFromFormattedDatastreamMetadata(
+      formattedMetadataNestedArr,
+      true,
+      "monthly",
+      "minimum"
+    );
+
+  return [
+    formattedObservationsMinimumMonthlyNestedArr,
+    extractedFormattedDatastreamProperties,
+  ];
+};
+
+export {
+  calculateAndFormatDailyMinimumObservations,
+  calculateAndFormatMonthlyMinimumObservations,
+};
diff --git a/public/js/src_modules/dropDownListAggregationSum.mjs b/public/js/src_modules/dropDownListAggregationSum.mjs
new file mode 100644
index 0000000..472db00
--- /dev/null
+++ b/public/js/src_modules/dropDownListAggregationSum.mjs
@@ -0,0 +1,117 @@
+"use strict";
+
+import {
+  extractUniqueCalendarMonthsFromCalendarDates,
+  formatAggregationResultForChart,
+} from "./aggregateHelpers.mjs";
+
+import { calculateSumOfObservationValuesWithinInterval } from "./aggregate.mjs";
+
+import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataProcessing.mjs";
+
+/**
+ * Calculate the daily sum of observations and format these aggregated observations
+ *
+ * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
+ * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
+ * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
+ * @returns {Array} An array whose first element is the formatted aggregated (daily sum) observations. The second element is an object made up of extracted & formatted datastream properties
+ */
+const calculateAndFormatDailySumObservations = function (
+  uniqueCalendarDatesNestedArr,
+  observationsAggregationNestedArr,
+  selectedSamplingRateAbbrev,
+  formattedMetadataNestedArr
+) {
+  // Calculate SUM / DAILY of values of observations
+  const observationsSumDailyNestedArr =
+    calculateSumOfObservationValuesWithinInterval(
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      uniqueCalendarDatesNestedArr,
+      "daily"
+    );
+
+  // Format the observations
+  const formattedObservationsSumDailyNestedArr =
+    observationsSumDailyNestedArr.map((obsSumDailyArr, i) =>
+      formatAggregationResultForChart(
+        uniqueCalendarDatesNestedArr[i],
+        obsSumDailyArr
+      )
+    );
+
+  // Extract the formatted metadata properties
+  const extractedFormattedDatastreamProperties =
+    extractPropertiesFromFormattedDatastreamMetadata(
+      formattedMetadataNestedArr,
+      true,
+      "daily",
+      "sum"
+    );
+
+  return [
+    formattedObservationsSumDailyNestedArr,
+    extractedFormattedDatastreamProperties,
+  ];
+};
+
+/**
+ * Calculate the monthly sum of observations and format these aggregated observations
+ *
+ * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
+ * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
+ * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
+ * @returns {Array} An array whose first element is the formatted aggregated (monthly sum) observations. The second element is an object made up of extracted & formatted datastream properties
+ */
+const calculateAndFormatMonthlySumObservations = function (
+  uniqueCalendarDatesNestedArr,
+  observationsAggregationNestedArr,
+  selectedSamplingRateAbbrev,
+  formattedMetadataNestedArr
+) {
+  // Unique calendar months
+  const uniqueCalendarMonthsNestedArr = uniqueCalendarDatesNestedArr.map(
+    (uniqueCalendarDatesArr) =>
+      extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
+  );
+
+  // Calculate SUM / MONTHLY of values of observations
+  const observationsSumMonthlyNestedArr =
+    calculateSumOfObservationValuesWithinInterval(
+      observationsAggregationNestedArr,
+      selectedSamplingRateAbbrev,
+      uniqueCalendarMonthsNestedArr,
+      "monthly"
+    );
+
+  // Format the observations
+  const formattedObservationsSumMonthlyNestedArr =
+    observationsSumMonthlyNestedArr.map((obsSumMonthlyArr, i) =>
+      formatAggregationResultForChart(
+        uniqueCalendarMonthsNestedArr[i],
+        obsSumMonthlyArr
+      )
+    );
+
+  // Extract the formatted metadata properties
+  const extractedFormattedDatastreamProperties =
+    extractPropertiesFromFormattedDatastreamMetadata(
+      formattedMetadataNestedArr,
+      true,
+      "monthly",
+      "sum"
+    );
+
+  return [
+    formattedObservationsSumMonthlyNestedArr,
+    extractedFormattedDatastreamProperties,
+  ];
+};
+
+export {
+  calculateAndFormatDailySumObservations,
+  calculateAndFormatMonthlySumObservations,
+};
diff --git a/public/js/src_modules/dropDownListChartColumn.mjs b/public/js/src_modules/dropDownListChartColumn.mjs
index eda51d7..e412fdc 100644
--- a/public/js/src_modules/dropDownListChartColumn.mjs
+++ b/public/js/src_modules/dropDownListChartColumn.mjs
@@ -5,13 +5,22 @@ import { drawColumnChartHighcharts } from "./chartColumn.mjs";
 import {
   calculateAndFormatDailySumObservations,
   calculateAndFormatMonthlySumObservations,
+} from "./dropDownListAggregationSum.mjs";
+
+import {
   calculateAndFormatDailyMaximumObservations,
   calculateAndFormatMonthlyMaximumObservations,
+} from "./dropDownListAggregationMaximum.mjs";
+
+import {
   calculateAndFormatDailyMinimumObservations,
   calculateAndFormatMonthlyMinimumObservations,
+} from "./dropDownListAggregationMinimum.mjs";
+
+import {
   calculateAndFormatDailyAverageObservations,
   calculateAndFormatMonthlyAverageObservations,
-} from "./dropDownListProcessing.mjs";
+} from "./dropDownListAggregationAverage.mjs";
 
 /**
  * Draw a column chart based on the selected aggregation options from a drop-down list
diff --git a/public/js/src_modules/dropDownListChartLine.mjs b/public/js/src_modules/dropDownListChartLine.mjs
index 7d10a0d..70e721d 100644
--- a/public/js/src_modules/dropDownListChartLine.mjs
+++ b/public/js/src_modules/dropDownListChartLine.mjs
@@ -5,13 +5,22 @@ import { drawLineChartHighcharts } from "./chartLine.mjs";
 import {
   calculateAndFormatDailySumObservations,
   calculateAndFormatMonthlySumObservations,
+} from "./dropDownListAggregationSum.mjs";
+
+import {
   calculateAndFormatDailyMaximumObservations,
   calculateAndFormatMonthlyMaximumObservations,
+} from "./dropDownListAggregationMaximum.mjs";
+
+import {
   calculateAndFormatDailyMinimumObservations,
   calculateAndFormatMonthlyMinimumObservations,
+} from "./dropDownListAggregationMinimum.mjs";
+
+import {
   calculateAndFormatDailyAverageObservations,
   calculateAndFormatMonthlyAverageObservations,
-} from "./dropDownListProcessing.mjs";
+} from "./dropDownListAggregationAverage.mjs";
 
 /**
  * Draw a line chart based on the selected aggregation options from a drop-down list
diff --git a/public/js/src_modules/dropDownListProcessing.mjs b/public/js/src_modules/dropDownListProcessing.mjs
deleted file mode 100644
index 508a73d..0000000
--- a/public/js/src_modules/dropDownListProcessing.mjs
+++ /dev/null
@@ -1,434 +0,0 @@
-"use strict";
-
-import {
-  extractUniqueCalendarMonthsFromCalendarDates,
-  formatAggregationResultForChart,
-} from "./aggregateHelpers.mjs";
-
-import {
-  calculateMinimumObservationValuesWithinInterval,
-  calculateMaximumObservationValuesWithinInterval,
-  calculateSumOfObservationValuesWithinInterval,
-  calculateAverageOfObservationValuesWithinInterval,
-} from "./aggregate.mjs";
-
-import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataProcessing.mjs";
-
-/**
- * Calculate the daily sum of observations and format these aggregated observations
- *
- * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
- * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
- * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
- * @returns {Array} An array whose first element is the formatted aggregated (daily sum) observations. The second element is an object made up of extracted & formatted datastream properties
- */
-const calculateAndFormatDailySumObservations = function (
-  uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
-  selectedSamplingRateAbbrev,
-  formattedMetadataNestedArr
-) {
-  // Calculate SUM / DAILY of values of observations
-  const observationsSumDailyNestedArr =
-    calculateSumOfObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      uniqueCalendarDatesNestedArr,
-      "daily"
-    );
-
-  // Format the observations
-  const formattedObservationsSumDailyNestedArr =
-    observationsSumDailyNestedArr.map((obsSumDailyArr, i) =>
-      formatAggregationResultForChart(
-        uniqueCalendarDatesNestedArr[i],
-        obsSumDailyArr
-      )
-    );
-
-  // Extract the formatted metadata properties
-  const extractedFormattedDatastreamProperties =
-    extractPropertiesFromFormattedDatastreamMetadata(
-      formattedMetadataNestedArr,
-      true,
-      "daily",
-      "sum"
-    );
-
-  return [
-    formattedObservationsSumDailyNestedArr,
-    extractedFormattedDatastreamProperties,
-  ];
-};
-
-/**
- * Calculate the monthly sum of observations and format these aggregated observations
- *
- * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
- * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
- * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
- * @returns {Array} An array whose first element is the formatted aggregated (monthly sum) observations. The second element is an object made up of extracted & formatted datastream properties
- */
-const calculateAndFormatMonthlySumObservations = function (
-  uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
-  selectedSamplingRateAbbrev,
-  formattedMetadataNestedArr
-) {
-  // Unique calendar months
-  const uniqueCalendarMonthsNestedArr = uniqueCalendarDatesNestedArr.map(
-    (uniqueCalendarDatesArr) =>
-      extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
-  );
-
-  // Calculate SUM / MONTHLY of values of observations
-  const observationsSumMonthlyNestedArr =
-    calculateSumOfObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      uniqueCalendarMonthsNestedArr,
-      "monthly"
-    );
-
-  // Format the observations
-  const formattedObservationsSumMonthlyNestedArr =
-    observationsSumMonthlyNestedArr.map((obsSumMonthlyArr, i) =>
-      formatAggregationResultForChart(
-        uniqueCalendarMonthsNestedArr[i],
-        obsSumMonthlyArr
-      )
-    );
-
-  // Extract the formatted metadata properties
-  const extractedFormattedDatastreamProperties =
-    extractPropertiesFromFormattedDatastreamMetadata(
-      formattedMetadataNestedArr,
-      true,
-      "monthly",
-      "sum"
-    );
-
-  return [
-    formattedObservationsSumMonthlyNestedArr,
-    extractedFormattedDatastreamProperties,
-  ];
-};
-
-/**
- * Calculate the daily maximum of observations and format these aggregated observations
- *
- * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
- * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
- * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
- * @returns {Array} An array whose first element is the formatted aggregated (daily maximum) observations. The second element is an object made up of extracted & formatted datastream properties
- */
-const calculateAndFormatDailyMaximumObservations = function (
-  uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
-  selectedSamplingRateAbbrev,
-  formattedMetadataNestedArr
-) {
-  // Calculate MAXIMUM / DAILY of values of observations
-  const observationsMaximumDailyNestedArr =
-    calculateMaximumObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      uniqueCalendarDatesNestedArr,
-      "daily"
-    );
-
-  // Format the observations
-  const formattedObservationsMaximumDailyNestedArr =
-    observationsMaximumDailyNestedArr.map((obsMinDailyArr, i) =>
-      formatAggregationResultForChart(
-        uniqueCalendarDatesNestedArr[i],
-        obsMinDailyArr
-      )
-    );
-
-  // Extract the formatted metadata properties
-  const extractedFormattedDatastreamProperties =
-    extractPropertiesFromFormattedDatastreamMetadata(
-      formattedMetadataNestedArr,
-      true,
-      "daily",
-      "maximum"
-    );
-
-  return [
-    formattedObservationsMaximumDailyNestedArr,
-    extractedFormattedDatastreamProperties,
-  ];
-};
-
-/**
- * Calculate the monthly maximum of observations and format these aggregated observations
- *
- * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
- * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
- * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
- * @returns {Array} An array whose first element is the formatted aggregated (monthly maximum) observations. The second element is an object made up of extracted & formatted datastream properties
- */
-const calculateAndFormatMonthlyMaximumObservations = function (
-  uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
-  selectedSamplingRateAbbrev,
-  formattedMetadataNestedArr
-) {
-  // Unique calendar months
-  const uniqueCalendarMonthsNestedArr = uniqueCalendarDatesNestedArr.map(
-    (uniqueCalendarDatesArr) =>
-      extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
-  );
-
-  // Calculate MAXIMUM / MONTHLY of values of observations
-  const observationsMaximumMonthlyNestedArr =
-    calculateMaximumObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      uniqueCalendarMonthsNestedArr,
-      "monthly"
-    );
-
-  // Format the observations
-  const formattedObservationsMaximumMonthlyNestedArr =
-    observationsMaximumMonthlyNestedArr.map((obsMaxMonthlyArr, i) =>
-      formatAggregationResultForChart(
-        uniqueCalendarMonthsNestedArr[i],
-        obsMaxMonthlyArr
-      )
-    );
-
-  // Extract the formatted metadata properties
-  const extractedFormattedDatastreamProperties =
-    extractPropertiesFromFormattedDatastreamMetadata(
-      formattedMetadataNestedArr,
-      true,
-      "monthly",
-      "maximum"
-    );
-
-  return [
-    formattedObservationsMaximumMonthlyNestedArr,
-    extractedFormattedDatastreamProperties,
-  ];
-};
-
-/**
- * Calculate the daily minimum of observations and format these aggregated observations
- *
- * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
- * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
- * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
- * @returns {Array} An array whose first element is the formatted aggregated (daily minimum) observations. The second element is an object made up of extracted & formatted datastream properties
- */
-const calculateAndFormatDailyMinimumObservations = function (
-  uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
-  selectedSamplingRateAbbrev,
-  formattedMetadataNestedArr
-) {
-  // Calculate MINIMUM / DAILY of values of observations
-  const observationsMinimumDailyNestedArr =
-    calculateMinimumObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      uniqueCalendarDatesNestedArr,
-      "daily"
-    );
-
-  // Format the observations
-  const formattedObservationsMinimumDailyNestedArr =
-    observationsMinimumDailyNestedArr.map((obsMinDailyArr, i) =>
-      formatAggregationResultForChart(
-        uniqueCalendarDatesNestedArr[i],
-        obsMinDailyArr
-      )
-    );
-
-  // Extract the formatted metadata properties
-  const extractedFormattedDatastreamProperties =
-    extractPropertiesFromFormattedDatastreamMetadata(
-      formattedMetadataNestedArr,
-      true,
-      "daily",
-      "minimum"
-    );
-
-  return [
-    formattedObservationsMinimumDailyNestedArr,
-    extractedFormattedDatastreamProperties,
-  ];
-};
-
-/**
- * Calculate the monthly minimum of observations and format these aggregated observations
- *
- * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
- * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
- * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
- * @returns {Array} An array whose first element is the formatted aggregated (monthly minimum) observations. The second element is an object made up of extracted & formatted datastream properties
- */
-const calculateAndFormatMonthlyMinimumObservations = function (
-  uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
-  selectedSamplingRateAbbrev,
-  formattedMetadataNestedArr
-) {
-  // Unique calendar months
-  const uniqueCalendarMonthsNestedArr = uniqueCalendarDatesNestedArr.map(
-    (uniqueCalendarDatesArr) =>
-      extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
-  );
-
-  // Calculate MINIMUM / MONTHLY of values of observations
-  const observationsMinimumMonthlyNestedArr =
-    calculateMinimumObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      uniqueCalendarMonthsNestedArr,
-      "monthly"
-    );
-
-  // Format the observations
-  const formattedObservationsMinimumMonthlyNestedArr =
-    observationsMinimumMonthlyNestedArr.map((obsMinMonthlyArr, i) =>
-      formatAggregationResultForChart(
-        uniqueCalendarMonthsNestedArr[i],
-        obsMinMonthlyArr
-      )
-    );
-
-  // Extract the formatted metadata properties
-  const extractedFormattedDatastreamProperties =
-    extractPropertiesFromFormattedDatastreamMetadata(
-      formattedMetadataNestedArr,
-      true,
-      "monthly",
-      "minimum"
-    );
-
-  return [
-    formattedObservationsMinimumMonthlyNestedArr,
-    extractedFormattedDatastreamProperties,
-  ];
-};
-
-/**
- * Calculate the daily average of observations and format these aggregated observations
- *
- * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
- * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
- * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
- * @returns {Array} An array whose first element is the formatted aggregated (daily average) observations. The second element is an object made up of extracted & formatted datastream properties
- */
-const calculateAndFormatDailyAverageObservations = function (
-  uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
-  selectedSamplingRateAbbrev,
-  formattedMetadataNestedArr
-) {
-  // Calculate AVERAGE / DAILY of values of observations
-  const observationsAverageDailyNestedArr =
-    calculateAverageOfObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      uniqueCalendarDatesNestedArr,
-      "daily"
-    );
-
-  // Format the observations
-  const formattedObservationsAverageDailyNestedArr =
-    observationsAverageDailyNestedArr.map((obsAverageDailyArr, i) =>
-      formatAggregationResultForChart(
-        uniqueCalendarDatesNestedArr[i],
-        obsAverageDailyArr
-      )
-    );
-
-  // Extract the formatted metadata properties
-  const extractedFormattedDatastreamProperties =
-    extractPropertiesFromFormattedDatastreamMetadata(
-      formattedMetadataNestedArr,
-      true,
-      "daily",
-      "average"
-    );
-
-  return [
-    formattedObservationsAverageDailyNestedArr,
-    extractedFormattedDatastreamProperties,
-  ];
-};
-
-/**
- * Calculate the monthly average of observations and format these aggregated observations
- *
- * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
- * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
- * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
- * @returns {Array} An array whose first element is the formatted aggregated (monthly average) observations. The second element is an object made up of extracted & formatted datastream properties
- */
-const calculateAndFormatMonthlyAverageObservations = function (
-  uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
-  selectedSamplingRateAbbrev,
-  formattedMetadataNestedArr
-) {
-  // Unique calendar months
-  const uniqueCalendarMonthsNestedArr = uniqueCalendarDatesNestedArr.map(
-    (uniqueCalendarDatesArr) =>
-      extractUniqueCalendarMonthsFromCalendarDates(uniqueCalendarDatesArr)
-  );
-
-  // Calculate AVERAGE / MONTHLY of values of observations
-  const observationsAverageMonthlyNestedArr =
-    calculateAverageOfObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      uniqueCalendarMonthsNestedArr,
-      "monthly"
-    );
-
-  // Format the observations
-  const formattedObservationsAverageMonthlyNestedArr =
-    observationsAverageMonthlyNestedArr.map((obsAverageMonthlyArr, i) =>
-      formatAggregationResultForChart(
-        uniqueCalendarMonthsNestedArr[i],
-        obsAverageMonthlyArr
-      )
-    );
-
-  // Extract the formatted metadata properties
-  const extractedFormattedDatastreamProperties =
-    extractPropertiesFromFormattedDatastreamMetadata(
-      formattedMetadataNestedArr,
-      true,
-      "monthly",
-      "average"
-    );
-
-  return [
-    formattedObservationsAverageMonthlyNestedArr,
-    extractedFormattedDatastreamProperties,
-  ];
-};
-
-export {
-  calculateAndFormatDailySumObservations,
-  calculateAndFormatMonthlySumObservations,
-  calculateAndFormatDailyMaximumObservations,
-  calculateAndFormatMonthlyMaximumObservations,
-  calculateAndFormatDailyMinimumObservations,
-  calculateAndFormatMonthlyMinimumObservations,
-  calculateAndFormatDailyAverageObservations,
-  calculateAndFormatMonthlyAverageObservations,
-};
-- 
GitLab


From 5993e89767d9904f5733387d02ae5268f7b92263 Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Tue, 26 Oct 2021 15:14:33 +0200
Subject: [PATCH 8/9] Edit function: draw line chart based on selection

Use spread operator to replace the references that contain the values
for the formatted observations and formatted metadata
---
 .../dropDownListAggregationAverage.mjs        |  12 +-
 .../dropDownListAggregationMaximum.mjs        |  12 +-
 .../dropDownListAggregationMinimum.mjs        |  12 +-
 .../dropDownListAggregationSum.mjs            |  12 +-
 .../src_modules/dropDownListChartColumn.mjs   |  73 ++++---
 .../js/src_modules/dropDownListChartLine.mjs  | 188 +++++++-----------
 6 files changed, 140 insertions(+), 169 deletions(-)

diff --git a/public/js/src_modules/dropDownListAggregationAverage.mjs b/public/js/src_modules/dropDownListAggregationAverage.mjs
index 98098af..d2d6c32 100644
--- a/public/js/src_modules/dropDownListAggregationAverage.mjs
+++ b/public/js/src_modules/dropDownListAggregationAverage.mjs
@@ -13,21 +13,21 @@ import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataP
  * Calculate the daily average of observations and format these aggregated observations
  *
  * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
  * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {Array} An array whose first element is the formatted aggregated (daily average) observations. The second element is an object made up of extracted & formatted datastream properties
  */
 const calculateAndFormatDailyAverageObservations = function (
   uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
+  observationsNestedArr,
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
   // Calculate AVERAGE / DAILY of values of observations
   const observationsAverageDailyNestedArr =
     calculateAverageOfObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       uniqueCalendarDatesNestedArr,
       "daily"
@@ -61,14 +61,14 @@ const calculateAndFormatDailyAverageObservations = function (
  * Calculate the monthly average of observations and format these aggregated observations
  *
  * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
  * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {Array} An array whose first element is the formatted aggregated (monthly average) observations. The second element is an object made up of extracted & formatted datastream properties
  */
 const calculateAndFormatMonthlyAverageObservations = function (
   uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
+  observationsNestedArr,
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
@@ -81,7 +81,7 @@ const calculateAndFormatMonthlyAverageObservations = function (
   // Calculate AVERAGE / MONTHLY of values of observations
   const observationsAverageMonthlyNestedArr =
     calculateAverageOfObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       uniqueCalendarMonthsNestedArr,
       "monthly"
diff --git a/public/js/src_modules/dropDownListAggregationMaximum.mjs b/public/js/src_modules/dropDownListAggregationMaximum.mjs
index 3ef25d3..bb5464d 100644
--- a/public/js/src_modules/dropDownListAggregationMaximum.mjs
+++ b/public/js/src_modules/dropDownListAggregationMaximum.mjs
@@ -13,21 +13,21 @@ import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataP
  * Calculate the daily maximum of observations and format these aggregated observations
  *
  * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
  * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {Array} An array whose first element is the formatted aggregated (daily maximum) observations. The second element is an object made up of extracted & formatted datastream properties
  */
 const calculateAndFormatDailyMaximumObservations = function (
   uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
+  observationsNestedArr,
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
   // Calculate MAXIMUM / DAILY of values of observations
   const observationsMaximumDailyNestedArr =
     calculateMaximumObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       uniqueCalendarDatesNestedArr,
       "daily"
@@ -61,14 +61,14 @@ const calculateAndFormatDailyMaximumObservations = function (
  * Calculate the monthly maximum of observations and format these aggregated observations
  *
  * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
  * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {Array} An array whose first element is the formatted aggregated (monthly maximum) observations. The second element is an object made up of extracted & formatted datastream properties
  */
 const calculateAndFormatMonthlyMaximumObservations = function (
   uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
+  observationsNestedArr,
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
@@ -81,7 +81,7 @@ const calculateAndFormatMonthlyMaximumObservations = function (
   // Calculate MAXIMUM / MONTHLY of values of observations
   const observationsMaximumMonthlyNestedArr =
     calculateMaximumObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       uniqueCalendarMonthsNestedArr,
       "monthly"
diff --git a/public/js/src_modules/dropDownListAggregationMinimum.mjs b/public/js/src_modules/dropDownListAggregationMinimum.mjs
index 2fec44e..fa1d050 100644
--- a/public/js/src_modules/dropDownListAggregationMinimum.mjs
+++ b/public/js/src_modules/dropDownListAggregationMinimum.mjs
@@ -13,21 +13,21 @@ import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataP
  * Calculate the daily minimum of observations and format these aggregated observations
  *
  * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
  * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {Array} An array whose first element is the formatted aggregated (daily minimum) observations. The second element is an object made up of extracted & formatted datastream properties
  */
 const calculateAndFormatDailyMinimumObservations = function (
   uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
+  observationsNestedArr,
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
   // Calculate MINIMUM / DAILY of values of observations
   const observationsMinimumDailyNestedArr =
     calculateMinimumObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       uniqueCalendarDatesNestedArr,
       "daily"
@@ -61,14 +61,14 @@ const calculateAndFormatDailyMinimumObservations = function (
  * Calculate the monthly minimum of observations and format these aggregated observations
  *
  * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
  * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {Array} An array whose first element is the formatted aggregated (monthly minimum) observations. The second element is an object made up of extracted & formatted datastream properties
  */
 const calculateAndFormatMonthlyMinimumObservations = function (
   uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
+  observationsNestedArr,
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
@@ -81,7 +81,7 @@ const calculateAndFormatMonthlyMinimumObservations = function (
   // Calculate MINIMUM / MONTHLY of values of observations
   const observationsMinimumMonthlyNestedArr =
     calculateMinimumObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       uniqueCalendarMonthsNestedArr,
       "monthly"
diff --git a/public/js/src_modules/dropDownListAggregationSum.mjs b/public/js/src_modules/dropDownListAggregationSum.mjs
index 472db00..4d15328 100644
--- a/public/js/src_modules/dropDownListAggregationSum.mjs
+++ b/public/js/src_modules/dropDownListAggregationSum.mjs
@@ -13,21 +13,21 @@ import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataP
  * Calculate the daily sum of observations and format these aggregated observations
  *
  * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
  * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {Array} An array whose first element is the formatted aggregated (daily sum) observations. The second element is an object made up of extracted & formatted datastream properties
  */
 const calculateAndFormatDailySumObservations = function (
   uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
+  observationsNestedArr,
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
   // Calculate SUM / DAILY of values of observations
   const observationsSumDailyNestedArr =
     calculateSumOfObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       uniqueCalendarDatesNestedArr,
       "daily"
@@ -61,14 +61,14 @@ const calculateAndFormatDailySumObservations = function (
  * Calculate the monthly sum of observations and format these aggregated observations
  *
  * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
  * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {Array} An array whose first element is the formatted aggregated (monthly sum) observations. The second element is an object made up of extracted & formatted datastream properties
  */
 const calculateAndFormatMonthlySumObservations = function (
   uniqueCalendarDatesNestedArr,
-  observationsAggregationNestedArr,
+  observationsNestedArr,
   selectedSamplingRateAbbrev,
   formattedMetadataNestedArr
 ) {
@@ -81,7 +81,7 @@ const calculateAndFormatMonthlySumObservations = function (
   // Calculate SUM / MONTHLY of values of observations
   const observationsSumMonthlyNestedArr =
     calculateSumOfObservationValuesWithinInterval(
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       uniqueCalendarMonthsNestedArr,
       "monthly"
diff --git a/public/js/src_modules/dropDownListChartColumn.mjs b/public/js/src_modules/dropDownListChartColumn.mjs
index e412fdc..49af49c 100644
--- a/public/js/src_modules/dropDownListChartColumn.mjs
+++ b/public/js/src_modules/dropDownListChartColumn.mjs
@@ -27,31 +27,31 @@ import {
  *
  * @param {String} selectedAggregationType A string representing the selected aggregation type. The currently supported strings include `Sum`, `Maximum`, `Minimum` and `Average`
  * @param {String} selectedAggregationDuration A string representing the selected aggregation duration. The currently supported strings include `Daily` and `Monthly`
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
  * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
  * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {undefined} undefined
  */
 export const drawColumnChartBasedOnSelectedAggregationOptions = function (
-  selectedAggregationTypeArr,
+  selectedAggregationType,
   selectedAggregationDuration,
-  observationsAggregationNestedArr,
+  observationsNestedArr,
   selectedSamplingRateAbbrev,
   uniqueCalendarDatesNestedArr,
   formattedMetadataNestedArr
 ) {
+  // Daily / sum
   if (
-    selectedAggregationTypeArr === "Sum" &&
+    selectedAggregationType === "Sum" &&
     selectedAggregationDuration === "Daily"
   ) {
-    // Formatted observations and metadata for chart - daily / sum
     const [
       formattedObservationsSumDailyNestedArr,
       extractedFormattedDatastreamProperties,
     ] = calculateAndFormatDailySumObservations(
       uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       formattedMetadataNestedArr
     );
@@ -60,17 +60,18 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
       formattedObservationsSumDailyNestedArr,
       extractedFormattedDatastreamProperties
     );
-  } else if (
-    selectedAggregationTypeArr === "Sum" &&
+  }
+  // Monthly / sum
+  else if (
+    selectedAggregationType === "Sum" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    // Formatted observations and metadata for chart - monthly / sum
     const [
       formattedObservationsSumMonthlyNestedArr,
       extractedFormattedDatastreamProperties,
     ] = calculateAndFormatMonthlySumObservations(
       uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       formattedMetadataNestedArr
     );
@@ -79,8 +80,10 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
       formattedObservationsSumMonthlyNestedArr,
       extractedFormattedDatastreamProperties
     );
-  } else if (
-    selectedAggregationTypeArr === "Maximum" &&
+  }
+  // Daily / maximum
+  else if (
+    selectedAggregationType === "Maximum" &&
     selectedAggregationDuration === "Daily"
   ) {
     // Formatted observations and metadata for chart - daily / maximum
@@ -89,7 +92,7 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
       extractedFormattedDatastreamProperties,
     ] = calculateAndFormatDailyMaximumObservations(
       uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       formattedMetadataNestedArr
     );
@@ -98,17 +101,18 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
       formattedObservationsMaximumDailyNestedArr,
       extractedFormattedDatastreamProperties
     );
-  } else if (
-    selectedAggregationTypeArr === "Maximum" &&
+  }
+  // Monthly / maximum
+  else if (
+    selectedAggregationType === "Maximum" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    // Formatted observations and metadata for chart - monthly / maximum
     const [
       formattedObservationsMaximumMonthlyNestedArr,
       extractedFormattedDatastreamProperties,
     ] = calculateAndFormatMonthlyMaximumObservations(
       uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       formattedMetadataNestedArr
     );
@@ -117,8 +121,10 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
       formattedObservationsMaximumMonthlyNestedArr,
       extractedFormattedDatastreamProperties
     );
-  } else if (
-    selectedAggregationTypeArr === "Minimum" &&
+  }
+  // Daily / minimum
+  else if (
+    selectedAggregationType === "Minimum" &&
     selectedAggregationDuration === "Daily"
   ) {
     // Formatted observations and metadata for chart - daily / minimum
@@ -127,7 +133,7 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
       extractedFormattedDatastreamProperties,
     ] = calculateAndFormatDailyMinimumObservations(
       uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       formattedMetadataNestedArr
     );
@@ -136,17 +142,18 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
       formattedObservationsMinimumDailyNestedArr,
       extractedFormattedDatastreamProperties
     );
-  } else if (
-    selectedAggregationTypeArr === "Minimum" &&
+  }
+  // Monthly / minimum
+  else if (
+    selectedAggregationType === "Minimum" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    // Formatted observations and metadata for chart - monthly / minimum
     const [
       formattedObservationsMinimumMonthlyNestedArr,
       extractedFormattedDatastreamProperties,
     ] = calculateAndFormatMonthlyMinimumObservations(
       uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       formattedMetadataNestedArr
     );
@@ -155,17 +162,18 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
       formattedObservationsMinimumMonthlyNestedArr,
       extractedFormattedDatastreamProperties
     );
-  } else if (
-    selectedAggregationTypeArr === "Average" &&
+  }
+  // Daily / average
+  else if (
+    selectedAggregationType === "Average" &&
     selectedAggregationDuration === "Daily"
   ) {
-    // Formatted observations and metadata for chart - daily / average
     const [
       formattedObservationsAverageDailyNestedArr,
       extractedFormattedDatastreamProperties,
     ] = calculateAndFormatDailyAverageObservations(
       uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       formattedMetadataNestedArr
     );
@@ -174,17 +182,18 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
       formattedObservationsAverageDailyNestedArr,
       extractedFormattedDatastreamProperties
     );
-  } else if (
-    selectedAggregationTypeArr === "Average" &&
+  }
+  // Monthly / average
+  else if (
+    selectedAggregationType === "Average" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    // Formatted observations and metadata for chart - monthly / average
     const [
       formattedObservationsAverageMonthlyNestedArr,
       extractedFormattedDatastreamProperties,
     ] = calculateAndFormatMonthlyAverageObservations(
       uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
+      observationsNestedArr,
       selectedSamplingRateAbbrev,
       formattedMetadataNestedArr
     );
diff --git a/public/js/src_modules/dropDownListChartLine.mjs b/public/js/src_modules/dropDownListChartLine.mjs
index 70e721d..494e466 100644
--- a/public/js/src_modules/dropDownListChartLine.mjs
+++ b/public/js/src_modules/dropDownListChartLine.mjs
@@ -27,7 +27,7 @@ import {
  *
  * @param {String} selectedAggregationType A string representing the selected aggregation type. The currently supported strings include `Sum`, `Maximum`, `Minimum` and `Average`
  * @param {String} selectedAggregationDuration A string representing the selected aggregation duration. The currently supported strings include `Daily` and `Monthly`
- * @param {Array} observationsAggregationNestedArr An array made up of sub-array(s) of aggregated observations
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
  * @param {String} selectedSamplingRateAbbrev A string representing the abbreviated form of the selected sampling rate option
  * @param {Array} uniqueCalendarDatesNestedArr An array made up of sub-array(s) of unique calendar date(s) string(s)
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
@@ -36,162 +36,124 @@ import {
 export const drawLineChartBasedOnSelectedAggregationOptions = function (
   selectedAggregationType,
   selectedAggregationDuration,
-  observationsAggregationNestedArr,
+  observationsNestedArr,
   selectedSamplingRateAbbrev,
   uniqueCalendarDatesNestedArr,
   formattedMetadataNestedArr
 ) {
+  // Daily / sum
   if (
     selectedAggregationType === "Sum" &&
     selectedAggregationDuration === "Daily"
   ) {
-    // Formatted observations and metadata for chart - daily / sum
-    const [
-      formattedObservationsSumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailySumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
+    // Note: The `drawColumChart` function expects two arguments,
+    // these are obtained by using the spread operator on the
+    // result returned from the `calculateAndFormat...` functions
     drawLineChartHighcharts(
-      formattedObservationsSumDailyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatDailySumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
-  } else if (
+  }
+  // Monthly / sum
+  else if (
     selectedAggregationType === "Sum" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    // Formatted observations and metadata for chart - monthly / sum
-    const [
-      formattedObservationsSumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlySumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawLineChartHighcharts(
-      formattedObservationsSumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatMonthlySumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
-  } else if (
+  }
+  // Daily / maximum
+  else if (
     selectedAggregationType === "Maximum" &&
     selectedAggregationDuration === "Daily"
   ) {
-    // Formatted observations and metadata for chart - daily / maximum
-    const [
-      formattedObservationsMaximumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyMaximumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawLineChartHighcharts(
-      formattedObservationsMaximumDailyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatDailyMaximumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
-  } else if (
+  }
+  // Monthly / maximum
+  else if (
     selectedAggregationType === "Maximum" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    // Formatted observations and metadata for chart - monthly / maximum
-    const [
-      formattedObservationsMaximumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyMaximumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawLineChartHighcharts(
-      formattedObservationsMaximumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatMonthlyMaximumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
-  } else if (
+  }
+  // Daily / minimum
+  else if (
     selectedAggregationType === "Minimum" &&
     selectedAggregationDuration === "Daily"
   ) {
-    // Formatted observations and metadata for chart - daily / minimum
-    const [
-      formattedObservationsMinimumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyMinimumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawLineChartHighcharts(
-      formattedObservationsMinimumDailyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatDailyMinimumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
-  } else if (
+  }
+  // Monthly / minimum
+  else if (
     selectedAggregationType === "Minimum" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    // Formatted observations and metadata for chart - monthly / minimum
-    const [
-      formattedObservationsMinimumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyMinimumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawLineChartHighcharts(
-      formattedObservationsMinimumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatMonthlyMinimumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
-  } else if (
+  }
+  // Daily / average
+  else if (
     selectedAggregationType === "Average" &&
     selectedAggregationDuration === "Daily"
   ) {
-    // Formatted observations and metadata for chart - daily / average
-    const [
-      formattedObservationsAverageDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyAverageObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawLineChartHighcharts(
-      formattedObservationsAverageDailyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatDailyAverageObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
-  } else if (
+  }
+  // Monthly / average
+  else if (
     selectedAggregationType === "Average" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    // Formatted observations and metadata for chart - monthly / average
-    const [
-      formattedObservationsAverageMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyAverageObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsAggregationNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawLineChartHighcharts(
-      formattedObservationsAverageMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatMonthlyAverageObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
   }
 };
-- 
GitLab


From f7b471cfaeab5b275124253966ec4d8fbc73c2f6 Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Tue, 26 Oct 2021 15:19:06 +0200
Subject: [PATCH 9/9] Edit function: draw column chart, selection-based

Use spread operator to replace the references that contain the values
for the formatted observations and formatted metadata
---
 public/js/appChart.js                         |   2 +-
 .../src_modules/dropDownListChartColumn.mjs   | 149 ++++++------------
 public/js/src_modules/fetchData.mjs           |   2 +-
 3 files changed, 53 insertions(+), 100 deletions(-)

diff --git a/public/js/appChart.js b/public/js/appChart.js
index bb1f8d3..24f5468 100644
--- a/public/js/appChart.js
+++ b/public/js/appChart.js
@@ -193,7 +193,7 @@ const drawChartUsingSelectedOptions = async function () {
           )
         : selectedBuildingsDataPointsSamplingRateAbbrevNestedArr;
 
-    // Check if we have dT (temperature difference)
+    // Check if we have dT (temperature difference), if so, extract these options
     const selectedBuildingsDataPointsSamplingRateAbbrevTempDiffArr =
       checkIfSelectedOptionsContainTemperatureDifference(
         selectedBuildingsDataPointsSamplingRateAbbrevNestedArr
diff --git a/public/js/src_modules/dropDownListChartColumn.mjs b/public/js/src_modules/dropDownListChartColumn.mjs
index 49af49c..7c2aeee 100644
--- a/public/js/src_modules/dropDownListChartColumn.mjs
+++ b/public/js/src_modules/dropDownListChartColumn.mjs
@@ -46,19 +46,16 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
     selectedAggregationType === "Sum" &&
     selectedAggregationDuration === "Daily"
   ) {
-    const [
-      formattedObservationsSumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailySumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
+    // Note: The `drawColumnChart` function expects two arguments,
+    // these are obtained by using the spread operator on the
+    // result returned from the `calculateAndFormat...` functions
     drawColumnChartHighcharts(
-      formattedObservationsSumDailyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatDailySumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
   }
   // Monthly / sum
@@ -66,19 +63,13 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
     selectedAggregationType === "Sum" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    const [
-      formattedObservationsSumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlySumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawColumnChartHighcharts(
-      formattedObservationsSumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatMonthlySumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
   }
   // Daily / maximum
@@ -86,20 +77,13 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
     selectedAggregationType === "Maximum" &&
     selectedAggregationDuration === "Daily"
   ) {
-    // Formatted observations and metadata for chart - daily / maximum
-    const [
-      formattedObservationsMaximumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyMaximumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawColumnChartHighcharts(
-      formattedObservationsMaximumDailyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatDailyMaximumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
   }
   // Monthly / maximum
@@ -107,19 +91,13 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
     selectedAggregationType === "Maximum" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    const [
-      formattedObservationsMaximumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyMaximumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawColumnChartHighcharts(
-      formattedObservationsMaximumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatMonthlyMaximumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
   }
   // Daily / minimum
@@ -127,20 +105,13 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
     selectedAggregationType === "Minimum" &&
     selectedAggregationDuration === "Daily"
   ) {
-    // Formatted observations and metadata for chart - daily / minimum
-    const [
-      formattedObservationsMinimumDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyMinimumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawColumnChartHighcharts(
-      formattedObservationsMinimumDailyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatDailyMinimumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
   }
   // Monthly / minimum
@@ -148,19 +119,13 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
     selectedAggregationType === "Minimum" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    const [
-      formattedObservationsMinimumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyMinimumObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawColumnChartHighcharts(
-      formattedObservationsMinimumMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatMonthlyMinimumObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
   }
   // Daily / average
@@ -168,19 +133,13 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
     selectedAggregationType === "Average" &&
     selectedAggregationDuration === "Daily"
   ) {
-    const [
-      formattedObservationsAverageDailyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatDailyAverageObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawColumnChartHighcharts(
-      formattedObservationsAverageDailyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatDailyAverageObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
   }
   // Monthly / average
@@ -188,19 +147,13 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
     selectedAggregationType === "Average" &&
     selectedAggregationDuration === "Monthly"
   ) {
-    const [
-      formattedObservationsAverageMonthlyNestedArr,
-      extractedFormattedDatastreamProperties,
-    ] = calculateAndFormatMonthlyAverageObservations(
-      uniqueCalendarDatesNestedArr,
-      observationsNestedArr,
-      selectedSamplingRateAbbrev,
-      formattedMetadataNestedArr
-    );
-
     drawColumnChartHighcharts(
-      formattedObservationsAverageMonthlyNestedArr,
-      extractedFormattedDatastreamProperties
+      ...calculateAndFormatMonthlyAverageObservations(
+        uniqueCalendarDatesNestedArr,
+        observationsNestedArr,
+        selectedSamplingRateAbbrev,
+        formattedMetadataNestedArr
+      )
     );
   }
 };
diff --git a/public/js/src_modules/fetchData.mjs b/public/js/src_modules/fetchData.mjs
index 7b2cca2..f1d207d 100644
--- a/public/js/src_modules/fetchData.mjs
+++ b/public/js/src_modules/fetchData.mjs
@@ -35,7 +35,7 @@ const getDatastream = function (urlDatastream) {
 };
 
 /**
- * Perform a GET request using the Axios library
+ * Perform a GET request to fetch Observations using the Axios library
  * @param {String} urlObservations A URL that fetches Observations from an STA instance
  * @param {Object} urlParamObj The URL parameters to be sent together with the GET request
  * @returns {Promise} A promise that contains the first page of results when fulfilled
-- 
GitLab