Skip to content

Commit

Permalink
rate & area work together
Browse files Browse the repository at this point in the history
This simplifies the logic and removes a bug where did not see rate on
line graphic if also did area. It now always normalizes but uses 1
if none or if rate is per hour.
  • Loading branch information
huss committed Jul 11, 2023
1 parent 2fe0318 commit f86670e
Showing 1 changed file with 21 additions and 38 deletions.
59 changes: 21 additions & 38 deletions src/client/app/containers/LineChartContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ function mapStateToProps(state: State) {
unitLabel = returned.unitLabel
needsRateScaling = returned.needsRateScaling;
}
// If the current rate is per hour (default rate) then don't bother with the extra calculations since we'd be multiplying by 1
needsRateScaling = needsRateScaling && (currentSelectedRate.rate != 1);
}
// 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 line plot
for (const meterID of state.graph.selectedMeters) {
Expand All @@ -50,12 +50,13 @@ function mapStateToProps(state: State) {
// Note the second part may not be used based on next checks but do here since simple.
if (byMeterID !== undefined && byMeterID[timeInterval.toString()] !== 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
// 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)) {
if (state.graph.areaNormalization) {
// convert the meter area into the proper unit, if needed
meterArea *= getAreaUnitConversion(state.meters.byMeterID[meterID].areaUnit, state.graph.selectedAreaUnit);
}
// 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 (readingsData !== undefined && !readingsData.isFetching) {
const label = state.meters.byMeterID[meterID].identifier;
Expand All @@ -69,37 +70,19 @@ function mapStateToProps(state: State) {
const yData: 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);
xData.push(timeReading.format('YYYY-MM-DD HH:mm:ss'));
yData.push(reading.reading * rate);
hoverText.push(`<b> ${timeReading.format('ddd, ll LTS')} </b> <br> ${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);
xData.push(timeReading.format('YYYY-MM-DD HH:mm:ss'));
let readingValue = reading.reading;
if (state.graph.areaNormalization) {
readingValue /= meterArea;
}
yData.push(readingValue);
hoverText.push(`<b> ${timeReading.format('ddd, ll LTS')} </b> <br> ${label}: ${readingValue.toPrecision(6)} ${unitLabel}`);
});
}
// The scaling is the factor to change the reading by. It divides by the area while will be 1 if no scaling by area.
// const scaling = currentSelectedRate.rate / meterArea;
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);
xData.push(timeReading.format('YYYY-MM-DD HH:mm:ss'));
const readingValue = reading.reading * scaling;
yData.push(readingValue);
hoverText.push(`<b> ${timeReading.format('ddd, ll LTS')} </b> <br> ${label}: ${readingValue.toPrecision(6)} ${unitLabel}`);
});

/*
get the min and max timestamp of the meter, and compare it to the global values
Expand Down

0 comments on commit f86670e

Please sign in to comment.