Skip to content
Snippets Groups Projects
Verified Commit 381ef5a2 authored by Alexander-Krause's avatar Alexander-Krause
Browse files

first version for cytoscape and agent rendering

parent 9d110d7e
No related branches found
No related tags found
No related merge requests found
Showing
with 345 additions and 85 deletions
import DS from 'ember-data';
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';
import ENV from 'explorviz-frontend/config/environment';
const {JSONAPIAdapter} = DS;
const {APP} = ENV;
/**
* This Adapter operates as communication abstraction for all network requests,
* that refer to Process objects. It provides functions for fetching,
* updating and uploading.
*
* TODO more description
*
* @class Process-Adapter
* @extends DS.JSONAPIAdapter
*
* @module explorviz.extension.discovery
* @submodule network
*/
export default JSONAPIAdapter.extend(DataAdapterMixin,{
authorizer: 'authorizers:authorizers',
host: APP.API_ROOT,
namespace: "extension/discovery",
headers: {
"Accept": "application/vnd.api+json"
},
//@Override
urlForQueryRecord(query) {
const baseUrl = this.buildURL();
return `${baseUrl}/${query}`;
}
});
import Component from '@ember/component';
import layout from '../templates/components/node-overview';
import { inject as service } from '@ember/service';
// Declare globals
/*global cytoscape*/
......@@ -7,6 +8,9 @@ import layout from '../templates/components/node-overview';
export default Component.extend({
layout,
agentRepo: service("repos/agent-repository"),
cytoscapeGraph: null,
// @Override
/**
......@@ -17,10 +21,38 @@ export default Component.extend({
*/
didRender(){
this._super(...arguments);
this.setupListener();
this.initCytoscape();
},
// @Override
/**
* This overridden Ember Component lifecycle hook enables calling
* custom cleanup code.
*
* @method willDestroyElement
*/
willDestroyElement() {
this._super(...arguments);
this.removeListener();
},
setupListener() {
const self = this;
this.get('agentRepo').on('updated', function(newAgentList) {
self.updateCytoscapeGraph(newAgentList);
});
},
removeListener() {
this.get('agentRepo').off('updated');
},
/**
* This function is called once on the didRender event.
* It initializes cytoscape
......@@ -28,9 +60,8 @@ export default Component.extend({
* @method initCytoscape
*/
initCytoscape() {
// UNTESTED
var cy = cytoscape({
const cy = cytoscape({
container: document.getElementById('cy'),
boxSelectionEnabled: false,
......@@ -41,6 +72,12 @@ export default Component.extend({
.css({
'content': 'data(id)'
})
.selector('#explorVizBackend')
.css({
'content': '',
'background-fit': 'cover',
'background-image': 'img/explorviz-logo.png'
})
.selector('edge')
.css({
'curve-style': 'bezier',
......@@ -60,33 +97,22 @@ export default Component.extend({
elements: {
nodes: [
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{ data: { id: 'c' } },
{ data: { id: 'd' } },
{ data: { id: 'e' } }
{ data: { id: 'explorVizBackend' } }
],
edges: [
{ data: { id: 'a"e', weight: 1, source: 'a', target: 'e' } },
{ data: { id: 'ab', weight: 3, source: 'a', target: 'b' } },
{ data: { id: 'be', weight: 4, source: 'b', target: 'e' } },
{ data: { id: 'bc', weight: 5, source: 'b', target: 'c' } },
{ data: { id: 'ce', weight: 6, source: 'c', target: 'e' } },
{ data: { id: 'cd', weight: 2, source: 'c', target: 'd' } },
{ data: { id: 'de', weight: 7, source: 'd', target: 'e' } }
]
edges: []
},
layout: {
name: 'breadthfirst',
directed: true,
roots: '#a',
roots: '#explorVizBackend',
padding: 10
}
});
var bfs = cy.elements().bfs('#a', function(){}, true);
this.set('cytoscapeGraph', cy);
/*var bfs = cy.elements().bfs('#a', function(){}, true);
var i = 0;
var highlightNextEle = function(){
......@@ -99,6 +125,47 @@ export default Component.extend({
};
// kick off first highlight
highlightNextEle();
highlightNextEle();*/
},
updateCytoscapeGraph(newAgentList) {
this.debug('updating cytoscapeGraph');
const cy = this.get('cytoscapeGraph');
if(!cy) {
return;
}
newAgentList.forEach((agentRecord) => {
const processes = agentRecord.get('processes');
cy.startBatch();
processes.forEach((process) => {
const pid = process.get('pid');
console.log(pid);
cy.add(
{
group: "nodes",
data: { id: pid }
},
{
group: "edges",
data: { id: pid, source: pid, target: 'explorVizBackend' }
}
);
});
});
cy.endBatch();
//cy.layout();
cy.fit();
}
});
......@@ -11,6 +11,8 @@ export function initialize(appInstance) {
Router.map(function() {
this.route("discovery");
});
appInstance.lookup("service:agent-reload");
}
export default {
......
......@@ -17,9 +17,9 @@ import Model from 'ember-data/model';
*/
export default Model.extend({
agentIP: attr("string"),
agentPort: attr("string"),
ip: attr("string"),
port: attr("string"),
processList: hasMany("process")
processes: hasMany("process")
});
......@@ -24,6 +24,6 @@ export default Model.extend({
monitoredFlag: attr("boolean"),
webserverFlag: attr("boolean"),
responsibleAgent: belongsTo("agent")
agent: belongsTo("agent")
});
import Reload from 'explorviz-frontend/services/data-reload';
import AlertifyHandler from 'explorviz-frontend/mixins/alertify-handler';
import { inject as service } from '@ember/service';
/**
* This service reloads the latest-landscape every tenth second. See
* {{#crossLink "Service-Start"}}{{/crossLink}} for more information.
*
* @class Landscape-Reload-Service
* @extends Data-Reload-Service
*/
export default Reload.extend(AlertifyHandler, {
agentRepo: service("repos/agent-repository"),
// @Override
/**
* TODO
*
* @method init
*/
init() {
this._super(...arguments);
this.set('shallReload', true);
},
// @Override
/**
* TODO
*
* @method updateObject
*/
updateObject(){
const self = this;
this.debug("start agents-request");
this.get("store").findAll('agent', {include: 'processes'})
.then(success, failure).catch(error);
//--------------inner functions--------------
function success(agentList){
self.debug("end agents-request");
self.set('agentRepo.agentList', agentList);
self.get('agentRepo').notify();
}
function failure(e){
self.showAlertifyMessage("Agents couldn't be requested!" +
" Backend offline?");
self.debug("Agents couldn't be requested!", e);
}
function error(e){
self.debug("Error when fetching agents: ", e);
}
//------------End of inner functions------------
}
});
import Service from '@ember/service';
import Evented from '@ember/object/evented';
import { observer } from '@ember/object';
/**
* TODO
*
* @class Landscape-Repository-Service
* @extends Ember.Service
*/
export default Service.extend(Evented, {
agentList: null,
observer: observer("agentList.processList", function(){
this.trigger("updated", this.get("agentList"));
}),
notify() {
//this.trigger("updated", this.get("agentList"));
}
});
\ No newline at end of file
<div id="cy" class="cytoscape-container"></div>
\ No newline at end of file
<div id="cy" class="container cytoscape-container"></div>
<!-- {{#each post.comments as |comment|}}
{{#if comment.isLoading}}
<!-- Show spinner -->
{{else}}
<!-- Show the comment here -->
{{/if}}
{{/each}}
-->
\ No newline at end of file
<div class="container-fluid pre-scrollable" style="min-height: 100%;">
{{node-overview}}
<!-- <div class="container-fluid pre-scrollable" style="min-height: 100%;">
<!-- {{#each processList as |processPair|}}
<div class="row">
{{#each processPair as |process|}}
......@@ -7,6 +9,6 @@
</div>
{{/each}}
</div>
{{/each}} -->
{{node-overview}}
</div>
\ No newline at end of file
{{/each}}
</div>-->
\ No newline at end of file
export { default } from 'explorviz-frontend-extension-discovery/adapters/agent';
export { default } from 'explorviz-frontend-extension-discovery/services/agent-reload';
export { default } from 'explorviz-frontend-extension-discovery/services/repos/agent-repository';
/* jshint node: true */
'use strict';
var mergeTrees = require('broccoli-merge-trees');
var Funnel = require('broccoli-funnel');
module.exports = {
name: 'explorviz-frontend-extension-discovery',
// enable auto reload
isDevelopingAddon() {
return true;
},
// import public folder in host app
treeForPublic: function(tree) {
var assetsTree = new Funnel('public');
return mergeTrees([tree, assetsTree], {
overwrite: true
});
},
// import code files in host system
included: function(app) {
this._super.included.apply(this, arguments);
app.import('vendor/style.css');
app.import('vendor/cytoscape.min.js');
app.import('vendor/explorviz-logo.png');
}
};
public/img/explorviz-logo.png

54.9 KiB

import { moduleFor, test } from 'ember-qunit';
moduleFor('adapter:agent', 'Unit | Adapter | agent', {
// Specify the other units that are required for this test.
// needs: ['serializer:foo']
});
// Replace this with your real tests.
test('it exists', function(assert) {
let adapter = this.subject();
assert.ok(adapter);
});
import { moduleFor, test } from 'ember-qunit';
moduleFor('service:agent-reload', 'Unit | Service | agent reload', {
// Specify the other units that are required for this test.
// needs: ['service:foo']
});
// Replace this with your real tests.
test('it exists', function(assert) {
let service = this.subject();
assert.ok(service);
});
import { moduleFor, test } from 'ember-qunit';
moduleFor('service:repos/agent-repository', 'Unit | Service | repos/agent repository', {
// Specify the other units that are required for this test.
// needs: ['service:foo']
});
// Replace this with your real tests.
test('it exists', function(assert) {
let service = this.subject();
assert.ok(service);
});
......@@ -7,9 +7,7 @@
}
.cytoscape-container {
height: 100%;
height: 80%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment