Commit dc2e7ae0 authored by Pithon Kabiro's avatar Pithon Kabiro
Browse files

Merge branch 'wip_chart-column-2' into 'master'

Update column chart

Refine column chart drawing logic

See merge request !10
parents 9e9002e7 2c5e4d70
......@@ -25,11 +25,12 @@ import {
drawColumnChartHighcharts,
} from "./src_modules/chartColumn.mjs";
import { getMetadataPlusObservationsFromSingleOrMultipleDatastreams } from "./src_modules/fetchData.mjs";
import {
formatDatastreamMetadataForChart,
extractPropertiesFromFormattedDatastreamMetadata,
getMetadataPlusObservationsFromSingleOrMultipleDatastreams,
} from "./src_modules/fetchData.mjs";
} from "./src_modules/fetchedDataProcess.mjs";
import { calculateVorlaufMinusRuecklaufTemperature } from "./src_modules/calculateTemperatureDiff.mjs";
......@@ -73,13 +74,14 @@ const drawHeatmapHCUsingTempDifference = async function () {
// Format the metadata
const formattedTempDiff225MetadataNestedArr =
metadataTemperatureDiff225NestedArr.map((metadataObj) =>
formatDatastreamMetadataForChart(metadataObj)
formatDatastreamMetadataForChart(metadataObj, false)
);
// Extract the formatted metadata properties
const extractedFormattedTempDiff225Properties =
extractPropertiesFromFormattedDatastreamMetadata(
formattedTempDiff225MetadataNestedArr
formattedTempDiff225MetadataNestedArr,
false
);
// First need to extract the formatted observations from the nested array
......@@ -127,13 +129,14 @@ const drawScatterPlotHCTest2 = async function () {
// Create formatted array(s) for metadata
const formattedMetadataNestedArr = metadataNestedArr.map((metadataObj) =>
formatDatastreamMetadataForChart(metadataObj)
formatDatastreamMetadataForChart(metadataObj, false)
);
// Extract the formatted metadata properties
const extractedFormattedDatastreamProperties =
extractPropertiesFromFormattedDatastreamMetadata(
formattedMetadataNestedArr
formattedMetadataNestedArr,
false
);
drawScatterPlotHighcharts(
......@@ -175,13 +178,14 @@ const testLineChartMultipleSeries = async function () {
// Format the metadata
const formattedMetadataNestedArr = metadataNestedArr.map((metadataArr) =>
formatDatastreamMetadataForChart(metadataArr)
formatDatastreamMetadataForChart(metadataArr, false)
);
// Extract the formatted metadata properties
const extractedFormattedDatastreamProperties =
extractPropertiesFromFormattedDatastreamMetadata(
formattedMetadataNestedArr
formattedMetadataNestedArr,
false
);
drawLineChartHighcharts(
......@@ -260,13 +264,16 @@ const drawColumnChartMonthlySumTest = async function () {
// Format the metadata
const formattedMetadataNestedArr = metadataNestedArr.map((metadataObj) =>
formatDatastreamMetadataForChart(metadataObj)
formatDatastreamMetadataForChart(metadataObj, true)
);
// Extract the formatted metadata properties
const extractedFormattedDatastreamProperties =
extractPropertiesFromFormattedDatastreamMetadata(
formattedMetadataNestedArr
formattedMetadataNestedArr,
true,
"monthly",
"sum"
);
drawColumnChartHighcharts(
......@@ -339,13 +346,16 @@ const drawColumnChartDailySumTest = async function () {
// Format the metadata
const formattedMetadataNestedArr = metadataNestedArr.map((metadataObj) =>
formatDatastreamMetadataForChart(metadataObj)
formatDatastreamMetadataForChart(metadataObj, true)
);
// Extract the formatted metadata properties
const extractedFormattedDatastreamProperties =
extractPropertiesFromFormattedDatastreamMetadata(
formattedMetadataNestedArr
formattedMetadataNestedArr,
true,
"daily",
"sum"
);
drawColumnChartHighcharts(
......@@ -423,14 +433,17 @@ const drawLineChartMonthlyAverageTest = async function () {
);
// Format the metadata
// NOTE: we use the `false` flag here because line charts are meant to work with non-aggregated data
const formattedMetadataNestedArr = metadataNestedArr.map((metadataObj) =>
formatDatastreamMetadataForChart(metadataObj)
formatDatastreamMetadataForChart(metadataObj, false)
);
// Extract the formatted metadata properties
// NOTE: we use the `false` flag here because line charts are meant to work with non-aggregated data
const extractedFormattedDatastreamProperties =
extractPropertiesFromFormattedDatastreamMetadata(
formattedMetadataNestedArr
formattedMetadataNestedArr,
false
);
drawLineChartHighcharts(
......@@ -502,14 +515,17 @@ const drawLineChartDailyAverageTest = async function () {
);
// Format the metadata
// NOTE: we use the `false` flag here because line charts are meant to work with non-aggregated data
const formattedMetadataNestedArr = metadataNestedArr.map((metadataObj) =>
formatDatastreamMetadataForChart(metadataObj)
formatDatastreamMetadataForChart(metadataObj, false)
);
// Extract the formatted metadata properties
// NOTE: we use the `false` flag here because line charts are meant to work with non-aggregated data
const extractedFormattedDatastreamProperties =
extractPropertiesFromFormattedDatastreamMetadata(
formattedMetadataNestedArr
formattedMetadataNestedArr,
false
);
drawLineChartHighcharts(
......
......@@ -5,11 +5,12 @@ import {
QUERY_PARAMS_COMBINED,
} from "./src_modules/baseUrlPlusQueryParams.mjs";
import { getMetadataPlusObservationsFromSingleOrMultipleDatastreams } from "./src_modules/fetchData.mjs";
import {
formatDatastreamMetadataForChart,
extractPropertiesFromFormattedDatastreamMetadata,
getMetadataPlusObservationsFromSingleOrMultipleDatastreams,
} from "./src_modules/fetchData.mjs";
} from "./src_modules/fetchedDataProcess.mjs";
import {
formatSensorThingsApiResponseForLineChart,
......@@ -84,7 +85,7 @@ const getUniqueValues = function (dataArr, index) {
/**
* Populate the HTML elements that make up a drop down list
* @param {String} element String corresponding to the ID of a drop down HTML element
* @param {Object} element HTMLElement object of a drop down list element
* @param {Array} uniqueValuesArr An array of unique values
* @returns {undefined}
*/
......@@ -100,8 +101,8 @@ const populateDropDown = function (element, uniqueValuesArr) {
/**
* Filter an array using filter strings of variable length
* @param {*} dataArr Input array
* @param {*} filtersAsArray An array of filter strings
* @param {Array} dataArr Input array
* @param {Array} filtersAsArray An array of filter strings
* @returns {Array} An array that contains the filter result
*/
const filterArray = function (dataArr, filtersAsArray) {
......@@ -112,9 +113,9 @@ const filterArray = function (dataArr, filtersAsArray) {
/**
* Create a drop down list in the HTML document
* @param {*} dataArr Input array
* @param {*} filtersAsArray An array of strings tp be used as filters
* @param {*} targetElement String corresponding to the ID of a drop down HTML element
* @param {Array} dataArr Input array
* @param {Array} filtersAsArray An array of strings tp be used as filters
* @param {Object} targetElement HTMLElement object of a drop down list element
* @returns {undefined}
*/
const makeDropDown = function (dataArr, filtersAsArray, targetElement) {
......@@ -292,12 +293,15 @@ const selectChartTypeFromDropDown = async function () {
// Create formatted array(s) for metadata - same for both chart types
const formattedMetadataArr = metadataNestedArr.map((metadataObj) =>
formatDatastreamMetadataForChart(metadataObj)
formatDatastreamMetadataForChart(metadataObj, false)
);
// Extract the formatted metadata properties
const extractedFormattedDatastreamProperties =
extractPropertiesFromFormattedDatastreamMetadata(formattedMetadataArr);
extractPropertiesFromFormattedDatastreamMetadata(
formattedMetadataArr,
false
);
if (selectedChartType === "Line") {
drawLineChartHighcharts(
......
......@@ -14,7 +14,7 @@ const calculateSumOfObservationValuesWithinDatesInterval = function (
obsValuesForDaysIntervalArr
) {
return obsValuesForDaysIntervalArr.reduce(
(accumulator, currentValue) => accumulator + currentValue
(accumulator, obsValue) => accumulator + obsValue
);
};
......@@ -42,7 +42,7 @@ const calculateSumOfObservationValuesWithinMonthInterval = function (
obsValuesForMonthIntervalArr
) {
return obsValuesForMonthIntervalArr.reduce(
(accumulator, currentValue) => accumulator + currentValue
(accumulator, obsValue) => accumulator + obsValue
);
};
......
"use strict";
import {
extractPhenomenonNameFromDatastreamName,
getMetadataPlusObservationsFromSingleOrMultipleDatastreams,
} from "./fetchData.mjs";
import { getMetadataPlusObservationsFromSingleOrMultipleDatastreams } from "./fetchData.mjs";
import { extractPhenomenonNameFromDatastreamName } from "./fetchedDataProcess.mjs";
/**
* Calculate the temperature difference, dT, between Vorlauf temperature [VL] and Rücklauf temperature [RL] (i.e., dT = VL - RL)
......
"use strict";
import { chartExportOptions } from "./chartHelpers.mjs";
import {
chartExportOptions,
createCombinedTextDelimitedByComma,
extractSamplingRateFromDatastreamName,
} from "./chartHelpers.mjs";
import { extractPhenomenonNameFromDatastreamName } from "./fetchedDataProcess.mjs";
/**
* Format a computed aggregation result to make it suitable for a column chart
......@@ -30,20 +36,19 @@ const formatAggregationResultForColumnChart = function (
/**
* Creates an options object for each series drawn in a column chart
* @param {Array} formattedAggregatedResultForColumnChart An array of formatted aggregated result array(s) from one or more datastreams
* @param {Array} phenomenonNamesArr An array of phenomenon name(s)
* @param {Array} phenomenonSymbolsArr An array of phenomenon symbol(s)
* @param {Array} buildingIdsPhenomenonNamesArr An array of string(s) made up of building ID(s) + phenomenon name(s)
* @returns {Array} An array made up of series options object(s)
*/
const createSeriesOptionsForColumnChart = function (
formattedAggregatedResultForColumnChart,
phenomenonNamesArr,
phenomenonSymbolsArr
buildingIdsPhenomenonNamesArr
) {
// Create an array of seriesOptions objects
// Assumes that the observation array of arrays, phenomenon names array and phenomenon symbols array are of equal length
// Use one of the arrays for looping
if (
formattedAggregatedResultForColumnChart.length !== phenomenonNamesArr.length
formattedAggregatedResultForColumnChart.length !==
buildingIdsPhenomenonNamesArr.length
)
throw new Error(
"The observations array and phenomenon names array have different lengths"
......@@ -52,7 +57,7 @@ const createSeriesOptionsForColumnChart = function (
return formattedAggregatedResultForColumnChart.map(
(formattedAggResArray, i) => {
return {
name: `${phenomenonNamesArr[i]} (${phenomenonSymbolsArr[i]})`,
name: `${buildingIdsPhenomenonNamesArr[i]}`,
data: formattedAggResArray,
turboThreshold: Number.MAX_VALUE, // #3404, remove after 4.0.5 release
};
......@@ -60,6 +65,64 @@ const createSeriesOptionsForColumnChart = function (
);
};
/**
* Creates a date string that is used as a header for a shared tooltip string for a column chart
* @param {Number} pointXAxisValue The x-axis value (Unix timestamp) which is common for a set of data points
* @param {String} aggregationInterval The aggregation interval as a string, either "daily" or "monthly"
* @returns {String} A calendar date or calendar month string that is common for a set of data points
*/
const createHeaderDateString = function (pointXAxisValue, aggregationInterval) {
if (aggregationInterval === "daily")
return `${Highcharts.dateFormat("%A, %b %e, %Y", pointXAxisValue)}`;
else if (aggregationInterval === "monthly")
return `${Highcharts.dateFormat("%b %Y", pointXAxisValue)}`;
};
/**
* Create a partial string for a column's chart title
* @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} Partial string for chart title
*/
const createPartialTitleForColumnChart = function (
aggregationInterval,
aggregationType
) {
// Case 1: No aggregation; return empty string
if (!aggregationInterval && !aggregationType) return ``;
// Case 2: Aggregation; capitalize the first characters
return `${
aggregationInterval.slice(0, 1).toUpperCase() + aggregationInterval.slice(1)
} ${aggregationType.slice(0, 1).toUpperCase() + aggregationType.slice(1)}`;
};
/**
* Create a full string for a column's chart title
* @param {Array} datastreamNamesArr An array of datastream 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
*/
const createFullTitleForColumnChart = function (
phenomenonNamesArr,
aggregationInterval,
aggregationType
) {
// Case 1: No aggregation; create a comma separated string of phenomenon names
if (!aggregationInterval && !aggregationType)
return `${createPartialTitleForColumnChart(
aggregationInterval,
aggregationType
)}${createCombinedTextDelimitedByComma(phenomenonNamesArr)}`;
// Case 2: Aggregation
return `${createPartialTitleForColumnChart(
aggregationInterval,
aggregationType
)} ${phenomenonNamesArr[0]}`;
};
/**
* Draw a column chart using Highcharts library
* @param {Array} formattedAggResultArraysForColumnChart An array made up of formatted aggregated result array(s) suitable for use in a column chart
......@@ -73,16 +136,39 @@ const drawColumnChartHighcharts = function (
// Arrays of datastream properties
const {
datastreamNamesArr,
phenomenonNamesArr,
buildingIdsPhenomenonNamesArr,
unitOfMeasurementSymbolsArr,
aggregationInterval,
aggregationType,
} = extractedFormattedDatastreamProperties;
// Create an array of phenomenon names
const phenomenonNamesArr = datastreamNamesArr.map((datastreamName) =>
extractPhenomenonNameFromDatastreamName(datastreamName)
);
// Create the array of series options object(s)
const seriesOptionsArr = createSeriesOptionsForColumnChart(
formattedAggResultArraysForColumnChart,
buildingIdsPhenomenonNamesArr
);
// Assume that we will be comparing similar phenomena, so we can use the first phenomenon name
const phenomenonName = phenomenonNamesArr[0];
// Assume that we will be comparing similar phenomena, so we can use the first phenomenon symbol
const unitOfMeasurementSymbol = unitOfMeasurementSymbolsArr[0];
const textChartTitle = createFullTitleForColumnChart(
phenomenonNamesArr,
unitOfMeasurementSymbolsArr
aggregationInterval,
aggregationType
);
const textChartSubtitle = `Sampling rate(s): ${createCombinedTextDelimitedByComma(
extractSamplingRateFromDatastreamName(datastreamNamesArr)
)}`;
Highcharts.chart("chart-column", {
chart: {
type: "column",
......@@ -90,11 +176,11 @@ const drawColumnChartHighcharts = function (
},
title: {
text: "Monthly Average Rainfall",
text: textChartTitle,
},
subtitle: {
text: "Source: WorldClimate.com",
text: textChartSubtitle,
},
xAxis: {
......@@ -110,21 +196,23 @@ const drawColumnChartHighcharts = function (
},
tooltip: {
headerFormat: `
<span style="font-size:10px">{point.key}</span>
<table>
`,
pointFormat: `
<tr>
<td style="color:{series.color};padding:0">{series.name}: </td>
<td style="padding:0"><b>{point.y:.1f} mm</b></td>
</tr>
`,
footerFormat: `
</table>
`,
formatter() {
// Our tooltip is shared
// this.x -- common for all points
// this.points -- an array containing properties for each series
// Note that our `reduce` method is in this format:
// ((accumulator, currentValue, currentIndex) => {...}, initialValue)
return this.points.reduce(
(accumulator, point, i) =>
`${accumulator} <br/> <span style="color:${point.color}">${
point.series.name
}</span>: <b>${point.y.toFixed(2)} ${
unitOfMeasurementSymbolsArr[i]
}</b>`,
`${createHeaderDateString(this.x, aggregationInterval)}`
);
},
shared: true,
useHTML: true,
},
plotOptions: {
......
......@@ -81,99 +81,6 @@ const getMetadataFromMultipleDatastreams = async function (datastreamsUrlArr) {
}
};
/**
* Match the unitOfMeasurement's string representation of a symbol to an actual symbol, where necessary
* @param {String} unitOfMeasurementSymbolString String representation of the unitOfMeasurement's symbol
* @returns {String} The unitOfMeasurement's symbol
*/
const matchUnitOfMeasurementSymbolStringToSymbol = function (
unitOfMeasurementSymbolString
) {
const unicodeCodePointDegreeSymbol = "\u00B0";
const unicodeCodePointSuperscriptThree = "\u00B3";
if (unitOfMeasurementSymbolString === "degC")
return `${unicodeCodePointDegreeSymbol}C`;
if (unitOfMeasurementSymbolString === "m3/h")
return `m${unicodeCodePointSuperscriptThree}/h`;
// If no symbol exists
return unitOfMeasurementSymbolString;
};
/**
* Extract the phenomenon name from a Datastream's name
* @param {String} datastreamName A string representing the Datastream's name
* @returns {String} The extracted phenomenon name
*/
const extractPhenomenonNameFromDatastreamName = function (datastreamName) {
const regex = /\/ (.*) DS/;
return datastreamName.match(regex)[1]; // use second element in array
};
/**
* Format the response containing a Datastream's metadata from Sensorthings API
* @param {Object} datastreamMetadata An object containing a Datastream's metadata
* @returns {Object} An object containing the formatted metadata that is suitable for use in a line chart or heatmap
*/
const formatDatastreamMetadataForChart = function (datastreamMetadata) {
const {
description: datastreamDescription,
name: datastreamName,
unitOfMeasurement,
} = datastreamMetadata;
// Extract phenomenon name from Datastream name
const phenomenonName =
extractPhenomenonNameFromDatastreamName(datastreamName);
// Get the unitOfMeasurement's symbol
const unitOfMeasurementSymbol = matchUnitOfMeasurementSymbolStringToSymbol(
unitOfMeasurement.symbol
);
return {
datastreamDescription,
datastreamName,
phenomenonName,
unitOfMeasurementSymbol,
};
};
/**
* Extract the properties that make up the formatted datastream metadata object(s)
* @param {Array} formattedDatastreamsMetadataArr An array of formatted metadata object(s) from one or more datastreams
* @returns {Object} An object that contains array(s) of formatted datastream metadata properties
*/
const extractPropertiesFromFormattedDatastreamMetadata = function (
formattedDatastreamsMetadataArr
) {
// Create arrays from the properties of the formatted datastream metadata
const datastreamDescriptionsArr = formattedDatastreamsMetadataArr.map(
(datastreamMetadata) => datastreamMetadata.datastreamDescription
);
const datastreamNamesArr = formattedDatastreamsMetadataArr.map(
(datastreamMetadata) => datastreamMetadata.datastreamName
);
const phenomenonNamesArr = formattedDatastreamsMetadataArr.map(
(datastreamMetadata) => datastreamMetadata.phenomenonName
);
const unitOfMeasurementSymbolsArr = formattedDatastreamsMetadataArr.map(
(datastreamMetadata) => datastreamMetadata.unitOfMeasurementSymbol
);
return {
datastreamDescriptionsArr,
datastreamNamesArr,
phenomenonNamesArr,
unitOfMeasurementSymbolsArr,
};
};
/**
* 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
......@@ -321,9 +228,4 @@ const getMetadataPlusObservationsFromSingleOrMultipleDatastreams =
}
};
export {
extractPhenomenonNameFromDatastreamName,
formatDatastreamMetadataForChart,
extractPropertiesFromFormattedDatastreamMetadata,
getMetadataPlusObservationsFromSingleOrMultipleDatastreams,
};
export { getMetadataPlusObservationsFromSingleOrMultipleDatastreams };
"use strict";
/**
* Match the unitOfMeasurement's string representation of a symbol to an actual symbol, where necessary
* @param {String} unitOfMeasurementSymbolString String representation of the unitOfMeasurement's symbol
* @returns {String} The unitOfMeasurement's symbol
*/
const matchUnitOfMeasurementSymbolStringToSymbol = function (
unitOfMeasurementSymbolString
) {
const unicodeCodePointDegreeSymbol = "\u00B0";
const unicodeCodePointSuperscriptThree = "\u00B3";
if (unitOfMeasurementSymbolString === "degC")
return `${unicodeCodePointDegreeSymbol}C`;
if (unitOfMeasurementSymbolString === "m3/h")
return `m${unicodeCodePointSuperscriptThree}/h`;
// If no symbol exists
return unitOfMeasurementSymbolString;
};
/**
* Extract the phenomenon name from a Datastream's name
* @param {String} datastreamName A string representing the Datastream's name
* @returns {String} The extracted phenomenon name
*/
const extractPhenomenonNameFromDatastreamName = function (datastreamName) {
const regex = /\/ (.*) DS/;
return datastreamName.match(regex)[1]; // use second element in array
};
/**
* Extract the building Id and phenomenon name from a Datastream's name
* @param {String} datastreamName A string representing the Datastream's name
* @returns {String} The extracted building ID and phenomenon name
*/
const extractBuildingIdPhenomenonNameFromDatastreamName = function (
datastreamName
) {
// The negative index should remove these nine characters: ` DS:60min`
return datastreamName.slice(0, -9);
};
/**
* Format the response containing a Datastream's metadata from Sensorthings API
* @param {Object} datastreamMetadata An object containing a Datastream's metadata
* @param {Boolean} isMetadataForAggregation A flag to determine if the datastream metadata will be used for aggregation. Set to `true` if metadata will be used for aggregation, `false` if not
* @returns {Object} An object containing the formatted metadata that is suitable for use in a chart
*/
const formatDatastreamMetadataForChart = function (
datastreamMetadata,
isMetadataForAggregation
) {
if (
datastreamMetadata === undefined ||
isMetadataForAggregation === undefined
)
throw new Error(
"This function expects two arguments, ensure that both have been supplied"
);
const {
description: datastreamDescription,
name: datastreamName,
unitOfMeasurement,
} = datastreamMetadata;
// Extract phenomenon name from Datastream name
const phenomenonName =
extractPhenomenonNameFromDatastreamName(datastreamName);
// Extract building ID + phenomenon name from Datastream name
const buildingIdPhenomenonName =
extractBuildingIdPhenomenonNameFromDatastreamName(datastreamName);
// Get the unitOfMeasurement's symbol
const unitOfMeasurementSymbol = matchUnitOfMeasurementSymbolStringToSymbol(
unitOfMeasurement.symbol
);
// Case 1: Metadata NOT USED for aggregation; "isMetadataForAggregation" = false
if (!isMetadataForAggregation)
return {
datastreamDescription,
datastreamName,
phenomenonName,
unitOfMeasurementSymbol,
};
// Case 2: Metadata USED for aggregation; "isMetadataForAggregation" = true
return {
datastreamDescription,
datastreamName,
buildingIdPhenomenonName,
unitOfMeasurementSymbol,
};
};
/**
* Extract the properties that make up the formatted datastream metadata object(s)
* @param {Array} formattedDatastreamsMetadataArr An array of formatted metadata object(s) from one or more datastreams
* @param {Boolean} isMetadataForAggregation A flag to determine if the datastream metadata will be used for aggregation. Set to `true` if metadata will be used for aggregation, `false` if not
* @param {String} [aggregationInterval] The aggregation interval as a string, either "daily" or "monthly". Required when `isMetadataForAggregation = true`
* @param {String} [aggregationType] The aggregation type as a string, either "sum" or "average". Required when `isMetadataForAggregation = true`
* @returns {Object} An object that contains array(s) of formatted datastream metadata properties
*/
const extractPropertiesFromFormattedDatastreamMetadata = function (
formattedDatastreamsMetadataArr,
isMetadataForAggregation,
aggregationInterval,
aggregationType
) {
if (
formattedDatastreamsMetadataArr === undefined ||
isMetadataForAggregation === undefined
)
throw new Error(
"This function expects two arguments, ensure that both have been supplied"
);
if (
formattedDatastreamsMetadataArr &&
isMetadataForAggregation &&
(aggregationInterval === undefined || aggregationType === undefined)
)
throw new Error(
"This function expects four arguments, ensure that all of them have been supplied"
);
if (
isMetadataForAggregation &&
aggregationInterval !== "daily" &&
aggregationInterval !== "monthly"
)
throw new Error(
`The supported aggegation interval strings are "daily" or "monthly"`
);
if (
isMetadataForAggregation &&
aggregationType !== "sum" &&
aggregationType !== "average"
)
throw new Error(
`The supported aggegation type strings are "sum" or "average"`
);
// Create arrays from the properties of the formatted datastream metadata
const datastreamDescriptionsArr = formattedDatastreamsMetadataArr.map(
(datastreamMetadata) => datastreamMetadata.datastreamDescription
);
const datastreamNamesArr = formattedDatastreamsMetadataArr.map(
(datastreamMetadata) => datastreamMetadata.datastreamName
);
const phenomenonNamesArr = formattedDatastreamsMetadataArr.map(
(datastreamMetadata) => datastreamMetadata.phenomenonName
);
const buildingIdsPhenomenonNamesArr = formattedDatastreamsMetadataArr.map(
(datastreamMetadata) => datastreamMetadata.buildingIdPhenomenonName
);
const unitOfMeasurementSymbolsArr = formattedDatastreamsMetadataArr.map(
(datastreamMetadata) => datastreamMetadata.unitOfMeasurementSymbol
);
// Case 1: Metadata NOT USED for aggregation; "isMetadataForAggregation" = false
if (!isMetadataForAggregation)
return {
datastreamDescriptionsArr,
datastreamNamesArr,
phenomenonNamesArr,
unitOfMeasurementSymbolsArr,
};
// Case 2: Metadata USED for aggregation; "isMetadataForAggregation" = true
return {
datastreamDescriptionsArr,
datastreamNamesArr,
buildingIdsPhenomenonNamesArr,
unitOfMeasurementSymbolsArr,
aggregationInterval,
aggregationType,
};
};
export {
extractPhenomenonNameFromDatastreamName,
formatDatastreamMetadataForChart,
extractPropertiesFromFormattedDatastreamMetadata,
};
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