Commit 970ff258 authored by Pithon Kabiro's avatar Pithon Kabiro
Browse files

Use third-party vanilla JS library for drop-downs

parent d3454541
......@@ -10,7 +10,7 @@
<meta name="description" content="" />
<meta name="author" content="" />
<title>Dashboard - iCity Bosch</title>
<link href="css/styles.css" rel="stylesheet" />
<link href="css/thirdparty/styles.css" rel="stylesheet" />
<link
href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css"
rel="stylesheet"
......@@ -53,16 +53,17 @@
<!-- Bootstrap dashboard template -->
<script
defer
src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
crossorigin="anonymous"
></script>
<script
defer
src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"
crossorigin="anonymous"
></script>
<script defer src="js/thirdparty/scripts.js"></script>
<script src="js/thirdparty/scripts.js"></script>
<!-- vanillaSelectBox -->
<link href="css/thirdparty/vanillaSelectBox.css" rel="stylesheet" />
<!--
Custom JS -->
......@@ -133,7 +134,7 @@
<div id="drop-down--bldg-parent">
<span><strong>Building</strong></span>
<div class="nowrap">
<select id="drop-down--bldg"></select>
<select id="drop-down--bldg" multiple></select>
</div>
</div>
<br />
......@@ -155,7 +156,6 @@
<span><strong>Chart type</strong></span>
<div class="nowrap">
<select id="drop-down--chart-type">
<option>--Select--</option>
<option>Line</option>
<option>Heatmap</option>
</select>
......
.hidden-search {
display: none !important;
}
li[data-parent].closed{
display:none !important;
}
li[data-parent].open:not(.hidden-search){
display:block !important;
}
.vsb-menu{
cursor:pointer;
z-index:1000;
display:block;
visibility: hidden;
position:absolute;/*Don't change*/
border:1px solid #B2B2B2;
background-color: #fff;
background-clip: padding-box;
border: 1px solid rgba(0,0,0,.15);
box-shadow: 0 6px 12px rgba(0,0,0,.175);
border-radius:4px;
font-size : 11px;
}
.vsb-js-search-zone{
position:absolute;/*Don't change*/
z-index:1001;
width: 80%;
min-height:1.8em;
padding: 2px;
background-color: #fff;
}
.vsb-js-search-zone input{
border: 1px solid grey;
margin-left: 2px;
width: 96%;
border-radius: 4px;
height: 25px !important;
}
.vsb-main{
position: relative;/*Don't change*/
display: inline-block;
vertical-align: middle;
text-align:left;
}
.vsb-menu li:hover {
background: linear-gradient(#f5f5f5, #e8e8e8);
}
.vsb-menu ul{
user-select:none;
list-style:none;
white-space: nowrap;
margin:0px;
margin-top:4px;
padding-left:10px;
padding-right:10px;
padding-bottom:3px;
color: #333;
cursor:pointer;
overflow-y:auto;
}
li.disabled{
cursor:not-allowed;
opacity:0.3;
background-color: #999;
}
li.overflow{
cursor:not-allowed;
opacity:0.3;
background-color: #999;
}
li.short{
overflow:hidden;
text-overflow: ellipsis;
}
.vsb-main button{
min-width: 120px;
border-radius: 0;
width: 100%;
text-align: left;
z-index: 1;
color: #333;
background: white !important;
border: 1px solid #999 !important;
line-height:20px;
font-size:14px;
padding:6px 12px;
}
.vsb-main button.disabled{
cursor:not-allowed;
opacity:0.65;
}
.vsb-main .title {
margin-right: 6px;
user-select:none;
}
.vsb-main li:hover {
background: linear-gradient(#f5f5f5, #e8e8e8);
}
.vsb-main ul{
white-space: nowrap;
}
.vsb-menu li {
font-size: 14px;
background-color: #fff;
min-height:1.4em;
padding: 0.2em 2em 0.2em 1em;
}
.vsb-menu li.grouped-option b {
display: inline-block;
font-size: 15px;
margin-left:10px;
transform: translate(-18px);
}
.vsb-menu li.grouped-option.open span {
display: inline-block;
font-size: inherit;
margin-top:-2px;
height: 8px;
width: 8px;
transform: translate(-38px) rotate(45deg);
border-bottom: 3px solid black;
border-right: 3px solid black;
border-radius:2px;
}
.vsb-menu li.grouped-option.closed span {
display: inline-block;
font-size: inherit;
height: 8px;
width: 8px;
transform: translate(-38px) rotate(-45deg);
border-bottom: 3px solid black;
border-right: 3px solid black;
border-radius:2px;
}
.vsb-menu li.grouped-option i {
display: inline-block;
font-size: inherit;
float:left;
font-weight:bold;
margin-left:22px;
margin-right:2px;
height: 11px;
width: 8px;
border : 1px solid;
border-radius : 3px;
padding: 1px 3px 2px 3px;
margin-top:0px;
color:black;
}
.vsb-menu li.grouped-option.checked i::after {
content: "";
display: inline-block;
font-size: inherit;
color: #333;
float:left;
margin-left:0px;
display: inline-block;
transform: rotate(45deg);
height: 8px;
width: 5px;
border-bottom: 3px solid black;
border-right: 3px solid black;
}
.vsb-menu :not(.multi) li.active {
margin-left:7px;
}
.vsb-menu :not(.multi) li.active::before {
content: "";
display: inline-block;
font-size: inherit;
margin-left:-18px;
transform: rotate(45deg);
height: 10px;
width: 5px;
border-bottom: 3px solid black;
border-right: 3px solid black;
border-radius:2px;
}
.vsb-menu .multi li {
font-size: 14px;
background-color: #fff;
min-height:1.4em;
padding: 0.2em 2em 0.2em 26px;
}
.vsb-menu .multi li.grouped-option {
font-size: 15px;
padding-left: 5px;
}
.vsb-menu .multi li.grouped-option:hover {
font-weight: bold;
text-decoration: underline;
color:rgb(52, 31, 112);
}
.vsb-menu .multi li:not(.grouped-option)::before{
content: "";
display: inline-block;
font-size: inherit;
float:left;
font-weight:bold;
margin-left:-22px;
margin-right:2px;
border : 1px solid;
border-radius : 3px;
padding : 7px;
margin-top:0px;
color:black;
}
.vsb-menu .multi li:not(.grouped-option).active::after {
content: "";
display: inline-block;
font-size: inherit;
color: #333;
float:left;
margin-left:-18px;
display: inline-block;
transform: rotate(45deg);
margin-top:1px;
height: 8px;
width: 5px;
border-bottom: 3px solid black;
border-right: 3px solid black;
}
.caret {
display: inline-block;
width: 0;
height: 0;
margin-left: 2px;
vertical-align: middle;
border-top: 4px dashed;
border-top: 4px solid;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
}
li[data-parent]{
padding-left: 50px !important;
}
......@@ -27,8 +27,10 @@ import {
hideLoadingSpinner,
} from "./src_modules/loadingIndicator.mjs";
import { vanillaSelectBox } from "./thirdparty/vanillaSelectBox.mjs";
const buildingsAvailableSensorsArr = [
["--Select--", "", ""],
// ["--Select--", "", ""],
["Bau 101", "Vorlauftemperatur", "15 min"],
["Bau 101", "Vorlauftemperatur", "60 min"],
......@@ -132,27 +134,42 @@ const makeDropDown = function (dataArr, filtersAsArray, targetElement) {
* Use the `makeDropDown` function to create the first two levels of the linked drop down lists
* @returns {undefined}
*/
const applyDropDown = function () {
const applyDropDownLevelOneTwo = function () {
const selectLevel1Value = document.querySelector("#drop-down--bldg").value;
const selectLevel2 = document.querySelector("#drop-down--sensor");
const selectLevel2DOMString = "#drop-down--sensor";
const selectLevel2 = document.querySelector(selectLevel2DOMString);
makeDropDown(buildingsAvailableSensorsArr, [selectLevel1Value], selectLevel2);
applyDropDown2();
applyDropDownLevelThree();
// Create our dropdown list using `vanillaSelectBox`
new vanillaSelectBox(selectLevel2DOMString, {
"placeHolder": "--Select--",
});
};
/**
* Use the `makeDropDown` function to create the third level of the linked drop down lists
* @returns {undefined}
*/
const applyDropDown2 = function () {
const applyDropDownLevelThree = function () {
const selectLevel1Value = document.querySelector("#drop-down--bldg").value;
const selectLevel2Value = document.querySelector("#drop-down--sensor").value;
const selectLevel3 = document.querySelector("#drop-down--sampling-rate");
const selectLevel3DOMString = "#drop-down--sampling-rate";
const selectLevel3 = document.querySelector(selectLevel3DOMString);
makeDropDown(
buildingsAvailableSensorsArr,
[selectLevel1Value, selectLevel2Value],
selectLevel3
);
// Create our dropdown list using `vanillaSelectBox`
new vanillaSelectBox(selectLevel3DOMString, {
"placeHolder": "--Select--",
});
// Create our fourth level dropdown
styleFourthLevelDropDown();
};
/**
......@@ -160,21 +177,53 @@ const applyDropDown2 = function () {
* @returns {undefined}
*/
const populateFirstLevelDropDown = function () {
const el = document.querySelector("#drop-down--bldg");
const selectLevel1DOMString = "#drop-down--bldg";
const selectLevel1 = document.querySelector(selectLevel1DOMString);
const uniqueList = getUniqueValues(buildingsAvailableSensorsArr, 0);
populateDropDown(el, uniqueList);
populateDropDown(selectLevel1, uniqueList);
// Create our dropdown list using `vanillaSelectBox`; supports the selection of multiple options
new vanillaSelectBox(selectLevel1DOMString, {
"disableSelectAll": true,
"maxSelect": 3,
"placeHolder": "--Select--",
"search": false,
});
};
/**
* Use the `vanillaDropDown` library to style the fourth level drop down list
*
* @returns {undefined}
*/
const styleFourthLevelDropDown = function () {
const selectLevel4DOMString = "#drop-down--chart-type";
// Create our dropdown list using `vanillaSelectBox`
new vanillaSelectBox(selectLevel4DOMString, {
"placeHolder": "--Select--",
});
};
document
.querySelector("#drop-down--bldg")
.addEventListener("change", applyDropDown);
.addEventListener("change", applyDropDownLevelOneTwo);
document
.querySelector("#drop-down--sensor")
.addEventListener("change", applyDropDown2);
.addEventListener("change", applyDropDownLevelThree);
/**
* Callback function that wraps the logic of populating the linked drop down lists.
* Will run on `DOMContentLoaded` event
*
* @returns {undefined}
*/
const afterDocumentLoads = function () {
populateFirstLevelDropDown();
applyDropDownLevelOneTwo();
};
// These functions run after "DOMContentLoaded" event
populateFirstLevelDropDown();
applyDropDown();
document.addEventListener("DOMContentLoaded", afterDocumentLoads);
/**
* Get the values from the currently selected options in the linked drop dpwn lists
......
"use strict";
import { checkForAndDeleteUniqueObservationsFromLargerArray } from "./chartHelpers.mjs";
import { getMetadataPlusObservationsFromSingleOrMultipleDatastreams } from "./fetchData.mjs";
import { extractPhenomenonNameFromDatastreamName } from "./fetchedDataProcessing.mjs";
/**
* Calculate the temperature difference, dT, between Vorlauf temperature [VL] and Rücklauf temperature [RL] (i.e., dT = VL - RL)
* @async
* @param {String} baseUrl Base URL of the STA server
* @param {Object} urlParams The URL parameters to be sent together with the GET request
* @param {String} buildingId The building ID as a string
......@@ -40,21 +43,47 @@ export const calculateVorlaufMinusRuecklaufTemperature = async function (
[metadataVorlauf, metadataRuecklauf],
] = observationsPlusMetadata;
// Compare the lengths of the observations arrays for VL and RL,
// delete the unique observation(s), if necessary
const [vorlaufTemperatureObsFinalArr, ruecklaufTemperatureObsFinalArr] =
vorlaufTemperatureObsArr.length === ruecklaufTemperatureObsArr.length
? [vorlaufTemperatureObsArr, ruecklaufTemperatureObsArr]
: checkForAndDeleteUniqueObservationsFromLargerArray(
vorlaufTemperatureObsArr,
ruecklaufTemperatureObsArr
);
// Extract the temperature values
const vorlaufTemperatureValues = vorlaufTemperatureObsArr.map(
const vorlaufTemperatureValues = vorlaufTemperatureObsFinalArr.map(
(vlTempObs) => vlTempObs[1]
);
const ruecklaufTemperatureValues = ruecklaufTemperatureObsArr.map(
const ruecklaufTemperatureValues = ruecklaufTemperatureObsFinalArr.map(
(rlTempObs) => rlTempObs[1]
);
// The arrays have equal length, we need only use one of them for looping
// Resulting array contains the following pairs (timestamp + dT)
const vorlaufMinusRuecklaufTemperatureObs = vorlaufTemperatureObsArr.map(
(vlTempObs, i) => [
vlTempObs[0], // timestamp
vorlaufTemperatureValues[i] - ruecklaufTemperatureValues[i],
]
(vlTempObs, i) => {
// Use timestamp from VL, since is equal to that of RL
const timestamp = vlTempObs[0];
// Case 1: One of the observation values is `null`,
// no need to calculate temperature difference
if (
vorlaufTemperatureValues[i] === null ||
ruecklaufTemperatureValues[i] === null
) {
return [timestamp, null];
}
// Case 2: Neither of the observation values is `null`,
// calculate temperature difference
return [
timestamp,
vorlaufTemperatureValues[i] - ruecklaufTemperatureValues[i],
];
}
);
// From Vorlauf metadata, extract `name` and `unitOfMeasurement`
......
......@@ -8,6 +8,173 @@ const chartExportOptions = {
},
};
/**
* Determines the timestamps that are missing from a smaller set of observations. Based on the comparison of two observation arrays, where one array is larger than the other
* @param {Array} obsTimestampArrayOne An array of timestamps for the first set of observations
* @param {Array} obsTimestampArrayTwo An array of timstamps for the second set of observations
* @returns {Array} An array of timestamps missing from either set of observations
*/
const getSymmetricDifferenceBetweenArrays = function (
obsTimestampArrayOne,
obsTimestampArrayTwo
) {
return obsTimestampArrayOne
.filter((timestampOne) => !obsTimestampArrayTwo.includes(timestampOne))
.concat(
obsTimestampArrayTwo.filter(
(timestampTwo) => !obsTimestampArrayOne.includes(timestampTwo)
)
);
};
/**
* Determines the indexes of timestamps that are unique to the larger set of observatiuons. Based on the comparison of two observation arrays, where one array is larger than the other
* @param {Array} uniqueTimestampsArr An array of timestamps unique to the larger set of observations
* @param {Array} largerObsTimestampArr An array of timestamps for the larger set of observations
* @returns {Array} An array of the indexes of the missing observations
*/
const getIndexesOfUniqueObservations = function (
uniqueTimestampsArr,
largerObsTimestampArr
) {
return uniqueTimestampsArr.map((index) =>
largerObsTimestampArr.indexOf(index)
);
};
/**
* Removes observations (by modifying array in place) that are unique to a larger set of observations. Based on the comparison of two observation arrays, where one array is larger than the other
* @param {Array} uniqueIndexesArr An array of the indexes unique to the larger set of observations
* @param {Array} largerObsArr The larger array of observations (timestamp + value)
* @returns {Array} The larger array with the unique indexes removed
*/
const removeUniqueObservationsFromLargerArray = function (
uniqueIndexesArr,
largerObsArr
) {
// Create a reversed copy of the indexes array, so that the larger index is removed first
const reversedUniqueIndexesArr = uniqueIndexesArr.reverse();
// Create a copy the larger observation array, will be modified in place
const processedLargerObsArr = largerObsArr;
reversedUniqueIndexesArr.forEach((index) => {
if (index > -1) {
processedLargerObsArr.splice(index, 1);
}
});
return processedLargerObsArr;
};
/**
* Compares the length of two input arrays to determine the larger one
* @param {Array} firstArr First input array
* @param {Array} secondArr Second input array
* @returns {Array} The larger array
*/
const getLargerArrayBetweenTwoInputArrays = function (firstArr, secondArr) {
if (firstArr.length === secondArr.length) return;
if (firstArr.length > secondArr.length) return firstArr;
if (firstArr.length < secondArr.length) return secondArr;
};
/**
* Compares the length of two input arrays to determine the smaller one
* @param {Array} firstArr First input array
* @param {Array} secondArr Second input array
* @returns {Array} The smaller array
*/
const getSmallerArrayBetweenTwoInputArrays = function (firstArr, secondArr) {
if (firstArr.length === secondArr.length) return;
if (firstArr.length < secondArr.length) return firstArr;
if (firstArr.length > secondArr.length) return secondArr;
};
/**
* Utility function for deleting the unique observations from a larger array
* @param {Array} obsArrayOne Array of observations (timestamp + value) that is response from SensorThings API
* @param {Array} obsArrayTwo Array of observations (timestamp + value) that is response from SensorThings API
* @returns {Array} Two arrays of observations (timestamp + value) with matching timestamps and equal lengths
*/
const deleteUniqueObservationsFromLargerArray = function (
obsArrayOne,
obsArrayTwo
) {
// Create arrays with timestamps only
const obsArrayOneTimestamp = obsArrayOne.map(
(obsTimeValue) => obsTimeValue[0]
);
const obsArrayTwoTimestamp = obsArrayTwo.map(
(obsTimeValue) => obsTimeValue[0]
);
const missingTimestamp = getSymmetricDifferenceBetweenArrays(
obsArrayOneTimestamp,
obsArrayTwoTimestamp
);
// Determine the larger observation timestamp array
const biggerObsTimestampArr = getLargerArrayBetweenTwoInputArrays(
obsArrayOneTimestamp,
obsArrayTwoTimestamp
);
// Indexes of the missing observations
const indexesMissingObsArr = getIndexesOfUniqueObservations(
missingTimestamp,
biggerObsTimestampArr
);
// Determine the larger observation array
const biggerObsArr = getLargerArrayBetweenTwoInputArrays(
obsArrayOne,
obsArrayTwo
);
// Determine the smaller observation array
const smallerObsArr = getSmallerArrayBetweenTwoInputArrays(
obsArrayOne,
obsArrayTwo
);
// Remove the missing observation from the larger array of observations
const modifiedBiggerObsArr = removeUniqueObservationsFromLargerArray(
indexesMissingObsArr,
biggerObsArr
);
return [modifiedBiggerObsArr, smallerObsArr];
};
/**
* Utility function for deleting the unique observations from a larger array AND ensuring the order of input arrays is maintained
* @param {Array} obsArrayOne Array of observations (timestamp + value) that is response from SensorThings API
* @param {Array} obsArrayTwo Array of observations (timestamp + value) that is response from SensorThings API
* @returns {Array} Two arrays of observations (timestamp + value) with matching timestamps and equal lengths
*/
const checkForAndDeleteUniqueObservationsFromLargerArray = function (
obsArrayOne,
obsArrayTwo
) {
if (obsArrayOne.length === obsArrayTwo.length) return;
// Case 1: obsArrayOne.length < obsArrayTwo.length
if (obsArrayOne.length < obsArrayTwo.length) {
const [biggerObsArr, smallerObsArr] =
deleteUniqueObservationsFromLargerArray(obsArrayOne, obsArrayTwo);
return [smallerObsArr, biggerObsArr];
}
// Case 2: obsArrayOne.length > obsArrayTwo.length
return deleteUniqueObservationsFromLargerArray(obsArrayOne, obsArrayTwo);
};
/**
* 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
......@@ -142,6 +309,7 @@ const removeTransparencyFromColor = function (rgbaColor) {
export {
chartExportOptions,
checkForAndDeleteUniqueObservationsFromLargerArray,
createCombinedTextDelimitedByAmpersand,
createCombinedTextDelimitedByComma,
createFullTitleForLineOrColumnChart,
......
......@@ -2,6 +2,7 @@
import {
chartExportOptions,
checkForAndDeleteUniqueObservationsFromLargerArray,
convertHexColorToRGBColor,
createCombinedTextDelimitedByAmpersand,
createCombinedTextDelimitedByComma,
......@@ -9,173 +10,6 @@ import {
removeTransparencyFromColor,
} from "./chartHelpers.mjs";
/**
* Determines the timestamps that are missing from a smaller set of observations. Based on the comparison of two observation arrays, where one array is larger than the other
* @param {Array} obsTimestampArrayOne An array of timestamps for the first set of observations
* @param {Array} obsTimestampArrayTwo An array of timstamps for the second set of observations
* @returns {Array} An array of timestamps missing from either set of observations
*/
const getSymmetricDifferenceBetweenArrays = function (
obsTimestampArrayOne,
obsTimestampArrayTwo
) {
return obsTimestampArrayOne
.filter((timestampOne) => !obsTimestampArrayTwo.includes(timestampOne))
.concat(
obsTimestampArrayTwo.filter(
(timestampTwo) => !obsTimestampArrayOne.includes(timestampTwo)
)
);
};
/**
* Determines the indexes of timestamps that are unique to the larger set of observatiuons. Based on the comparison of two observation arrays, where one array is larger than the other
* @param {Array} uniqueTimestampsArr An array of timestamps unique to the larger set of observations
* @param {Array} largerObsTimestampArr An array of timestamps for the larger set of observations
* @returns {Array} An array of the indexes of the missing observations
*/
const getIndexesOfUniqueObservations = function (
uniqueTimestampsArr,
largerObsTimestampArr
) {
return uniqueTimestampsArr.map((index) =>
largerObsTimestampArr.indexOf(index)
);
};
/**
* Removes observations (by modifying array in place) that are unique to a larger set of observations. Based on the comparison of two observation arrays, where one array is larger than the other
* @param {Array} uniqueIndexesArr An array of the indexes unique to the larger set of observations
* @param {Array} largerObsArr The larger array of observations (timestamp + value)
* @returns {Array} The larger array with the unique indexes removed
*/
const removeUniqueObservationsFromLargerArray = function (
uniqueIndexesArr,
largerObsArr
) {
// Create a reversed copy of the indexes array, so that the larger index is removed first
const reversedUniqueIndexesArr = uniqueIndexesArr.reverse();
// Create a copy the larger observation array, will be modified in place
const processedLargerObsArr = largerObsArr;
reversedUniqueIndexesArr.forEach((index) => {
if (index > -1) {
processedLargerObsArr.splice(index, 1);
}
});
return processedLargerObsArr;
};
/**
* Compares the length of two input arrays to determine the larger one
* @param {Array} firstArr First input array
* @param {Array} secondArr Second input array
* @returns {Array} The larger array
*/
const getLargerArrayBetweenTwoInputArrays = function (firstArr, secondArr) {
if (firstArr.length === secondArr.length) return;
if (firstArr.length > secondArr.length) return firstArr;
if (firstArr.length < secondArr.length) return secondArr;
};
/**
* Compares the length of two input arrays to determine the smaller one
* @param {Array} firstArr First input array
* @param {Array} secondArr Second input array
* @returns {Array} The smaller array
*/
const getSmallerArrayBetweenTwoInputArrays = function (firstArr, secondArr) {
if (firstArr.length === secondArr.length) return;
if (firstArr.length < secondArr.length) return firstArr;
if (firstArr.length > secondArr.length) return secondArr;
};
/**
* Utility function for deleting the unique observations from a larger array
* @param {Array} obsArrayOne Array of observations (timestamp + value) that is response from SensorThings API
* @param {Array} obsArrayTwo Array of observations (timestamp + value) that is response from SensorThings API
* @returns {Array} Two arrays of observations (timestamp + value) with matching timestamps and equal lengths
*/
const deleteUniqueObservationsFromLargerArray = function (
obsArrayOne,
obsArrayTwo
) {
// Create arrays with timestamps only
const obsArrayOneTimestamp = obsArrayOne.map(
(obsTimeValue) => obsTimeValue[0]
);
const obsArrayTwoTimestamp = obsArrayTwo.map(
(obsTimeValue) => obsTimeValue[0]
);
const missingTimestamp = getSymmetricDifferenceBetweenArrays(
obsArrayOneTimestamp,
obsArrayTwoTimestamp
);
// Determine the larger observation timestamp array
const biggerObsTimestampArr = getLargerArrayBetweenTwoInputArrays(
obsArrayOneTimestamp,
obsArrayTwoTimestamp
);
// Indexes of the missing observations
const indexesMissingObsArr = getIndexesOfUniqueObservations(
missingTimestamp,
biggerObsTimestampArr
);
// Determine the larger observation array
const biggerObsArr = getLargerArrayBetweenTwoInputArrays(
obsArrayOne,
obsArrayTwo
);
// Determine the smaller observation array
const smallerObsArr = getSmallerArrayBetweenTwoInputArrays(
obsArrayOne,
obsArrayTwo
);
// Remove the missing observation from the larger array of observations
const modifiedBiggerObsArr = removeUniqueObservationsFromLargerArray(
indexesMissingObsArr,
biggerObsArr
);
return [modifiedBiggerObsArr, smallerObsArr];
};
/**
* Utility function for deleting the unique observations from a larger array AND ensuring the order of input arrays is maintained
* @param {Array} obsArrayOne Array of observations (timestamp + value) that is response from SensorThings API
* @param {Array} obsArrayTwo Array of observations (timestamp + value) that is response from SensorThings API
* @returns {Array} Two arrays of observations (timestamp + value) with matching timestamps and equal lengths
*/
const checkForAndDeleteUniqueObservationsFromLargerArray = function (
obsArrayOne,
obsArrayTwo
) {
if (obsArrayOne.length === obsArrayTwo.length) return;
// Case 1: obsArrayOne.length < obsArrayTwo.length
if (obsArrayOne.length < obsArrayTwo.length) {
const [biggerObsArr, smallerObsArr] =
deleteUniqueObservationsFromLargerArray(obsArrayOne, obsArrayTwo);
return [smallerObsArr, biggerObsArr];
}
// Case 2: obsArrayOne.length > obsArrayTwo.length
return deleteUniqueObservationsFromLargerArray(obsArrayOne, obsArrayTwo);
};
/**
* Extracts and combines observation values from two input observation arrays of equal length
* @param {Array} obsArrayOne First set of N observations (timestamp + value)
......
This diff is collapsed.
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