From 9553d5406d6f41491067caee3fef4bd20ae7302c Mon Sep 17 00:00:00 2001 From: Mathis Neumann <mathis@simpletechs.net> Date: Mon, 20 Jun 2016 16:47:40 +0200 Subject: [PATCH] add bootstrap, navbar and layout selection for architecture view --- app/components/architecture-viewer.js | 20 ++++++ .../component.js | 67 +++++-------------- app/services/graphing-service.js | 2 +- app/styles/_custom_bootstrap.scss | 56 ++++++++++++++++ app/styles/app.scss | 8 ++- app/styles/components/_cytoscape.scss | 5 +- app/templates/application.hbs | 29 ++++++-- app/templates/architectures/single.hbs | 4 +- app/templates/components/.gitkeep | 0 .../components/architecture-viewer.hbs | 16 +++++ bower.json | 3 +- ember-cli-build.js | 3 + package.json | 4 +- .../components/architecture-viewer-test.js | 24 +++++++ 14 files changed, 176 insertions(+), 65 deletions(-) create mode 100644 app/components/architecture-viewer.js create mode 100644 app/styles/_custom_bootstrap.scss delete mode 100644 app/templates/components/.gitkeep create mode 100644 app/templates/components/architecture-viewer.hbs create mode 100644 tests/integration/components/architecture-viewer-test.js diff --git a/app/components/architecture-viewer.js b/app/components/architecture-viewer.js new file mode 100644 index 0000000..db4e486 --- /dev/null +++ b/app/components/architecture-viewer.js @@ -0,0 +1,20 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + graph: null, + layoutAlgorithm: 'cose', + layoutAlgorithms: [ + "cose", + "cola" + ], + init() { + this._super(); + this.debug('init!', this.get('graph'), this.get('layoutAlgorithm')); + }, + actions: { + selectLayoutAlgorithm(value) { + this.debug('value', value); + this.set('layoutAlgorithm', value); + } + } +}); diff --git a/app/components/architecture-visualisation-cytoscape/component.js b/app/components/architecture-visualisation-cytoscape/component.js index 0ceae58..33e4b7b 100644 --- a/app/components/architecture-visualisation-cytoscape/component.js +++ b/app/components/architecture-visualisation-cytoscape/component.js @@ -6,57 +6,21 @@ import cytoscapeStyle from './style'; import _ from 'npm:lodash'; export default Ember.Component.extend({ + layoutAlgorithm: 'cose', classNames: ['cytoscapeRenderingSpace'], - dummyGraph: { - nodes: [ - { data: { id: 'nodeWebnode', label: 'Webnode', type: 'node' } }, - { data: { id: 'nodeLogicnode', label: 'Logicnode', type: 'node' } }, - { data: { id: 'nodeAdapter', label: 'Adapter', type: 'node' } }, - { data: { id: 'nodeDatabase', label: 'Database', type: 'node' } }, - { data: { id: 'serviceInstanceFrontEnd', label: 'Database', type: 'serviceInstance', parent: 'nodeWebnode' } }, - { data: { id: 'serviceInstanceCashDesk', label: 'CashDesk', type: 'serviceInstance', parent: 'nodeLogicnode' } }, - { data: { id: 'serviceInstanceInventory', label: 'Inventory', type: 'serviceInstance' }, parent: 'nodeLogicnode' }, - { data: { id: 'serviceInstanceData', label: 'Data', type: 'serviceInstance', parent: 'nodeLogicnode' } }, - { data: { id: 'serviceInstancePostgresSQL', label: 'PostgresSQL', type: 'serviceInstance', parent: 'nodeDatabase' } }, - ], - edges: [ - { data: { id: 'ad', source: 'a', target: 'd', weight: 100 } }, - ] - }, init: function()Â { - cycola( cytoscape, cola ); - + cycola( cytoscape, window.cola ); this._super(); - const self = this; - const log = self.debug.bind(self); - log('loaded'); - // this.interval = setInterval(function() { - // const graph = self.get('graph'); - - // log('update interval called', graph); - - // if(!graph) { - // return; // eventual consistent - // } - // const edges = graph.edges || []; - // const index = Math.floor(Math.random()*edges.length); - // if(Math.random() > 0.5) { - // edges.splice(index, 1); - // } else { // FIXME: does not render updates - // const children = _.get(graph, 'children', []); - // const randomNodeIndex = Math.floor(Math.random()*children.length); - // const randomNodeId = children[randomNodeIndex].id; - // graph.edges = _.set(edges, `${index}.target`, randomNodeId); - // log(`updating random edge (${index}) to target a random node id ${randomNodeId}`, randomNodeIndex, edges); - // } - // self.set('graph', graph); - // self.renderGraph(); - // }, 1000); + this.debug('loaded', this.get('graph')); }, willDestroyElement() { clearInterval(this.interval); }, - didInsertElement: function() { + layoutChanged: Ember.observer('layout', function(newLayout) { + this.debug('layout changed!', newLayout); + }), + renderGraph: function() { + this.debug('graph', this.get('graph')); this.cytoscape = cytoscape({ container: this.element, @@ -65,13 +29,18 @@ export default Ember.Component.extend({ style: cytoscapeStyle, - elements: this.get('graph'), // TODO! + elements: _.cloneDeep(this.get('graph')), // TODO! layout: { - name: 'cola', - padding: 5, - maxSimulationTime: 1000 + name: this.get('layoutAlgorithm'), + maxSimulationTime: 1000, + padding: 6, + ungrabifyWhileSimulating: true, + infinite: false } }); - } + + window.cy = cytoscape; + window.cytoscape = this.cytoscape; + }.on('didInsertElement').observes('layoutAlgorithm', 'graph') }); diff --git a/app/services/graphing-service.js b/app/services/graphing-service.js index c9b7f0c..5983992 100644 --- a/app/services/graphing-service.js +++ b/app/services/graphing-service.js @@ -47,10 +47,10 @@ export default Ember.Service.extend({ communicationInstances.forEach(instance => { const data = instance.toJSON({includeId: true}); - data.label = data.name; data.source = data.sourceId; data.target = data.targetId; data.technology = instance.store.peekRecord('communication', data.communicationId).get('technology'); + data.label = data.technology; this.debug('technology', data.technology); network.edges.push({ diff --git a/app/styles/_custom_bootstrap.scss b/app/styles/_custom_bootstrap.scss new file mode 100644 index 0000000..2533e71 --- /dev/null +++ b/app/styles/_custom_bootstrap.scss @@ -0,0 +1,56 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +// Core variables and mixins +@import "bootstrap/variables"; +@import "bootstrap/mixins"; + +// Reset and dependencies +@import "bootstrap/normalize"; +@import "bootstrap/print"; +@import "bootstrap/glyphicons"; + +// Core CSS +@import "bootstrap/scaffolding"; +@import "bootstrap/type"; +@import "bootstrap/code"; +@import "bootstrap/grid"; +@import "bootstrap/tables"; +@import "bootstrap/forms"; +@import "bootstrap/buttons"; + +// Components +// @import "bootstrap/component-animations"; +// @import "bootstrap/dropdowns"; +// @import "bootstrap/button-groups"; +// @import "bootstrap/input-groups"; +@import "bootstrap/navs"; +@import "bootstrap/navbar"; +// @import "bootstrap/breadcrumbs"; +// @import "bootstrap/pagination"; +// @import "bootstrap/pager"; +@import "bootstrap/labels"; +// @import "bootstrap/badges"; +// @import "bootstrap/jumbotron"; +// @import "bootstrap/thumbnails"; +@import "bootstrap/alerts"; +// @import "bootstrap/progress-bars"; +// @import "bootstrap/media"; +// @import "bootstrap/list-group"; +// @import "bootstrap/panels"; +// @import "bootstrap/responsive-embed"; +// @import "bootstrap/wells"; +// @import "bootstrap/close"; + +// Components w/ JavaScript +// @import "bootstrap/modals"; +// @import "bootstrap/tooltip"; +// @import "bootstrap/popovers"; +// @import "bootstrap/carousel"; + +// Utility classes +@import "bootstrap/utilities"; +@import "bootstrap/responsive-utilities"; \ No newline at end of file diff --git a/app/styles/app.scss b/app/styles/app.scss index 9fb42c0..0be045f 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -1,7 +1,9 @@ -body { - font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; -} @import "components/_architecture"; @import "components/_cytoscape"; +$navbar-default-bg: #312312; +$light-orange: #ff8c00; +$navbar-default-color: $light-orange; + +@import "custom_bootstrap"; \ No newline at end of file diff --git a/app/styles/components/_cytoscape.scss b/app/styles/components/_cytoscape.scss index 4fe0241..61c56f4 100644 --- a/app/styles/components/_cytoscape.scss +++ b/app/styles/components/_cytoscape.scss @@ -1,7 +1,8 @@ .cytoscapeRenderingSpace { - height: 100%; + height: 720px; + max-height: 100%; width: 100%; - position: absolute; left: 0; top: 0; + border: solid 1px #ccc; } \ No newline at end of file diff --git a/app/templates/application.hbs b/app/templates/application.hbs index afbc629..b8ae549 100644 --- a/app/templates/application.hbs +++ b/app/templates/application.hbs @@ -1,8 +1,27 @@ {{loading-slider isLoading=loading duration=250}} -<h2 id="title">Welcome to Ember</h2> -<ul> - <li>Go to {{#link-to 'home'}}Home{{/link-to}}</li> - <li>Go to {{#link-to 'architectures'}}Architekturen{{/link-to}}</li> -</ul> + +<nav class="navbar"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + {{#link-to 'home' class="navbar-brand"}}iObserve{{/link-to}} + </div> + <div id="navbar" class="navbar-collapse collapse"> + <ul class="nav navbar-nav"> + {{#link-to 'home' tagName='li'}} + {{#link-to 'home'}}Startseite{{/link-to}} + {{/link-to}} + {{#link-to 'architectures' tagName='li'}} + {{#link-to 'architectures'}}Architekturen{{/link-to}} + {{/link-to}} + </ul> + </div><!--/.nav-collapse --> + </div> +</nav> {{outlet}} diff --git a/app/templates/architectures/single.hbs b/app/templates/architectures/single.hbs index f4a058b..c46db69 100644 --- a/app/templates/architectures/single.hbs +++ b/app/templates/architectures/single.hbs @@ -1,3 +1 @@ -<div class="visualisationContainer"> - {{architecture-visualisation-cytoscape graph=model}} -</div> +{{architecture-viewer graph=model}} \ No newline at end of file diff --git a/app/templates/components/.gitkeep b/app/templates/components/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/templates/components/architecture-viewer.hbs b/app/templates/components/architecture-viewer.hbs new file mode 100644 index 0000000..9f185d5 --- /dev/null +++ b/app/templates/components/architecture-viewer.hbs @@ -0,0 +1,16 @@ +<div class="row"> + <div class="col-md-10 visualisationContainer"> + {{architecture-visualisation-cytoscape graph=graph layoutAlgorithm=layoutAlgorithm}} + </div> + <div class="col-md-2"> + <div class="form-group"> + <label for="layoutAlgorithm">Layout:</label> + <select class="form-control" id="layoutAlgorithm" onchange={{action "selectLayoutAlgorithm" value="target.value"}}> + {{#each layoutAlgorithms as |algorithm|}} + <option>{{algorithm}}</option> + {{/each}} + </select> + </div> + </div> +</div> + diff --git a/bower.json b/bower.json index d24ee72..0dc2645 100644 --- a/bower.json +++ b/bower.json @@ -7,6 +7,7 @@ "ember-qunit-notifications": "0.1.0", "d3": "^3.5.16", "visionmedia-debug": "2.2", - "webcola": "^3.1.3" + "webcola": "^3.1.3", + "bootstrap-sass": "^3.3.6" } } diff --git a/ember-cli-build.js b/ember-cli-build.js index ac770c2..93dde05 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -5,6 +5,9 @@ var EmberApp = require('ember-cli/lib/broccoli/ember-app'); module.exports = function(defaults) { var app = new EmberApp(defaults, { // Add options here + 'ember-cli-bootstrap-sassy': { + 'js': [] + } }); // Use `app.import` to add additional libraries to the generated diff --git a/package.json b/package.json index 6966775..95085c4 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "ember-cli": "2.4.2", "ember-cli-app-version": "^1.0.0", "ember-cli-babel": "^5.1.5", + "ember-cli-bootstrap-sassy": "0.5.3", "ember-cli-d3": "1.1.6", "ember-cli-dependency-checker": "^1.2.0", "ember-cli-htmlbars": "^1.0.1", @@ -46,7 +47,8 @@ "ember-load-initializers": "^0.5.0", "ember-resolver": "^2.0.3", "loader.js": "^4.0.0", - "lodash": "^4.11.1" + "lodash": "^4.11.1", + "node-sass": "^3.8.0" }, "dependencies": { "cytoscape": "^2.6.12", diff --git a/tests/integration/components/architecture-viewer-test.js b/tests/integration/components/architecture-viewer-test.js new file mode 100644 index 0000000..8046093 --- /dev/null +++ b/tests/integration/components/architecture-viewer-test.js @@ -0,0 +1,24 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('architecture-viewer', 'Integration | Component | architecture viewer', { + 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`{{architecture-viewer}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#architecture-viewer}} + template block text + {{/architecture-viewer}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); -- GitLab