diff --git a/app/components/time-series-plot.js b/app/components/time-series-plot.js new file mode 100644 index 0000000000000000000000000000000000000000..df05cb3db69e1feb9a998f9b6309c46b8e0fdb8a --- /dev/null +++ b/app/components/time-series-plot.js @@ -0,0 +1,29 @@ +import Ember from 'ember'; +// requires flot.js to be included in vendor.js (via ember-cli-build.js) + +const { Component, on, observer, computed, String, get} = Ember; + +export default Component.extend({ + tagName: 'div', + attributeBindings: ['style'], + timeSeries: [], + options: {}, + height: 300, + plot: null, + style: computed('height', function () { // flot requires a fix height + return String.htmlSafe(`height: ${this.get('height')}px;`); + }), + renderPlot: on('didInsertElement', observer('timeSeries.[]', function () { + this.debug('rendering plot'); + if(!this.element) { + return; + } + const $this = this.$(); + // flot data points are tuples/arrays [x,y], graphs are arrays of these + // TODO: index is not enough, should show timestamp or other x-axis label + const plotData = this.get('timeSeries.series').map((valueObj, index) => [index, get(valueObj, 'value')]); + // wrap in additional array since flot can handle multiple graphs at once, we only need one + const plot = $this.plot([plotData], this.get('options')).data('plot'); + this.set('plot', plot); + })) +}); \ No newline at end of file diff --git a/app/components/time-series.js b/app/components/time-series.js new file mode 100644 index 0000000000000000000000000000000000000000..bd441b735a24731ec0c61bb8b9eb0e529a6b952b --- /dev/null +++ b/app/components/time-series.js @@ -0,0 +1,20 @@ +import Ember from 'ember'; + +const { Component, computed } = Ember; + +export default Component.extend({ + timeSeries: null, + currentTab: 0, + isCurrentTab: computed('currentTab', function(index) { + return this.get('currentTab') === index; + }), + currentSeries: computed('timeSeries', 'currentTab', function() { + const allSeries = this.get(`timeSeries`); + return allSeries && allSeries[this.get('currentTab')]; + }), + actions: { + clickTab(index){ + this.set('currentTab', index); + } + } +}); \ No newline at end of file diff --git a/app/templates/components/time-series.hbs b/app/templates/components/time-series.hbs new file mode 100644 index 0000000000000000000000000000000000000000..cd3cbd9447548ed79cb6572e123d1aa04349cc14 --- /dev/null +++ b/app/templates/components/time-series.hbs @@ -0,0 +1,9 @@ +Series: +<ul class="nav nav-tabs"> + {{#each timeSeries as |series index| }} + <li class="{{if isCurrentTab 'active'}}"><a {{action 'clickTab' index}} href="javascript:void()">{{series.label}}</a></li> + {{/each}} +</ul> +{{#if currentSeries}} + {{time-series-plot timeSeries=currentSeries}} +{{/if}} \ No newline at end of file diff --git a/app/templates/deployments/single/details.hbs b/app/templates/deployments/single/details.hbs index d82cf8bbe866b587fe42b3e24fe46786399fb3b4..de109561aee0b662fddbd128809f8ede355a6a71 100644 --- a/app/templates/deployments/single/details.hbs +++ b/app/templates/deployments/single/details.hbs @@ -1 +1,3 @@ {{entity-details entity=model}} + +{{time-series timeSeries=model.timeSeries}} \ No newline at end of file diff --git a/bower.json b/bower.json index 3373fa3bd143753d044b5885d9110649bb181381..ef080daed2fdffcd12b7abf6f188b5c8eb16b350 100644 --- a/bower.json +++ b/bower.json @@ -7,6 +7,7 @@ "ember-qunit-notifications": "0.1.0", "visionmedia-debug": "2.2", "webcola": "^3.1.3", - "bootstrap-sass": "^3.3.6" + "bootstrap-sass": "^3.3.6", + "Flot": "flot#^0.8.3" } } diff --git a/ember-cli-build.js b/ember-cli-build.js index 832458dcf0194ea74763a6a7a393fa8ede75d81b..08e735f4b6720edc2208551d13227609f7d2d98b 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -27,6 +27,7 @@ module.exports = function(defaults) { // along with the exports of each module as its value. app.import('bower_components/webcola/WebCola/cola.js'); + app.import('bower_components/Flot/jquery.flot.js'); // time-series-plot component return app.toTree(); };