diff --git a/front/src/components/boxs/chart/ApexChartComponent.jsx b/front/src/components/boxs/chart/ApexChartComponent.jsx index f4d96144ee..9a74043f19 100644 --- a/front/src/components/boxs/chart/ApexChartComponent.jsx +++ b/front/src/components/boxs/chart/ApexChartComponent.jsx @@ -141,16 +141,105 @@ class ApexChartComponent extends Component { } else if (this.props.size === 'big' && !this.props.display_axes) { height = 80; } else { + console.log('height this.props', this.props); height = 200 + this.props.additionalHeight; } + console.log('height', height); + let seriesAnnotationsYaxis = []; + let seriesPoints = []; + console.log('this.props', this.props); + if (this.props.seriesAnnotationsYaxis) { + // console.log('seriesAnnotationsYaxis', this.props.seriesAnnotationsYaxis); + seriesAnnotationsYaxis = this.props.seriesAnnotationsYaxis.flatMap(annotation => { + const annotationY = { + y: annotation.y, // Valeur de la ligne min + borderColor: annotation.color, // Couleur de la ligne + // strokeDashArray: 2, + // fillColor: annotation.color, + + fillColor: annotation.color, + marker: { + size: 4, + fillColor: "#fff", + strokeWidth: 2, + strokeColor: "#333", + }, + // opacity: 0.5, + width: '200%', + }; + if (annotation.y2) { + annotationY.y2 = annotation.y2; + } + if (annotation.more_or_less === 'moreOrLess') { + const { y2, ...annotationYWithoutY2 } = annotationY; + const additionalAnnotationY = { + // Copy the existing properties except y2 + ...annotationYWithoutY2, + y: annotation.value, // Set 'y' to 'annotation.value' + + label: { + borderColor: annotation.color, + style: { + color: '#fff', + background: annotation.color + }, + text: annotation.name + } + }; + return [annotationY, additionalAnnotationY] + } else { + annotationY.label = { + borderColor: annotation.color, + style: { + color: '#fff', + background: annotation.color + }, + text: annotation.name + }; + } + return annotationY; + }); + } + if (this.props.seriesPoints) { + console.log('seriesAnnotationsXaxis', this.props.seriesAnnotationsXaxis); + seriesPoints = this.props.seriesPoints.map(point => { + console.log('point', point); + const data = point.data.map(p => { + return { + y: p.y, + // y2: 24, + x: new Date(p.x).getTime(), + borderColor: '#FF4560', + label: { + text: point.name + }, + // marker: { + // size: 4, + // fillColor: '#fff', + // strokeWidth: 2, + // strokeColor: "#333", // A visible stroke color + // shape: "circle", + // }, + // position: 'front' + }; + }); + console.log('data', data); + return data; + }); + seriesPoints = mergeArray(...seriesPoints); + } + console.log('getLineChartOptions seriesPoints', seriesPoints); const options = getApexChartLineOptions({ height, colors: mergeArray(this.props.colors, DEFAULT_COLORS), displayAxes: this.props.display_axes, series: this.props.series, locales: [fr, en, de], - defaultLocale: this.props.user.language + defaultLocale: this.props.user.language, + seriesPoints, + seriesAnnotationsYaxis }); + console.log('getLineChartOptions options', options); this.addDateFormatter(options); return options; }; @@ -223,6 +312,8 @@ class ApexChartComponent extends Component { } componentDidUpdate(nextProps) { const seriesDifferent = nextProps.series !== this.props.series; + const seriesPointsDifferent = nextProps.seriesPoints !== this.props.seriesPoints; + const seriesAnnotationsYaxisDifferent = nextProps.seriesAnnotationsYaxis !== this.props.seriesAnnotationsYaxis; const chartTypeDifferent = nextProps.chart_type !== this.props.chart_type; const displayAxesDifferent = nextProps.display_axes !== this.props.display_axes; const intervalDifferent = nextProps.interval !== this.props.interval; @@ -234,7 +325,9 @@ class ApexChartComponent extends Component { displayAxesDifferent || intervalDifferent || sizeDifferent || - additionalHeightDifferent + additionalHeightDifferent || + seriesPointsDifferent || + seriesAnnotationsYaxisDifferent ) { this.displayChart(); } diff --git a/front/src/components/boxs/chart/ApexChartLineOptions.js b/front/src/components/boxs/chart/ApexChartLineOptions.js index 24a9f2365d..0e59186c70 100644 --- a/front/src/components/boxs/chart/ApexChartLineOptions.js +++ b/front/src/components/boxs/chart/ApexChartLineOptions.js @@ -1,4 +1,4 @@ -const getApexChartLineOptions = ({ height, displayAxes, series, colors, locales, defaultLocale }) => { +const getApexChartLineOptions = ({ height, displayAxes, series, colors, locales, defaultLocale, seriesPoints, seriesAnnotationsYaxis }) => { const options = { chart: { locales, @@ -64,6 +64,72 @@ const getApexChartLineOptions = ({ height, displayAxes, series, colors, locales, legend: { show: displayAxes, position: 'bottom' + }, + annotations: { + yaxis: seriesAnnotationsYaxis, + // points: seriesPoints, + + // points: [ + // // { + // // y: 5, // Valeur de la ligne min + // // borderColor: '#FF0000', // Couleur de la ligne + // // label: { + // // borderColor: '#FF0000', + // // style: { + // // color: '#fff', + // // background: '#FF0000' + // // }, + // // text: 'Min Value' + // // } + // // }, + // // { + // // y: 20, // Valeur de la ligne max + // // borderColor: '#00FF00', // Couleur de la ligne + // // label: { + // // borderColor: '#00FF00', + // // style: { + // // color: '#fff', + // // background: '#00FF00' + // // }, + // // text: 'Max Value' + // // } + // // }, + // // { + // // y: 22, + // // y2: 24, + // // borderColor: '#00E396', + // // label: { + // // text: 'Consigne 8:00' + // // } + // // }, + // // { + // // y: 17, + // // x: 3, // Position sur l'axe X (11:00) + // // borderColor: '#FEB019', + // // label: { + // // text: 'Consigne 11:00' + // // } + // // }, + // { + // y: 20, + // y2: 24, + // x: 1725638947166, // Position sur l'axe X (15:00) + // borderColor: '#FF4560', + // label: { + // text: 'Consigne 15:00' + // } + // }, + // { + // y: 20, + // y2: 24, + // x: 1725649979366, // Position sur l'axe X (15:00) + // borderColor: '#FF4560', + // label: { + // text: 'Consigne 15:00' + // } + // } + + // ] } }; return options; diff --git a/front/src/components/boxs/chart/Chart.jsx b/front/src/components/boxs/chart/Chart.jsx index 83502973f1..6ddc941b91 100644 --- a/front/src/components/boxs/chart/Chart.jsx +++ b/front/src/components/boxs/chart/Chart.jsx @@ -116,6 +116,8 @@ class Chartbox extends Component { }; getData = async () => { let deviceFeatures = this.props.box.device_features; + let deviceFeaturesTreshold = this.props.box.device_features_treshold; + let manualFeaturesTreshold = this.props.box.manual_features_treshold_details; let deviceFeatureNames = this.props.box.device_feature_names; let nbFeaturesDisplayed = deviceFeatures.length; @@ -208,7 +210,6 @@ class Chartbox extends Component { } const newState = { series, - loading: false, initialized: true, emptySeries, nbFeaturesDisplayed @@ -260,6 +261,63 @@ class Chartbox extends Component { } catch (e) { console.error(e); } + console.log('deviceFeaturesTreshold', deviceFeaturesTreshold); + if (!deviceFeaturesTreshold || deviceFeaturesTreshold.length === 0) { + await this.setState({ loading: false }); + return; + } + try { + const data = await this.props.httpClient.get(`/api/v1/device_feature/aggregated_states`, { + interval: this.state.interval, + max_states: 10, + device_features: deviceFeaturesTreshold.join(',') + }); + + const seriesPoints = data.map((oneFeature, index) => { + const unit = this.props.box.units[index]; + const deviceFeatureUnitShort = this.props.intl.dictionary.deviceFeatureUnitShort[unit]; + const { values, deviceFeature } = oneFeature; + const deviceName = deviceFeature.name; + const name = `${deviceName} (${deviceFeatureUnitShort})`; + return { + name, + data: values.map(value => { + return { + x: value.created_at, + y: value.value + }; + }) + }; + }); + await this.setState({ seriesPoints }); + } catch (e) { + console.error(e); + } + + if (manualFeaturesTreshold.length === 0) { + await this.setState({ loading: false }); + return; + } + + if (manualFeaturesTreshold.length > 0) { + const seriesAnnotationsYaxis = manualFeaturesTreshold.map((oneFeature, index) => { + const unit = oneFeature.unit; + const deviceFeatureUnitShort = this.props.intl.dictionary.deviceFeatureUnitShort[unit]; + const deviceName = oneFeature.name; + const value = oneFeature.more_or_less && oneFeature.more_or_less !== 'without' ? + `${oneFeature.min}/${oneFeature.max}` : `${oneFeature.value}`; + const name = `${deviceName} ${value}${deviceFeatureUnitShort}`; + return { + name, + value: oneFeature.value, + y: oneFeature.min ? oneFeature.min : oneFeature.value, + y2: oneFeature.max ? oneFeature.max : oneFeature.value_more_or_less, + color: oneFeature.color, + more_or_less: oneFeature.more_or_less + }; + }); + await this.setState({ seriesAnnotationsYaxis }); + } }; updateDeviceStateWebsocket = payload => { if ( @@ -318,6 +376,8 @@ class Chartbox extends Component { initialized, loading, series, + seriesPoints, + seriesAnnotationsYaxis, dropdown, variation, variationDownIsPositive, @@ -502,6 +562,8 @@ class Chartbox extends Component {