From 0ef2781ecf9e824e25d365fe2fa1a894e0259686 Mon Sep 17 00:00:00 2001 From: Pithon Kabiro <pithon.kabiro@hft-stuttgart.de> Date: Wed, 22 Sep 2021 15:45:37 +0200 Subject: [PATCH] Add logic for performing basic aggregation --- index.html | 1 + public/js/aggregate.js | 168 +++++++++++++++++++++ public/js/appChart.js | 299 +++++++++++++++++++++----------------- public/js/dropDownList.js | 35 +++-- 4 files changed, 353 insertions(+), 150 deletions(-) create mode 100644 public/js/aggregate.js diff --git a/index.html b/index.html index c90ef68..03e6482 100644 --- a/index.html +++ b/index.html @@ -73,6 +73,7 @@ <script defer type="module" src="js/appCesium.js"></script> <script defer type="module" src="js/appChart.js"></script> <script defer type="module" src="js/dropDownList.js"></script> + <script defer type="module" src="js/aggregate.js"></script> </head> <body class="sb-nav-fixed"> <nav class="sb-topnav navbar navbar-expand navbar-dark bg-dark"> diff --git a/public/js/aggregate.js b/public/js/aggregate.js new file mode 100644 index 0000000..5157411 --- /dev/null +++ b/public/js/aggregate.js @@ -0,0 +1,168 @@ +"use strict"; + +import { + BASE_URL, + QUERY_PARAMS_COMBINED, + getDatastreamIdFromBuildingNumber, + createObservationsUrl, + performGetRequestUsingAxios, + extractCombinedObservationsFromAllPages, +} from "./appChart.js"; + +/** + * Create 24-hour time strings for a time interval delimited by a start time and an end time. It is assumed that the start time is at "00:00:00" and the end time is at "23:45:00" (when the sampling rate of observations is 15 min) or "23:00:00" (when the sampling rate of observations is 60 min) + * @param {String} phenomenonSamplingRate The sampling rate of the phenomenon of interest represented as a string, e.g. "15 min", "60 min" + * @returns {Array} An array of two 24-hour strings representing the start time and end time + */ +const createTimeStringsForInterval = function (phenomenonSamplingRate) { + const fifteenMinutes = "15 min"; + const sixtyMinutes = "60 min"; + + const startTime = "00:00:00"; + const endTimeFifteenMinutes = "23:45:00"; + const endTimeSixtyMinutes = "23:00:00"; + + if ( + phenomenonSamplingRate !== fifteenMinutes && + phenomenonSamplingRate !== sixtyMinutes + ) + return; + + // 15 min sampling rate + if (phenomenonSamplingRate === fifteenMinutes) { + return [startTime, endTimeFifteenMinutes]; + } + + // 60 min sampling rate + if (phenomenonSamplingRate === sixtyMinutes) { + return [startTime, endTimeSixtyMinutes]; + } +}; + +/** + * Create an ISO 8601 date and time string + * @param {String} inputCalendarDate Calendar date string in "YYYY-MM-DD" format + * @param {String} inputTwentyFourHourTime 24-hour time string in "hh:mm:ss" format + * @returns {String} An ISO 8601 date and time string + */ +const createIso8601DateTimeString = function ( + inputCalendarDate, + inputTwentyFourHourTime +) { + return `${inputCalendarDate}T${inputTwentyFourHourTime}.000Z`; +}; + +/** + * Calculate the index of a timestamp in an array of timestamps + * @param {Array} inputTimestampArr An array of timestamps, extracted from an array of observations + * @param {String} timestampOfInterest A string representing the timestamp of interest in ISO 8601 format + * @returns {Number} An integer representing the index of the timestamp of interest in the array of timestamps + */ +const getIndexOfTimestamp = function (inputTimestampArr, timestampOfInterest) { + const timestampIndex = inputTimestampArr.findIndex( + (timestamp) => timestamp === timestampOfInterest + ); + + // If the timestamp does not exist in the timestamp array + if (timestampIndex === -1) + throw new Error( + "A start or end timestamp could not be found in the timestamp array" + ); + + // If the timestamp exists in the timestamp array + return timestampIndex; +}; + +/** + * Aggregate observations within a time interval delimited by a start date and end date. The start date may be the same as the end date. + * @param {Array} obsArray An array of observations (timestamp + value) that is response from SensorThings API + * @param {String} samplingRate The sampling rate of observations as a string, e.g. "15 min", "60 min" + * @param {String} startDate A 24-hour date string representing the start date + * @param {String} endDate A 24-hour date string representing the end date + * @returns {Number} A floating-point number representing the aggregated observation value + */ +const aggregateObservationsWithinTimeInterval = function ( + obsArray, + samplingRate, + startDate, + endDate +) { + // Extract the timestamps and values from the observations + const obsTimestampArr = obsArray.map((obs) => obs[0]); + const obsValuesArr = obsArray.map((obs) => obs[1]); + + // Create array of 24-hour strings for the start and end of interval + const startPlusEndTimeStrings = createTimeStringsForInterval(samplingRate); + + // Extract 24-hour strings for the start and end of interval + const [startTimeString, endTimeString] = startPlusEndTimeStrings; + + // Create ISO 8601 strings for the start and end of interval + const startIso8601DateTimeString = createIso8601DateTimeString( + startDate, + startTimeString + ); + const endIso8601DateTimeString = createIso8601DateTimeString( + endDate, + endTimeString + ); + + // Calculate the indexes of the timestamps for the start and end of interval + const indexStartTimestamp = getIndexOfTimestamp( + obsTimestampArr, + startIso8601DateTimeString + ); + const indexEndTimestamp = getIndexOfTimestamp( + obsTimestampArr, + endIso8601DateTimeString + ); + + // Extract the observations that fall within our time interval + const obsValuesForTimeIntervalArr = obsValuesArr.slice( + indexStartTimestamp, + indexEndTimestamp + 1 + ); + + // Calculate the aggregated observation value + const aggregatedObsValue = obsValuesForTimeIntervalArr.reduce( + (accumulator, currentValue) => accumulator + currentValue + ); + + return aggregatedObsValue; +}; + +/** + * Test aggregation of observations from a single datastream + */ +const testAggregation = async function () { + // Datastream ID + const datastreamIdBau225VL = getDatastreamIdFromBuildingNumber( + "225", + "vl", + "60min" + ); + + // Observations URL + const observationsUrlBau225VL = createObservationsUrl( + BASE_URL, + datastreamIdBau225VL + ); + + // Observations array + const observationsBau225VL = await extractCombinedObservationsFromAllPages( + performGetRequestUsingAxios(observationsUrlBau225VL, QUERY_PARAMS_COMBINED) + ); + + // Aggregated observations + const observationsBau225VLAggregated = + aggregateObservationsWithinTimeInterval( + observationsBau225VL, + "60 min", + "2020-02-01", + "2020-03-31" + ); + + // console.log(observationsBau225VLAggregated); +}; + +// testAggregation(); diff --git a/public/js/appChart.js b/public/js/appChart.js index bd1cce1..3b3a675 100644 --- a/public/js/appChart.js +++ b/public/js/appChart.js @@ -104,7 +104,7 @@ const getDatastreamIdFromBuildingNumber = function ( * @param {Number} datastreamID Integer representing the Datastream ID * @returns {String} URL string for fetching a single Datastream */ -const getDatastreamUrl = function (baseUrl, datastreamID) { +const createDatastreamUrl = function (baseUrl, datastreamID) { if (!datastreamID) return; const fullDatastreamURL = `${baseUrl}/Datastreams(${datastreamID})`; return fullDatastreamURL; @@ -116,7 +116,7 @@ const getDatastreamUrl = function (baseUrl, datastreamID) { * @param {Number} datastreamID Integer representing the Datastream ID * @returns {String} URL string for fetching Observations */ -const getObservationsUrl = function (baseUrl, datastreamID) { +const createObservationsUrl = function (baseUrl, datastreamID) { if (!datastreamID) return; const fullObservationsURL = `${baseUrl}/Datastreams(${datastreamID})/Observations`; return fullObservationsURL; @@ -134,7 +134,6 @@ const createTemporalFilterString = function (dateStart, dateStop) { return filterString; }; -// const BASE_URL_OBSERVATIONS = getObservationsUrl(80); const QUERY_PARAM_RESULT_FORMAT = "dataArray"; const QUERY_PARAM_ORDER_BY = "phenomenonTime asc"; const QUERY_PARAM_FILTER = createTemporalFilterString( @@ -155,7 +154,7 @@ const QUERY_PARAMS_COMBINED = { * @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 */ -const axiosGetRequest = function (urlObservations, urlParamObj) { +const performGetRequestUsingAxios = function (urlObservations, urlParamObj) { return axios.get(urlObservations, { params: urlParamObj, }); @@ -172,7 +171,7 @@ const getMetadataFromSingleDatastream = async function (urlDatastream) { // Extract properties of interest const { data: { description, name, unitOfMeasurement }, - } = await axiosGetRequest(urlDatastream); + } = await performGetRequestUsingAxios(urlDatastream); return { description, name, unitOfMeasurement }; } catch (err) { @@ -267,11 +266,11 @@ const formatDatastreamMetadataForChart = function (datastreamMetadata) { }; /** - * Format the response from SensorThings API to make it suitable for heatmap + * Format the response from SensorThings API to make it suitable for use in a heatmap * @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 heatmap */ -const formatSTAResponseForHeatMap = function (obsArray) { +const formatSensorThingsApiResponseForHeatMap = function (obsArray) { if (!obsArray) return; const dataSTAFormatted = obsArray.map((obs) => { @@ -322,7 +321,7 @@ const calculateMinMaxValuesForHeatmapColorAxis = function ( * @param {Object} formattedDatastreamMetadata Object containing Datastream metadata * @returns {undefined} undefined */ -const drawHeatMapHC = function ( +const drawHeatMapHighcharts = function ( formattedObsArrayForHeatmap, formattedDatastreamMetadata ) { @@ -431,11 +430,11 @@ const drawHeatMapHC = function ( }; /** - * Format the response from SensorThings API to make it suitable for line chart + * Format the response from SensorThings API to make it suitable for use in a line chart * @param {Array} obsArray Response from SensorThings API as array * @returns {Array} Array of formatted observations suitable for use in a line chart */ -const formatSTAResponseForLineChart = function (obsArray) { +const formatSensorThingsApiResponseForLineChart = function (obsArray) { if (!obsArray) return; const dataSTAFormatted = obsArray.map((result) => { @@ -453,7 +452,7 @@ const formatSTAResponseForLineChart = function (obsArray) { * @param {Object} formattedDatastreamMetadata Object containing Datastream metadata * @returns {undefined} undefined */ -const drawLineChartHC = function ( +const drawLineChartHighcharts = function ( formattedObsArrayForLineChart, formattedDatastreamMetadata ) { @@ -537,21 +536,26 @@ const getIndexesOfUniqueObservations = function ( /** * 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) which is modified in place - * @returns {undefined} + * @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 ) { - // Reverse the indexes array so that the larger index is removed first - uniqueIndexesArr.reverse(); + // 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; - uniqueIndexesArr.forEach((index) => { + reversedUniqueIndexesArr.forEach((index) => { if (index > -1) { - largerObsArr.splice(index, 1); + processedLargerObsArr.splice(index, 1); } }); + + return processedLargerObsArr; }; /** @@ -630,10 +634,12 @@ const deleteUniqueObservationsFromLargerArray = function ( ); // Remove the missing observation from the larger array of observations - // Modifies the array in place - removeUniqueObservationsFromLargerArray(indexesMissingObsArr, biggerObsArr); + const modifiedBiggerObsArr = removeUniqueObservationsFromLargerArray( + indexesMissingObsArr, + biggerObsArr + ); - return [biggerObsArr, smallerObsArr]; + return [modifiedBiggerObsArr, smallerObsArr]; }; /** @@ -661,7 +667,7 @@ const checkForAndDeleteUniqueObservationsFromLargerArray = function ( }; /** - * Extracts and combines observation values from two imput observation arrays of equal length + * Extracts and combines observation values from two input observation arrays of equal length * @param {Array} obsArrayOne First set of N observations (timestamp + value) * @param {Array} obsArrayTwo Second set of N observations (timestamp + value) * @returns {Array} A 2*N array of observation values from both input observation arrays @@ -680,12 +686,15 @@ const createCombinedObservationValues = function (obsArrayOne, obsArrayTwo) { }; /** - * Format the response from SensorThings API to make it suitable for scatter plot + * Format the response from SensorThings API to make it suitable for use in a scatter plot * @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} Array of formatted observations suitable for use in a scatter plot */ -const formatSTAResponseForScatterPlot = function (obsArrayOne, obsArrayTwo) { +const formatSensorThingsApiResponseForScatterPlot = function ( + obsArrayOne, + obsArrayTwo +) { // When our observation arrays have DIFFERENT lengths if (obsArrayOne.length !== obsArrayTwo.length) { const [obsArrayOneFinal, obsArrayTwoFinal] = @@ -708,7 +717,7 @@ const formatSTAResponseForScatterPlot = function (obsArrayOne, obsArrayTwo) { * @param {*} formattedDatastreamMetadataSeriesTwo Object containing Datastream metadata for the second chart series * @returns {undefined} */ -const drawScatterPlotHC = function ( +const drawScatterPlotHighcharts = function ( formattedObsArrayForSeriesOnePlusSeriesTwo, formattedDatastreamMetadataSeriesOne, formattedDatastreamMetadataSeriesTwo @@ -830,61 +839,67 @@ const drawScatterPlotHC = function ( }; /** - * Follows "@iot.nextLink" links in SensorThingsAPI's response - * Appends new results to existing results + * Traverses all the pages that make up the response from a SensorThingsAPI instance. The link to the next page, if present, is denoted by the presence of a "@iot.nextLink" property in the response object. This function concatenates all the values so that the complete results are returned in one array. * @async - * @param {Promise} responsePromise Promise object resulting from an Axios GET request - * @returns {Object} Object containing results from all the "@iot.nextLink" links + * @param {Promise} httpGetRequestPromise Promise object resulting from an Axios GET request + * @returns {Promise} A promise that contains an object containing results from all the pages when fulfilled */ -const followNextLink = function (responsePromise) { - if (!responsePromise) return; - return responsePromise - .then((lastSuccess) => { - if (lastSuccess.data["@iot.nextLink"]) { - return followNextLink( - axios.get(lastSuccess.data["@iot.nextLink"]) - ).then((nextLinkSuccess) => { - nextLinkSuccess.data.value = lastSuccess.data.value.concat( - nextLinkSuccess.data.value - ); - return nextLinkSuccess; - }); - } else { - return lastSuccess; - } - }) - .catch((err) => { - console.error(err); - }); +const combineResultsFromAllPages = async function (httpGetRequestPromise) { + try { + if (!httpGetRequestPromise) return; + + const lastSuccess = await httpGetRequestPromise; + if (lastSuccess.data["@iot.nextLink"]) { + const nextLinkSuccess = await combineResultsFromAllPages( + axios.get(lastSuccess.data["@iot.nextLink"]) + ); + nextLinkSuccess.data.value = lastSuccess.data.value.concat( + nextLinkSuccess.data.value + ); + return nextLinkSuccess; + } else { + return lastSuccess; + } + } catch (err) { + console.error(err); + } }; /** - * Retrieve all the Observations from a Datastream after traversing all the "@iot.nextLink" links + * Traverses all the pages that make up the response from a SensorThingsAPI instance and extracts the combined Observations * @async * @param {Promise} httpGetRequestPromise Promise object resulting from an Axios GET request - * @returns {Promise} A promise that contains an array of Observations from a single Datastream when fulfilled + * @returns {Promise} A promise that contains an array of Observations when fulfilled */ -const getCombinedObservationsFromAllNextLinks = function ( +const extractCombinedObservationsFromAllPages = async function ( httpGetRequestPromise ) { - return followNextLink(httpGetRequestPromise) - .then((success) => { - const successValue = success.data.value; - // Array that will hold the combined observations - const combinedObservations = []; - successValue.forEach((dataObj) => { - // Each page of results will have a dataArray that holds the observations - const dataArrays = dataObj.dataArray; - combinedObservations.push(...dataArrays); - }); - - return new Promise((resolve, reject) => { - resolve(combinedObservations); - }); - }) - .catch((err) => { - console.error(err); + try { + const successResponse = await combineResultsFromAllPages( + httpGetRequestPromise + ); + + // Extract value array from the success response object + const { + data, + data: { value: valueArr }, + } = successResponse; + + // Array that will hold the combined observations + const combinedObservations = []; + + valueArr.forEach((val) => { + // Each page of results will have a dataArray that holds the observations + const { dataArray } = val; + combinedObservations.push(...dataArray); + }); + + return new Promise((resolve, reject) => { + resolve(combinedObservations); }); + } catch (err) { + console.error(err); + } }; /** @@ -959,18 +974,18 @@ const getMetadataPlusObservationsFromMultipleDatastreams = async function ( // Observations URLs const observationsUrlArr = datastreamsIdsArr.map((datastreamId) => - getObservationsUrl(BASE_URL, datastreamId) + createObservationsUrl(BASE_URL, datastreamId) ); // Datastreams URLs const datastreamsUrlArr = datastreamsIdsArr.map((datastreamId) => - getDatastreamUrl(BASE_URL, datastreamId) + createDatastreamUrl(BASE_URL, datastreamId) ); // Promise objects - Observations const observationsPromisesArr = observationsUrlArr.map((obsUrl) => - getCombinedObservationsFromAllNextLinks( - axiosGetRequest(obsUrl, QUERY_PARAMS_COMBINED) + extractCombinedObservationsFromAllPages( + performGetRequestUsingAxios(obsUrl, QUERY_PARAMS_COMBINED) ) ); @@ -995,73 +1010,86 @@ const getMetadataPlusObservationsFromMultipleDatastreams = async function ( * @async * @param {String} buildingId The building ID as a string * @param {String} samplingRate The sampling rate as a string - * @returns A promise that contains an array (that is made up of a temperature difference array and a metadata object) when fulfilled + * @returns {Promise} A promise that contains an array (that is made up of a temperature difference array and a metadata object) when fulfilled */ const calculateVorlaufMinusRuecklaufTemperature = async function ( buildingId, samplingRate ) { - const bldgSensorSamplingRateArr = [ - [buildingId, "vl", samplingRate], - [buildingId, "rl", samplingRate], - ]; - - const BUILDING_ID = buildingId; - const SAMPLING_RATE = samplingRate; + try { + const bldgSensorSamplingRateArr = [ + [buildingId, "vl", samplingRate], + [buildingId, "rl", samplingRate], + ]; - const observationsPlusMetadata = - await getMetadataPlusObservationsFromMultipleDatastreams( - bldgSensorSamplingRateArr - ); + const BUILDING_ID = buildingId; + const SAMPLING_RATE = samplingRate; - // Extract Vorlauf temperature and Ruecklauf temperature - const [[vorlaufTemp, ruecklaufTemp], [metadataVorlauf, metadataRuecklauf]] = - observationsPlusMetadata; + const observationsPlusMetadata = + await getMetadataPlusObservationsFromMultipleDatastreams( + bldgSensorSamplingRateArr + ); - const vorlaufTempValues = vorlaufTemp.map((obs) => obs[1]); - const ruecklaufTempValues = ruecklaufTemp.map((obs) => obs[1]); + // Extract Vorlauf temperature, Ruecklauf temperature and metadata + const [[vorlaufTemp, ruecklaufTemp], [metadataVorlauf, metadataRuecklauf]] = + observationsPlusMetadata; - // The arrays have equal length, we need only use one of them for looping - // Resulting array contains the following pairs (timestamp + dT) - const vorlaufMinusRuecklaufTemp = vorlaufTemp.map((obs, i) => [ - obs[0], - vorlaufTempValues[i] - ruecklaufTempValues[i], - ]); + // Extract the temperature values + const vorlaufTempValues = vorlaufTemp.map((obs) => obs[1]); + const ruecklaufTempValues = ruecklaufTemp.map((obs) => obs[1]); - // From Vorlauf metadata, extract `name` and `unitOfMeasurement` - const { name: datastreamNameVorlauf, unitOfMeasurement } = metadataVorlauf; + // The arrays have equal length, we need only use one of them for looping + // Resulting array contains the following pairs (timestamp + dT) + const vorlaufMinusRuecklaufTemp = vorlaufTemp.map((obs, i) => [ + obs[0], + vorlaufTempValues[i] - ruecklaufTempValues[i], + ]); - // From Ruecklauf metadata, extract `name` - const { name: datastreamNameRuecklauf } = metadataRuecklauf; + // From Vorlauf metadata, extract `name` and `unitOfMeasurement` + const { + name: datastreamNameVorlauf, + unitOfMeasurement: unitOfMeasurementVorlauf, + } = metadataVorlauf; - // Extract the phenomenon names from Datastream names - const phenomenonNameVorlauf = extractPhenomenonNameFromDatastreamName( - datastreamNameVorlauf - ); - const phenomenonNameRuecklauf = extractPhenomenonNameFromDatastreamName( - datastreamNameRuecklauf - ); + // From Ruecklauf metadata, extract `name` + const { name: datastreamNameRuecklauf } = metadataRuecklauf; - // Create our custom datastream description text - const descriptionCombined = `Computed dT: ${phenomenonNameVorlauf} minus ${phenomenonNameRuecklauf}`; + // Extract the phenomenon names from the Datastream names + const phenomenonNameVorlauf = extractPhenomenonNameFromDatastreamName( + datastreamNameVorlauf + ); + const phenomenonNameRuecklauf = extractPhenomenonNameFromDatastreamName( + datastreamNameRuecklauf + ); - // The resulting datastream description string has two `temperature` substrings; - // replace the first occurence with an empty string - const description = descriptionCombined.replace("temperature", ""); + // Create our custom datastream description text + // The resulting datastream description string has two `temperature` substrings; + // replace the first occurence with an empty string + const descriptionTempDifference = + `Computed dT: ${phenomenonNameVorlauf} minus ${phenomenonNameRuecklauf}`.replace( + "temperature", + "" + ); - // Create our custom datastream name text - const name = `BOSCH_${BUILDING_ID} / dT Temperature difference (VL-RL) DS:${SAMPLING_RATE}`; + // Create our custom datastream name text + const nameTempDifference = `BOSCH_${BUILDING_ID} / dT Temperature difference (VL-RL) DS:${SAMPLING_RATE}`; - return [ - vorlaufMinusRuecklaufTemp, + // The datastream object that we return needs to have these property names + const description = descriptionTempDifference; + const name = nameTempDifference; + const unitOfMeasurement = unitOfMeasurementVorlauf; - // The datastream metadata object needs to have these property names - { - description, - name, - unitOfMeasurement, - }, - ]; + return [ + vorlaufMinusRuecklaufTemp, + { + description, + name, + unitOfMeasurement, + }, + ]; + } catch (err) { + console.error(err); + } }; /** @@ -1071,8 +1099,8 @@ const drawHeatmapHCUsingTempDifference = async function () { const [tempDifferenceObsArrBau225, tempDifferenceMetadataBau225] = await calculateVorlaufMinusRuecklaufTemperature("225", "60min"); - drawHeatMapHC( - formatSTAResponseForHeatMap(tempDifferenceObsArrBau225), + drawHeatMapHighcharts( + formatSensorThingsApiResponseForHeatMap(tempDifferenceObsArrBau225), formatDatastreamMetadataForChart(tempDifferenceMetadataBau225) ); }; @@ -1099,8 +1127,11 @@ const drawScatterPlotHCTest2 = async function () { [metadataSensorOne, metadataSensorTwo], ] = observationsPlusMetadata; - drawScatterPlotHC( - formatSTAResponseForScatterPlot(obsSensorOneArr, obsSensorTwoArr), + drawScatterPlotHighcharts( + formatSensorThingsApiResponseForScatterPlot( + obsSensorOneArr, + obsSensorTwoArr + ), formatDatastreamMetadataForChart(metadataSensorOne), formatDatastreamMetadataForChart(metadataSensorTwo) ); @@ -1115,16 +1146,16 @@ export { BASE_URL, QUERY_PARAMS_COMBINED, getDatastreamIdFromBuildingNumber, - getDatastreamUrl, - getObservationsUrl, + createDatastreamUrl, + createObservationsUrl, createTemporalFilterString, - axiosGetRequest, + performGetRequestUsingAxios, getMetadataFromSingleDatastream, formatDatastreamMetadataForChart, - formatSTAResponseForHeatMap, - drawHeatMapHC, - formatSTAResponseForLineChart, - drawLineChartHC, - getCombinedObservationsFromAllNextLinks, + formatSensorThingsApiResponseForHeatMap, + drawHeatMapHighcharts, + formatSensorThingsApiResponseForLineChart, + drawLineChartHighcharts, + extractCombinedObservationsFromAllPages, getMetadataPlusObservationsFromSingleDatastream, }; diff --git a/public/js/dropDownList.js b/public/js/dropDownList.js index 5281763..e069f2b 100644 --- a/public/js/dropDownList.js +++ b/public/js/dropDownList.js @@ -4,16 +4,16 @@ import { BASE_URL, QUERY_PARAMS_COMBINED, getDatastreamIdFromBuildingNumber, - getDatastreamUrl, - getObservationsUrl, - axiosGetRequest, + createDatastreamUrl, + createObservationsUrl, + performGetRequestUsingAxios, getMetadataFromSingleDatastream, formatDatastreamMetadataForChart, - formatSTAResponseForHeatMap, - drawHeatMapHC, - formatSTAResponseForLineChart, - drawLineChartHC, - getCombinedObservationsFromAllNextLinks, + formatSensorThingsApiResponseForHeatMap, + drawHeatMapHighcharts, + formatSensorThingsApiResponseForLineChart, + drawLineChartHighcharts, + extractCombinedObservationsFromAllPages, getMetadataPlusObservationsFromSingleDatastream, } from "./appChart.js"; @@ -285,14 +285,17 @@ const selectChartTypeFromDropDown = async function () { // Display the loading indicator showLoadingSpinner(); - const URL_DATASTREAM = getDatastreamUrl(BASE_URL, selectedDatastream); - const URL_OBSERVATIONS = getObservationsUrl(BASE_URL, selectedDatastream); + const URL_DATASTREAM = createDatastreamUrl(BASE_URL, selectedDatastream); + const URL_OBSERVATIONS = createObservationsUrl( + BASE_URL, + selectedDatastream + ); // Create promises const promiseDatastreamMetadata = getMetadataFromSingleDatastream(URL_DATASTREAM); - const promiseCombinedObservations = getCombinedObservationsFromAllNextLinks( - axiosGetRequest(URL_OBSERVATIONS, QUERY_PARAMS_COMBINED) + const promiseCombinedObservations = extractCombinedObservationsFromAllPages( + performGetRequestUsingAxios(URL_OBSERVATIONS, QUERY_PARAMS_COMBINED) ); // Pass promises to our async function @@ -307,13 +310,13 @@ const selectChartTypeFromDropDown = async function () { const datastreamMetadata = metadataPlusObservations[1]; if (selectedChartType === "Line") { - drawLineChartHC( - formatSTAResponseForLineChart(combinedObs), + drawLineChartHighcharts( + formatSensorThingsApiResponseForLineChart(combinedObs), formatDatastreamMetadataForChart(datastreamMetadata) ); } else if (selectedChartType === "Heatmap") { - drawHeatMapHC( - formatSTAResponseForHeatMap(combinedObs), + drawHeatMapHighcharts( + formatSensorThingsApiResponseForHeatMap(combinedObs), formatDatastreamMetadataForChart(datastreamMetadata) ); } -- GitLab