From 09c75c4f187f4a841a358e7dde17dcc7739073f0 Mon Sep 17 00:00:00 2001 From: Laura Fuentes Grau Date: Sun, 3 Jan 2021 15:40:37 +0100 Subject: [PATCH] Plot Widget: make line colors editable #275 --- src/widget/edit-widget/color-picker.js | 10 +- .../edit-widget-color-zones-control.js | 4 +- .../edit-widget-control-creator.js | 6 +- .../edit-widget-plot-colors-control.js | 101 ++++++++++++++++++ src/widget/widget-factory.js | 1 + src/widget/widget-plot/plot-legend.js | 11 +- src/widget/widget-plot/plot.js | 11 +- src/widget/widgets/plot.js | 4 +- 8 files changed, 135 insertions(+), 13 deletions(-) create mode 100644 src/widget/edit-widget/edit-widget-plot-colors-control.js diff --git a/src/widget/edit-widget/color-picker.js b/src/widget/edit-widget/color-picker.js index f49700b..a8e6615 100644 --- a/src/widget/edit-widget/color-picker.js +++ b/src/widget/edit-widget/color-picker.js @@ -55,6 +55,9 @@ class ColorPicker extends React.Component { if(this.props.controlId === 'strokeStyle'){ temp.customProperties.zones[this.props.zoneIndex]['strokeStyle'] = color.hex; } + else if(this.props.controlId === 'lineColor'){ + temp.customProperties.lineColors[this.props.lineIndex] = color.hex; + } else{ let parts = this.props.controlId.split('.'); let isCustomProperty = true; @@ -96,7 +99,12 @@ class ColorPicker extends React.Component { if(this.props.controlId === 'strokeStyle'){ if(typeof this.state.widget.customProperties.zones[this.props.zoneIndex] !== 'undefined'){ - hexColor = this.state.widget.customProperties.zones[this.props.zoneIndex]['strokeStyle']; + hexColor = this.state.widget.customProperties.zones[this.props.zoneIndex]['strokeStyle']; + } + } + else if(this.props.controlId === 'lineColor'){ + if(typeof this.state.widget.customProperties.lineColors[this.props.lineIndex] !== 'undefined'){ + hexColor = this.state.widget.customProperties.lineColors[this.props.lineIndex]; } } else{ diff --git a/src/widget/edit-widget/edit-widget-color-zones-control.js b/src/widget/edit-widget/edit-widget-color-zones-control.js index 4ade39f..415fbd0 100644 --- a/src/widget/edit-widget/edit-widget-color-zones-control.js +++ b/src/widget/edit-widget/edit-widget-color-zones-control.js @@ -191,7 +191,7 @@ class EditWidgetColorZonesControl extends React.Component { } return - Color zones + Color Zones
@@ -205,8 +205,6 @@ class EditWidgetColorZonesControl extends React.Component { height: '40px' } - - return ( ) diff --git a/src/widget/edit-widget/edit-widget-control-creator.js b/src/widget/edit-widget/edit-widget-control-creator.js index da3d7b6..1153569 100644 --- a/src/widget/edit-widget/edit-widget-control-creator.js +++ b/src/widget/edit-widget/edit-widget-control-creator.js @@ -31,6 +31,7 @@ import EditWidgetCheckboxControl from './edit-widget-checkbox-control'; import EditWidgetColorZonesControl from './edit-widget-color-zones-control'; import EditWidgetMinMaxControl from './edit-widget-min-max-control'; import EditWidgetParametersControl from './edit-widget-parameters-control'; +import EditWidgetPlotColorsControl from './edit-widget-plot-colors-control'; //import EditWidgetHTMLContent from './edit-widget-html-content'; export default function CreateControls(widgetType = null, widget = null, sessionToken = null, files = null, signals, handleChange) { @@ -70,8 +71,9 @@ export default function CreateControls(widgetType = null, widget = null, session DialogControls.push( handleChange(e)} />, handleChange(e)} direction={'out'}/>, - handleChange(e)} />, - handleChange(e)} /> + handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} /> ); break; case 'Table': diff --git a/src/widget/edit-widget/edit-widget-plot-colors-control.js b/src/widget/edit-widget/edit-widget-plot-colors-control.js new file mode 100644 index 0000000..567e84f --- /dev/null +++ b/src/widget/edit-widget/edit-widget-plot-colors-control.js @@ -0,0 +1,101 @@ +/** + * This file is part of VILLASweb. + * + * VILLASweb is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * VILLASweb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with VILLASweb. If not, see . + ******************************************************************************/ + +import React, { Component } from 'react'; +import { FormGroup, OverlayTrigger, Tooltip , FormLabel, Button } from 'react-bootstrap'; +import ColorPicker from './color-picker' +import Icon from "../../common/icon"; + +// schemeCategory20 no longer available in d3 + +class EditWidgetPlotColorsControl extends Component { + + constructor(props) { + super(props); + + this.state = { + widget: {}, + showColorPicker: false, + originalColor: null, + selectedIndex: null + }; + } + + static getDerivedStateFromProps(props, state){ + return { + widget: props.widget + }; + } + +//same here + + closeEditModal = (data) => { + this.setState({showColorPicker: false}) + if(typeof data === 'undefined'){ + + let temp = this.state.widget; + temp.customProperties.lineColors[this.state.selectedIndex] = this.state.originalColor; + this.setState({ widget: temp }); + } + } + + editLineColor = (index) => { + if(this.state.selectedIndex !== index){ + let color = this.state.widget.customProperties.lineColors[index]; + this.setState({selectedIndex: index, showColorPicker: true, originalColor: color}); + } + else{ + this.setState({selectedIndex: null}); + } + } + + render() { + + return ( + + Line Colors + +
+ { + this.state.widget.signalIDs.map((signalID, idx) => { + let color = this.state.widget.customProperties.lineColors[signalID]; + let width = 260 / this.state.widget.signalIDs.length; + let style = { + backgroundColor: color, + width: width, + height: '40px' + } + + let signal = this.props.signals.find(signal => signal.id === signalID); + + return ({signal.name}}> + + + ) + }) + } +
+ + this.closeEditModal(data)} widget={this.state.widget} lineIndex={this.state.selectedIndex} controlId={'lineColor'} disableOpacity={true}/> +
+ + ) + } +} + +export default EditWidgetPlotColorsControl; diff --git a/src/widget/widget-factory.js b/src/widget/widget-factory.js index d21f2bb..cc21b05 100644 --- a/src/widget/widget-factory.js +++ b/src/widget/widget-factory.js @@ -89,6 +89,7 @@ class WidgetFactory { widget.customProperties.yMin = 0; widget.customProperties.yMax = 10; widget.customProperties.yUseMinMax = false; + widget.customProperties.lineColors = []; break; case 'Table': widget.minWidth = 200; diff --git a/src/widget/widget-plot/plot-legend.js b/src/widget/widget-plot/plot-legend.js index 75add6d..1ada30d 100644 --- a/src/widget/widget-plot/plot-legend.js +++ b/src/widget/widget-plot/plot-legend.js @@ -20,13 +20,17 @@ import { scaleOrdinal} from 'd3-scale'; import {schemeCategory10} from 'd3-scale-chromatic' function Legend(props){ + const signal = props.sig; const hasScalingFactor = (signal.scalingFactor !== 1); + const newLineColor = scaleOrdinal(schemeCategory10); + + let color = typeof props.lineColor === "undefined" ? newLineColor(signal.id) : props.lineColor; if(hasScalingFactor){ return ( -
  • +
  • {signal.name} {signal.unit} {signal.scalingFactor} @@ -34,7 +38,7 @@ function Legend(props){ ) } else { return ( -
  • +
  • {signal.name} {signal.unit}
  • @@ -45,13 +49,12 @@ function Legend(props){ class PlotLegend extends React.Component { render() { - const colorScale = scaleOrdinal(schemeCategory10); return
      { this.props.signals.map( signal => - + )}
    ; diff --git a/src/widget/widget-plot/plot.js b/src/widget/widget-plot/plot.js index 0b3d4a8..1677915 100644 --- a/src/widget/widget-plot/plot.js +++ b/src/widget/widget-plot/plot.js @@ -203,14 +203,21 @@ class Plot extends React.Component { // generate paths from data const sparkLine = line().x(p => xScale(p.x)).y(p => yScale(p.y)); - const lineColor = scaleOrdinal(schemeCategory10); + const newLineColor = scaleOrdinal(schemeCategory10); - const lines = this.state.data.map((values, index) => ); + const lines = this.state.data.map((values, index) => { + let signalID = this.props.signalIDs[index]; + if (typeof this.props.lineColors[signalID] === "undefined") { + this.props.lineColors[signalID] = newLineColor(signalID); + } + return + }); this.setState({ lines, xAxis, yAxis }); } render() { + const yLabelPos = { x: 12, y: this.props.height / 2 diff --git a/src/widget/widgets/plot.js b/src/widget/widgets/plot.js index e87e7d1..1479081 100644 --- a/src/widget/widgets/plot.js +++ b/src/widget/widgets/plot.js @@ -103,9 +103,11 @@ class WidgetPlot extends React.Component { yUseMinMax={this.props.widget.customProperties.yUseMinMax} paused={this.props.paused} yLabel={this.props.widget.customProperties.ylabel} + lineColors={this.props.widget.customProperties.lineColors} + signalIDs={this.props.widget.signalIDs} />
    - + ; } }