From 87be9069f191ed4679ec8b84a4e327a5740a5a6a Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 19 Feb 2020 15:04:37 +0100 Subject: [PATCH] WIP resolving dependencies of widgets on simulation models (use signals instead) --- src/dashboard/dashboard.js | 21 +++- .../edit-widget-control-creator.js | 104 ++++++++---------- .../edit-widget/edit-widget-signal-control.js | 23 +--- .../edit-widget-signals-control.js | 27 ++--- src/widget/edit-widget/edit-widget.js | 60 +++++----- src/widget/widget-area.js | 3 +- src/widget/widget-factory.js | 27 +---- src/widget/widget.js | 70 ++++++------ src/widget/widgets/custom-action.js | 7 +- src/widget/widgets/gauge.js | 42 ++++--- src/widget/widgets/input.js | 23 ++-- src/widget/widgets/lamp.js | 12 +- src/widget/widgets/slider.js | 23 ++-- src/widget/widgets/table.js | 28 +++-- src/widget/widgets/value.js | 27 +++-- 15 files changed, 244 insertions(+), 253 deletions(-) diff --git a/src/dashboard/dashboard.js b/src/dashboard/dashboard.js index cdb1924..288ac70 100644 --- a/src/dashboard/dashboard.js +++ b/src/dashboard/dashboard.js @@ -33,7 +33,8 @@ import DashboardButtonGroup from './dashboard-button-group'; import LoginStore from '../user/login-store'; import DashboardStore from './dashboard-store'; -import SimulationModelStore from '../simulationmodel/simulation-model-store'; +//import SimulationModelStore from '../simulationmodel/simulation-model-store'; +import SignalStore from '../signal/signal-store' import FileStore from '../file/file-store'; import WidgetStore from '../widget/widget-store'; import AppDispatcher from '../common/app-dispatcher'; @@ -44,7 +45,7 @@ class Dashboard extends Component { static lastWidgetKey = 0; static getStores() { - return [ DashboardStore, SimulationModelStore, FileStore, LoginStore, WidgetStore ]; + return [ DashboardStore, FileStore, LoginStore, WidgetStore, SignalStore ]; } static calculateState(prevState, props) { @@ -75,15 +76,18 @@ class Dashboard extends Component { return thisWidgetHeight > maxHeightSoFar? thisWidgetHeight : maxHeightSoFar; }, 0); - let simulationModels = []; + //let simulationModels = []; //if (prevState.simulation != null) { // simulationModels = SimulationModelStore.getState().filter(m => prevState.simulation.models.includes(m._id)); //} + // TODO filter signals to the ones belonging to the scenario at hand! + let signals = SignalStore.getState(); + return { dashboard, widgets, - simulationModels, + signals, sessionToken: sessionToken, files: null, @@ -398,7 +402,14 @@ class Dashboard extends Component { )} - + diff --git a/src/widget/edit-widget/edit-widget-control-creator.js b/src/widget/edit-widget/edit-widget-control-creator.js index f435085..5db44a9 100644 --- a/src/widget/edit-widget/edit-widget-control-creator.js +++ b/src/widget/edit-widget/edit-widget-control-creator.js @@ -38,7 +38,7 @@ import EditWidgetMinMaxControl from './edit-widget-min-max-control'; import EditWidgetHTMLContent from './edit-widget-html-content'; import EditWidgetParametersControl from './edit-widget-parameters-control'; -export default function CreateControls(widgetType = null, widget = null, sessionToken = null, files = null, validateForm, simulationModels, handleChange) { +export default function CreateControls(widgetType = null, widget = null, sessionToken = null, files = null, validateForm, signals, handleChange) { // Use a list to concatenate the controls according to the widget type var DialogControls = []; @@ -47,54 +47,47 @@ export default function CreateControls(widgetType = null, widget = null, session DialogControls.push( validateForm(id)} handleChange={e => handleChange(e)} />, validateForm(id)} handleChange={e => handleChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - handleChange(e)} /> - ) + handleChange(e)} /> + ); break; case 'Action': DialogControls.push( - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} /> - ) + validateForm(id)} signals={signals} handleChange={(e) => handleChange(e)} />, + ); break; case 'Value': let valueBoundOnChange = (e) => { handleChange([e, {target: {id: 'signal', value: 0}}]); - } + }; DialogControls.push( validateForm(id)} handleChange={e => handleChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => valueBoundOnChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - handleChange(e)} />, - handleChange(e)} /> + validateForm(id)} signals={signals} handleChange={(e) => handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} /> ); break; case 'Lamp': let lampBoundOnChange = (e) => { handleChange([e, {target: {id: 'signal', value: 0}}]); - } + }; DialogControls.push( - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => lampBoundOnChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - validateForm(id)} handleChange={e => handleChange(e)} />, - validateForm(id)} handleChange={(e) => handleChange(e)} />, - validateForm(id)} handleChange={(e) => handleChange(e)} />, + validateForm(id)} signals={signals} handleChange={(e) => handleChange(e)} />, + validateForm(id)} handleChange={e => handleChange(e)} />, + validateForm(id)} handleChange={(e) => handleChange(e)} />, + validateForm(id)} handleChange={(e) => handleChange(e)} />, ); break; case 'Plot': - let plotBoundOnChange = (e) => { - handleChange([e, {target: {id: 'signals', value: []}}]); - } DialogControls.push( - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => plotBoundOnChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - handleChange(e)} />, - handleChange(e)} /> + validateForm(id)} handleChange={(e) => handleChange(e)} />, + validateForm(id)} signals={signals} handleChange={(e) => handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} /> ); break; case 'Table': DialogControls.push( - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, + validateForm(id)} signals={signals} handleChange={(e) => handleChange(e)} />, handleChange(e)} /> ); break; @@ -102,59 +95,55 @@ export default function CreateControls(widgetType = null, widget = null, session // Restrict to only image file types (MIME) let imageControlFiles = files == null? [] : files.filter(file => file.type.includes('image')); DialogControls.push( - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, + validateForm(id)} handleChange={(e) => handleChange(e)} />, handleChange(e)} /> ); break; case 'Gauge': let gaugeBoundOnChange = (e) => { handleChange([e, {target: {id: 'signal', value: ''}}]); - } + }; DialogControls.push( validateForm(id)} handleChange={e => handleChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => gaugeBoundOnChange(e) } />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - handleChange(e)} />, - handleChange(e)} />, - handleChange(e)} /> + validateForm(id)} signals={signals} handleChange={(e) => handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} /> ); break; case 'PlotTable': let plotTableBoundOnChange = (e) => { - handleChange([e, {target: {id: 'preselectedSignals', value: []}}]); - } + handleChange([e, {target: {id: 'signalIDs', value: []}}]); + }; DialogControls.push( - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => plotTableBoundOnChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - handleChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - handleChange(e)} /> + validateForm(id)} signals={signals} handleChange={(e) => handleChange(e)} />, + handleChange(e)} />, + validateForm(id)} handleChange={(e) => handleChange(e)} />, + handleChange(e)} /> ); break; case 'Slider': DialogControls.push( handleChange(e)} validate={id => validateForm(id)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - handleChange(e)} />, - handleChange(e)} />, - handleChange(e)} />, - handleChange(e)} />, - handleChange(e)} /> + validateForm(id)} handleChange={(e) => handleChange(e)} />, + validateForm(id)} signals={signals} handleChange={(e) => handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} /> ); break; case 'Button': let buttonBoundOnChange = (e) => { handleChange([e, {target: {id: 'signal', value: 0}}]); - } + }; DialogControls.push( handleChange(e)} validate={id => validateForm(id)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => buttonBoundOnChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} />, - handleChange(e)} />, - handleChange(e)} />, - handleChange(e)} /> + validateForm(id)} signals={signals} handleChange={(e) => handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} />, + handleChange(e)} /> ); break; case 'Box': @@ -179,18 +168,17 @@ export default function CreateControls(widgetType = null, widget = null, session // Restrict to only xml files (MIME) let topologyControlFiles = files == null? [] : files.filter( file => file.type.includes('xml')); DialogControls.push( - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} /> + validateForm(id)} handleChange={(e) => handleChange(e)} /> ); break; case 'Input': let inputBoundOnChange = (e) => { handleChange([e, {target: {id: 'signal', value: 0}}]); - } + }; DialogControls.push( validateForm(id)} handleChange={e => handleChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => inputBoundOnChange(e)} />, - validateForm(id)} simulationModels={simulationModels} handleChange={(e) => handleChange(e)} /> + validateForm(id)} signals={signals} handleChange={(e) => handleChange(e)} /> ); break; diff --git a/src/widget/edit-widget/edit-widget-signal-control.js b/src/widget/edit-widget/edit-widget-signal-control.js index 1f01bb7..1feb090 100644 --- a/src/widget/edit-widget/edit-widget-signal-control.js +++ b/src/widget/edit-widget/edit-widget-signal-control.js @@ -27,9 +27,7 @@ class EditWidgetSignalControl extends Component { super(props); this.state = { - widget: { - simulationModel: '' - } + widget: {} }; } @@ -40,28 +38,17 @@ class EditWidgetSignalControl extends Component { } render() { - const simulationModel = this.props.simulationModels.find(m => m._id === this.state.widget.simulationModel); - - let signalsToRender = []; - - if (simulationModel != null) { - if (this.props.input) { - signalsToRender = simulationModel ? simulationModel.inputMapping : []; - } else { - signalsToRender = simulationModel ? simulationModel.outputMapping : []; - } - } return ( Signal - this.props.handleChange(e)}> + this.props.handleChange(e)}> { - signalsToRender.length === 0 ? ( + this.props.signals.length === 0 ? ( ) : ( - signalsToRender.map((signal, index) => ( - + this.props.signals.map((signal, index) => ( + )) ) } diff --git a/src/widget/edit-widget/edit-widget-signals-control.js b/src/widget/edit-widget/edit-widget-signals-control.js index 947e8fc..2f38506 100644 --- a/src/widget/edit-widget/edit-widget-signals-control.js +++ b/src/widget/edit-widget/edit-widget-signals-control.js @@ -27,9 +27,7 @@ class EditWidgetSignalsControl extends Component { super(props); this.state = { - widget: { - simulator: {} - } + widget: { } }; } @@ -39,40 +37,31 @@ class EditWidgetSignalsControl extends Component { }; } - handleSignalChange(checked, index) { - var signals = this.state.widget[this.props.controlId]; + handleSignalChange(checked, signalID) { + var signals = this.state.widget.signalIDs; var new_signals; if (checked) { // add signal - new_signals = signals.concat(index); + new_signals = signals.concat(signalID); } else { // remove signal - new_signals = signals.filter( (idx) => idx !== index ); + new_signals = signals.filter( (id) => id !== signalID ); } this.props.handleChange({ target: { id: this.props.controlId, value: new_signals } }); } render() { - const simulationModel = this.props.simulationModels.find(m => m._id === this.state.widget.simulationModel); - - let signalsToRender = []; - - if (simulationModel != null) { - // If simulation model update the signals to render - signalsToRender = simulationModel ? simulationModel.outputMapping : []; - } - return ( Signals { - signalsToRender.length === 0 || !this.state.widget.hasOwnProperty(this.props.controlId)? ( + this.props.signals === 0 || !this.state.widget.hasOwnProperty(this.props.controlId)? ( No signals available ) : ( - signalsToRender.map((signal, index) => ( - this.handleSignalChange(e.target.checked, index)}>{signal.name} + this.props.signals.map((signal, index) => ( + this.handleSignalChange(e.target.checked, signal.id)}>{signal.name} )) ) } diff --git a/src/widget/edit-widget/edit-widget.js b/src/widget/edit-widget/edit-widget.js index 1a2a0f6..64fefea 100644 --- a/src/widget/edit-widget/edit-widget.js +++ b/src/widget/edit-widget/edit-widget.js @@ -69,7 +69,7 @@ class EditWidgetDialog extends React.Component { handleChange(e) { // TODO: check what we really need in this function. Can we reduce its complexity? - if (e.constructor === Array) { + if (e.constructor === Array) { // Every property in the array will be updated let changes = e.reduce( (changesObject, event) => { changesObject[event.target.id] = event.target.value; @@ -80,46 +80,42 @@ class EditWidgetDialog extends React.Component { this.setState({ temporal: Object.assign({}, this.state.temporal, changes ) }); } - if(e.target.type !== 'text'){ - let changeObject = {}; - if (e.target.id === 'lockAspect') { - changeObject[e.target.id] = e.target.checked; + if(e.target.type !== 'text'){ + let changeObject = {}; + if (e.target.id === 'lockAspect') { + changeObject[e.target.id] = e.target.checked; - // correct image aspect if turned on - if (e.target.checked) { - changeObject = this.assignAspectRatio(changeObject, this.state.temporal.file); - } - } else if (e.target.id === 'file') { - changeObject[e.target.id] = e.target.value; - - // get file and update size (if it's an image) - if ('lockAspect' in this.state.temporal && this.state.temporal.lockAspect) { - changeObject = this.assignAspectRatio(changeObject, e.target.value); - } - } else if (e.target.type === 'checkbox') { - changeObject[e.target.id] = e.target.checked; - } else if (e.target.type === 'number') { - changeObject[e.target.id] = Number(e.target.value); + // correct image aspect if turned on + if (e.target.checked) { + changeObject = this.assignAspectRatio(changeObject, this.state.temporal.file); } + } else if (e.target.id === 'file') { + changeObject[e.target.id] = e.target.value; - else { - changeObject[e.target.id] = e.target.value; + // get file and update size (if it's an image) + if ('lockAspect' in this.state.temporal && this.state.temporal.lockAspect) { + changeObject = this.assignAspectRatio(changeObject, e.target.value); } + } else if (e.target.type === 'checkbox') { + changeObject[e.target.id] = e.target.checked; + } else if (e.target.type === 'number') { + changeObject[e.target.id] = Number(e.target.value); + } else { + changeObject[e.target.id] = e.target.value; + } + let finalChange = this.state.temporal; + finalChange.customProperties[e.target.id] = changeObject[e.target.id]; + this.setState({ temporal: finalChange}); + } else { + if(this.state.temporal[e.target.id]){ let finalChange = this.state.temporal; - finalChange.customProperties[e.target.id] = changeObject[e.target.id]; + finalChange[e.target.id] = e.target.value; this.setState({ temporal: finalChange}); } - else{ - if(this.state.temporal[e.target.id]){ - let finalChange = this.state.temporal; - - finalChange[e.target.id] = e.target.value; - this.setState({ temporal: finalChange}); - } - } + } } resetState() { @@ -151,7 +147,7 @@ class EditWidgetDialog extends React.Component { this.props.sessionToken, this.props.files, (id) => this.validateForm(id), - this.props.simulationModels, + this.props.signals, (e) => this.handleChange(e)); } diff --git a/src/widget/widget-area.js b/src/widget/widget-area.js index 69b0367..d33504c 100644 --- a/src/widget/widget-area.js +++ b/src/widget/widget-area.js @@ -40,7 +40,7 @@ class WidgetArea extends React.Component { position.x = this.snapToGrid(position.x); position.y = this.snapToGrid(position.y); - const widget = WidgetFactory.createWidgetOfType(item.name, position, this.props.defaultSimulationModel); + const widget = WidgetFactory.createWidgetOfType(item.name, position); if (this.props.onWidgetAdded != null) { this.props.onWidgetAdded(widget); @@ -66,7 +66,6 @@ WidgetArea.propTypes = { children: PropTypes.node, //TODO is .node correct here? Was .children before leading to compile error editing: PropTypes.bool, grid: PropTypes.number, - defaultSimulationModel: PropTypes.string, //widgets: PropTypes.array, onWidgetAdded: PropTypes.func }; diff --git a/src/widget/widget-factory.js b/src/widget/widget-factory.js index eb2dc68..b6905fa 100644 --- a/src/widget/widget-factory.js +++ b/src/widget/widget-factory.js @@ -25,7 +25,7 @@ import WidgetSlider from './widgets/slider'; class WidgetFactory { - static createWidgetOfType(type, position, defaultSimulationModel = null) { + static createWidgetOfType(type, position) { let widget = { name: 'Name', @@ -36,7 +36,8 @@ class WidgetFactory { y: position.y, z: position.z, locked: false, - customProperties: {} + customProperties: {}, + signalIDs: [], }; // set type specific properties @@ -60,14 +61,10 @@ class WidgetFactory { widget.customProperties.icon = 'star'; widget.width = 100; widget.height = 50; - widget.customProperties.simulationModel = defaultSimulationModel; break; case 'Action': - widget.customProperties.simulationModel = defaultSimulationModel; break; case 'Lamp': - widget.customProperties.simulationModel = defaultSimulationModel; - widget.customProperties.signal = 0; widget.minWidth = 5; widget.minHeight = 5; widget.width = 20; @@ -77,8 +74,6 @@ class WidgetFactory { widget.customProperties.threshold = 0.5; break; case 'Value': - widget.customProperties.simulationModel = defaultSimulationModel; - widget.customProperties.signal = 0; widget.minWidth = 70; widget.minHeight = 20; widget.width = 120; @@ -88,8 +83,6 @@ class WidgetFactory { widget.customProperties.showUnit = false; break; case 'Plot': - widget.customProperties.simulationModel = defaultSimulationModel; - widget.customProperties.signals = [ 0 ]; widget.customProperties.ylabel = ''; widget.customProperties.time = 60; widget.minWidth = 400; @@ -101,7 +94,6 @@ class WidgetFactory { widget.customProperties.yUseMinMax = false; break; case 'Table': - widget.customProperties.simulationModel = defaultSimulationModel; widget.minWidth = 200; widget.width = 300; widget.height = 200; @@ -116,9 +108,6 @@ class WidgetFactory { widget.customProperties.fontColor = 0; break; case 'PlotTable': - widget.customProperties.simulationModel = defaultSimulationModel; - widget.customProperties.preselectedSignals = []; - widget.customProperties.signals = []; // initialize selected signals widget.customProperties.ylabel = ''; widget.minWidth = 200; widget.minHeight = 100; @@ -143,16 +132,12 @@ class WidgetFactory { widget.height = 100; widget.customProperties.background_color = 1; widget.customProperties.font_color = 0; - widget.customProperties.simulationModel = defaultSimulationModel; - widget.customProperties.signal = 0; break; case 'Input': widget.minWidth = 200; widget.minHeight = 50; widget.width = 200; widget.height = 50; - widget.customProperties.simulationModel = defaultSimulationModel; - widget.customProperties.signal = 0; break; case 'Slider': widget.minWidth = 380; @@ -160,17 +145,13 @@ class WidgetFactory { widget.width = 400; widget.height = 50; widget.customProperties.orientation = WidgetSlider.OrientationTypes.HORIZONTAL.value; // Assign default orientation - widget.customProperties.simulationModel = defaultSimulationModel; - widget.customProperties.signal = 0; widget.customProperties.rangeMin = 0; widget.customProperties.rangeMax = 200; widget.customProperties.rangeUseMinMax = true; - widget.customProperties.showUnit = true + widget.customProperties.showUnit = true; break; case 'Gauge': - widget.customProperties.simulationModel = defaultSimulationModel; - widget.customProperties.signal = 0; widget.minWidth = 100; widget.minHeight = 150; widget.width = 150; diff --git a/src/widget/widget.js b/src/widget/widget.js index b227f41..ced0e4c 100644 --- a/src/widget/widget.js +++ b/src/widget/widget.js @@ -27,6 +27,7 @@ import LoginStore from '../user/login-store'; import SimulatorDataStore from '../simulator/simulator-data-store'; import SimulationModelStore from '../simulationmodel/simulation-model-store'; import FileStore from '../file/file-store'; +import SignalStore from '../signal/signal-store' import EditableWidgetContainer from './editable-widget-container'; import WidgetContainer from './widget-container'; @@ -52,7 +53,7 @@ import '../styles/widgets.css'; class Widget extends React.Component { static getStores() { - return [ SimulatorDataStore, SimulationModelStore, FileStore, LoginStore ]; + return [ SimulatorDataStore, SimulationModelStore, FileStore, LoginStore, SignalStore]; } static calculateState(prevState, props) { @@ -67,10 +68,25 @@ class Widget extends React.Component { simulatorData = SimulatorDataStore.getState(); } + // Get the simulator IDs and signal indexes for all signals of the widget + let simulationModels = SimulationModelStore.getState(); + // TODO make sure that the signals are only the signals that belong to the scenario at hand + let signals = SignalStore.getState(); + let simulatorIDs = []; + if ( props.data.signalIDs.length > 0){ + for (let i in props.data.signalIDs.length){ + let signal = signals.find(s => s.id === props.data.signalIDs[i]); + let model = simulationModels.find(m => m.id === signal.simulationModelID); + simulatorIDs[i] = model.simulatorID; + } + } + + return { simulatorData, + signals: signals, + simulatorIDs: simulatorIDs, files: FileStore.getState(), - simulationModels: SimulationModelStore.getState(), sequence: prevState != null ? prevState.sequence + 1 : 0, @@ -90,71 +106,53 @@ class Widget extends React.Component { });*/ // TODO no not load simulation models here, since they are loaded via the scenario, pass them as props - + /* AppDispatcher.dispatch({ type: 'simulationModels/start-load', token: this.state.sessionToken, param: '?scenarioID=1' // TODO do not hardcode scenarioID! }); - + */ } inputDataChanged(widget, data) { - let simulationModel = null; - - for (let model of this.state.simulationModels) { - if (model.id !== widget.simulationModel) { - continue; - } - - simulationModel = model; - } - + // The following assumes that a widget modifies/ uses exactly one signal AppDispatcher.dispatch({ type: 'simulatorData/inputChanged', - simulator: simulationModel.simulator, - signal: widget.signal, + simulator: this.state.simulatorIDs[0], + signal: this.state.signals[0].index, data }); } createWidget(widget) { - let simulationModel = null; - - for (let model of this.state.simulationModels) { - if (model.id !== widget.simulationModel) { - continue; - } - - simulationModel = model; - } if (widget.type === 'CustomAction') { - return + return } else if (widget.type === 'Action') { - return + return } else if (widget.type === 'Lamp') { - return + return } else if (widget.type === 'Value') { - return + return } else if (widget.type === 'Plot') { - return + return } else if (widget.type === 'Table') { - return + return } else if (widget.type === 'Label') { return } else if (widget.type === 'PlotTable') { - return this.props.onWidgetStatusChange(w, this.props.index)} paused={this.props.paused} /> + return this.props.onWidgetStatusChange(w, this.props.index)} paused={this.props.paused} /> } else if (widget.type === 'Image') { return } else if (widget.type === 'Button') { - return this.inputDataChanged(widget, value)} /> + return this.inputDataChanged(widget, value)} signals={this.state.signals} /> } else if (widget.type === 'NumberInput') { - return this.inputDataChanged(widget, value)} /> + return this.inputDataChanged(widget, value)} /> } else if (widget.type === 'Slider') { - return this.props.onWidgetStatusChange(w, this.props.index) } onInputChanged={value => this.inputDataChanged(widget, value)} /> + return this.props.onWidgetStatusChange(w, this.props.index) } onInputChanged={value => this.inputDataChanged(widget, value)} signals={this.state.signals}/> } else if (widget.type === 'Gauge') { - return + return } else if (widget.type === 'Box') { return } else if (widget.type === 'HTML') { diff --git a/src/widget/widgets/custom-action.js b/src/widget/widgets/custom-action.js index 4a3c0ca..15954de 100644 --- a/src/widget/widgets/custom-action.js +++ b/src/widget/widgets/custom-action.js @@ -41,11 +41,12 @@ class WidgetCustomAction extends Component { } static getDerivedStateFromProps(props, state){ - if (props.simulationModel === null) - return null; //no change + if(props.widget.signalIDs.length === 0){ + return null; + } return{ - simulator: SimulatorStore.getState().find(s => s._id === props.simulationModel.simulator), + simulator: SimulatorStore.getState().find(s => s.id === props.simulatorIDs[0]), sessionToken: LoginStore.getState().token }; } diff --git a/src/widget/widgets/gauge.js b/src/widget/widgets/gauge.js index 6d29e80..f029344 100644 --- a/src/widget/widgets/gauge.js +++ b/src/widget/widgets/gauge.js @@ -33,6 +33,7 @@ class WidgetGauge extends Component { this.state = { value: 0, + unit: '', minValue: null, maxValue: null, }; @@ -69,11 +70,21 @@ class WidgetGauge extends Component { } static getDerivedStateFromProps(props, state){ - if (props.simulationModel == null) { - return{value:0}; + + if(props.widget.signalIDs.length === 0){ + return null; } - const simulator = props.simulationModel.simulator; + let returnState = {} + + // Update unit (assuming there is exactly one signal for this widget) + let signalID = props.widget.signalIDs[0]; + let widgetSignal = props.signals.find(sig => sig.id === signalID); + if(widgetSignal !== undefined){ + returnState["unit"] = widgetSignal.unit; + } + + const simulator = props.simulatorIDs[0]; // update value if (props.data == null @@ -82,7 +93,7 @@ class WidgetGauge extends Component { || props.data[simulator].output.values == null || props.data[simulator].output.values.length === 0 || props.data[simulator].output.values[0].length === 0) { - return{value:0}; + returnState["value"] = 0; } // memorize if min or max value is updated @@ -91,11 +102,11 @@ class WidgetGauge extends Component { let updateMaxValue = false; // check if value has changed - const signal = props.data[simulator].output.values[props.widget.customProperties.signal]; + const signalData = props.data[simulator].output.values[widgetSignal.index]; // Take just 3 decimal positions // Note: Favor this method over Number.toFixed(n) in order to avoid a type conversion, since it returns a String - if (signal != null) { - const value = Math.round(signal[signal.length - 1].y * 1e3) / 1e3; + if (signalData != null) { + const value = Math.round(signalData[signalData.length - 1].y * 1e3) / 1e3; let minValue = null; let maxValue = null; if (state.value !== value && value != null) { @@ -149,7 +160,6 @@ class WidgetGauge extends Component { } // prepare returned state - let returnState = null; if(updateValue === true){ returnState["value"] = value; } @@ -160,8 +170,13 @@ class WidgetGauge extends Component { returnState["maxValue"] = maxValue; } - return returnState - } // if there is a signal + if (returnState !== {}){ + return returnState; + } + else{ + return null; + } + } // if there is signal data } @@ -218,17 +233,12 @@ class WidgetGauge extends Component { render() { const componentClass = this.props.editing ? "gauge-widget editing" : "gauge-widget"; - let signalType = null; - - if (this.props.simulationModel != null) { - signalType = (this.props.simulationModel != null && this.props.simulationModel.outputLength > 0 && this.props.widget.customProperties.signal < this.props.simulationModel.outputLength) ? this.props.simulationModel.outputMapping[this.props.widget.customProperties.signal].type : ''; - } return (
{this.props.widget.name}
this.gaugeCanvas = node} /> -
{signalType}
+
{this.state.unit}
{this.state.value}
); diff --git a/src/widget/widgets/input.js b/src/widget/widgets/input.js index dfd1318..566dd16 100644 --- a/src/widget/widgets/input.js +++ b/src/widget/widgets/input.js @@ -35,24 +35,31 @@ class WidgetInput extends Component { } static getDerivedStateFromProps(props, state){ - if (props.simulationModel == null) { + + if(props.widget.signalIDs.length === 0){ return null; } - let returnState = null; + let returnState = {}; + // Update value if (props.widget.customProperties.default_value && this.state.value === undefined) { returnState["value"] = props.widget.customProperties.default_value; } - // Update unit - if (props.widget.customProperties.simulationModel - && props.simulationModel.inputMapping - && state.unit !== props.simulationModel.inputMapping[props.widget.customProperties.signal].type) { - returnState["unit"] = props.simulationModel.inputMapping[props.widget.customProperties.signal].type; + // Update unit (assuming there is exactly one signal for this widget) + let signalID = props.widget.signalIDs[0]; + let signal = props.signals.find(sig => sig.id === signalID); + if(signal !== undefined){ + returnState["unit"] = signal.unit; } - return returnState; + if (returnState !== {}){ + return returnState; + } + else{ + return null; + } } valueIsChanging(newValue) { diff --git a/src/widget/widgets/lamp.js b/src/widget/widgets/lamp.js index 061803c..2c1cc63 100644 --- a/src/widget/widgets/lamp.js +++ b/src/widget/widgets/lamp.js @@ -34,11 +34,13 @@ class WidgetLamp extends Component { } static getDerivedStateFromProps(props, state){ - if (props.simulationModel == null) { + if(props.widget.signalIDs.length === 0){ return{ value: ''}; } - const simulator = props.simulationModel.simulator; + const simulator = props.simulatorIDs[0]; + let signalID = props.widget.signalIDs[0]; + let widgetSignal = props.signals.find(sig => sig.id === signalID); // update value if (props.data == null @@ -49,9 +51,9 @@ class WidgetLamp extends Component { } // check if value has changed - const signal = props.data[simulator].output.values[props.widget.customProperties.signal]; - if (signal != null && state.value !== signal[signal.length - 1].y) { - return { value: signal[signal.length - 1].y }; + const signalData = props.data[simulator].output.values[widgetSignal.index]; + if (signalData != null && state.value !== signalData[signalData.length - 1].y) { + return { value: signalData[signalData.length - 1].y }; } return null; diff --git a/src/widget/widgets/slider.js b/src/widget/widgets/slider.js index 602ad92..e082c60 100644 --- a/src/widget/widgets/slider.js +++ b/src/widget/widgets/slider.js @@ -39,14 +39,21 @@ class WidgetSlider extends Component { super(props); this.state = { - unit: 'bla', + unit: '', }; } static getDerivedStateFromProps(props, state){ - if (props.simulationModel == null) { - return null; + if(props.widget.signalIDs.length === 0){ + + // set value to default + if (props.widget.customProperties.default_value && state.value === undefined) { + returnState["value"] = props.widget.customProperties.default_value; + } else { // if no default available + return null; + } + } let returnState = {}; @@ -56,11 +63,11 @@ class WidgetSlider extends Component { returnState["value"] = props.widget.customProperties.default_value; } - // Update unit - if (props.widget.customProperties.simulationModel - && props.simulationModel.inputMapping && - state.unit !== props.simulationModel.inputMapping[props.widget.customProperties.signal].type) { - returnState["unit"] = props.simulationModel.inputMapping[props.widget.customProperties.signal].type; + // Update unit (assuming there is exactly one signal for this widget) + let signalID = props.widget.signalIDs[0]; + let signal = props.signals.find(sig => sig.id === signalID); + if(signal !== undefined){ + returnState["unit"] = signal.unit; } if (returnState !== {}){ diff --git a/src/widget/widgets/table.js b/src/widget/widgets/table.js index 2843c8e..a56d1be 100644 --- a/src/widget/widgets/table.js +++ b/src/widget/widgets/table.js @@ -38,14 +38,24 @@ class WidgetTable extends Component { static getDerivedStateFromProps(props, state){ - if (props.simulationModel == null) { + + if(props.widget.signalIDs.length === 0){ return{ rows: [], sequence: null, }; } - const simulator = props.simulationModel.simulator; + + const simulator = props.simulatorIDs[0]; + let widgetSignals = props.signals.find(sig => { + for (let id of props.widget.signalIDs){ + if (id === sig.id){ + return true; + } + } + return false; + }); // check data if (props.data == null @@ -62,19 +72,17 @@ class WidgetTable extends Component { }; } - // check if new data, otherwise skip - /*if (state.sequence >= props.data[simulator.node][simulator.simulator].sequence) { - return; - }*/ - // get rows const rows = []; props.data[simulator].output.values.forEach((signal, index) => { - if (index < props.simulationModel.outputMapping.length) { + let s = widgetSignals.find( sig => sig.index === index); + // if the signal is used by the widget + if (s !== undefined) { + // push data of the signal rows.push({ - name: props.simulationModel.outputMapping[index].name, - unit: props.simulationModel.outputMapping[index].type, + name: s.name, + unit: s.unit, value: signal[signal.length - 1].y }); } diff --git a/src/widget/widgets/value.js b/src/widget/widgets/value.js index 6c9d32b..3293feb 100644 --- a/src/widget/widgets/value.js +++ b/src/widget/widgets/value.js @@ -33,26 +33,33 @@ class WidgetValue extends Component { } static getDerivedStateFromProps(props, state){ - if (props.simulationModel == null) { - return{ value: '' }; + if(props.widget.signalIDs.length === 0){ + return null; } - const simulator = props.simulationModel.simulator; + const simulator = props.simulatorIDs[0]; // update value - if (props.data == null || props.data[simulator] == null || props.data[simulator].output == null || props.data[simulator].output.values == null) { + if (props.data == null + || props.data[simulator] == null + || props.data[simulator].output == null + || props.data[simulator].output.values == null) { return{ value: '' }; } - // TODO fixme (unit) - //const unit = props.simulationModel.outputMapping[props.widget.customProperties.signal].type; - const unit = 42; + // Update unit (assuming there is exactly one signal for this widget) + let unit = ''; + let signalID = props.widget.signalIDs[0]; + let signal = props.signals.find(sig => sig.id === signalID); + if(signal !== undefined){ + unit = signal.unit; + } // check if value has changed - const signal = props.data[simulator].output.values[props.widget.customProperties.signal]; - if (signal != null && state.value !== signal[signal.length - 1].y) { + const signalData = props.data[simulator].output.values[signal.index]; + if (signalData != null && state.value !== signalData[signalData.length - 1].y) { return { - value: signal[signal.length - 1].y, + value: signalData[signalData.length - 1].y, unit: unit, }; }