1
0
Fork 0
This commit is contained in:
hkernbach 2016-07-07 16:44:21 +02:00
parent 9cf2fb9826
commit 87ddbf7f1d
9 changed files with 583 additions and 160 deletions

View File

@ -64,13 +64,16 @@
"frontend/js/lib/sigma.layout.noverlap.js",
"frontend/js/lib/sigma.plugins.fullScreen.js",
"frontend/js/lib/sigma.layout.fruchtermanReingold.js",
"frontend/js/lib/sigma.exporters.svg.js",
"frontend/js/lib/worker.js",
"frontend/js/lib/supervisor.js",
// END SIGMA LIBRARIES
// START NEW
"frontend/js/lib/wheelnav.slicePath.js",
"frontend/js/lib/wheelnav.min.js",
"frontend/js/lib/raphael.min.js",
"frontend/js/lib/raphael.icons.min.js",
// END NEW LIBRARIES
"frontend/js/lib/jsoneditor-min.js",
"frontend/js/lib/strftime-min.js",
"frontend/js/lib/d3.fisheye.min.js",

View File

@ -1,28 +1,31 @@
/* global AQL_EXECUTE */
'use strict';
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2010-2013 triAGENS GmbH, Cologne, Germany
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Michael Hackstein
/// @author Alan Plum
////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////
// DISCLAIMER
//
// Copyright 2010-2013 triAGENS GmbH, Cologne, Germany
// Copyright 2016 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// @author Michael Hackstein
// @author Heiko Kernbach
// @author Alan Plum
// //////////////////////////////////////////////////////////////////////////////
const joi = require('joi');
const dd = require('dedent');
@ -42,7 +45,7 @@ API_DOCS.basePath = `/_db/${encodeURIComponent(db._name())}`;
const router = createRouter();
module.exports = router;
router.get('/config.js', function(req, res) {
router.get('/config.js', function (req, res) {
const scriptName = req.get('x-script-name');
const basePath = req.trustProxy && scriptName || '';
res.send(
@ -56,7 +59,7 @@ router.get('/config.js', function(req, res) {
})
.response(['text/javascript']);
router.get('/whoAmI', function(req, res) {
router.get('/whoAmI', function (req, res) {
res.json({user: req.arangoUser || null});
})
.summary('Return the current user')
@ -65,7 +68,6 @@ router.get('/whoAmI', function(req, res) {
Returns "false" if authentication is disabled.
`);
const authRouter = createRouter();
router.use(authRouter);
@ -78,9 +80,8 @@ authRouter.use((req, res, next) => {
next();
});
router.get('/api/*', module.context.apiDocumentation({
swaggerJson(req, res) {
swaggerJson (req, res) {
res.json(API_DOCS);
}
}))
@ -89,8 +90,7 @@ router.get('/api/*', module.context.apiDocumentation({
Mounts the system API documentation.
`);
authRouter.get('shouldCheckVersion', function(req, res) {
authRouter.get('shouldCheckVersion', function (req, res) {
const versions = notifications.versions();
res.json(Boolean(versions && versions.enableVersionNotification));
})
@ -99,8 +99,7 @@ authRouter.get('shouldCheckVersion', function(req, res) {
Check if version check is allowed.
`);
authRouter.post('disableVersionCheck', function(req, res) {
authRouter.post('disableVersionCheck', function (req, res) {
notifications.setVersions({enableVersionNotification: false});
res.json('ok');
})
@ -109,8 +108,7 @@ authRouter.post('disableVersionCheck', function(req, res) {
Disable the version check in web interface
`);
authRouter.post('/query/explain', function(req, res) {
authRouter.post('/query/explain', function (req, res) {
const bindVars = req.body.bindVars;
const query = req.body.query;
const id = req.body.id;
@ -145,8 +143,7 @@ authRouter.post('/query/explain', function(req, res) {
Explains a query in a more user-friendly way than the query_api/explain
`);
authRouter.post('/query/upload/:user', function(req, res) {
authRouter.post('/query/upload/:user', function (req, res) {
let user = req.pathParams.user;
try {
@ -187,8 +184,7 @@ authRouter.post('/query/upload/:user', function(req, res) {
This function uploads all given user queries.
`);
authRouter.get('/query/download/:user', function(req, res) {
authRouter.get('/query/download/:user', function (req, res) {
let user = req.pathParams.user;
try {
@ -210,14 +206,12 @@ authRouter.get('/query/download/:user', function(req, res) {
Download and export all queries from the given username.
`);
authRouter.get('/query/result/download/:query', function(req, res) {
authRouter.get('/query/result/download/:query', function (req, res) {
let query;
try {
query = internal.base64Decode(req.pathParams.query);
query = JSON.parse(query);
}
catch (e) {
} catch (e) {
res.throw('bad request', e.message, {cause: e});
}
@ -232,8 +226,7 @@ authRouter.get('/query/result/download/:query', function(req, res) {
This function downloads the result of a user query.
`);
authRouter.post('/graph-examples/create/:name', function(req, res) {
authRouter.post('/graph-examples/create/:name', function (req, res) {
const name = req.pathParams.name;
if (['knows_graph', 'social', 'routeplanner'].indexOf(name) === -1) {
@ -249,8 +242,7 @@ authRouter.post('/graph-examples/create/:name', function(req, res) {
Create one of the given example graphs.
`);
authRouter.post('/job', function(req, res) {
authRouter.post('/job', function (req, res) {
db._frontend.save(Object.assign(req.body, {model: 'job'}));
res.json(true);
})
@ -265,8 +257,7 @@ authRouter.post('/job', function(req, res) {
Create a new job id entry in a specific system database with a given id.
`);
authRouter.delete('/job', function(req, res) {
authRouter.delete('/job', function (req, res) {
db._frontend.removeByExample({model: 'job'}, false);
res.json(true);
})
@ -275,8 +266,7 @@ authRouter.delete('/job', function(req, res) {
Delete all jobs in a specific system database with a given id.
`);
authRouter.delete('/job/:id', function(req, res) {
authRouter.delete('/job/:id', function (req, res) {
db._frontend.removeByExample({id: req.pathParams.id}, false);
res.json(true);
})
@ -285,8 +275,7 @@ authRouter.delete('/job/:id', function(req, res) {
Delete an existing job id entry in a specific system database with a given id.
`);
authRouter.get('/job', function(req, res) {
authRouter.get('/job', function (req, res) {
const result = db._frontend.all().toArray();
res.json(result);
})
@ -295,28 +284,30 @@ authRouter.get('/job', function(req, res) {
This function returns the job ids of all currently running jobs.
`);
authRouter.get('/graph/:name', function(req, res) {
var _ = require("lodash");
authRouter.get('/graph/:name', function (req, res) {
var _ = require('lodash');
var name = req.pathParams.name;
var gm = require("@arangodb/general-graph");
//var traversal = require("@arangodb/graph/traversal");
var gm = require('@arangodb/general-graph');
// var traversal = require("@arangodb/graph/traversal");
var graph = gm._graph(name);
var vertexName = graph._vertexCollections()[0].name();
var startVertex = db[vertexName].any();
var aqlQuery =
'FOR v, e, p IN 1..3 ANY "' + startVertex._id + '" GRAPH "' + name + '"' +
var aqlQuery =
'FOR v, e, p IN 1..3 ANY "' + startVertex._id + '" GRAPH "' + name + '"' +
'RETURN p'
;
var cursor = AQL_EXECUTE(aqlQuery);
var nodesObj = {}, nodesArr = [], edgesObj = {}, edgesArr = [];
var nodesObj = {};
var nodesArr = [];
var edgesObj = {};
var edgesArr = [];
_.each(cursor.json, function(obj) {
_.each(obj.edges, function(edge) {
_.each(cursor.json, function (obj) {
_.each(obj.edges, function (edge) {
if (edge._to && edge._from) {
edgesObj[edge._from + edge._to] = {
id: edge._id,
@ -327,11 +318,10 @@ authRouter.get('/graph/:name', function(req, res) {
}
});
var label;
_.each(obj.vertices, function(node) {
_.each(obj.vertices, function (node) {
if (node.label) {
label = node.label;
}
else {
} else {
label = node._id;
}
@ -346,11 +336,11 @@ authRouter.get('/graph/:name', function(req, res) {
});
});
//array format for sigma.js
_.each(edgesObj, function(node) {
// array format for sigma.js
_.each(edgesObj, function (node) {
edgesArr.push(node);
});
_.each(nodesObj, function(node) {
_.each(nodesObj, function (node) {
nodesArr.push(node);
});
@ -358,7 +348,6 @@ authRouter.get('/graph/:name', function(req, res) {
nodes: nodesArr,
edges: edgesArr
});
})
.summary('Return vertices and edges of a graph.')
.description(dd`

View File

@ -2,7 +2,7 @@
/* jshint strict: false, unused: false */
/* global Backbone, window, arangoDocumentModel, $, arangoHelper */
window.arangoDocument = Backbone.Collection.extend({
window.ArangoDocument = Backbone.Collection.extend({
url: '/_api/document/',
model: arangoDocumentModel,
collectionInfo: {},

View File

@ -0,0 +1,248 @@
;(function(undefined) {
'use strict';
/**
* Sigma SVG Exporter
* ===================
*
* This plugin is designed to export a graph to a svg file that can be
* downloaded or just used elsewhere.
*
* Author: Guillaume Plique (Yomguithereal)
* Version: 0.0.1
*/
// Terminating if sigma were not to be found
if (typeof sigma === 'undefined')
throw 'sigma.renderers.snapshot: sigma not in scope.';
/**
* Polyfills
*/
var URL = this.URL || this.webkitURL || this;
/**
* Utilities
*/
function createBlob(data) {
return new Blob(
[data],
{type: 'image/svg+xml;charset=utf-8'}
);
}
function download(string, filename) {
if (typeof safari !== 'undefined') {
var msg = "File download does not work in Safari. Please use a modern web browser such as Firefox, Chrome, or Internet Explorer 11.";
alert(msg);
throw new Error(msg);
}
// Blob
var blob = createBlob(string),
objectUrl = window.URL.createObjectURL(blob);
if (navigator.msSaveBlob) { // IE11+ : (has Blob, but not a[download])
navigator.msSaveBlob(blob, filename);
} else if (navigator.msSaveOrOpenBlob) { // IE10+ : (has Blob, but not a[download])
navigator.msSaveOrOpenBlob(blob, filename);
} else {
// A-download
var anchor = document.createElement('a');
anchor.setAttribute('href', objectUrl);
anchor.setAttribute('download', filename);
// Firefox requires the link to be added to the DOM before it can be clicked.
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
}
setTimeout(function() { // Firefox needs a timeout
window.URL.revokeObjectURL(objectUrl);
}, 0);
}
/**
* Defaults
*/
var DEFAULTS = {
size: '1000',
width: '1000',
height: '1000',
margin: 0.05,
classes: true,
labels: true,
data: false,
download: false,
filename: 'graph.svg'
};
var XMLNS = 'http://www.w3.org/2000/svg';
/**
* Subprocesses
*/
function optimize(svg, prefix, params) {
var nodeColorIndex = {},
edgeColorIndex = {},
count = 0,
color,
style,
styleText = '',
f,
i,
l;
// Creating style tag if needed
if (params.classes) {
style = document.createElementNS(XMLNS, 'style');
svg.insertBefore(style, svg.firstChild);
}
// Iterating over nodes
var nodes = svg.querySelectorAll('[id="' + prefix + '-group-nodes"] > [class="' + prefix + '-node"]');
for (i = 0, l = nodes.length, f = true; i < l; i++) {
color = nodes[i].getAttribute('fill');
if (!params.data)
nodes[i].removeAttribute('data-node-id');
if (params.classes) {
if (!(color in nodeColorIndex)) {
nodeColorIndex[color] = (f ? prefix + '-node' : 'c-' + (count++));
styleText += '.' + nodeColorIndex[color] + '{fill: ' + color + '}';
}
if (nodeColorIndex[color] !== prefix + '-node')
nodes[i].setAttribute('class', nodes[i].getAttribute('class') + ' ' + nodeColorIndex[color]);
nodes[i].removeAttribute('fill');
}
f = false;
}
// Iterating over edges
var edges = svg.querySelectorAll('[id="' + prefix + '-group-edges"] > [class="' + prefix + '-edge"]');
for (i = 0, l = edges.length, f = true; i < l; i++) {
color = edges[i].getAttribute('stroke');
if (!params.data)
edges[i].removeAttribute('data-edge-id');
if (params.classes) {
if (!(color in edgeColorIndex)) {
edgeColorIndex[color] = (f ? prefix + '-edge' : 'c-' + (count++));
styleText += '.' + edgeColorIndex[color] + '{stroke: ' + color + '}';
}
if (edgeColorIndex[color] !== prefix + '-edge')
edges[i].setAttribute('class', edges[i].getAttribute('class') + ' ' + edgeColorIndex[color]);
edges[i].removeAttribute('stroke');
}
f = false;
}
if (params.classes)
style.appendChild(document.createTextNode(styleText));
}
/**
* Extending prototype
*/
sigma.prototype.toSVG = function(params) {
params = params || {};
var prefix = this.settings('classPrefix'),
w = params.size || params.width || DEFAULTS.size,
h = params.size || params.height || DEFAULTS.size,
margin = params.margin || DEFAULTS.margin;
// Creating a dummy container
var container = document.createElement('div');
container.setAttribute('width', w);
container.setAttribute('height', h);
container.setAttribute('style', 'position:absolute; top: 0px; left:0px; width: ' + w + 'px; height: ' + h + 'px;');
// Add margin to deal with curved edges
var sideMargin = this.settings('sideMargin');
this.settings('sideMargin', margin);
// Fit graph to viewport
var autoRescale = this.settings('autoRescale');
this.settings('autoRescale', true);
// Creating a camera
var camera = this.addCamera();
// Creating a svg renderer
var renderer = this.addRenderer({
camera: camera,
container: container,
type: 'svg',
forceLabels: !!params.labels
});
// Refreshing
renderer.resize(w, h);
this.refresh();
// Dropping camera and renderers before something nasty happens
this.killRenderer(renderer);
this.killCamera(camera);
// reset setting
this.settings('sideMargin', sideMargin);
this.settings('autoRescale', autoRescale);
// Retrieving svg
var svg = container.querySelector('svg');
svg.removeAttribute('style');
svg.setAttribute('width', w + 'px');
svg.setAttribute('height', h + 'px');
svg.setAttribute('x', '0px');
svg.setAttribute('y', '0px');
// svg.setAttribute('viewBox', '0 0 1000 1000');
// Dropping labels
if (!params.labels) {
var labelGroup = svg.querySelector('[id="' + prefix + '-group-labels"]');
svg.removeChild(labelGroup);
}
// Dropping hovers
var hoverGroup = svg.querySelector('[id="' + prefix + '-group-hovers"]');
svg.removeChild(hoverGroup);
// Optims?
params.classes = (params.classes !== false);
if (!params.data || params.classes)
optimize(svg, prefix, params);
// Retrieving svg string
var svgString = svg.outerHTML;
// Paranoid cleanup
container = null;
// Output string
var output = '<?xml version="1.0" encoding="utf-8"?>\n';
output += '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n';
output += svgString;
if (params.download)
download(output, params.filename || DEFAULTS.filename);
return output;
};
}).call(this);

View File

@ -857,6 +857,9 @@
if (this.queryView) {
this.queryView.resize();
}
if (this.graphViewer2) {
this.graphViewer2.resize();
}
if (this.documentsView) {
this.documentsView.resize();
}

View File

@ -30,8 +30,38 @@
<div class="pure-g pure-table pure-table-body">
<% _.each(specific, function(val, key) { %>
<div class="<%= genClass %> left"><%=key%></div>
<div class="<%= genClass %> left"><%=val%></div>
<div class="<%= genClass %> left"><%=val.name%></div>
<div class="<%= genClass %> left">
<% var VALUE; %>
<% if (val.value) { %>
<% VALUE = val.value %>
<% } else { %>
<% VALUE = val.default %>
<% } %>
<% if (val.type === 'string') { %>
<input type="text" value="<%=VALUE%>" placeholder=""></input>
<% } %>
<% if (val.type === 'color') { %>
<input type='color' name='color' value="<%=VALUE%>"/>
<% } %>
<% if (val.type === 'select') { %>
<div class="<%= genClass %> left">
<select>
<% _.each(val, function(option, optKey) { %>
<% if (option.name) { %>
<option> <%=option.name%> </option>
<% } %>
<% }); %>
</select>
</div>
<% } %>
</div>
<% }); %>
</div>
@ -55,15 +85,33 @@
</div>
<div class="pure-g pure-table pure-table-body">
<% _.each(general, function(val, key) { %>
<div class="<%= genClass %> left"><%=key%></div>
<div class="<%= genClass %> left"><%=val%></div>
<% if (val.type === 'select') { %>
<div class="<%= genClass %> left">
<select>
<% _.each(val, function(option, optKey) { %>
<% if (option.name) { %>
<option> <%=option.name%> </option>
<% } %>
<% }); %>
</select>
</div>
<% } %>
<% if (val.type === 'numeric') { %>
<input type="text" id="<%=val %>" value="<%=val.value %>" placeholder=""></input>
<% } %>
<% }); %>
</div>
</div>
<button id="saveGraphSettings" style="margin-top: 20px;" class="button-success pull-right">Save</button>
<button id="saveGraphSettings" style="margin-top: 20px;" class="button-success pull-right">Restore defaults</button>
</div>
</script>

View File

@ -5,10 +5,23 @@
<div class="headerButtonBar" style="margin: 0;">
<ul class="headerButtonList">
<li class="enabled">
<a id="addDocument" class="headerButton">
<span title="Add new document">
<i class="fa fa-file fa-stack-1x"></i>
<i class="fa fa-plus fa-stack-1x fa-top"></i>
<a id="graph-fullscreen-btn" class="headerButton">
<span title="Switch to fullscreen mode">
<i class="fa fa-television"></i>
</span>
</a>
</li>
<li class="enabled">
<a id="downloadPNG" class="headerButton">
<span title="Download visible graph as png image">
<i class="fa fa-camera fa-stack-1x"></i>
</span>
</a>
</li>
<li class="enabled">
<a id="selectNodes" class="headerButton">
<span title="Download visible graph as png image">
<i class="fa fa-pencil fa-stack-1x"></i>
</span>
</a>
</li>
@ -16,7 +29,7 @@
</div>
</div>
<div id="graph-fullscreen-btn"><i class="fa fa-television"></i></div>
<!--<div id="graph-fullscreen-btn"><i class="fa fa-desktop"></i></div>-->
<div id="graph-container" oncontextmenu="return false;"></div>
</div>
</script>

View File

@ -8,14 +8,81 @@
el: '#content',
general: {
'layout': undefined,
'depth': undefined
'Layout': {
type: 'select',
noverlap: {
name: 'No overlap (fast)'
},
force: {
name: 'Force (slow)'
},
fruchtermann: {
name: 'Fruchtermann (very slow)'
}
},
'Renderer': {
type: 'select',
canvas: {
name: 'Canvas (editable)'
},
webgl: {
name: 'WebGL (only display)'
}
},
'depth': {
type: 'numeric',
value: 2
}
},
specific: {
'node_label': undefined,
'node_color': undefined,
'node_size': undefined
'nodeLabel': {
type: 'string',
name: 'Node label',
desc: 'Default node color. RGB or HEX value.',
default: '_key'
},
'nodeColor': {
type: 'color',
name: 'Node color',
desc: 'Default node color. RGB or HEX value.',
default: '#2ecc71'
},
'nodeSize': {
type: 'string',
name: 'Node size',
desc: 'Default node size. Numeric value > 0.',
value: undefined
},
'edgeLabel': {
type: 'string',
name: 'Edge label',
desc: 'Default edge label.',
value: undefined
},
'edgeColor': {
type: 'color',
name: 'Edge color',
desc: 'Default edge color. RGB or HEX value.',
default: '#cccccc'
},
'edgeSize': {
type: 'string',
name: 'Edge thickness',
desc: 'Default edge thickness. Numeric value > 0.',
value: undefined
},
'edgeType': {
type: 'select',
name: 'Edge type',
desc: 'The type of the edge',
canvas: {
name: 'Straight'
},
webgl: {
name: 'Curved'
}
}
},
template: templateEngine.createTemplate('graphSettingsView.ejs'),
@ -24,6 +91,14 @@
this.name = options.name;
},
loadGraphSettings: function () {
},
saveGraphSettings: function () {
},
events: {
},
@ -33,6 +108,9 @@
specific: this.specific
}));
arangoHelper.buildGraphSubNav(this.name, 'Settings');
// load graph settings from local storage
// apply those values to view then
}
});

View File

@ -14,6 +14,10 @@
this.initSigma();
},
events: {
'click #downloadPNG': 'downloadSVG'
},
initSigma: function () {
// init sigma
try {
@ -30,19 +34,40 @@
} catch (ignore) {}
},
downloadSVG: function () {
var self = this;
this.currentGraph.toSVG({
download: true,
filename: self.name + '.svg',
size: 1000
});
},
resize: function () {
// adjust container widht + height
$('#graph-container').width($('.centralContent').width());
$('#graph-container').height($('.centralRow').height() - 150);
},
render: function () {
this.$el.html(this.template.render({}));
arangoHelper.buildGraphSubNav(this.name, 'Content');
// adjust container widht + height
$('#graph-container').width($('.centralContent').width());
$('#graph-container').height($('.centralRow').height() - 150);
this.resize();
this.fetchGraph();
},
fetchGraph: function () {
var self = this;
$('#content').append(
'<div id="calculatingGraph" style="position: absolute; left: 25px; top: 130px;">' +
'<i class="fa fa-circle-o-notch fa-spin" style="margin-right: 10px;"></i>' +
'Calculating layout. Please wait ... </div>'
);
// TODO LOAD GRAPH SETTINGS
// var settings = this.loadGraphSettings();
$.ajax({
type: 'GET',
@ -50,6 +75,9 @@
contentType: 'application/json',
success: function (data) {
self.renderGraph(data);
},
error: function () {
$('#calculatingGraph').html('Failed to fetch graph information.');
}
});
},
@ -117,6 +145,12 @@
generateMenu(e, nodeId);
},
loadGraphSettings: function () {
var settings;
return settings;
},
editNode: function (id) {
var callback = function () {};
@ -132,35 +166,50 @@
this.Sigma = sigma;
var algorithm = 'force';
var renderer = 'webgl';
var settings = {
doubleClickEnabled: false,
minEdgeSize: 0.5,
maxEdgeSize: 4,
enableEdgeHovering: true,
// edgeHoverColor: 'edge',
// defaultEdgeHoverColor: '#000',
// defaultEdgeType: 'curve',
edgeHoverSizeRatio: 1,
edgeHoverExtremities: true
};
// adjust display settings for big graphs
if (graph.nodes.length > 500) {
// show node label if size is 20
settings.labelThreshold = 20;
}
// adjust display settings for webgl renderer
if (renderer === 'webgl') {
settings.enableEdgeHovering = false;
}
// create sigma graph
var s = new this.Sigma({
graph: graph,
container: 'graph-container',
renderer: {
container: document.getElementById('graph-container'),
type: 'canvas'
type: renderer
},
settings: {
doubleClickEnabled: false,
minEdgeSize: 0.5,
maxEdgeSize: 4,
enableEdgeHovering: true,
// edgeHoverColor: 'edge',
// defaultEdgeHoverColor: '#000',
// defaultEdgeType: 'curve',
edgeHoverSizeRatio: 1,
edgeHoverExtremities: true
}
settings: settings
});
this.currentGraph = s;
sigma.plugins.fullScreen({
container: 'graph-container',
btnId: 'graph-fullscreen-btn'
});
var renderer = 'fruchtermann';
if (renderer === 'noverlap') {
if (algorithm === 'noverlap') {
var noverlapListener = s.configNoverlap({
nodeMargin: 0.1,
scaleNodes: 1.05,
@ -175,7 +224,7 @@
if (e.type === 'interpolate') {
}
});
} else if (renderer === 'fruchtermann') {
} else if (algorithm === 'fruchtermann') {
var frListener = sigma.layouts.fruchtermanReingold.configure(s, {
iterations: 500,
easing: 'quadraticInOut',
@ -192,70 +241,60 @@
e.originalColor = e.color;
});
if (document.addEventListener) {
document.addEventListener('contextmenu', function (e) {
// my custom functionality on right click
e.preventDefault();
}, false);
} else {
document.attachEvent('oncontextmenu', function () {
// my custom functionality on right click
window.event.returnValue = false;
if (renderer !== 'webgl') {
s.bind('rightClickNode', function (e) {
var nodeId = e.data.node.id;
self.createNodeContextMenu(nodeId, e);
});
s.bind('doubleClickNode', function (e) {
var nodeId = e.data.node.id;
var toKeep = s.graph.neighbors(nodeId);
toKeep[nodeId] = e.data.node;
s.graph.nodes().forEach(function (n) {
if (toKeep[n.id]) {
n.color = n.originalColor;
} else {
n.color = '#eee';
}
});
s.graph.edges().forEach(function (e) {
if (toKeep[e.source] && toKeep[e.target]) {
e.color = 'rgb(64, 74, 83)';
} else {
e.color = '#eee';
}
});
s.refresh();
});
s.bind('doubleClickStage', function () {
s.graph.nodes().forEach(function (n) {
n.color = n.originalColor;
});
s.graph.edges().forEach(function (e) {
e.color = e.originalColor;
});
s.refresh();
});
s.bind('clickStage', function () {
self.clearOldContextMenu();
});
}
s.bind('rightClickNode', function (e) {
var nodeId = e.data.node.id;
self.createNodeContextMenu(nodeId, e);
});
s.bind('doubleClickNode', function (e) {
var nodeId = e.data.node.id;
var toKeep = s.graph.neighbors(nodeId);
toKeep[nodeId] = e.data.node;
s.graph.nodes().forEach(function (n) {
if (toKeep[n.id]) {
n.color = n.originalColor;
} else {
n.color = '#eee';
}
});
s.graph.edges().forEach(function (e) {
if (toKeep[e.source] && toKeep[e.target]) {
e.color = 'rgb(64, 74, 83)';
} else {
e.color = '#eee';
}
});
s.refresh();
});
s.bind('doubleClickStage', function () {
s.graph.nodes().forEach(function (n) {
n.color = n.originalColor;
});
s.graph.edges().forEach(function (e) {
e.color = e.originalColor;
});
s.refresh();
});
s.bind('clickStage', function () {
self.clearOldContextMenu();
});
var dragListener;
// Initialize the dragNodes plugin:
if (renderer === 'noverlap') {
if (algorithm === 'noverlap') {
s.startNoverlap();
// allow draggin nodes
dragListener = sigma.plugins.dragNodes(s, s.renderers[0]);
} else if (renderer === 'force') {
} else if (algorithm === 'force') {
s.startForceAtlas2({worker: true, barnesHutOptimize: false});
window.setTimeout(function () {
@ -263,7 +302,7 @@
dragListener = sigma.plugins.dragNodes(s, s.renderers[0]);
console.log('stopped force');
}, 3000);
} else if (renderer === 'fruchtermann') {
} else if (algorithm === 'fruchtermann') {
// Start the Fruchterman-Reingold algorithm:
sigma.layouts.fruchtermanReingold.start(s);
dragListener = sigma.plugins.dragNodes(s, s.renderers[0]);
@ -271,6 +310,8 @@
dragListener = sigma.plugins.dragNodes(s, s.renderers[0]);
}
console.log(dragListener);
$('#calculatingGraph').remove();
}
});