diff --git a/src/client/app/containers/RadarChartContainer.ts b/src/client/app/containers/RadarChartContainer.ts
index 7109739ef..76a4eb413 100644
--- a/src/client/app/containers/RadarChartContainer.ts
+++ b/src/client/app/containers/RadarChartContainer.ts
@@ -11,56 +11,45 @@ import translate from '../utils/translate';
import Plot from 'react-plotly.js';
import Locales from '../types/locales';
import { DataType } from '../types/Datasources';
-//Make your own radarUnitLabel later. Lets see if this works first.
-import { lineUnitLabel } from '../utils/graphics';
+// Make your own radarUnitLabel later. Lets see if this works first
+import { barUnitLabel } from '../utils/graphics';
import { AreaUnitType, getAreaUnitConversion } from '../utils/getAreaUnitConversion';
function mapStateToProps(state: State) {
const timeInterval = state.graph.timeInterval;
const unitID = state.graph.selectedUnit;
const datasets: any[] = [];
+ const barDuration = state.graph.barDuration;
+ //For largest and smallest usage in reading.reading.
+ let minR: number | undefined;
+ let maxR: number | undefined;
// The unit label depends on the unit which is in selectUnit state.
const graphingUnit = state.graph.selectedUnit;
- // The current selected rate
- /* Might want to go back and change this currentSelectedRate */
- const currentSelectedRate = state.graph.lineGraphRate;
let unitLabel = '';
- let needsRateScaling = false;
- // variables to determine the slider min and max
- let minTimestamp: number | undefined;
- let maxTimestamp: number | undefined;
// If graphingUnit is -99 then none selected and nothing to graph so label is empty.
// This will probably happen when the page is first loaded.
if (graphingUnit !== -99) {
const selectUnitState = state.units.units[state.graph.selectedUnit];
if (selectUnitState !== undefined) {
- // Determine the y-axis label and if the rate needs to be scaled.
- /** Might want to go back and change this lineUnitLabel function */
- const returned = lineUnitLabel(selectUnitState, currentSelectedRate, state.graph.areaNormalization, state.graph.selectedAreaUnit);
- unitLabel = returned.unitLabel
- needsRateScaling = returned.needsRateScaling;
+ // Determine the r-axis label.
+ unitLabel = barUnitLabel(selectUnitState, state.graph.areaNormalization, state.graph.selectedAreaUnit);
}
}
- // The rate will be 1 if it is per hour (since state readings are per hour) or no rate scaling so no change.
- const rateScaling = needsRateScaling ? currentSelectedRate.rate : 1;
// Add all valid data from existing meters to the radar plot
for (const meterID of state.graph.selectedMeters) {
- const byMeterID = state.readings.radar.byMeterID[meterID];
- // Make sure have the meter data. If you already have the meter, unselect, change
- // the timeInterval via another meter and then reselect then this new timeInterval
- // may not yet be in state so verify with the second condition on the if.
- // Note the second part may not be used based on next checks but do here since simple.
- if (byMeterID !== undefined && byMeterID[timeInterval.toString()] !== undefined) {
- const meterArea = state.meters.byMeterID[meterID].area;
+ const byMeterID = state.readings.bar.byMeterID[meterID];
+ if (byMeterID !== undefined && byMeterID[timeInterval.toString()] !== undefined &&
+ byMeterID[timeInterval.toString()][barDuration.toISOString()] !== undefined) {
+ let meterArea = state.meters.byMeterID[meterID].area;
// We either don't care about area, or we do in which case there needs to be a nonzero area.
if (!state.graph.areaNormalization || (meterArea > 0 && state.meters.byMeterID[meterID].areaUnit != AreaUnitType.none)) {
// Convert the meter area into the proper unit if normalizing by area or use 1 if not so won't change reading values.
- const areaScaling = state.graph.areaNormalization ?
- meterArea * getAreaUnitConversion(state.meters.byMeterID[meterID].areaUnit, state.graph.selectedAreaUnit) : 1;
- // Divide areaScaling into the rate so have complete scaling factor for readings.
- const scaling = rateScaling / areaScaling;
- const readingsData = byMeterID[timeInterval.toString()][unitID];
+ if (state.graph.areaNormalization) {
+ // convert the meter area into the proper unit, if needed
+ meterArea *= getAreaUnitConversion(state.meters.byMeterID[meterID].areaUnit, state.graph.selectedAreaUnit);
+ }
+ const readingsData = byMeterID[timeInterval.toString()][barDuration.toISOString()][unitID];
if (readingsData !== undefined && !readingsData.isFetching) {
const label = state.meters.byMeterID[meterID].identifier;
const colorID = meterID;
@@ -80,24 +69,29 @@ function mapStateToProps(state: State) {
const st = moment.utc(reading.startTimestamp);
// Time reading is in the middle of the start and end timestamp
const timeReading = st.add(moment.utc(reading.endTimestamp).diff(st) / 2);
- thetaData.push(timeReading.format('YYYY-MM-DD HH:mm:ss'));
- const readingValue = reading.reading * scaling;
+ // thetaData.push(timeReading.format('YYYY-MM-DD HH:mm:ss'));
+ thetaData.push(timeReading.format('ddd, ll LTS'));
+ let readingValue = reading.reading;
+ if (state.graph.areaNormalization) {
+ readingValue /= meterArea;
+ }
rData.push(readingValue);
- hoverText.push(` ${timeReading.format('ddd, ll LTS')}
${label}: ${readingValue.toPrecision(6)} ${unitLabel}`);
+ // only display a range of dates for the hover text if there is more than one day in the range
+ let timeRange: string = `${moment.utc(reading.startTimestamp).format('ll')}`;
+ if (barDuration.asDays() != 1) {
+ // subtracting one extra day caused by day ending at midnight of the next day.
+ // Going from DB unit timestamp that is UTC so force UTC with moment, as usual.
+ timeRange += ` - ${moment.utc(reading.endTimestamp).subtract(1, 'days').format('ll')}`;
+ }
+ hoverText.push(` ${timeRange}
${label}: ${readingValue.toPrecision(6)} ${unitLabel}`);
});
- /*
- get the min and max timestamp of the meter, and compare it to the global values
- TODO: If we know the interval and frequency of meter data, these calculations should be able to be simplified
- */
- if (readings.length > 0) {
- if (minTimestamp == undefined || readings[0]['startTimestamp'] < minTimestamp) {
- minTimestamp = readings[0]['startTimestamp'];
- }
- if (maxTimestamp == undefined || readings[readings.length - 1]['endTimestamp'] >= maxTimestamp) {
- // Need to add one extra reading interval to avoid range truncation. The max bound seems to be treated as non-inclusive
- maxTimestamp = readings[readings.length - 1]['endTimestamp'] + (readings[0]['endTimestamp'] - readings[0]['startTimestamp']);
- }
+ //Find the largest and smallest usage in rData.
+ if (minR == undefined || minR > Math.min(...rData)) {
+ minR = Math.min(...rData);
+ }
+ if (maxR == undefined || maxR < Math.max(...rData)) {
+ maxR = Math.max(...rData);
}
// This variable contains all the elements (x and y values, line type, etc.) assigned to the data parameter of the Plotly object
@@ -120,25 +114,96 @@ function mapStateToProps(state: State) {
}
}
- /**
- *
- *ADD GROUPS FOR RADAR!!!!!!!!!!
- */
+ //THIS DOES NOT WORK YET AND IT'S STILL USING RADAR READINGS I MOVED TO BAR READINGS
+ // for (const groupID of state.graph.selectedGroups) {
+ // const byGroupID = state.readings.line.byGroupID[groupID];
+ // if (byGroupID !== undefined && byGroupID[timeInterval.toString()] !== undefined) {
+ // let groupArea = state.groups.byGroupID[groupID].area;
+ // if (!state.graph.areaNormalization || (groupArea > 0 && state.groups.byGroupID[groupID].areaUnit != AreaUnitType.none)) {
+ // if (state.graph.areaNormalization) {
+ // // convert the meter area into the proper unit, if needed
+ // groupArea *= getAreaUnitConversion(state.groups.byGroupID[groupID].areaUnit, state.graph.selectedAreaUnit);
+ // }
+ // const readingsData = byGroupID[timeInterval.toString()][unitID];
+ // if (readingsData !== undefined && !readingsData.isFetching) {
+ // const label = state.groups.byGroupID[groupID].name;
+ // const colorID = groupID;
+ // if (readingsData.readings === undefined) {
+ // throw new Error('Unacceptable condition: readingsData.readings is undefined.');
+ // }
- // set the bounds for the slider
- if (minTimestamp == undefined) {
- minTimestamp = 0;
- maxTimestamp = 0;
- }
- const root: any = document.getElementById('root');
- root.setAttribute('min-timestamp', minTimestamp);
- root.setAttribute('max-timestamp', maxTimestamp);
+ // // Create two arrays for the x and y values. Fill the array with the data from the line readings
+ // const thetaData: string[] = [];
+ // const rData: number[] = [];
+ // const hoverText: string[] = [];
+ // const readings = _.values(readingsData.readings);
+ // // Check if reading needs scaling outside of the loop so only one check is needed
+ // // Results in more code but SLIGHTLY better efficiency :D
+ // if (needsRateScaling) {
+ // const rate = currentSelectedRate.rate;
+ // readings.forEach(reading => {
+ // // As usual, we want to interpret the readings in UTC. We lose the timezone as this as the start/endTimestamp
+ // // are equivalent to Unix timestamp in milliseconds.
+ // const st = moment.utc(reading.startTimestamp);
+ // // Time reading is in the middle of the start and end timestamp
+ // const timeReading = st.add(moment.utc(reading.endTimestamp).diff(st) / 2);
+ // // thetaData.push(timeReading.utc().format('YYYY-MM-DD HH:mm:ss'));
+ // thetaData.push(timeReading.utc().format('ddd, ll LTS'));
+ // rData.push(reading.reading * rate);
+ // hoverText.push(` ${timeReading.format('ddd, ll LTS')}
${label}: ${(reading.reading * rate).toPrecision(6)} ${unitLabel}`);
+ // });
+ // }
+ // else {
+ // readings.forEach(reading => {
+ // // As usual, we want to interpret the readings in UTC. We lose the timezone as this as the start/endTimestamp
+ // // are equivalent to Unix timestamp in milliseconds.
+ // const st = moment.utc(reading.startTimestamp);
+ // // Time reading is in the middle of the start and end timestamp
+ // const timeReading = st.add(moment.utc(reading.endTimestamp).diff(st) / 2);
+ // // thetaData.push(timeReading.utc().format('YYYY-MM-DD HH:mm:ss'));
+ // thetaData.push(timeReading.utc().format('ddd, ll LTS'));
+ // let readingValue = reading.reading;
+ // if (state.graph.areaNormalization) {
+ // readingValue /= groupArea;
+ // }
+ // rData.push(readingValue);
+ // hoverText.push(` ${timeReading.format('ddd, ll LTS')}
${label}: ${readingValue.toPrecision(6)} ${unitLabel}`);
+ // });
+ // }
+
+ // //Find the largest and smallest usage in rData.
+ // if (minR == undefined || minR > Math.min(...rData)) {
+ // minR = Math.min(...rData);
+ // }
+ // if (maxR == undefined || maxR < Math.max(...rData)) {
+ // maxR = Math.max(...rData);
+ // }
- // Use the min/max time found for the readings (and shifted as desired) as the
- // x-axis range for the graph.
- // Avoid pesky shifting timezones with utc.
- const start = moment.utc(minTimestamp).toISOString(); // Need this????????????????????????????????????????????????????
- const end = moment.utc(maxTimestamp).toISOString();
+ // // This variable contains all the elements (x and y values, line type, etc.) assigned to the data parameter of the Plotly object
+ // datasets.push({
+ // name: label,
+ // x: thetaData,
+ // y: rData,
+ // text: hoverText,
+ // hoverinfo: 'text',
+ // type: 'scatterpolar',
+ // mode: 'lines',
+ // line: {
+ // shape: 'spline',
+ // width: 2,
+ // color: getGraphColor(colorID, DataType.Group)
+ // }
+ // });
+ // }
+ // }
+ // }
+ // }
+
+ // No range if minR or maxR is undefined.
+ if (minR == undefined || maxR == undefined) {
+ minR = 0;
+ maxR = 0;
+ }
let layout: any;
// Customize the layout of the plot
@@ -180,7 +245,8 @@ function mapStateToProps(state: State) {
polar: {
radialaxis: {
title: unitLabel,
- range: [start, end], // Specifies the start and end points of visible part of graph
+ // Specifies the start and end points of the usage.
+ range: [minR, maxR],
showgrid: true,
gridcolor: '#ddd'
}