From 7917116cb0bb7f77ec1fccbd2f4ac891c6477e81 Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Thu, 28 Oct 2021 09:59:23 +0200
Subject: [PATCH 1/4] Create new module drop-down list styling logic

---
 public/js/appChart.js                         | 151 ++++--------------
 public/js/src_modules/dropDownListStyling.mjs |  53 ++++++
 2 files changed, 86 insertions(+), 118 deletions(-)
 create mode 100644 public/js/src_modules/dropDownListStyling.mjs

diff --git a/public/js/appChart.js b/public/js/appChart.js
index 24f5468..b4d1e7b 100644
--- a/public/js/appChart.js
+++ b/public/js/appChart.js
@@ -30,7 +30,7 @@ import {
   enableDrawChartButton,
 } from "./src_modules/loadingIndicator.mjs";
 
-import { vanillaSelectBox } from "./thirdparty/vanillaSelectBox.mjs";
+import { styleAllDropDownLists } from "./src_modules/dropDownListStyling.mjs";
 
 import {
   extractObservationsWithinDatesInterval,
@@ -57,66 +57,6 @@ import { drawLineChartBasedOnSelectedAggregationOptions } from "./src_modules/dr
 
 import { drawScatterPlotFromChartSelection } from "./src_modules/dropDownListChartScatterPlot.mjs";
 
-/**
- * Use the `vanillaDropDown` library to style the buildings & data points drop down list
- *
- * @returns {undefined}
- */
-const styleBuildingsDataPointsDropDown = function () {
-  // Create our dropdown list using `vanillaSelectBox`; supports the selection of multiple options
-  new vanillaSelectBox("#drop-down--bldg-data-point", {
-    "disableSelectAll": true,
-    "maxSelect": 5,
-    "placeHolder": "--Select--",
-    "search": false,
-  });
-};
-
-/**
- * Use the `vanillaDropDown` library to style the aggregation type drop down list
- *
- * @returns {undefined}
- */
-const styleAggregationDropDown = function () {
-  // Create our dropdown list using `vanillaSelectBox`
-  new vanillaSelectBox("#drop-down--aggregation-type", {
-    "disableSelectAll": true,
-    "maxSelect": 1,
-    "placeHolder": "--Select--",
-    "search": false,
-  });
-};
-
-/**
- * Use the `vanillaDropDown` library to style the third sampling rate down list
- *
- * @returns {undefined}
- */
-const styleSamplingRateDropDown = function () {
-  // Create our dropdown list using `vanillaSelectBox`
-  new vanillaSelectBox("#drop-down--sampling-rate", {
-    "disableSelectAll": true,
-    "maxSelect": 1,
-    "placeHolder": "--Select--",
-    "search": false,
-  });
-};
-
-/**
- * Use the `vanillaDropDown` library to style the chart type drop down list
- *
- * @returns {undefined}
- */
-const styleChartTypeDropDown = function () {
-  // Create our dropdown list using `vanillaSelectBox`
-  new vanillaSelectBox("#drop-down--chart-type", {
-    "disableSelectAll": true,
-    "maxSelect": 1,
-    "placeHolder": "--Select--",
-    "search": false,
-  });
-};
-
 /**
  * Callback function that wraps the logic of populating the linked drop down lists.
  * Will run on `DOMContentLoaded` event
@@ -124,10 +64,7 @@ const styleChartTypeDropDown = function () {
  * @returns {undefined}
  */
 const afterDocumentLoads = function () {
-  styleBuildingsDataPointsDropDown();
-  styleAggregationDropDown();
-  styleSamplingRateDropDown();
-  styleChartTypeDropDown();
+  styleAllDropDownLists();
 };
 
 /**
@@ -140,33 +77,34 @@ const afterDocumentLoads = function () {
  */
 const drawChartUsingSelectedOptions = async function () {
   try {
-    const selectedOptionsAllDropDownLists =
-      getSelectedOptionsFromAllDropDownLists();
-
     // Note: The chart type amd aggregation type + duration are the first and
     // third elements respectively, we have ignored the second and fourth elements
     const [selectedChartTypeArr, , selectedAggregationTypeDurationArr] =
-      selectedOptionsAllDropDownLists;
+      getSelectedOptionsFromAllDropDownLists();
 
-    // Create an array of aggregation type and duration
-    const selectedAggregationTypeDurationSplitNestedArr =
+    // Note: the resulting array is nested, it only has one sub-array
+    // Separate the aggregation type and the aggregation duration strings
+    const [[selectedAggregationType, selectedAggregationDuration]] =
       splitMultipleOptionsTextDelimitedBySlash(
         selectedAggregationTypeDurationArr
       );
 
-    // Separate the aggregation type and the aggregation duration strings
-    const [selectedAggregationTypeDurationSplitArr] =
-      selectedAggregationTypeDurationSplitNestedArr;
-
-    const [selectedAggregationType, selectedAggregationDuration] =
-      selectedAggregationTypeDurationSplitArr;
-
     // Array of building(s) + data point(s) + sampling rate
     const selectedBuildingsDataPointsSamplingRateAbbrevNestedArr =
       getAbbreviationsForSelectedOptionsFromAllDropDownLists(
-        selectedOptionsAllDropDownLists
+        getSelectedOptionsFromAllDropDownLists()
       );
 
+    // The formatted abbreviations array is nested, we are interested in the first sub-array
+    // We assume that all the phenomena have the same sampling rate
+    // Extract the formatted sampling rate string - used by ALL chart types
+    const [[, , selectedSamplingRateAbbrev]] =
+      selectedBuildingsDataPointsSamplingRateAbbrevNestedArr;
+
+    // User-specified start date and end date for aggregation - used by MULTIPLE chart types
+    const AGGREGATION_START_DATE = "2020-01-01";
+    const AGGREGATION_STOP_DATE = "2020-12-31";
+
     // The values of these references is either equal to `true` or an error will be thrown
     // We would like the errors to be thrown at this point before we begin performing any asynchronous tasks
     const selectedAggregationOptionsAreValid =
@@ -209,8 +147,8 @@ const drawChartUsingSelectedOptions = async function () {
     // Disable the 'draw chart' button
     disableDrawChartButton();
 
-    // Fetch the observations + metadata / raw observations
-    const observationsRawPlusMetadataArr =
+    // Fetch and extract the observations + metadata / raw observations
+    const [observationsRawNestedArr, metadataRawNestedArr] =
       selectedBuildingsDataPointsSamplingRateAbbrevRawObsArr.length === 0
         ? [[], []]
         : await getMetadataPlusObservationsFromSingleOrMultipleDatastreams(
@@ -219,8 +157,8 @@ const drawChartUsingSelectedOptions = async function () {
             selectedBuildingsDataPointsSamplingRateAbbrevRawObsArr
           );
 
-    // Fetch the observations + metadata / temperature difference (dT)
-    const observationsTempDiffPlusMetadataArr =
+    // Fetch and extract the observations + metadata / temperature difference (dT)
+    const [observationsTempDiffNestedArr, metadataTempDiffNestedArr] =
       selectedBuildingsDataPointsSamplingRateAbbrevTempDiffArr.length === 0
         ? [[], []]
         : await calculateVorlaufMinusRuecklaufTemperature(
@@ -231,59 +169,36 @@ const drawChartUsingSelectedOptions = async function () {
             )
           );
 
-    // Extract the combined arrays for observations and metadata / raw observations
-    const [observationsRawNestedArr, metadataRawNestedArr] =
-      observationsRawPlusMetadataArr;
-
-    // Extract the combined arrays for observations and metadata / temperature difference (dT)
-    const [observationsTempDiffNestedArr, metadataTempDiffNestedArr] =
-      observationsTempDiffPlusMetadataArr;
-
-    // Create a combined array of observations and metadata
-    const observationsPlusMetadataCombined = [
+    // Create and extract the combined observations and metadata
+    const [observationsCombinedNestedArr, metadataCombinedNestedArr] = [
       [...observationsRawNestedArr, ...observationsTempDiffNestedArr],
       [...metadataRawNestedArr, ...metadataTempDiffNestedArr],
     ];
 
-    const [observationsComboNestedArr, metadataComboNestedArr] =
-      observationsPlusMetadataCombined;
-
     // Create formatted array(s) for metadata - used by ALL chart types
-    const formattedMetadataNestedArr = metadataComboNestedArr.map(
+    const formattedMetadataNestedArr = metadataCombinedNestedArr.map(
       (metadataObj) => formatDatastreamMetadataForChart(metadataObj)
     );
 
     // Extract the formatted metadata properties for the raw observations - used by ALL chart types
-    const rawObservationsExtractedFormattedDatastreamProperties =
+    const rawObsExtractedFormattedDatastreamProperties =
       extractPropertiesFromFormattedDatastreamMetadata(
         formattedMetadataNestedArr,
         false
       );
 
-    // The formatted abbreviations array is nested
-    const [selectedBuildingsDataPointsSamplingRateAbbrevArr] =
-      selectedBuildingsDataPointsSamplingRateAbbrevNestedArr;
-
-    // Extract the formatted sampling rate string - used by ALL chart types
-    const [, , selectedSamplingRateAbbrev] =
-      selectedBuildingsDataPointsSamplingRateAbbrevArr;
-
-    // User-specified start date and end date for aggregation - used by MULTIPLE chart types
-    const aggregationStartDate = "2020-01-01";
-    const aggregationEndDate = "2020-12-31";
-
     // Create final array of observations- used by MULTIPLE chart types
     // If we are performing aggregation, it was envisioned that the user would
     // select observations that fall within a start and end date
     const observationsComboNestedFinalArr =
       selectedAggregationType === "None (raw data)"
-        ? observationsComboNestedArr
-        : observationsComboNestedArr.map((observationsArr) =>
+        ? observationsCombinedNestedArr
+        : observationsCombinedNestedArr.map((observationsArr) =>
             extractObservationsWithinDatesInterval(
               observationsArr,
               selectedSamplingRateAbbrev,
-              aggregationStartDate,
-              aggregationEndDate
+              AGGREGATION_START_DATE,
+              AGGREGATION_STOP_DATE
             )
           );
 
@@ -303,7 +218,7 @@ const drawChartUsingSelectedOptions = async function () {
           ) {
             drawHeatmapBasedOnSelectedOptions(
               observationsComboNestedFinalArr,
-              rawObservationsExtractedFormattedDatastreamProperties
+              rawObsExtractedFormattedDatastreamProperties
             );
           }
           break;
@@ -316,7 +231,7 @@ const drawChartUsingSelectedOptions = async function () {
           ) {
             drawScatterPlotFromChartSelection(
               observationsComboNestedFinalArr,
-              rawObservationsExtractedFormattedDatastreamProperties
+              rawObsExtractedFormattedDatastreamProperties
             );
           }
           break;
@@ -335,7 +250,7 @@ const drawChartUsingSelectedOptions = async function () {
 
             drawLineChartHighcharts(
               formattedRawObservationsLineChartNestedArr,
-              rawObservationsExtractedFormattedDatastreamProperties
+              rawObsExtractedFormattedDatastreamProperties
             );
           }
           // Aggregated observations
@@ -365,7 +280,7 @@ const drawChartUsingSelectedOptions = async function () {
 
             drawColumnChartHighcharts(
               formattedRawObservationsColumnChartNestedArr,
-              rawObservationsExtractedFormattedDatastreamProperties
+              rawObsExtractedFormattedDatastreamProperties
             );
           }
           // Aggregated observations
diff --git a/public/js/src_modules/dropDownListStyling.mjs b/public/js/src_modules/dropDownListStyling.mjs
new file mode 100644
index 0000000..acc0284
--- /dev/null
+++ b/public/js/src_modules/dropDownListStyling.mjs
@@ -0,0 +1,53 @@
+"use strict";
+
+import { vanillaSelectBox } from "../thirdparty/vanillaSelectBox.mjs";
+
+/**
+ * Use the `vanillaDropDown` library to style the buildings & data points drop down list
+ *
+ * @returns {undefined}
+ */
+const styleBuildingsDataPointsDropDown = function () {
+  // Create our dropdown list using `vanillaSelectBox`; supports the selection of multiple options
+  new vanillaSelectBox("#drop-down--bldg-data-point", {
+    disableSelectAll: true,
+    maxSelect: 5,
+    placeHolder: "--Select--",
+    search: false,
+  });
+};
+
+/**
+ * Use the `vanillaDropDown` library to style the chart type,
+ * aggregation type and sampling rates drop down lists
+ *
+ * @returns {undefined} undefined
+ */
+const styleOtherDropDownLists = function () {
+  // Array of CSS selector strings
+  const cssSelectorStringsArr = [
+    "#drop-down--chart-type",
+    "#drop-down--aggregation-type",
+    "#drop-down--sampling-rate",
+  ];
+
+  // Create our dropdown lists using `vanillaSelectBox`
+  cssSelectorStringsArr.forEach((cssSelectorString) => {
+    new vanillaSelectBox(cssSelectorString, {
+      disableSelectAll: true,
+      maxSelect: 1,
+      placeHolder: "--Select--",
+      search: false,
+    });
+  });
+};
+
+/**
+ *  Use the `vanillaDropDown` library to style all the drop down lists
+ *
+ * @returns {undefined} undefined
+ */
+export const styleAllDropDownLists = function () {
+  styleBuildingsDataPointsDropDown();
+  styleOtherDropDownLists();
+};
-- 
GitLab


From 0c17e4f13b2080c78766391db986072604d596fb Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Thu, 28 Oct 2021 10:04:33 +0200
Subject: [PATCH 2/4] New function: draw column chart selection-based

This function wraps the logic for drawing column charts based on the
selected options for both raw and aggregated observations
---
 public/js/appChart.js                         | 43 ++++----------
 .../src_modules/dropDownListChartColumn.mjs   | 59 ++++++++++++++++++-
 .../src_modules/dropDownListChartHeatmap.mjs  |  3 +-
 .../dropDownListChartScatterPlot.mjs          |  5 +-
 4 files changed, 74 insertions(+), 36 deletions(-)

diff --git a/public/js/appChart.js b/public/js/appChart.js
index b4d1e7b..4ab1d8a 100644
--- a/public/js/appChart.js
+++ b/public/js/appChart.js
@@ -21,8 +21,6 @@ import { formatSensorThingsApiResponseForLineOrColumnChart } from "./src_modules
 
 import { drawLineChartHighcharts } from "./src_modules/chartLine.mjs";
 
-import { drawColumnChartHighcharts } from "./src_modules/chartColumn.mjs";
-
 import {
   showLoadingSpinner,
   hideLoadingSpinner,
@@ -49,13 +47,13 @@ import {
   getAbbreviationsForSelectedOptionsFromAllDropDownLists,
 } from "./src_modules/dropDownListHelpers.mjs";
 
-import { drawColumnChartBasedOnSelectedAggregationOptions } from "./src_modules/dropDownListChartColumn.mjs";
+import { drawColumnChartBasedOnSelectedOptions } 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";
+import { drawScatterPlotBasedOnSelectedOptions } from "./src_modules/dropDownListChartScatterPlot.mjs";
 
 /**
  * Callback function that wraps the logic of populating the linked drop down lists.
@@ -229,7 +227,7 @@ const drawChartUsingSelectedOptions = async function () {
             selectedAggregationOptionsAreValid &&
             selectedBuildingDataPointsOptionsAreValid
           ) {
-            drawScatterPlotFromChartSelection(
+            drawScatterPlotBasedOnSelectedOptions(
               observationsComboNestedFinalArr,
               rawObsExtractedFormattedDatastreamProperties
             );
@@ -266,34 +264,15 @@ const drawChartUsingSelectedOptions = async function () {
           }
           break;
 
-        // We are interested in BOTH raw observations and aggregated observations
         case "Column":
-          // Raw observations
-          if (selectedAggregationType === "None (raw data)") {
-            // Create formatted array(s) for observations
-            const formattedRawObservationsColumnChartNestedArr =
-              observationsComboNestedFinalArr.map((observationsArr) =>
-                formatSensorThingsApiResponseForLineOrColumnChart(
-                  observationsArr
-                )
-              );
-
-            drawColumnChartHighcharts(
-              formattedRawObservationsColumnChartNestedArr,
-              rawObsExtractedFormattedDatastreamProperties
-            );
-          }
-          // Aggregated observations
-          else {
-            drawColumnChartBasedOnSelectedAggregationOptions(
-              selectedAggregationType,
-              selectedAggregationDuration,
-              observationsComboNestedFinalArr,
-              selectedSamplingRateAbbrev,
-              uniqueCalendarDatesNestedArr,
-              formattedMetadataNestedArr
-            );
-          }
+          drawColumnChartBasedOnSelectedOptions(
+            selectedAggregationType,
+            selectedAggregationDuration,
+            observationsComboNestedFinalArr,
+            selectedSamplingRateAbbrev,
+            uniqueCalendarDatesNestedArr,
+            formattedMetadataNestedArr
+          );
           break;
 
         default:
diff --git a/public/js/src_modules/dropDownListChartColumn.mjs b/public/js/src_modules/dropDownListChartColumn.mjs
index 7c2aeee..78bf21d 100644
--- a/public/js/src_modules/dropDownListChartColumn.mjs
+++ b/public/js/src_modules/dropDownListChartColumn.mjs
@@ -1,5 +1,9 @@
 "use strict";
 
+import { formatSensorThingsApiResponseForLineOrColumnChart } from "./chartHelpers.mjs";
+
+import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataProcessing.mjs";
+
 import { drawColumnChartHighcharts } from "./chartColumn.mjs";
 
 import {
@@ -33,7 +37,7 @@ import {
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {undefined} undefined
  */
-export const drawColumnChartBasedOnSelectedAggregationOptions = function (
+const drawColumnChartBasedOnSelectedAggregationOptions = function (
   selectedAggregationType,
   selectedAggregationDuration,
   observationsNestedArr,
@@ -157,3 +161,56 @@ export const drawColumnChartBasedOnSelectedAggregationOptions = function (
     );
   }
 };
+
+/**
+ * Draw a column chart based on the selected options from a drop-down list.
+ * This chart type supports both raw observations and aggregated observations
+ *
+ * @param {String} selectedAggregationType The selected aggregation type. The currently supported strings include `Sum`, `Maximum`, `Minimum` and `Average`
+ * @param {String} selectedAggregationDuration The selected aggregation duration. The currently supported strings include `Daily` and `Monthly`
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
+ * @param {String} selectedSamplingRateAbbrev 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 drawColumnChartBasedOnSelectedOptions = function (
+  selectedAggregationType,
+  selectedAggregationDuration,
+  observationsNestedArr,
+  selectedSamplingRateAbbrev,
+  uniqueCalendarDatesNestedArr,
+  formattedMetadataNestedArr
+) {
+  // Case 1: Raw observations
+  if (selectedAggregationType === "None (raw data)") {
+    // Create formatted array(s) for observations
+    const formattedRawObservationsColumnChartNestedArr =
+      observationsNestedArr.map((observationsArr) =>
+        formatSensorThingsApiResponseForLineOrColumnChart(observationsArr)
+      );
+
+    // Extract formatted metadata properties
+    const rawObsExtractedFormattedDatastreamProperties =
+      extractPropertiesFromFormattedDatastreamMetadata(
+        formattedMetadataNestedArr,
+        false
+      );
+
+    drawColumnChartHighcharts(
+      formattedRawObservationsColumnChartNestedArr,
+      rawObsExtractedFormattedDatastreamProperties
+    );
+  }
+  // Case 2: Aggregated observations
+  else {
+    drawColumnChartBasedOnSelectedAggregationOptions(
+      selectedAggregationType,
+      selectedAggregationDuration,
+      observationsNestedArr,
+      selectedSamplingRateAbbrev,
+      uniqueCalendarDatesNestedArr,
+      formattedMetadataNestedArr
+    );
+  }
+};
diff --git a/public/js/src_modules/dropDownListChartHeatmap.mjs b/public/js/src_modules/dropDownListChartHeatmap.mjs
index cad7760..d5ee1b6 100644
--- a/public/js/src_modules/dropDownListChartHeatmap.mjs
+++ b/public/js/src_modules/dropDownListChartHeatmap.mjs
@@ -6,7 +6,8 @@ import {
 } from "./chartHeatmap.mjs";
 
 /**
- * Draw a heatmap based on the selected options from a drop-down list
+ * Draw a heatmap based on the selected options from a drop-down list.
+ * Currently, this chart type only supports raw observations
  *
  * @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
diff --git a/public/js/src_modules/dropDownListChartScatterPlot.mjs b/public/js/src_modules/dropDownListChartScatterPlot.mjs
index 9307a48..1f42d2f 100644
--- a/public/js/src_modules/dropDownListChartScatterPlot.mjs
+++ b/public/js/src_modules/dropDownListChartScatterPlot.mjs
@@ -6,13 +6,14 @@ import {
 } from "./chartScatterPlot.mjs";
 
 /**
- * Draw a scatter plot based on the selected options from a drop-down list
+ * Draw a scatter plot based on the selected options from a drop-down list.
+ * Currently, this chart type only supports raw observations
  *
  * @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 (
+export const drawScatterPlotBasedOnSelectedOptions = function (
   observationsComboNestedArr,
   extractedFormattedDatastreamProperties
 ) {
-- 
GitLab


From cc1a36ef9e2a0274f03ab0a54474ee0c4f0c1c5a Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Thu, 28 Oct 2021 10:08:13 +0200
Subject: [PATCH 3/4] New function: draw line chart based on selection

This function wraps the logic for drawing column charts based on the
selected options for both raw and aggregated observations
---
 public/js/appChart.js                         | 43 +++-----------
 .../js/src_modules/dropDownListChartLine.mjs  | 59 ++++++++++++++++++-
 2 files changed, 67 insertions(+), 35 deletions(-)

diff --git a/public/js/appChart.js b/public/js/appChart.js
index 4ab1d8a..f4c567f 100644
--- a/public/js/appChart.js
+++ b/public/js/appChart.js
@@ -17,10 +17,6 @@ import {
   extractPropertiesFromFormattedDatastreamMetadata,
 } from "./src_modules/fetchedDataProcessing.mjs";
 
-import { formatSensorThingsApiResponseForLineOrColumnChart } from "./src_modules/chartHelpers.mjs";
-
-import { drawLineChartHighcharts } from "./src_modules/chartLine.mjs";
-
 import {
   showLoadingSpinner,
   hideLoadingSpinner,
@@ -51,7 +47,7 @@ import { drawColumnChartBasedOnSelectedOptions } from "./src_modules/dropDownLis
 
 import { drawHeatmapBasedOnSelectedOptions } from "./src_modules/dropDownListChartHeatmap.mjs";
 
-import { drawLineChartBasedOnSelectedAggregationOptions } from "./src_modules/dropDownListChartLine.mjs";
+import { drawLineChartBasedOnSelectedOptions } from "./src_modules/dropDownListChartLine.mjs";
 
 import { drawScatterPlotBasedOnSelectedOptions } from "./src_modules/dropDownListChartScatterPlot.mjs";
 
@@ -208,7 +204,6 @@ const drawChartUsingSelectedOptions = async function () {
 
     for (const selectedChartType of selectedChartTypeArr) {
       switch (selectedChartType) {
-        // We are interested in raw observations ONLY
         case "Heatmap":
           if (
             selectedAggregationOptionsAreValid &&
@@ -221,7 +216,6 @@ const drawChartUsingSelectedOptions = async function () {
           }
           break;
 
-        // We are interested in raw observations ONLY
         case "Scatter Plot":
           if (
             selectedAggregationOptionsAreValid &&
@@ -234,34 +228,15 @@ const drawChartUsingSelectedOptions = async function () {
           }
           break;
 
-        // We are interested in BOTH raw observations and aggregated observations
         case "Line":
-          // Raw observations
-          if (selectedAggregationType === "None (raw data)") {
-            // Create formatted array(s) for observations
-            const formattedRawObservationsLineChartNestedArr =
-              observationsComboNestedFinalArr.map((observationsArr) =>
-                formatSensorThingsApiResponseForLineOrColumnChart(
-                  observationsArr
-                )
-              );
-
-            drawLineChartHighcharts(
-              formattedRawObservationsLineChartNestedArr,
-              rawObsExtractedFormattedDatastreamProperties
-            );
-          }
-          // Aggregated observations
-          else {
-            drawLineChartBasedOnSelectedAggregationOptions(
-              selectedAggregationType,
-              selectedAggregationDuration,
-              observationsComboNestedFinalArr,
-              selectedSamplingRateAbbrev,
-              uniqueCalendarDatesNestedArr,
-              formattedMetadataNestedArr
-            );
-          }
+          drawLineChartBasedOnSelectedOptions(
+            selectedAggregationType,
+            selectedAggregationDuration,
+            observationsComboNestedFinalArr,
+            selectedSamplingRateAbbrev,
+            uniqueCalendarDatesNestedArr,
+            formattedMetadataNestedArr
+          );
           break;
 
         case "Column":
diff --git a/public/js/src_modules/dropDownListChartLine.mjs b/public/js/src_modules/dropDownListChartLine.mjs
index 494e466..6f182f2 100644
--- a/public/js/src_modules/dropDownListChartLine.mjs
+++ b/public/js/src_modules/dropDownListChartLine.mjs
@@ -1,5 +1,9 @@
 "use strict";
 
+import { formatSensorThingsApiResponseForLineOrColumnChart } from "./chartHelpers.mjs";
+
+import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataProcessing.mjs";
+
 import { drawLineChartHighcharts } from "./chartLine.mjs";
 
 import {
@@ -33,7 +37,7 @@ import {
  * @param {Array} formattedMetadataNestedArr An array of sub-arrays of formatted metadata properties
  * @returns {undefined} undefined
  */
-export const drawLineChartBasedOnSelectedAggregationOptions = function (
+const drawLineChartBasedOnSelectedAggregationOptions = function (
   selectedAggregationType,
   selectedAggregationDuration,
   observationsNestedArr,
@@ -157,3 +161,56 @@ export const drawLineChartBasedOnSelectedAggregationOptions = function (
     );
   }
 };
+
+/**
+ * Draw a line chart based on the selected options from a drop-down list.
+ * This chart type supports both raw observations and aggregated observations
+ *
+ * @param {String} selectedAggregationType The selected aggregation type. The currently supported strings include `Sum`, `Maximum`, `Minimum` and `Average`
+ * @param {String} selectedAggregationDuration The selected aggregation duration. The currently supported strings include `Daily` and `Monthly`
+ * @param {Array} observationsNestedArr An array made up of sub-array(s) of observations
+ * @param {String} selectedSamplingRateAbbrev 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 drawLineChartBasedOnSelectedOptions = function (
+  selectedAggregationType,
+  selectedAggregationDuration,
+  observationsNestedArr,
+  selectedSamplingRateAbbrev,
+  uniqueCalendarDatesNestedArr,
+  formattedMetadataNestedArr
+) {
+  // Raw observations
+  if (selectedAggregationType === "None (raw data)") {
+    // Create formatted array(s) for observations
+    const formattedRawObservationsLineChartNestedArr =
+      observationsNestedArr.map((observationsArr) =>
+        formatSensorThingsApiResponseForLineOrColumnChart(observationsArr)
+      );
+
+    // Extract formatted metadata properties
+    const rawObsExtractedFormattedDatastreamProperties =
+      extractPropertiesFromFormattedDatastreamMetadata(
+        formattedMetadataNestedArr,
+        false
+      );
+
+    drawLineChartHighcharts(
+      formattedRawObservationsLineChartNestedArr,
+      rawObsExtractedFormattedDatastreamProperties
+    );
+  }
+  // Aggregated observations
+  else {
+    drawLineChartBasedOnSelectedAggregationOptions(
+      selectedAggregationType,
+      selectedAggregationDuration,
+      observationsNestedArr,
+      selectedSamplingRateAbbrev,
+      uniqueCalendarDatesNestedArr,
+      formattedMetadataNestedArr
+    );
+  }
+};
-- 
GitLab


From 015ec0df3ef402f40d25e2e199943fdb60179232 Mon Sep 17 00:00:00 2001
From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de>
Date: Thu, 28 Oct 2021 10:11:02 +0200
Subject: [PATCH 4/4] Create a configuration module file

... that conatains information about the SensorThings API server url
and Cesium access token
---
 .gitignore                                       |  3 +++
 public/js/appCesium.js                           |  5 +++--
 public/js/appChart.js                            | 11 +++++------
 public/js/src_modules/baseUrlPlusQueryParams.mjs |  6 +-----
 4 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/.gitignore b/.gitignore
index 6704566..f600fad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+# Our custom config file
+config.mjs
+
 # Logs
 logs
 *.log
diff --git a/public/js/appCesium.js b/public/js/appCesium.js
index 709aae5..c32da22 100644
--- a/public/js/appCesium.js
+++ b/public/js/appCesium.js
@@ -1,7 +1,8 @@
 "use strict";
 
-Cesium.Ion.defaultAccessToken =
-  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyODgxYzJlNi1kNDZiLTQ3ZmQtYmUxYy0yMWI0OGM3NDA5MzAiLCJpZCI6NDczOSwic2NvcGVzIjpbImFzciIsImdjIl0sImlhdCI6MTU0MTUyMzU0MX0.shj2hM3pvsvcmE_wMb2aBDuk_cKWmFmbolltInGImwU";
+import { CESIUM_ION_ACCESS_TOKEN } from "./config.mjs";
+
+Cesium.Ion.defaultAccessToken = CESIUM_ION_ACCESS_TOKEN;
 
 // Flag to determine models that will be loaded
 // Set to `true` or `false`
diff --git a/public/js/appChart.js b/public/js/appChart.js
index f4c567f..de1a5cf 100644
--- a/public/js/appChart.js
+++ b/public/js/appChart.js
@@ -1,9 +1,8 @@
 "use strict";
 
-import {
-  BASE_URL,
-  QUERY_PARAMS_COMBINED,
-} from "./src_modules/baseUrlPlusQueryParams.mjs";
+import { SENSORTHINGS_API_BASE_URL } from "./config.mjs";
+
+import { QUERY_PARAMS_COMBINED } from "./src_modules/baseUrlPlusQueryParams.mjs";
 
 import { calculateVorlaufMinusRuecklaufTemperature } from "./src_modules/calculateTemperatureDiff.mjs";
 
@@ -146,7 +145,7 @@ const drawChartUsingSelectedOptions = async function () {
       selectedBuildingsDataPointsSamplingRateAbbrevRawObsArr.length === 0
         ? [[], []]
         : await getMetadataPlusObservationsFromSingleOrMultipleDatastreams(
-            BASE_URL,
+            SENSORTHINGS_API_BASE_URL,
             QUERY_PARAMS_COMBINED,
             selectedBuildingsDataPointsSamplingRateAbbrevRawObsArr
           );
@@ -156,7 +155,7 @@ const drawChartUsingSelectedOptions = async function () {
       selectedBuildingsDataPointsSamplingRateAbbrevTempDiffArr.length === 0
         ? [[], []]
         : await calculateVorlaufMinusRuecklaufTemperature(
-            BASE_URL,
+            SENSORTHINGS_API_BASE_URL,
             QUERY_PARAMS_COMBINED,
             extractBuildingPlusSamplingRate(
               selectedBuildingsDataPointsSamplingRateAbbrevTempDiffArr
diff --git a/public/js/src_modules/baseUrlPlusQueryParams.mjs b/public/js/src_modules/baseUrlPlusQueryParams.mjs
index 4c2b8b6..93207d2 100644
--- a/public/js/src_modules/baseUrlPlusQueryParams.mjs
+++ b/public/js/src_modules/baseUrlPlusQueryParams.mjs
@@ -1,7 +1,5 @@
 "use strict";
 
-const BASE_URL = "http://193.196.39.91:8080/frost-icity-tp31/v1.1";
-
 /**
  * Create a temporal filter string for the fetched Observations
  * @param {String} dateStart Start date in YYYY-MM-DD format
@@ -33,9 +31,7 @@ const createUrlParametersForGetRequest = function (dateStart, dateStop) {
   };
 };
 
-const QUERY_PARAMS_COMBINED = createUrlParametersForGetRequest(
+export const QUERY_PARAMS_COMBINED = createUrlParametersForGetRequest(
   "2020-01-01",
   "2021-01-01"
 );
-
-export { BASE_URL, QUERY_PARAMS_COMBINED };
-- 
GitLab