Skip to content

Commit

Permalink
Multiple chart fixes (#1357)
Browse files Browse the repository at this point in the history
* Add warning on chart box saying that Gladys needs time to collect enough data

* In chart, if two charts are displayed with different unit, display only the first + add units to legend
  • Loading branch information
Pierre-Gilles authored Nov 11, 2021
1 parent d389a14 commit b3fa509
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 27 deletions.
69 changes: 50 additions & 19 deletions front/src/components/boxs/chart/Chart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Text } from 'preact-i18n';
import style from './style.css';
import { WEBSOCKET_MESSAGE_TYPES } from '../../../../../server/utils/constants';
import get from 'get-value';
import withIntlAsProp from '../../../utils/withIntlAsProp';
import ApexChartComponent from './ApexChartComponent';

const ONE_HOUR_IN_MINUTES = 60;
Expand Down Expand Up @@ -57,6 +58,8 @@ const calculateVariation = (firstValue, lastValue) => {
return Math.round(((lastValue - firstValue) / Math.abs(firstValue)) * 100);
};

const allEqual = arr => arr.every(val => val === arr[0]);

class Chartbox extends Component {
toggleDropdown = () => {
this.setState({
Expand Down Expand Up @@ -136,9 +139,12 @@ class Chartbox extends Component {

let emptySeries = true;

const series = data.map(oneFeature => {
const series = data.map((oneFeature, index) => {
const oneUnit = this.props.box.units ? this.props.box.units[index] : this.props.box.unit;
const oneUnitTranslated = oneUnit ? this.props.intl.dictionary.deviceFeatureUnitShort[oneUnit] : null;
const name = oneUnitTranslated ? `${oneFeature.device.name} (${oneUnitTranslated})` : oneFeature.device.name;
return {
name: oneFeature.device.name,
name,
data: oneFeature.values.map(value => {
emptySeries = false;
return {
Expand All @@ -156,22 +162,44 @@ class Chartbox extends Component {
};

if (data.length > 0) {
const lastValuesArray = [];
const variationArray = [];
data.forEach(oneFeature => {
// Before now, there was a "unit" attribute in this box instead of "units",
// so we need to support "unit" as some users may already have the box with that param
const unit = this.props.box.units ? this.props.box.units[0] : this.props.box.unit;
// We check if all deviceFeatures selected are in the same unit
const allUnitsAreSame = this.props.box.units ? allEqual(this.props.box.units) : false;

// If all deviceFeatures selected are in the same unit
// We do a average of all values
if (allUnitsAreSame) {
const lastValuesArray = [];
const variationArray = [];
data.forEach(oneFeature => {
const { values } = oneFeature;
if (values.length === 0) {
return;
}
const firstElement = values[0];
const lastElement = values[values.length - 1];
const variation = calculateVariation(firstElement.value, lastElement.value);
const lastValue = lastElement.value;
variationArray.push(variation);
lastValuesArray.push(lastValue);
});
newState.variation = average(variationArray);
newState.lastValueRounded = roundWith2DecimalIfNeeded(average(lastValuesArray));
newState.unit = unit;
} else {
// If not, we only display the first value
const oneFeature = data[0];
const { values } = oneFeature;
if (values.length === 0) {
return;
if (values.length > 0) {
const firstElement = values[0];
const lastElement = values[values.length - 1];
newState.variation = calculateVariation(firstElement.value, lastElement.value);
newState.lastValueRounded = roundWith2DecimalIfNeeded(lastElement.value);
newState.unit = unit;
}
const firstElement = values[0];
const lastElement = values[values.length - 1];
const variation = calculateVariation(firstElement.value, lastElement.value);
const lastValue = lastElement.value;
variationArray.push(variation);
lastValuesArray.push(lastValue);
});
newState.variation = average(variationArray);
newState.lastValueRounded = roundWith2DecimalIfNeeded(average(lastValuesArray));
}
}

await this.setState(newState);
Expand Down Expand Up @@ -228,7 +256,7 @@ class Chartbox extends Component {
this.updateDeviceStateWebsocket
);
}
render(props, { loading, series, labels, dropdown, variation, lastValueRounded, interval, emptySeries }) {
render(props, { loading, series, labels, dropdown, variation, lastValueRounded, interval, emptySeries, unit }) {
const displayVariation = props.box.display_variation;
return (
<div class="card">
Expand Down Expand Up @@ -308,7 +336,7 @@ class Chartbox extends Component {
{notNullNotUndefined(lastValueRounded) && !Number.isNaN(lastValueRounded) && (
<div class="h1 mb-0 mr-2">
{lastValueRounded}
{props.box.unit !== undefined && <Text id={`deviceFeatureUnitShort.${props.box.unit}`} />}
{unit !== undefined && <Text id={`deviceFeatureUnitShort.${unit}`} />}
</div>
)}
<div
Expand Down Expand Up @@ -412,6 +440,9 @@ class Chartbox extends Component {
<i class="fe fe-alert-circle mr-2" />
<Text id="dashboard.boxes.chart.noValue" />
</div>
<div class={style.smallTextEmptyState}>
<Text id="dashboard.boxes.chart.noValueWarning" />
</div>
</div>
)}
{emptySeries === false && !props.box.display_axes && (
Expand All @@ -431,4 +462,4 @@ class Chartbox extends Component {
}
}

export default connect('httpClient,session,user')(Chartbox);
export default withIntlAsProp(connect('httpClient,session,user')(Chartbox));
13 changes: 9 additions & 4 deletions front/src/components/boxs/chart/EditChart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,19 @@ class EditChart extends Component {
const deviceFeaturesSelectors = selectedDeviceFeaturesOptions.map(
selectedDeviceFeaturesOption => selectedDeviceFeaturesOption.value
);
const firstDeviceFeature = this.deviceFeatureBySelector.get(selectedDeviceFeaturesOptions[0].value);
const units = selectedDeviceFeaturesOptions.map(selectedDeviceFeaturesOption => {
const deviceFeature = this.deviceFeatureBySelector.get(selectedDeviceFeaturesOption.value);
return deviceFeature.unit;
});
this.props.updateBoxConfig(this.props.x, this.props.y, {
device_features: deviceFeaturesSelectors,
unit: firstDeviceFeature && firstDeviceFeature.unit ? firstDeviceFeature.unit : undefined
units,
unit: undefined
});
} else {
this.props.updateBoxConfig(this.props.x, this.props.y, {
device_features: [],
units: [],
unit: undefined
});
}
Expand Down Expand Up @@ -138,8 +143,8 @@ class EditChart extends Component {

componentDidUpdate(previousProps) {
const deviceFeatureChanged = get(previousProps, 'box.device_feature') !== get(this.props, 'box.device_feature');
const unitChanged = get(previousProps, 'box.unit') !== get(this.props, 'box.unit');
if (deviceFeatureChanged || unitChanged) {
const unitsChanged = get(previousProps, 'box.units') !== get(this.props, 'box.units');
if (deviceFeatureChanged || unitsChanged) {
this.getDeviceFeatures();
}
}
Expand Down
10 changes: 9 additions & 1 deletion front/src/components/boxs/chart/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,13 @@

.bigEmptyState {
margin-top: 0rem;
margin-bottom: 2.2rem;
margin-bottom: 1rem;
}

.smallTextEmptyState {
margin-top: 1rem;
font-size: 12px;
padding-left: 1.5rem;
padding-right: 1.5rem;
text-align: justify;
}
3 changes: 2 additions & 1 deletion front/src/config/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,8 @@
"lastThirtyDays": "Last 30 days",
"lastThreeMonths": "Last 3 months",
"lastYear": "Last year",
"noValue": "No values recorded on this interval",
"noValue": "No values recorded on this interval.",
"noValueWarning": "Warning: if you just configured this device, it may take some time before you see something here as Gladys needs some time to collect enough data. For interval superior to 24h, it may take up to 24h before you see something here.",
"editNameLabel": "Enter the name of this box",
"editDeviceFeaturesLabel": "Select the device you want to display here",
"editRoomLabel": "Select the room you want to display here",
Expand Down
5 changes: 3 additions & 2 deletions front/src/config/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,13 @@
"chart": {
"defaultInterval": "Intervalle par défaut",
"lastHour": "Dernière heure",
"lastDay": "Dernière 24h",
"lastDay": "Dernières 24h",
"lastSevenDays": "Derniers 7 jours",
"lastThirtyDays": "Derniers 30 jours",
"lastThreeMonths": "Derniers 3 mois",
"lastYear": "Dernière année",
"noValue": "Pas de valeurs sur cet interval",
"noValue": "Pas de valeurs sur cet intervalle.",
"noValueWarning": "Attention, si vous venez de configurer cet appareil, les données peuvent mettre un certain temps avant d'être aggrégées. Pour les intervalles supérieurs à 24h, cela prend jusqu'à 24h le temps que Gladys collecte assez de données.",
"editNameLabel": "Entrez le nom de cette box",
"editNamePlaceholder": "Nom affiché sur le tableau de bord",
"editDeviceFeaturesLabel": "Sélectionnez les appareils que vous voulez afficher",
Expand Down
1 change: 1 addition & 0 deletions server/models/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const boxesSchema = Joi.array().items(
device_features: Joi.array().items(Joi.string()),
device_feature: Joi.string(),
unit: Joi.string(),
units: Joi.array().items(Joi.string()),
title: Joi.string(),
interval: Joi.string(),
display_axes: Joi.boolean(),
Expand Down

0 comments on commit b3fa509

Please sign in to comment.