mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-09 00:00:01 +01:00
Add visualizations and plots
Plots can be added via drag'n'drop.
This commit is contained in:
parent
5bc260b81c
commit
8337550390
25 changed files with 365 additions and 5 deletions
26
app/components/draggable-dropzone.js
Normal file
26
app/components/draggable-dropzone.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
var { set } = Ember;
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: [ 'draggableDropzone' ],
|
||||
classNameBindings: [ 'dragClass' ],
|
||||
dragClass: 'deactivated',
|
||||
|
||||
dragLeave(event) {
|
||||
event.preventDefault();
|
||||
set(this, 'dragClass', 'deactivated');
|
||||
},
|
||||
|
||||
dragOver(event) {
|
||||
event.preventDefault();
|
||||
set(this, 'dragClass', 'activated');
|
||||
},
|
||||
|
||||
drop(event) {
|
||||
var data = event.dataTransfer.getData('text/data');
|
||||
this.sendAction('dropped', data);
|
||||
|
||||
set(this, 'dragClass', 'deactivated');
|
||||
}
|
||||
});
|
13
app/components/draggable-item.js
Normal file
13
app/components/draggable-item.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
var { get } = Ember;
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: [ 'draggableItem' ],
|
||||
attributeBindings: [ 'draggable' ],
|
||||
draggable: 'true',
|
||||
|
||||
dragStart(event) {
|
||||
return event.dataTransfer.setData('text/data', get(this, 'content'));
|
||||
}
|
||||
});
|
4
app/components/plot-chart.js
Normal file
4
app/components/plot-chart.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
});
|
17
app/components/plot-container.js
Normal file
17
app/components/plot-container.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'div',
|
||||
attributeBindings: [ 'style' ],
|
||||
|
||||
plot: null,
|
||||
|
||||
style: function() {
|
||||
return 'width: ' + this.get('plot.width') + 'px; height: ' + this.get('plot.height') + 'px; border: 1px solid black;';
|
||||
}.property('plot'),
|
||||
|
||||
isTable: function() {
|
||||
var modelName = this.get('plot.constructor.modelName');
|
||||
return modelName === 'plot-table';
|
||||
}.property('plot.type')
|
||||
});
|
5
app/components/plot-table.js
Normal file
5
app/components/plot-table.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'table'
|
||||
});
|
4
app/components/plot-value.js
Normal file
4
app/components/plot-value.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
});
|
31
app/controllers/visualization/index.js
Normal file
31
app/controllers/visualization/index.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
plots: [],
|
||||
|
||||
actions: {
|
||||
addPlot(name) {
|
||||
var plot = null;
|
||||
|
||||
if (name === 'chart') {
|
||||
// create new chart plot
|
||||
plot = this.store.createRecord('plot', { name: 'Chart 1', signal: 'Signal 1' });
|
||||
} else if (name === 'table') {
|
||||
plot = this.store.createRecord('plot-table', { name: 'Table 1', signal: 'Signal 1', width: 500 });
|
||||
} else if (name === 'value') {
|
||||
plot = this.store.createRecord('plot', { name: 'Value 1', signal: 'Signal 1' });
|
||||
} else {
|
||||
// DEBUG
|
||||
console.log('Add plot: ' + name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (plot != null) {
|
||||
// add plot to visualization
|
||||
this.plots.pushObject(plot);
|
||||
} else {
|
||||
console.error('Unknown plot type: ' + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
7
app/models/plot-table.js
Normal file
7
app/models/plot-table.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import Plot from './plot';
|
||||
// import attr from 'ember-data/attr';
|
||||
// import { belongsTo, hasMany } from 'ember-data/relationships';
|
||||
|
||||
export default Plot.extend({
|
||||
type: 'table'
|
||||
});
|
|
@ -5,8 +5,9 @@ import attr from 'ember-data/attr';
|
|||
export default Model.extend({
|
||||
name: attr('string'),
|
||||
signal: attr('string'),
|
||||
//position:
|
||||
//size:
|
||||
title: attr('string')
|
||||
//backgroundColor:
|
||||
width: attr('number', { defaultValue: 100 }),
|
||||
height: attr('number', { defaultValue: 100 }),
|
||||
title: attr('string'),
|
||||
|
||||
type: 'plot'
|
||||
});
|
||||
|
|
|
@ -98,9 +98,53 @@ footer {
|
|||
}
|
||||
|
||||
#login {
|
||||
|
||||
|
||||
}
|
||||
|
||||
#login-form {
|
||||
padding: 20px 20px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visualization
|
||||
*/
|
||||
.plots {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.plot-toolbox {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.draggableDropzone {
|
||||
display: block;
|
||||
|
||||
min-height: 200px;
|
||||
|
||||
padding-top: 5px;
|
||||
padding-left: 10px;
|
||||
|
||||
border: 3px dashed #aaa;
|
||||
|
||||
&.activated {
|
||||
border-color: #2ecc71;
|
||||
}
|
||||
&.deactivated {
|
||||
border-color: #e1e1e1;
|
||||
}
|
||||
}
|
||||
|
||||
.draggableItem[draggable=true] {
|
||||
display: inline-block;
|
||||
background: #e1e1e1;
|
||||
cursor: move;
|
||||
|
||||
padding: 5px 10px;
|
||||
|
||||
border: 1px solid gray;
|
||||
|
||||
&:hover {
|
||||
background-color: #aaa;
|
||||
}
|
||||
}
|
||||
|
|
1
app/templates/components/draggable-dropzone.hbs
Normal file
1
app/templates/components/draggable-dropzone.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
1
app/templates/components/draggable-item.hbs
Normal file
1
app/templates/components/draggable-item.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
1
app/templates/components/plot-chart.hbs
Normal file
1
app/templates/components/plot-chart.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
5
app/templates/components/plot-container.hbs
Normal file
5
app/templates/components/plot-container.hbs
Normal file
|
@ -0,0 +1,5 @@
|
|||
{{#if isTable}}
|
||||
{{#plot-table plot=plot}}{{/plot-table}}
|
||||
{{else}}
|
||||
<strong>Plot</strong>
|
||||
{{/if}}
|
8
app/templates/components/plot-table.hbs
Normal file
8
app/templates/components/plot-table.hbs
Normal file
|
@ -0,0 +1,8 @@
|
|||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Signal X</td>
|
||||
<td>1.234</td>
|
||||
</tr>
|
1
app/templates/components/plot-value.hbs
Normal file
1
app/templates/components/plot-value.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{yield}}
|
|
@ -1,5 +1,28 @@
|
|||
<h1>{{model.name}}</h1>
|
||||
|
||||
<div class="plot-toolbox">
|
||||
<h3>Toolbox</h3>
|
||||
{{#draggable-item content='chart'}}
|
||||
<span>Chart</span>
|
||||
{{/draggable-item}}
|
||||
|
||||
{{#draggable-item content='table'}}
|
||||
<span>Table</span>
|
||||
{{/draggable-item}}
|
||||
|
||||
{{#draggable-item content='value'}}
|
||||
<span>Value</span>
|
||||
{{/draggable-item}}
|
||||
</div>
|
||||
|
||||
<div class="plots">
|
||||
{{#draggable-dropzone dropped='addPlot'}}
|
||||
{{#each plots as |plot|}}
|
||||
{{#plot-container plot=plot}}{{/plot-container}}
|
||||
{{/each}}
|
||||
{{/draggable-dropzone}}
|
||||
</div>
|
||||
|
||||
<p>
|
||||
{{#link-to "visualization.edit" model.id}}Edit visualization{{/link-to}}
|
||||
{{#link-to "visualization.delete" model.id}}Delete visualization{{/link-to}}
|
||||
|
|
24
tests/integration/components/draggable-dropzone-test.js
Normal file
24
tests/integration/components/draggable-dropzone-test.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('draggable-dropzone', 'Integration | Component | draggable dropzone', {
|
||||
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`{{draggable-dropzone}}`);
|
||||
|
||||
assert.equal(this.$().text().trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
this.render(hbs`
|
||||
{{#draggable-dropzone}}
|
||||
template block text
|
||||
{{/draggable-dropzone}}
|
||||
`);
|
||||
|
||||
assert.equal(this.$().text().trim(), 'template block text');
|
||||
});
|
24
tests/integration/components/draggable-item-test.js
Normal file
24
tests/integration/components/draggable-item-test.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('draggable-item', 'Integration | Component | draggable item', {
|
||||
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`{{draggable-item}}`);
|
||||
|
||||
assert.equal(this.$().text().trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
this.render(hbs`
|
||||
{{#draggable-item}}
|
||||
template block text
|
||||
{{/draggable-item}}
|
||||
`);
|
||||
|
||||
assert.equal(this.$().text().trim(), 'template block text');
|
||||
});
|
24
tests/integration/components/plot-chart-test.js
Normal file
24
tests/integration/components/plot-chart-test.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('plot-chart', 'Integration | Component | plot chart', {
|
||||
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`{{plot-chart}}`);
|
||||
|
||||
assert.equal(this.$().text().trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
this.render(hbs`
|
||||
{{#plot-chart}}
|
||||
template block text
|
||||
{{/plot-chart}}
|
||||
`);
|
||||
|
||||
assert.equal(this.$().text().trim(), 'template block text');
|
||||
});
|
24
tests/integration/components/plot-container-test.js
Normal file
24
tests/integration/components/plot-container-test.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('plot-container', 'Integration | Component | plot container', {
|
||||
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`{{plot-container}}`);
|
||||
|
||||
assert.equal(this.$().text().trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
this.render(hbs`
|
||||
{{#plot-container}}
|
||||
template block text
|
||||
{{/plot-container}}
|
||||
`);
|
||||
|
||||
assert.equal(this.$().text().trim(), 'template block text');
|
||||
});
|
24
tests/integration/components/plot-table-test.js
Normal file
24
tests/integration/components/plot-table-test.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('plot-table', 'Integration | Component | plot table', {
|
||||
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`{{plot-table}}`);
|
||||
|
||||
assert.equal(this.$().text().trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
this.render(hbs`
|
||||
{{#plot-table}}
|
||||
template block text
|
||||
{{/plot-table}}
|
||||
`);
|
||||
|
||||
assert.equal(this.$().text().trim(), 'template block text');
|
||||
});
|
24
tests/integration/components/plot-value-test.js
Normal file
24
tests/integration/components/plot-value-test.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('plot-value', 'Integration | Component | plot value', {
|
||||
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`{{plot-value}}`);
|
||||
|
||||
assert.equal(this.$().text().trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
this.render(hbs`
|
||||
{{#plot-value}}
|
||||
template block text
|
||||
{{/plot-value}}
|
||||
`);
|
||||
|
||||
assert.equal(this.$().text().trim(), 'template block text');
|
||||
});
|
12
tests/unit/controllers/visualization/index-test.js
Normal file
12
tests/unit/controllers/visualization/index-test.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:visualization/index', 'Unit | Controller | visualization/index', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
12
tests/unit/models/plot-table-test.js
Normal file
12
tests/unit/models/plot-table-test.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { moduleForModel, test } from 'ember-qunit';
|
||||
|
||||
moduleForModel('plot-table', 'Unit | Model | plot table', {
|
||||
// Specify the other units that are required for this test.
|
||||
needs: []
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let model = this.subject();
|
||||
// let store = this.store();
|
||||
assert.ok(!!model);
|
||||
});
|
Loading…
Add table
Reference in a new issue