mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-09 00:00:01 +01:00
Add missing files
This commit is contained in:
parent
c40974acf5
commit
3ec9cc3497
8 changed files with 353 additions and 13 deletions
27
app/components/flow-plot.js
Normal file
27
app/components/flow-plot.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'div',
|
||||
classNames: [ 'flow-plot' ],
|
||||
attributeBindings: [ 'style' ],
|
||||
|
||||
plot: null,
|
||||
data: [],
|
||||
options: {},
|
||||
height: '85%',
|
||||
|
||||
setupPlot: Ember.on('didInsertElement', function() {
|
||||
var plot = Ember.$.plot('#' + this.get('element').id, this.get('data'), this.get('options'));
|
||||
this.set('plot', plot);
|
||||
}),
|
||||
|
||||
updateData: Ember.observer('data.@each', function() {
|
||||
// update plot
|
||||
var plot = Ember.$.plot('#' + this.get('element').id, this.get('data'), this.get('options'));
|
||||
this.set('plot', plot);
|
||||
}),
|
||||
|
||||
style: Ember.computed('height', function() {
|
||||
return Ember.String.htmlSafe("height: " + this.get('height') + ";");
|
||||
})
|
||||
});
|
205
app/components/widget-plot.js
Normal file
205
app/components/widget-plot.js
Normal file
|
@ -0,0 +1,205 @@
|
|||
/**
|
||||
* File: widget-value.js
|
||||
* Author: Markus Grigull <mgrigull@eonerc.rwth-aachen.de>
|
||||
* Date: 08.12.2016
|
||||
* Copyright: 2016, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
**********************************************************************************/
|
||||
|
||||
import Ember from 'ember';
|
||||
import WidgetAbstract from './widget-abstract';
|
||||
|
||||
export default WidgetAbstract.extend({
|
||||
classNames: [ 'widgetPlot' ],
|
||||
|
||||
plotData: Ember.A([]),
|
||||
|
||||
plotOptions: {
|
||||
series: {
|
||||
lines: {
|
||||
show: true,
|
||||
lineWidth: 2
|
||||
},
|
||||
shadowSize: 0
|
||||
},
|
||||
xaxis: {
|
||||
mode: 'time',
|
||||
timeformat: '%M:%S',
|
||||
/*min: firstTimestamp,
|
||||
max: lastTimestamp,*/
|
||||
axisLabel: 'time [min]',
|
||||
axisLabelUseCanvas: true
|
||||
}/*,
|
||||
yaxis: {
|
||||
tickDecimals: 1,
|
||||
axisLabel: this.data.get('type'),
|
||||
axisLabelUseCanvas: true
|
||||
}*/
|
||||
},
|
||||
|
||||
signals: Ember.A([]),
|
||||
|
||||
_updateDataObserver: Ember.on('init', Ember.observer('widget.widgetData.simulator', function() {
|
||||
// get query for observer
|
||||
let simulatorId = this.get('widget.widgetData.simulator');
|
||||
let query = 'data.' + simulatorId + '.sequence';
|
||||
|
||||
// get plot settings
|
||||
let signals = this.get('widget.widgetData.signals');
|
||||
this.set('signals', signals);
|
||||
|
||||
this.addObserver(query, function() {
|
||||
// get values from array
|
||||
let values = this.get('data.' + simulatorId + '.flotValues');
|
||||
var updatedValues = this.get('plotData');
|
||||
|
||||
// update values
|
||||
var index = 0;
|
||||
|
||||
this.get('signals').forEach(function(signal) {
|
||||
updatedValues.replace(index, 1, Ember.A([ values[signal] ]));
|
||||
index += 1;
|
||||
});
|
||||
|
||||
this.set('plotData', updatedValues);
|
||||
});
|
||||
})),
|
||||
|
||||
doubleClick() {
|
||||
if (this.get('editing') === true) {
|
||||
// prepare modal
|
||||
this.set('name', this.get('widget.name'));
|
||||
this.set('errorMessage', null);
|
||||
|
||||
// get signal mapping for simulation model
|
||||
let self = this;
|
||||
let simulatorid = this.get('widget.widgetData.simulator');
|
||||
|
||||
this.get('widget.visualization').then((visualization) => {
|
||||
visualization.get('project').then((project) => {
|
||||
project.get('simulation').then((simulation) => {
|
||||
simulation.get('models').then((simulationModels) => {
|
||||
// find simulation model by simulatorid
|
||||
simulationModels.forEach(function(simulationModel) {
|
||||
simulationModel.get('simulator').then((simulator) => {
|
||||
if (simulator.get('simulatorid') === simulatorid) {
|
||||
// set simulation model
|
||||
self.set('simulationModel', simulationModel);
|
||||
self.set('simulationModelName', simulationModel.get('name'));
|
||||
|
||||
// set signals
|
||||
let mapping = simulationModel.get('mapping');
|
||||
|
||||
// uncheck all signals
|
||||
mapping.forEach(function(key) {
|
||||
self.set(key + 'Checked', false);
|
||||
});
|
||||
|
||||
self.get('signals').forEach(function(signal) {
|
||||
self.set(mapping[signal] + 'Checked', true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// show modal
|
||||
this.set('isShowingModal', true);
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
submitModal() {
|
||||
// verify properties
|
||||
let properties = this.getProperties('name');
|
||||
|
||||
if (properties['name'] === null || properties['name'] === "") {
|
||||
this.set('errorMessage', 'Widget name is missing');
|
||||
return;
|
||||
}
|
||||
|
||||
// set simulator by simulation model name
|
||||
let simulationModelName = this.get('simulationModelName');
|
||||
let self = this;
|
||||
|
||||
this.get('widget.visualization').then((visualization) => {
|
||||
visualization.get('project').then((project) => {
|
||||
project.get('simulation').then((simulation) => {
|
||||
simulation.get('models').then((simulationModels) => {
|
||||
// find simulation model by name
|
||||
simulationModels.forEach(function(simulationModel) {
|
||||
if (simulationModel.get('name') === simulationModelName) {
|
||||
simulationModel.get('simulator').then((simulator) => {
|
||||
// set simulator
|
||||
let widgetData = {};
|
||||
widgetData.simulator = simulator.get('simulatorid');
|
||||
|
||||
// set signals
|
||||
let mapping = simulationModel.get('mapping');
|
||||
widgetData.signals = [];
|
||||
|
||||
// uncheck all signals
|
||||
for (var i = 0; i < mapping.length; i++) {
|
||||
if (self.get(mapping[i] + 'Checked')) {
|
||||
widgetData.signals.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
// save properties
|
||||
properties['widgetData'] = widgetData;
|
||||
|
||||
console.log(properties);
|
||||
|
||||
self.get('widget').setProperties(properties);
|
||||
|
||||
self.get('widget').save().then(function() {
|
||||
self.set('isShowingModal', false);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
cancelModal() {
|
||||
this.set('isShowingModal', false);
|
||||
},
|
||||
|
||||
deleteModal() {
|
||||
// delete widget
|
||||
this.get('widget').destroyRecord();
|
||||
|
||||
this.set('isShowingModal', false);
|
||||
},
|
||||
|
||||
selectSimulationModel(simulationModelName) {
|
||||
// save simulation model
|
||||
this.set('simulationModelName', simulationModelName);
|
||||
|
||||
// get signal mapping for simulation model
|
||||
let self = this;
|
||||
|
||||
this.get('widget.visualization').then((visualization) => {
|
||||
visualization.get('project').then((project) => {
|
||||
project.get('simulation').then((simulation) => {
|
||||
simulation.get('models').then((simulationModels) => {
|
||||
// find simulation model by name
|
||||
simulationModels.forEach(function(simulationModel) {
|
||||
if (simulationModel.get('name') === simulationModelName) {
|
||||
self.set('simulationModel', simulationModel);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
|
@ -62,8 +62,8 @@ export default Ember.Controller.extend(FetchLiveDataMixin, {
|
|||
properties.type = 'widget-plot';
|
||||
properties.name = 'Plot';
|
||||
properties.width = 500;
|
||||
properties.height = 200;
|
||||
properties.widgetData = { signal: 0, simulator: defaultSimulatorid };
|
||||
properties.height = 400;
|
||||
properties.widgetData = { signals: [0], simulator: defaultSimulatorid, type: 'multiple' };
|
||||
} else {
|
||||
// DEBUG
|
||||
console.log('Add unknown widget ' + name);
|
||||
|
|
|
@ -24,19 +24,22 @@ export default Model.extend({
|
|||
|
||||
_flotValues: [],
|
||||
|
||||
historyValues: Ember.computed('_history', function() {
|
||||
return this._history;
|
||||
}),
|
||||
|
||||
_history: [],
|
||||
|
||||
_updateHistories: Ember.observer('values', function() {
|
||||
// save set of values with timestamp
|
||||
this._flotValues.push([this.get('timestamp'), this.get('values')[0]]);
|
||||
// update flot values
|
||||
let values = this.get('values');
|
||||
|
||||
// discard old values
|
||||
while (this._flotValues.length > 100) {
|
||||
this._flotValues.shift();
|
||||
// add empty arrays for each value
|
||||
while (this._flotValues.length < values.length) {
|
||||
this._flotValues.push([]);
|
||||
}
|
||||
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
this._flotValues[i].push([this.get('timestamp'), values[i]]);
|
||||
|
||||
// discard old values
|
||||
while (this._flotValues[i].length > 100) {
|
||||
this._flotValues[i].shift();
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
1
app/templates/components/flow-plot.hbs
Normal file
1
app/templates/components/flow-plot.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
56
app/templates/components/widget-plot.hbs
Normal file
56
app/templates/components/widget-plot.hbs
Normal file
|
@ -0,0 +1,56 @@
|
|||
<h4>{{widget.name}}</h4>
|
||||
|
||||
{{flow-plot data=plotData options=plotOptions}}
|
||||
|
||||
{{#if isShowingModal}}
|
||||
{{#modal-dialog attachment="middle center" translucentOverlay=true}}
|
||||
<h1>Plot</h1>
|
||||
|
||||
<form class="form-widget-plot" {{action 'submitModal' on='submit'}} >
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="name">Name</label>
|
||||
</td>
|
||||
<td>
|
||||
{{input id='name' placeholder='Enter widget name' value=name}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="simulator">Simulator</label>
|
||||
</td>
|
||||
<td>
|
||||
<select onchange={{action "selectSimulationModel" value="target.value"}} >
|
||||
{{#each widget.visualization.project.simulation.models as |simulationModel|}}
|
||||
<option value={{simulationModel.name}} selected={{eq simulationModelName simulationModel.name}}>{{simulationModel.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="signals">Signals</label>
|
||||
</td>
|
||||
<td>
|
||||
{{#each simulationModel.mapping as |signal|}}
|
||||
<input type='checkbox' name={{signal}} checked={{concat signal "Checked"}} /><label for={{signal}}> {{signal}}</label>
|
||||
<br />
|
||||
{{/each}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<button {{action 'cancelModal'}}>Cancel</button>
|
||||
<button type="submit">Save</button>
|
||||
<button {{action 'deleteModal'}}>Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
{{#if errorMessage}}
|
||||
<p><b>Error:</b> {{errorMessage}}</p>
|
||||
{{/if}}
|
||||
{{/modal-dialog}}
|
||||
{{/if}}
|
24
tests/integration/components/flow-plot-test.js
Normal file
24
tests/integration/components/flow-plot-test.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('flow-plot', 'Integration | Component | flow plot', {
|
||||
integration: true
|
||||
});
|
||||
|
||||
test('it renders', function(assert) {
|
||||
// Set any properties with this.set('myProperty', 'value');
|
||||
// Handle any actions with this.on('myAction', function(val) { ... });
|
||||
|
||||
this.render(hbs`{{flow-plot}}`);
|
||||
|
||||
assert.equal(this.$().text().trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
this.render(hbs`
|
||||
{{#flow-plot}}
|
||||
template block text
|
||||
{{/flow-plot}}
|
||||
`);
|
||||
|
||||
assert.equal(this.$().text().trim(), 'template block text');
|
||||
});
|
24
tests/integration/components/widget-plot-test.js
Normal file
24
tests/integration/components/widget-plot-test.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('widget-plot', 'Integration | Component | widget plot', {
|
||||
integration: true
|
||||
});
|
||||
|
||||
test('it renders', function(assert) {
|
||||
// Set any properties with this.set('myProperty', 'value');
|
||||
// Handle any actions with this.on('myAction', function(val) { ... });
|
||||
|
||||
this.render(hbs`{{widget-plot}}`);
|
||||
|
||||
assert.equal(this.$().text().trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
this.render(hbs`
|
||||
{{#widget-plot}}
|
||||
template block text
|
||||
{{/widget-plot}}
|
||||
`);
|
||||
|
||||
assert.equal(this.$().text().trim(), 'template block text');
|
||||
});
|
Loading…
Add table
Reference in a new issue