Commit 59f58680 authored by Pithon Kabiro's avatar Pithon Kabiro
Browse files

Merge branch 'wip_select-sensors-dropdown-list-4' into 'master'

Update logic for drop-down list

Improve processing logic (non-GUI related) for drop-down list

See merge request !15
parents 3499df17 05ac1b56
......@@ -186,7 +186,10 @@
><strong>Aggregation (Type, Duration)</strong></span
>
<div class="nowrap">
<select id="drop-down--aggregation-type">
<!-- We need the `multiple` attribute for the dropdowns even if
we do not need to support multiple selections. This seems to
be a quirk of the `vanillaSelectBox` library -->
<select id="drop-down--aggregation-type" multiple>
<option>None (raw data)</option>
<option>Sum/Daily</option>
<option>Sum/Monthly</option>
......@@ -203,7 +206,10 @@
<div id="drop-down--sampling-rate-parent">
<span><strong>Sampling rate</strong></span>
<div class="nowrap">
<select id="drop-down--sampling-rate">
<!-- We need the `multiple` attribute for the dropdowns even if
we do not need to support multiple selections. This seems to
be a quirk of the `vanillaSelectBox` library -->
<select id="drop-down--sampling-rate" multiple>
<option>15 min</option>
<option>60 min</option>
</select>
......@@ -213,7 +219,10 @@
<div id="drop-down--chart-type-parent">
<span><strong>Chart type</strong></span>
<div class="nowrap">
<select id="drop-down--chart-type">
<!-- We need the `multiple` attribute for the dropdowns even if
we do not need to support multiple selections. This seems to
be a quirk of the `vanillaSelectBox` library -->
<select id="drop-down--chart-type" multiple>
<option>Column</option>
<option>Line</option>
<option>Heatmap</option>
......@@ -249,7 +258,7 @@
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-line mr-1"></i>
Line Chart Example
Line Chart
</div>
<div class="card-body">
<div id="chart-line" width="100%" height="40"></div>
......@@ -260,7 +269,7 @@
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-area mr-1"></i>
Area Chart Example
Heatmap
</div>
<div class="card-body">
<div id="chart-heatmap" width="100%" height="40"></div>
......@@ -274,7 +283,7 @@
<div class="card-header">
<!-- No free scatter plot icon available; use this instead -->
<i class="fas fa-braille mr-1"></i>
Scatter Plot Example
Scatter Plot
</div>
<div class="card-body">
<div id="chart-scatter-plot" width="100%" height="40"></div>
......@@ -285,7 +294,7 @@
<div class="card mb-4">
<div class="card-header">
<i class="far fa-chart-bar mr-1"></i>
Bar Chart Example
Column Chart
</div>
<div class="card-body">
<div id="chart-column" width="100%" height="40"></div>
......@@ -302,9 +311,15 @@
>
<div class="text-muted">Copyright &copy; HfT Stuttgart 2021</div>
<div>
<a href="#">Privacy Policy</a>
<a href="https://www.hft-stuttgart.de/impressum" target="_blank"
>Impressum</a
>
&middot;
<a href="#">Terms &amp; Conditions</a>
<a
href="https://www.hft-stuttgart.de/datenschutz"
target="_blank"
>Datenschutz</a
>
</div>
</div>
</div>
......
......@@ -52,7 +52,10 @@ const styleLevelOneDropDown = function () {
const styleLevelTwoDropDown = function () {
// Create our dropdown list using `vanillaSelectBox`
new vanillaSelectBox("#drop-down--aggregation-type", {
"disableSelectAll": true,
"maxSelect": 1,
"placeHolder": "--Select--",
"search": false,
});
};
......@@ -64,7 +67,10 @@ const styleLevelTwoDropDown = function () {
const styleLevelThreeDropDown = function () {
// Create our dropdown list using `vanillaSelectBox`
new vanillaSelectBox("#drop-down--sampling-rate", {
"disableSelectAll": true,
"maxSelect": 1,
"placeHolder": "--Select--",
"search": false,
});
};
......@@ -76,7 +82,10 @@ const styleLevelThreeDropDown = function () {
const styleLevelFourDropDown = function () {
// Create our dropdown list using `vanillaSelectBox`
new vanillaSelectBox("#drop-down--chart-type", {
"disableSelectAll": true,
"maxSelect": 1,
"placeHolder": "--Select--",
"search": false,
});
};
......@@ -94,24 +103,118 @@ const afterDocumentLoads = function () {
};
/**
* Get the values from the currently selected options in the linked drop dpwn lists
* @returns {Array} An array containing the values of the selected options
* Get the selected option(s) from a dropdown list
*
* @param {String} selectorStr A CSS selector string representing the dropdown list
* @returns {Array} An array of string(s) representing the value(s) of the selected `<option>` elements
*/
const getSelectedOptionsFromDropDownList = function (selectorStr) {
// Array to store our final result
const selectedOptionsArr = [];
// Select all the matching <option> elements as a NodeList
const optionElements = document.querySelectorAll(`${selectorStr} option`);
optionElements.forEach((optionEl) => {
if (optionEl.selected) {
selectedOptionsArr.push(optionEl.value);
}
});
return selectedOptionsArr;
};
/**
* Process the selected option(s) from a buildings & data points dropdown list.
* This is currently the first dropdown list in the UI.
*
* @param {Array} selectedOptionsArr An array of string(s) representing the value(s) of the selected `<option>` elements
* @returns {Array} An array of string(s) representing the processed value(s) of the selected buildings & data points option(s)
*/
const processSelectionsFromBuildingDataPointOptions = function (
selectedOptionsArr
) {
// Array to store our final result
const selectedOptionsBuildingDataPointArr = [];
selectedOptionsArr.forEach((optionStr) => {
if (optionStr.includes("/")) {
// Case 1: <option> element's value CONTAINS a "/" character
// We wish to create a string like this `Bau 101/VL`
// Split the <option> element's value into two substrings
const optionsStrPartOne = optionStr.slice(0, 3);
const optionsStrPartTwo = optionStr.slice(3);
// Create a new string for the first substring
const optionsStrPartOneNew = `Bau ${optionsStrPartOne}`;
// Create a new combined string
const optionsStrNew = optionsStrPartOneNew + optionsStrPartTwo;
selectedOptionsBuildingDataPointArr.push(optionsStrNew);
} else {
// Case 2: <option> element's value DOES NOT CONTAIN a "/" character
// We wish to create a string like this `Other/Außentemp`
selectedOptionsBuildingDataPointArr.push(`Other/${optionStr}`);
}
});
return selectedOptionsBuildingDataPointArr;
};
/**
* Split an option element's value (a string) using a forward slash character ("/") as the delimiter
*
* @param {Array} selectedOptionsArr An array of string(s) representing the value(s) of the selected `<option>` elements
* @returns {Array} An array made up of resulting strings after splitting
*/
const splitOptionsTextDelimitedBySlash = function (selectedOptionsArr) {
return selectedOptionsArr.map((selectedOption) => selectedOption.split("/"));
};
/**
* Get the values from the currently selected options in ALL the drop down lists
* @returns {Array} An array containing four arrays, where each array contains the values of the selected options
*/
const getSelectedOptionsFromDropDownLists = function () {
const selectedBuilding = document.querySelector("#drop-down--bldg").value;
const selectedSensor = document.querySelector("#drop-down--sensor").value;
const selectedSamplingRate = document.querySelector(
const getSelectedOptionsFromAllDropDownLists = function () {
const selectedBuildingDataPointOptionsArr =
processSelectionsFromBuildingDataPointOptions(
getSelectedOptionsFromDropDownList("#drop-down--bldg-data-point")
);
// Separate the building ID from the data point
const selectedBuildingDataPointOptionsSplitArr =
splitOptionsTextDelimitedBySlash(selectedBuildingDataPointOptionsArr);
const selectedAggregationOptionsArr = getSelectedOptionsFromDropDownList(
"#drop-down--aggregation-type"
);
const selectedSamplingRateArr = getSelectedOptionsFromDropDownList(
"#drop-down--sampling-rate"
).value;
);
const selectedChartTypeArr = getSelectedOptionsFromDropDownList(
"#drop-down--chart-type"
);
// Ensure that all the options have at least one selection
if (
selectedBuilding === "--Select--" ||
selectedSensor === "" ||
selectedSamplingRate === ""
selectedBuildingDataPointOptionsSplitArr.length === 0 ||
selectedAggregationOptionsArr.length === 0 ||
selectedSamplingRateArr.length === 0 ||
selectedChartTypeArr.length === 0
)
return;
return [selectedBuilding, selectedSensor, selectedSamplingRate];
return [
selectedBuildingDataPointOptionsSplitArr,
selectedAggregationOptionsArr,
selectedSamplingRateArr,
selectedChartTypeArr,
];
};
/**
......@@ -134,14 +237,18 @@ const getBuildingSensorSamplingRateAbbreviation = function (
"Bau 112": "112, 118",
"Bau 125": "125",
"Bau 225": "225",
"Other": "weather_station_521",
},
phenomenon: {
Vorlauftemperatur: "vl",
Rücklauftemperatur: "rl",
VL: "vl",
RL: "rl",
dT: "dT",
Durchfluss: "flow",
Leistung: "power",
Energie: "energy",
Energie_VERBR: "energy_verb",
Außentemp: "outside_temp",
},
samplingRate: {
"15 min": "15min",
......@@ -149,6 +256,29 @@ const getBuildingSensorSamplingRateAbbreviation = function (
},
};
if (
fullFormToAbbreviationMapping["buildings"]?.[buildingFullForm] === undefined
)
throw new Error(
"The provided building ID is not valid or is not supported by this function"
);
if (
fullFormToAbbreviationMapping["phenomenon"]?.[phenomenonFullForm] ===
undefined
)
throw new Error(
"The provided data point is not valid or is not supported by this function"
);
if (
fullFormToAbbreviationMapping["samplingRate"]?.[samplingRateFullForm] ===
undefined
)
throw new Error(
"The provided sampling rate is not valid or is not supported by this function"
);
const buildingAbbrev =
fullFormToAbbreviationMapping["buildings"]?.[buildingFullForm];
......@@ -161,6 +291,45 @@ const getBuildingSensorSamplingRateAbbreviation = function (
return [buildingAbbrev, phenomenonAbbrev, samplingRateAbbrev];
};
/**
* Get the abbreviated form for the currently selected options in ALL the drop down lists
*
* @param {Array} allSelectedOptionsArr An array containing four arrays, where each array contains the values of the selected options
* @returns {Array} An array which contains one or more nested arrays of abbreviations of building(s), data point(s) and sampling rate(s)
*/
const getAbbreviationsForSelectedOptionsFromAllDropDownLists = function (
allSelectedOptionsArr
) {
// Note: The sampling rate array is the third array, therefore we skip one element
const [selectedBuildingDataPointOptionsSplitArr, , selectedSamplingRateArr] =
allSelectedOptionsArr;
// The building is the first element
const selectedBuildingsArr = selectedBuildingDataPointOptionsSplitArr.map(
(selectedBuildingDataPoint) => selectedBuildingDataPoint[0]
);
// The data point is the second element
const selectedDataPointsArr = selectedBuildingDataPointOptionsSplitArr.map(
(selectedBuildingDataPoint) => selectedBuildingDataPoint[1]
);
// Assume that the buildings and data points arrays have equal length
// use one of the arrays for looping
if (selectedBuildingsArr.length !== selectedDataPointsArr.length)
throw new Error(
"The buildings array and data points array have different lengths"
);
return selectedBuildingsArr.map((selectedBuilding, i) =>
getBuildingSensorSamplingRateAbbreviation(
selectedBuilding,
selectedDataPointsArr[i],
...selectedSamplingRateArr
)
);
};
/**
* Callback function for chart selection using drop down list
* @returns {undefined}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment