Commit 04eb3a11 authored by Pithon Kabiro's avatar Pithon Kabiro
Browse files

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

Update logic for drop-down list

Tweak logic so that custom error messages are thrown before performing 
async tasks i.e. fetching observations and metadata

See merge request !17
Showing with 281 additions and 140 deletions
+281 -140
......@@ -40,7 +40,8 @@ import {
deleteTemperatureDifferenceOptions,
extractTemperatureDifferenceOptions,
extractBuildingPlusSamplingRate,
checkIfChartRequiresRawObservations,
checkIfSelectedBuildingDataPointsOptionsAreValid,
checkIfSelectedAggregationOptionsAreValid,
getAbbreviationsForSelectedOptionsFromAllDropDownLists,
} from "./src_modules/dropDownListHelpers.mjs";
......@@ -137,9 +138,9 @@ const drawChartUsingSelectedOptions = async function () {
const selectedOptionsAllDropDownLists =
getSelectedOptionsFromAllDropDownLists();
// Note: The aggregation type + duration and chart type are the second and
// fourth elements respectively, we have ignored the first and third elements
const [, selectedAggregationTypeDurationArr, , selectedChartTypeArr] =
// Note: The aggregation type + duration and chart type are the first and
// third elements respectively, we have ignored the second and fourth elements
const [selectedChartTypeArr, , selectedAggregationTypeDurationArr] =
selectedOptionsAllDropDownLists;
// Create an array of aggregation type and duration
......@@ -152,41 +153,56 @@ const drawChartUsingSelectedOptions = async function () {
const [selectedAggregationTypeDurationSplitArr] =
selectedAggregationTypeDurationSplitNestedArr;
const [selectedAggregationTypeArr, selectedAggregationDuration] =
const [selectedAggregationType, selectedAggregationDuration] =
selectedAggregationTypeDurationSplitArr;
// Array of building(s) + data point(s) + sampling rate
const selectedBuildingsDataPointsSamplingRateAbbrev =
const selectedBuildingsDataPointsSamplingRateAbbrevNestedArr =
getAbbreviationsForSelectedOptionsFromAllDropDownLists(
selectedOptionsAllDropDownLists
);
// 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 =
checkIfSelectedAggregationOptionsAreValid(
selectedChartTypeArr,
selectedAggregationType,
selectedAggregationDuration
);
const selectedBuildingDataPointsOptionsAreValid =
checkIfSelectedBuildingDataPointsOptionsAreValid(
selectedChartTypeArr,
selectedBuildingsDataPointsSamplingRateAbbrevNestedArr
);
// Create copies of the arrays of building(s) + data point(s) + sampling rate
const selectedBuildingsDataPointsSamplingRateAbbrevNonComputedCopy = [
...selectedBuildingsDataPointsSamplingRateAbbrev,
const selectedBuildingsDataPointsSamplingRateAbbrevNonComputedCopyArr = [
...selectedBuildingsDataPointsSamplingRateAbbrevNestedArr,
];
const selectedBuildingsDataPointsSamplingRateAbbrevComputedCopy = [
...selectedBuildingsDataPointsSamplingRateAbbrev,
const selectedBuildingsDataPointsSamplingRateAbbrevComputedCopyArr = [
...selectedBuildingsDataPointsSamplingRateAbbrevNestedArr,
];
// Check if we have non-computed
const selectedBuildingsDataPointsSamplingRateAbbrevNonComputed =
const selectedBuildingsDataPointsSamplingRateAbbrevNonComputedArr =
checkIfSelectedOptionsContainTemperatureDifference(
selectedBuildingsDataPointsSamplingRateAbbrevNonComputedCopy
selectedBuildingsDataPointsSamplingRateAbbrevNonComputedCopyArr
)
? deleteTemperatureDifferenceOptions(
selectedBuildingsDataPointsSamplingRateAbbrevNonComputedCopy
selectedBuildingsDataPointsSamplingRateAbbrevNonComputedCopyArr
)
: selectedBuildingsDataPointsSamplingRateAbbrevNonComputedCopy;
: selectedBuildingsDataPointsSamplingRateAbbrevNonComputedCopyArr;
// Check if we have computed / dT
const selectedBuildingsDataPointsSamplingRateAbbrevComputed =
const selectedBuildingsDataPointsSamplingRateAbbrevComputedArr =
checkIfSelectedOptionsContainTemperatureDifference(
selectedBuildingsDataPointsSamplingRateAbbrevComputedCopy
selectedBuildingsDataPointsSamplingRateAbbrevComputedCopyArr
)
? extractTemperatureDifferenceOptions(
selectedBuildingsDataPointsSamplingRateAbbrevComputedCopy
selectedBuildingsDataPointsSamplingRateAbbrevComputedCopyArr
)
: [];
......@@ -194,34 +210,34 @@ const drawChartUsingSelectedOptions = async function () {
showLoadingSpinner();
// Fetch the observations + metadata / non-computed
const observationsPlusMetadataNonComputed =
selectedBuildingsDataPointsSamplingRateAbbrevNonComputed.length === 0
const observationsPlusMetadataNonComputedArr =
selectedBuildingsDataPointsSamplingRateAbbrevNonComputedArr.length === 0
? [[], []]
: await getMetadataPlusObservationsFromSingleOrMultipleDatastreams(
BASE_URL,
QUERY_PARAMS_COMBINED,
selectedBuildingsDataPointsSamplingRateAbbrevNonComputed
selectedBuildingsDataPointsSamplingRateAbbrevNonComputedArr
);
// Fetch the observations + metadata / computed (dT)
const observationsPlusMetadataComputed =
selectedBuildingsDataPointsSamplingRateAbbrevComputed.length === 0
const observationsPlusMetadataComputedArr =
selectedBuildingsDataPointsSamplingRateAbbrevComputedArr.length === 0
? [[], []]
: await calculateVorlaufMinusRuecklaufTemperature(
BASE_URL,
QUERY_PARAMS_COMBINED,
extractBuildingPlusSamplingRate(
selectedBuildingsDataPointsSamplingRateAbbrevComputed
selectedBuildingsDataPointsSamplingRateAbbrevComputedArr
)
);
// Extract the combined arrays for observations and metadata / non-computed
const [observationsNestedNonComputedArr, metadataNestedNonComputedArr] =
observationsPlusMetadataNonComputed;
observationsPlusMetadataNonComputedArr;
// Extract the combined arrays for observations and metadata / computed (dT)
const [observationsNestedComputedArr, metadataNestedComputedArr] =
observationsPlusMetadataComputed;
observationsPlusMetadataComputedArr;
// Create a combined array of observations and metadata
const observationsPlusMetadataCombined = [
......@@ -246,7 +262,7 @@ const drawChartUsingSelectedOptions = async function () {
// The formatted abbreviations array is nested
const [selectedBuildingsDataPointsSamplingRateAbbrevArr] =
selectedBuildingsDataPointsSamplingRateAbbrev;
selectedBuildingsDataPointsSamplingRateAbbrevNestedArr;
// Extract the formatted sampling rate string - used by ALL chart types
const [, , selectedSamplingRateAbbrev] =
......@@ -273,50 +289,38 @@ const drawChartUsingSelectedOptions = async function () {
extractUniqueCalendarDatesFromTimestamp(observationsArr)
);
selectedChartTypeArr.forEach((selectedChartType) => {
for (const selectedChartType of selectedChartTypeArr) {
if (selectedChartType === "Heatmap") {
// We are interested in raw observations
if (
checkIfChartRequiresRawObservations(
selectedAggregationTypeArr,
selectedAggregationDuration
)
selectedAggregationOptionsAreValid &&
selectedBuildingDataPointsOptionsAreValid
) {
drawHeatmapBasedOnSelectedOptions(
selectedBuildingsDataPointsSamplingRateAbbrev,
observationsComboNestedArr,
extractedFormattedDatastreamProperties
);
} else {
throw new Error(
"This type of chart (Heatmap) does not support aggregated results"
);
}
}
if (selectedChartType === "Scatter Plot") {
// We are interested in raw observations
if (
checkIfChartRequiresRawObservations(
selectedAggregationTypeArr,
selectedAggregationDuration
)
selectedAggregationOptionsAreValid &&
selectedBuildingDataPointsOptionsAreValid
) {
drawScatterPlotFromChartSelection(
selectedBuildingsDataPointsSamplingRateAbbrev,
observationsComboNestedArr,
extractedFormattedDatastreamProperties
);
} else {
throw new Error(
"This type of chart (Scatter Plot) does not support aggregated results"
);
}
}
if (selectedChartType === "Line") {
// We are interested in raw observations or aggregated observations
// Raw observations
if (selectedAggregationTypeArr === "None (raw data)") {
if (selectedAggregationType === "None (raw data)") {
// Create formatted array(s) for observations
const formattedRawObservationsLineChartNestedArr =
observationsComboNestedArr.map((observationsArr) =>
......@@ -331,7 +335,7 @@ const drawChartUsingSelectedOptions = async function () {
// Aggregated observations
else {
drawLineChartBasedOnSelectedAggregationOptions(
selectedAggregationTypeArr,
selectedAggregationType,
selectedAggregationDuration,
observationsAggregationNestedArr,
selectedSamplingRateAbbrev,
......@@ -340,11 +344,12 @@ const drawChartUsingSelectedOptions = async function () {
);
}
}
if (selectedChartType === "Column") {
// We are interested in raw observations or aggregated observations
// Raw observations
if (selectedAggregationTypeArr === "None (raw data)") {
if (selectedAggregationType === "None (raw data)") {
// Create formatted array(s) for observations
const formattedRawObservationsColumnChartNestedArr =
observationsComboNestedArr.map((observationsArr) =>
......@@ -359,7 +364,7 @@ const drawChartUsingSelectedOptions = async function () {
// Aggregated observations
else {
drawColumnChartBasedOnSelectedAggregationOptions(
selectedAggregationTypeArr,
selectedAggregationType,
selectedAggregationDuration,
observationsAggregationNestedArr,
selectedSamplingRateAbbrev,
......@@ -368,7 +373,7 @@ const drawChartUsingSelectedOptions = async function () {
);
}
}
});
}
} catch (err) {
console.error(err);
} finally {
......
......@@ -2,10 +2,9 @@
import {
chartExportOptions,
createCombinedTextDelimitedByComma,
createFullTitleForLineOrColumnChart,
createSubtitleForChart,
createTooltipDateString,
extractSamplingRateFromDatastreamName,
} from "./chartHelpers.mjs";
/**
......@@ -122,9 +121,7 @@ const drawColumnChartHighcharts = function (
aggregationType
);
const textChartSubtitle = `Sampling rate(s): ${createCombinedTextDelimitedByComma(
extractSamplingRateFromDatastreamName(datastreamNamesArr)
)}`;
const textChartSubtitle = createSubtitleForChart(datastreamNamesArr);
Highcharts.chart("chart-column", {
chart: {
......
"use strict";
import { chartExportOptions } from "./chartHelpers.mjs";
import {
chartExportOptions,
createTitleForHeatmap,
createSubtitleForHeatmap,
} from "./chartHelpers.mjs";
/**
* Format the response from SensorThings API to make it suitable for use in a heatmap
......@@ -73,6 +77,10 @@ const drawHeatMapHighcharts = function (
const [PHENOMENON_NAME] = phenomenonNamesArr;
const [PHENOMENON_SYMBOL] = unitOfMeasurementSymbolsArr;
const TEXT_CHART_TITLE = createTitleForHeatmap(phenomenonNamesArr);
const TEXT_CHART_SUBTITLE = createSubtitleForHeatmap(datastreamNamesArr);
const {
minObsValue: MINIMUM_VALUE_COLOR_AXIS,
maxObsValue: MAXIMUM_VALUE_COLOR_AXIS,
......@@ -89,13 +97,13 @@ const drawHeatMapHighcharts = function (
},
title: {
text: DATASTREAM_DESCRIPTION,
text: TEXT_CHART_TITLE,
align: "left",
x: 40,
},
subtitle: {
text: DATASTREAM_NAME,
text: TEXT_CHART_SUBTITLE,
align: "left",
x: 40,
},
......
......@@ -224,6 +224,34 @@ const createCombinedTextDelimitedByComma = function (metadataPropertiesArr) {
return metadataPropertiesArr.join(", ");
};
/**
* Extracts the sampling rate substring from a datastream name string
* @param {Array} datastreamNamesArr An array of datastream name(s)
* @returns {Array} An array containing the sampling rate substring(s)
*/
const extractSamplingRateFromDatastreamName = function (datastreamNamesArr) {
// First split the Datastream name string based on a single space (" ").
// The sampling rate string is the last word in the resulting string.
// We then split the resulting string using the ':' character.
// Our interest is also in the last word in the resulting string
return datastreamNamesArr.map((datastreamName) =>
datastreamName.split(" ").pop().split(":").pop()
);
};
/**
* Extract the building ID substring from a datastream name string
*
* @param {Array} datastreamNamesArr An array of datastream name(s)
* @returns {Array} An array containing the building ID substring(s)
*/
const extractBuildingIdFromDatastreamName = function (datastreamNamesArr) {
// The building ID string is the first word in the Datastream name string
return datastreamNamesArr.map((datastreamName) =>
datastreamName.split(" ").shift()
);
};
/**
* Create a partial string for a line chart or column chart title
* @param {String} aggregationInterval The aggregation interval as a string, either "daily" or "monthly"
......@@ -245,7 +273,7 @@ const createPartialTitleForLineOrColumnChart = function (
/**
* Create a full string for a line chart or column chart title
* @param {Array} datastreamNamesArr An array of datastream names as strings
* @param {Array} phenomenonNamesArr An array of phenomenon names as strings
* @param {String} aggregationInterval The aggregation interval as a string, either "daily" or "monthly"
* @param {String} aggregationType The aggregation type as a string, either "sum" or "average"
* @returns {String} Full string for chart title
......@@ -269,6 +297,54 @@ const createFullTitleForLineOrColumnChart = function (
)}: ${createCombinedTextDelimitedByComma(phenomenonNamesArr)}`;
};
/**
* Create a title for a heatmap
*
* @param {Array} phenomenonNamesArr An array of phenomenon names as strings
* @returns {String} A string that represents the heatmap title
*/
const createTitleForHeatmap = function (phenomenonNamesArr) {
return createCombinedTextDelimitedByComma(phenomenonNamesArr);
};
/**
* Create a subtitle for the following charts: column chart, line chart and scatter plot
*
* @param {Array} datastreamNamesArr An array of datastream name(s)
* @returns {String} A subtitle string
*/
const createSubtitleForChart = function (datastreamNamesArr) {
// Case 1: We only have one sampling rate string
if (datastreamNamesArr.length === 1) {
return `Sampling rate: ${createCombinedTextDelimitedByComma(
extractSamplingRateFromDatastreamName(datastreamNamesArr)
)}`;
}
// Case 2: We have more than one sampling rate string
else if (datastreamNamesArr.length > 1) {
return `Sampling rate(s): ${createCombinedTextDelimitedByComma(
extractSamplingRateFromDatastreamName(datastreamNamesArr)
)} respectively`;
}
};
/**
* Create a subtitle for a heatmap which is different from the subtitles used for the other
* types of charts, i.e. column charts, line charts and scatter plots
*
* @param {Array} datastreamNamesArr An array of datastream name(s)
* @returns {String} A subtitle string
*/
const createSubtitleForHeatmap = function (datastreamNamesArr) {
// Note: the `datastreamNamesArr` here contains only one element
// We use the `createCombinedTextDelimitedByComma` function to "spread" the resulting arrays
return `Building, Sampling rate: ${createCombinedTextDelimitedByComma(
extractBuildingIdFromDatastreamName(datastreamNamesArr)
)}, ${createCombinedTextDelimitedByComma(
extractSamplingRateFromDatastreamName(datastreamNamesArr)
)}`;
};
/**
* Creates a date string that is used in a shared tooltip for a line or column chart
* @param {Number} pointXAxisValue The x-axis value (Unix timestamp) which is common for a set of data points
......@@ -286,18 +362,6 @@ const createTooltipDateString = function (
return `${Highcharts.dateFormat("%b %Y", pointXAxisValue)}`;
};
/**
* Extracts the sampling rate substring from a datastream name string
* @param {Array} datastreamNamesArr An array of datastream name(s)
* @returns {Array} An array containing the sampling rate substring(s)
*/
const extractSamplingRateFromDatastreamName = function (datastreamNamesArr) {
// The sampling rate string is the last word in the Datastream name string
return datastreamNamesArr.map((datastreamName) =>
datastreamName.split(" ").pop()
);
};
/**
* Remove the transparency (alpha channel) from a color
* @param {String} rgbaColor A color expressed in RGBA format
......@@ -313,8 +377,10 @@ export {
createCombinedTextDelimitedByAmpersand,
createCombinedTextDelimitedByComma,
createFullTitleForLineOrColumnChart,
createTitleForHeatmap,
createSubtitleForChart,
createSubtitleForHeatmap,
createTooltipDateString,
convertHexColorToRGBColor,
extractSamplingRateFromDatastreamName,
removeTransparencyFromColor,
};
......@@ -3,8 +3,8 @@
import {
chartExportOptions,
createFullTitleForLineOrColumnChart,
createSubtitleForChart,
createTooltipDateString,
extractSamplingRateFromDatastreamName,
} from "./chartHelpers.mjs";
/**
......@@ -114,9 +114,7 @@ const drawLineChartHighcharts = function (
aggregationType
);
const textChartSubtitle = `Sampling rate(s): ${createCombinedTextForLineChartTitles(
extractSamplingRateFromDatastreamName(datastreamNamesArr)
)}`;
const textChartSubtitle = createSubtitleForChart(datastreamNamesArr);
// Create the array of series options object(s)
const seriesOptionsArr = createSeriesOptionsForLineChart(
......
......@@ -6,7 +6,7 @@ import {
convertHexColorToRGBColor,
createCombinedTextDelimitedByAmpersand,
createCombinedTextDelimitedByComma,
extractSamplingRateFromDatastreamName,
createSubtitleForChart,
removeTransparencyFromColor,
} from "./chartHelpers.mjs";
......@@ -200,9 +200,7 @@ const drawScatterPlotHighcharts = function (
const CHART_TITLE =
createCombinedTextForScatterPlotTitles(phenomenonNamesArr);
const CHART_SUBTITLE = `Sampling rate(s): ${createCombinedTextDelimitedByComma(
extractSamplingRateFromDatastreamName(datastreamNamesArr)
)}`;
const CHART_SUBTITLE = createSubtitleForChart(datastreamNamesArr);
const X_AXIS_TITLE = createXAxisTitleTextScatterPlot(
phenomenonNamesArr,
......
......@@ -109,19 +109,23 @@ const getSelectedOptionsFromAllDropDownLists = function () {
);
// Ensure that all the options have at least one selection
if (
selectedBuildingDataPointOptionsSplitArr.length === 0 ||
selectedAggregationOptionsArr.length === 0 ||
selectedSamplingRateArr.length === 0 ||
selectedChartTypeArr.length === 0
)
return;
if (selectedChartTypeArr.length === 0)
throw new Error("Please ensure that the chart type is selected");
if (selectedBuildingDataPointOptionsSplitArr.length === 0)
throw new Error("Please ensure that at least one data point is selected");
if (selectedSamplingRateArr.length === 0)
throw new Error("Please ensure that the aggregation type is selected");
if (selectedSamplingRateArr.length === 0)
throw new Error("Please ensure that the sampling rate is selected");
return [
selectedChartTypeArr,
selectedBuildingDataPointOptionsSplitArr,
selectedAggregationOptionsArr,
selectedSamplingRateArr,
selectedChartTypeArr,
];
};
......@@ -296,6 +300,82 @@ const checkIfChartRequiresRawObservations = function (
}
};
/**
* Check if the selected building(s) + data point(s) options are valid for
* drawing either a heatmp or scatter plot. If these options are
* invalid, throw an error
*
* @param {Array} selectedChartTypeArr An array of string(s) representing the selected chart type(s)
* @param {Array} selectedBuildingsDataPointsSamplingRateAbbrevNestedArr An array that is made up of sub array(s) whose elements are strings representing the selected buildings, data points and sampling rates
* @returns {Boolean} true, if there are no errors thrown
*/
const checkIfSelectedBuildingDataPointsOptionsAreValid = function (
selectedChartTypeArr,
selectedBuildingsDataPointsSamplingRateAbbrevNestedArr
) {
for (const selectedChartType of selectedChartTypeArr) {
// A heatmap can only visualize one data point
if (selectedChartType === "Heatmap") {
if (selectedBuildingsDataPointsSamplingRateAbbrevNestedArr.length === 1)
return true;
else if (
selectedBuildingsDataPointsSamplingRateAbbrevNestedArr.length > 1
) {
throw new Error("A heatmap can only display one data point at a time");
}
}
// A scatter plot requires at least two data points
if (selectedChartType === "Scatter Plot") {
if (selectedBuildingsDataPointsSamplingRateAbbrevNestedArr.length >= 2)
return true;
else if (
selectedBuildingsDataPointsSamplingRateAbbrevNestedArr.length < 2
) {
throw new Error("A scatter plot requires at least two data points");
}
}
}
};
/**
* Check if the selected aggregation type options are valid for
* drawing either a heatmp or scatter plot. If these options are
* invalid, throw an error
*
* @param {Array} selectedChartTypeArr An array of string(s) representing the selected chart type(s)
* @param {String} selectedAggregationType The selected aggregation type
* @param {String} selectedAggregationDuration The selected aggregation duration
* @returns {Boolean} true, if there are no errors thrown
*/
const checkIfSelectedAggregationOptionsAreValid = function (
selectedChartTypeArr,
selectedAggregationType,
selectedAggregationDuration
) {
for (const selectedChartType of selectedChartTypeArr) {
if (
selectedChartType === "Heatmap" ||
selectedChartType === "Scatter Plot"
) {
// For both chart types, we are interested in raw observations
if (
checkIfChartRequiresRawObservations(
selectedAggregationType,
selectedAggregationDuration
)
)
return true;
// Throw error if we attempt to use aggregated observations
else {
throw new Error(
"The selected chart type does not support aggregated results"
);
}
}
}
};
/**
* Get the abbreviated form of building IDs, phenomenon names and sensor sampling rates
* @param {String} buildingFullForm A string representation of the full form of a building ID
......@@ -380,9 +460,14 @@ const getBuildingSensorSamplingRateAbbreviation = function (
const getAbbreviationsForSelectedOptionsFromAllDropDownLists = function (
allSelectedOptionsArr
) {
// Note: The sampling rate array is the third array, therefore we skip one element
const [selectedBuildingDataPointOptionsSplitArr, , selectedSamplingRateArr] =
allSelectedOptionsArr;
// Note: The buildings + data points array is the second element and
// the sampling rate array is the fourth element, therefore we skip the first and third elementa
const [
,
selectedBuildingDataPointOptionsSplitArr,
,
selectedSamplingRateArr,
] = allSelectedOptionsArr;
// The building is the first element
const selectedBuildingsArr = selectedBuildingDataPointOptionsSplitArr.map(
......@@ -417,6 +502,7 @@ export {
deleteTemperatureDifferenceOptions,
extractTemperatureDifferenceOptions,
extractBuildingPlusSamplingRate,
checkIfChartRequiresRawObservations,
checkIfSelectedBuildingDataPointsOptionsAreValid,
checkIfSelectedAggregationOptionsAreValid,
getAbbreviationsForSelectedOptionsFromAllDropDownLists,
};
......@@ -29,75 +29,58 @@ import { extractPropertiesFromFormattedDatastreamMetadata } from "./fetchedDataP
/**
* Draw a heatmap based on the selected options from a drop-down list
*
* @param {Array} selectedBuildingsDataPointsSamplingRateAbbrevArr An array which contains one or more nested arrays of abbreviations of building(s), data point(s) and sampling rate(s)
* @param {Array} observationsComboNestedArr An array that contains non-computed (raw) observations and computed (temperature difference, dT) observations
* @param {Object} extractedFormattedDatastreamProperties An object that contains array(s) of formatted Datastream properties
* @returns {undefined} undefined
*/
const drawHeatmapBasedOnSelectedOptions = function (
selectedBuildingsDataPointsSamplingRateAbbrevArr,
observationsComboNestedArr,
extractedFormattedDatastreamProperties
) {
if (selectedBuildingsDataPointsSamplingRateAbbrevArr.length === 1) {
// Create formatted array(s) for observations
const formattedObservationsHeatMapNestedArr =
observationsComboNestedArr.map((observationsArr) =>
formatSensorThingsApiResponseForHeatMap(observationsArr)
);
// Note: The resulting array is nested and is not suitable for heatmap,
// extract the nested array
const [formattedObservationsHeatMapArr] =
formattedObservationsHeatMapNestedArr;
drawHeatMapHighcharts(
formattedObservationsHeatMapArr,
extractedFormattedDatastreamProperties
);
} else if (selectedBuildingsDataPointsSamplingRateAbbrevArr.length < 1) {
throw new Error("Please select at least one data point");
} else {
throw new Error(
"This type of chart (Heatmap) can only display one data point at a time"
);
}
// Create formatted array(s) for observations
const formattedObservationsHeatMapNestedArr = observationsComboNestedArr.map(
(observationsArr) =>
formatSensorThingsApiResponseForHeatMap(observationsArr)
);
// Note: The resulting array is nested and is not suitable for heatmap,
// extract the nested array
const [formattedObservationsHeatMapArr] =
formattedObservationsHeatMapNestedArr;
drawHeatMapHighcharts(
formattedObservationsHeatMapArr,
extractedFormattedDatastreamProperties
);
};
/**
* Draw a scatter plot based on the selected options from a drop-down list
*
* @param {Array} selectedBuildingsDataPointsSamplingRateAbbrevArr An array which contains one or more nested arrays of abbreviations of building(s), data point(s) and sampling rate(s)
* @param {Array} observationsComboNestedArr An array that contains non-computed (raw) observations and computed (temperature difference, dT) observations
* @param {Object} extractedFormattedDatastreamProperties An object that contains array(s) of formatted Datastream properties
* @returns {undefined} undefined
*/
const drawScatterPlotFromChartSelection = function (
selectedBuildingsDataPointsSamplingRateAbbrevArr,
observationsComboNestedArr,
extractedFormattedDatastreamProperties
) {
// Check the length of buildings + data points + sampling rate array
if (selectedBuildingsDataPointsSamplingRateAbbrevArr.length >= 2) {
// Extract values for x-axis and y-axis
// x-axis values are first element of nested observations array
const [obsXAxisArr] = observationsComboNestedArr.slice(0, 1);
// y-axis values are rest of elements of nested observations array
const obsYAxisNestedArr = observationsComboNestedArr.slice(1);
// Create formatted array(s) for observations
const formattedObservationsScatterPlotArr = obsYAxisNestedArr.map(
(obsYAxisArr) =>
formatSensorThingsApiResponseForScatterPlot(obsXAxisArr, obsYAxisArr)
);
drawScatterPlotHighcharts(
formattedObservationsScatterPlotArr,
extractedFormattedDatastreamProperties
);
} else {
throw new Error("A scatter plot chart requires at least two data points");
}
// Extract values for x-axis and y-axis
// x-axis values are first element of nested observations array
const [obsXAxisArr] = observationsComboNestedArr.slice(0, 1);
// y-axis values are rest of elements of nested observations array
const obsYAxisNestedArr = observationsComboNestedArr.slice(1);
// Create formatted array(s) for observations
const formattedObservationsScatterPlotArr = obsYAxisNestedArr.map(
(obsYAxisArr) =>
formatSensorThingsApiResponseForScatterPlot(obsXAxisArr, obsYAxisArr)
);
drawScatterPlotHighcharts(
formattedObservationsScatterPlotArr,
extractedFormattedDatastreamProperties
);
};
/**
......
Supports Markdown
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