Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple chart fixes #1357

Merged
merged 5 commits into from Nov 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
69 changes: 50 additions & 19 deletions front/src/components/boxs/chart/Chart.jsx
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
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
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
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
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
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