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
parents 6838b0dd 0c48cb36
......@@ -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
);
};
/**
......
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