mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-09 00:00:01 +01:00
display signals with PlotTable widget #218
This commit is contained in:
parent
c1b513cd34
commit
a7ca4d4514
3 changed files with 61 additions and 96 deletions
|
@ -80,7 +80,7 @@ class Plot extends React.Component {
|
|||
}
|
||||
|
||||
// check if data is invalid
|
||||
if (props.data == null || props.data.length === 0 || props.data[0].length === 0) {
|
||||
if (props.data == null || props.data.length === 0) {
|
||||
// create empty plot axes
|
||||
let xScale;
|
||||
let yScale;
|
||||
|
@ -116,11 +116,14 @@ class Plot extends React.Component {
|
|||
|
||||
// only show data in requested time
|
||||
let data = props.data;
|
||||
let icDataset = data.find(function(element) {
|
||||
return element !== undefined;
|
||||
})
|
||||
|
||||
const firstTimestamp = data[0][data[0].length - 1].x - (props.time + 1) * 1000;
|
||||
if (data[0][0].x < firstTimestamp) {
|
||||
const firstTimestamp = icDataset[icDataset.length - 1].x - (props.time + 1) * 1000;
|
||||
if (icDataset[0].x < firstTimestamp) {
|
||||
// only show data in range (+100 ms)
|
||||
const index = data[0].findIndex(value => value.x >= firstTimestamp - 100);
|
||||
const index = icDataset.findIndex(value => value.x >= firstTimestamp - 100);
|
||||
data = data.map(values => values.slice(index));
|
||||
}
|
||||
|
||||
|
@ -177,7 +180,11 @@ class Plot extends React.Component {
|
|||
if (this.props.yUseMinMax) {
|
||||
yRange = [this.props.yMin, this.props.yMax];
|
||||
} else if (this.props.data.length > 0) {
|
||||
yRange = [this.props.data[0][0].y, this.props.data[0][0].y];
|
||||
let icDataset = this.props.data.find(function(element) {
|
||||
return element !== undefined;
|
||||
})
|
||||
|
||||
yRange = [icDataset[0].y, icDataset[0].y];
|
||||
|
||||
this.props.data.forEach(values => {
|
||||
const range = extent(values, p => p.y);
|
||||
|
|
|
@ -69,14 +69,12 @@ class Widget extends React.Component {
|
|||
// TODO make sure that the signals are only the signals that belong to the scenario at hand
|
||||
let signals = SignalStore.getState();
|
||||
let icIDs = [];
|
||||
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 config = configs.find(m => m.id === signal.configID);
|
||||
icIDs[i] = config.icID;
|
||||
}
|
||||
}
|
||||
|
||||
for (let id of props.data.signalIDs){
|
||||
let signal = signals.find(s => s.id === id);
|
||||
let config = configs.find(m => m.id === signal.configID);
|
||||
icIDs[signal.id] = config.icID;
|
||||
}
|
||||
|
||||
return {
|
||||
icData: icData,
|
||||
|
@ -138,7 +136,7 @@ class Widget extends React.Component {
|
|||
} else if (widget.type === 'Label') {
|
||||
return <WidgetLabel widget={widget} />
|
||||
} else if (widget.type === 'PlotTable') {
|
||||
return <WidgetPlotTable widget={widget} data={this.state.icData} dummy={this.state.sequence} editing={this.props.editing} onWidgetChange={(w) => this.props.onWidgetStatusChange(w, this.props.index)} paused={this.props.paused} />
|
||||
return <WidgetPlotTable widget={widget} data={this.state.icData} dummy={this.state.sequence} signals={this.state.signals} icIDs={this.state.icIDs} editing={this.props.editing} onWidgetChange={(w) => this.props.onWidgetStatusChange(w, this.props.index)} paused={this.props.paused} />
|
||||
} else if (widget.type === 'Image') {
|
||||
return <WidgetImage widget={widget} files={this.state.files} token={this.state.sessionToken} />
|
||||
} else if (widget.type === 'Button') {
|
||||
|
|
|
@ -27,124 +27,85 @@ class WidgetPlotTable extends Component {
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
preselectedSignals: [],
|
||||
signals: []
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Readonly<P>, prevState: Readonly<S>, snapshot: SS): void {
|
||||
if (this.props.config == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update internal selected signals state with props (different array objects)
|
||||
if (prevProps.widget.customProperties.signals !== this.props.widget.customProperties.signals) {
|
||||
this.setState( {signals: this.props.widget.customProperties.signals});
|
||||
}
|
||||
|
||||
// Identify if there was a change in the preselected signals
|
||||
if (JSON.stringify(prevProps.widget.customProperties.preselectedSignals) !== JSON.stringify(this.props.widget.customProperties.preselectedSignals)
|
||||
|| this.state.preselectedSignals.length === 0) {
|
||||
// Update the currently selected signals by intersecting with the preselected signalsWidget
|
||||
// Do the same with the plot values
|
||||
var intersection = this.computeIntersection(this.props.widget.customProperties.preselectedSignals, this.props.widget.customProperties.signals);
|
||||
this.setState({ signals: intersection });
|
||||
|
||||
this.updatePreselectedSignalsState(this.props);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the intersection of the lists, alternatively could be done with Sets ensuring unique values
|
||||
computeIntersection(preselectedSignals, selectedSignals) {
|
||||
return preselectedSignals.filter( s => selectedSignals.includes(s));
|
||||
}
|
||||
|
||||
updatePreselectedSignalsState(props) {
|
||||
// Create checkboxes using the signal indices from component config
|
||||
if(props.config.outputMapping){
|
||||
const preselectedSignals = props.config.outputMapping.reduce(
|
||||
// Loop through component config signals
|
||||
(accum, signal, signal_index) => {
|
||||
// Append them if they belong to the current selected type
|
||||
if (props.widget.customProperties.preselectedSignals.indexOf(signal_index) > -1) {
|
||||
accum.push(
|
||||
{
|
||||
index: signal_index,
|
||||
name: signal.name,
|
||||
type: signal.type
|
||||
}
|
||||
)
|
||||
// Identify if there was a change in the selected signals
|
||||
if (JSON.stringify(prevProps.widget.signalIDs) !== JSON.stringify(this.props.widget.signalIDs)
|
||||
|| this.state.signals.length === 0) {
|
||||
// Update the currently selected signals
|
||||
let intersection = []
|
||||
let signalID, sig;
|
||||
for (signalID of this.props.widget.signalIDs) {
|
||||
for (sig of this.props.signals) {
|
||||
if (signalID === sig.id) {
|
||||
intersection.push(sig);
|
||||
}
|
||||
return accum;
|
||||
}, []);
|
||||
|
||||
this.setState({ preselectedSignals });
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({signals: intersection});
|
||||
}
|
||||
}
|
||||
|
||||
updateSignalSelection(signal_index, checked) {
|
||||
// Update the selected signals and propagate to parent component
|
||||
var new_widget = Object.assign({}, this.props.widget, {
|
||||
signals: checked? this.state.signals.concat(signal_index) : this.state.signals.filter( (idx) => idx !== signal_index )
|
||||
signals: checked ? this.state.signals.concat(signal_index) : this.state.signals.filter((idx) => idx !== signal_index)
|
||||
});
|
||||
this.props.onWidgetChange(new_widget);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
let checkBoxes = [];
|
||||
let icData = [];
|
||||
let legendSignals = [];
|
||||
// Data passed to plot
|
||||
if (this.props.config) {
|
||||
let showLegend = false;
|
||||
|
||||
const ic = this.props.config.icID;
|
||||
if (this.state.signals.length > 0) {
|
||||
|
||||
if (this.props.data[ic] != null && this.props.data[ic].output != null && this.props.data[ic].output.values != null) {
|
||||
icData = this.props.data[ic].output.values.filter((values, index) => (
|
||||
this.props.widget.customProperties.signals.findIndex(value => value === index) !== -1
|
||||
));
|
||||
}
|
||||
showLegend = true;
|
||||
|
||||
// get data of preselected signals
|
||||
let signal;
|
||||
for (signal of this.state.signals) {
|
||||
|
||||
// determine ID of infrastructure component related to signal (via config)
|
||||
let icID = this.props.icIDs[signal.id]
|
||||
|
||||
if (this.props.data[icID] != null && this.props.data[icID].output != null && this.props.data[icID].output.values != null) {
|
||||
if (this.props.data[icID].output.values[signal.index] !== undefined){
|
||||
icData.push(this.props.data[icID].output.values[signal.index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state.preselectedSignals && this.state.preselectedSignals.length > 0) {
|
||||
// Create checkboxes using the signal indices from component config
|
||||
checkBoxes = this.state.preselectedSignals.map( (signal) => {
|
||||
var checked = this.state.signals.indexOf(signal.index) > -1;
|
||||
var chkBxClasses = classNames({
|
||||
checkBoxes = this.state.signals.map((signal) => {
|
||||
let checked = this.state.signals.indexOf(signal.index) > -1;
|
||||
let chkBxClasses = classNames({
|
||||
'btn': true,
|
||||
'btn-default': true,
|
||||
'active': checked
|
||||
});
|
||||
return <FormCheck key={signal.index} className={chkBxClasses} checked={checked} disabled={ this.props.editing } onChange={(e) => this.updateSignalSelection(signal.index, e.target.checked) } > { signal.name } </FormCheck>
|
||||
return <FormCheck key={signal.index} className={chkBxClasses} checked={checked} disabled={this.props.editing}
|
||||
onChange={(e) => this.updateSignalSelection(signal.index, e.target.checked)}> {signal.name} </FormCheck>
|
||||
});
|
||||
}
|
||||
|
||||
// Prepare an array with the signals to show in the legend
|
||||
legendSignals = this.state.preselectedSignals.reduce( (accum, signal, i) => {
|
||||
if (this.state.signals.includes(signal.index)) {
|
||||
accum.push({
|
||||
index: signal.index,
|
||||
name: signal.name,
|
||||
type: signal.type
|
||||
});
|
||||
}
|
||||
return accum;
|
||||
}, []);}
|
||||
|
||||
let showLegend = false;
|
||||
if(legendSignals !== []){
|
||||
showLegend = true;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="plot-table-widget" ref="wrapper">
|
||||
<div className="content">
|
||||
<div className="table-plot-row">
|
||||
<div className="widget-table">
|
||||
{ checkBoxes.length > 0 ? (
|
||||
{checkBoxes.length > 0 ? (
|
||||
<FormGroup className="btn-group-vertical">
|
||||
{ checkBoxes }
|
||||
{checkBoxes}
|
||||
</FormGroup>
|
||||
) : ( <small>No signal has been pre-selected.</small> )
|
||||
) : (<small>No signal has been pre-selected.</small>)
|
||||
}
|
||||
</div>
|
||||
|
||||
|
@ -162,13 +123,12 @@ class WidgetPlotTable extends Component {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
{showLegend? (
|
||||
<PlotLegend signals={legendSignals} /> ) : (<div></div>)
|
||||
{showLegend ? (
|
||||
<PlotLegend signals={this.state.signals}/>) : (<div></div>)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default WidgetPlotTable;
|
||||
|
|
Loading…
Add table
Reference in a new issue