mirror of https://gitee.com/bigwinds/arangodb
GraphViewer: Added GraphViewer to Admin Interface, however Menu is still hidden. Also started with a spec to test if the generated UI conforms to Admin Interface css
This commit is contained in:
parent
7abe9aa342
commit
cc9b9407af
|
@ -39,6 +39,9 @@
|
|||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="js/graphViewer/style/graphlayout.css" type="text/css"/>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -82,7 +85,6 @@
|
|||
<script src="js/lib/d3.v3.js"></script>
|
||||
<script src="js/lib/nv.d3.js"></script>
|
||||
|
||||
|
||||
<script src="js/lib/ColVis.js"></script>
|
||||
<script src="js/lib/ejs_fulljslint.js"></script>
|
||||
<script src="js/lib/ejs_0.9_alpha_1_production.js"></script>
|
||||
|
@ -96,6 +98,24 @@
|
|||
<script src='js/lib/swagger-ui.js' type='text/javascript'></script>
|
||||
<script src='js/lib/highlight.7.3.pack.js' type='text/javascript'></script>
|
||||
|
||||
<!-- graphViewer -->
|
||||
<script src="js/graphViewer/graph/colourMapper.js"></script>
|
||||
<script src="js/graphViewer/graph/forceLayouter.js"></script>
|
||||
<script src="js/graphViewer/graph/eventLibrary.js"></script>
|
||||
<script src="js/graphViewer/graph/eventDispatcher.js"></script>
|
||||
<script src="js/graphViewer/graph/nodeShaper.js"></script>
|
||||
<script src="js/graphViewer/graph/edgeShaper.js"></script>
|
||||
<script src="js/graphViewer/graph/arangoAdapter.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/graphViewer/ui/modalDialogHelper.js"></script>
|
||||
<script type="text/javascript" src="js/graphViewer/ui/nodeShaperControls.js"></script>
|
||||
<script type="text/javascript" src="js/graphViewer/ui/edgeShaperControls.js"></script>
|
||||
<script type="text/javascript" src="js/graphViewer/ui/uiComponentsHelper.js"></script>
|
||||
<script type="text/javascript" src="js/graphViewer/ui/eventDispatcherControls.js"></script>
|
||||
<script type="text/javascript" src="js/graphViewer/ui/graphViewerUI.js"></script>
|
||||
|
||||
<script src="js/graphViewer/graphViewer.js"></script>
|
||||
|
||||
|
||||
<!-- arango -->
|
||||
<script src="js/arango/arango.js"></script>
|
||||
|
@ -163,6 +183,7 @@
|
|||
<script src="js/views/foxxEditView.js"></script>
|
||||
<script src="js/views/foxxMountView.js"></script>
|
||||
<script src="js/views/appDocumentationView.js"></script>
|
||||
<script src="js/views/graphView.js"></script>
|
||||
|
||||
<!-- router -->
|
||||
<script src="js/routers/router.js"></script>
|
||||
|
|
|
@ -53,6 +53,14 @@
|
|||
document.body.appendChild(div);
|
||||
ui = new GraphViewerUI(div, adapterConfig);
|
||||
this.addMatchers({
|
||||
toBeTag: function(name) {
|
||||
var el = this.actual;
|
||||
this.message = function() {
|
||||
return el.tagName.toLowerCase() + " to be a " + name;
|
||||
};
|
||||
return el.tagName.toLowerCase() === name;
|
||||
},
|
||||
|
||||
toBeADropdownMenu: function() {
|
||||
var div = this.actual,
|
||||
btn = div.children[0],
|
||||
|
@ -208,6 +216,24 @@
|
|||
expect(false).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should have the same layout as the web interface', function() {
|
||||
var header = div.children[0],
|
||||
transHeader = header.firstChild;
|
||||
searchField = transHeader.children[0],
|
||||
|
||||
content = div.children[1];
|
||||
expect(header).toBeTag("ul");
|
||||
expect(header.id).toEqual("menubar");
|
||||
expect(header.className).toEqual("thumbnails2");
|
||||
expect(transHeader).toBeTag("div");
|
||||
expect(transHeader.id).toEqual("transparentHeader");
|
||||
|
||||
expect(searchField).toBeTag("div");
|
||||
expect(searchField.id).toEqual("transparentPlaceholder");
|
||||
expect(searchField.className).toEqual("pull-left");
|
||||
expect(searchField.children[0].id).toEqual("nodeid");
|
||||
expect(searchField.children[1].id).toEqual("loadnode");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ $(document).ready(function() {
|
|||
"application/available/:key" : "applicationInstall",
|
||||
"applications/installed" : "applicationsInstalled",
|
||||
"applications/available" : "applicationsAvailable",
|
||||
"applications/documentation" : "applicationsDocumentation"
|
||||
"applications/documentation" : "applicationsDocumentation",
|
||||
"graph" : "graph"
|
||||
|
||||
},
|
||||
initialize: function () {
|
||||
|
@ -63,6 +64,7 @@ $(document).ready(function() {
|
|||
this.footerView = new window.footerView();
|
||||
this.naviView.render();
|
||||
this.footerView.render();
|
||||
this.graphView = new window.graphView();
|
||||
},
|
||||
collections: function() {
|
||||
var naviView = this.naviView;
|
||||
|
@ -157,6 +159,11 @@ $(document).ready(function() {
|
|||
});
|
||||
},
|
||||
|
||||
graph: function() {
|
||||
this.graphView.render();
|
||||
this.naviView.selectMenuItem('graph-menu');
|
||||
},
|
||||
|
||||
applicationsAvailable: function() {
|
||||
if (this.foxxList === undefined) {
|
||||
this.foxxList = new window.FoxxCollection();
|
||||
|
|
|
@ -1,18 +1,32 @@
|
|||
<ul class="thumbnails2">
|
||||
<div id="transparentHeader">
|
||||
<h4>Graph Editor</h4>
|
||||
<form action="javascript:void(0);" autocomplete="on" class="form-horizontal" id="creationDialog">
|
||||
<fieldset>
|
||||
<legend>Create the Viewer</legend>
|
||||
<fieldset>
|
||||
<legend>Setup Arango Connection</legend>
|
||||
<div class="control-group">
|
||||
<label for="host" class="control-label">Host</label>
|
||||
<div class="controls">
|
||||
<input id="host" type="text" name="host" placeholder="Host" maxlength="75" class="input-xlarge" value="http://localhost:8529">
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
<div id="queryDiv" class="form-actions">
|
||||
<div id="outputLabel">Output</div>
|
||||
<div id="graphOutput" class="thumbnail">
|
||||
<svg id="graphSVG">
|
||||
</svg>
|
||||
</div>
|
||||
<i class="icon-trash clearicon"></i>
|
||||
<div class="control-group">
|
||||
<label for="nodeCollection" class="control-label">Node Collection</label>
|
||||
<div class="controls">
|
||||
<input id="nodeCollection" type="text" name="nodeCollection" placeholder="Node Collection" maxlength="75" class="input-xlarge" value="Classes">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="edgeCollection" class="control-label">Edge Collection</label>
|
||||
<div class="controls">
|
||||
<input id="edgeCollection" type="text" name="edgeCollection" placeholder="Edge Collection" maxlength="75" class="input-xlarge" value="Connections">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div id="editorLabel">Input</div>
|
||||
<div id="aqlEditor"></div>
|
||||
<button id="submitQueryButton" class="btn btn-success">Submit</button>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary" id="createViewer" >Create</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
|
@ -1,132 +1,42 @@
|
|||
var graphView = Backbone.View.extend({
|
||||
window.graphView = Backbone.View.extend({
|
||||
el: '#content',
|
||||
svgWidth: 898,
|
||||
svgHeight: 350,
|
||||
scaleFactor: 1,
|
||||
NODERADIUS: 12, // Constant Node Radius
|
||||
LINKDIST: 100, // Constant Link Distance
|
||||
handles: {},
|
||||
|
||||
template: new EJS({url: 'js/templates/graphView.ejs'}),
|
||||
|
||||
initialize: function () {
|
||||
var self = this;
|
||||
self.force = d3.layout.force();
|
||||
self.force.size([self.svgWidth, self.svgHeight]);
|
||||
self.force.charge(-300);
|
||||
|
||||
},
|
||||
|
||||
events: {
|
||||
'click #submitQueryIcon' : 'submitQuery',
|
||||
'click #submitQueryButton' : 'submitQuery',
|
||||
'click .clearicon': 'clearOutput'
|
||||
"click #createViewer" : "createViewer"
|
||||
},
|
||||
|
||||
clearOutput: function() {
|
||||
$('#graphOutput').empty();
|
||||
createViewer: function() {
|
||||
var host,
|
||||
ecol,
|
||||
ncol,
|
||||
aaconfig;
|
||||
|
||||
host = $("#host")[0].value;
|
||||
ecol = $("#edgeCollection")[0].value;
|
||||
ncol = $("#nodeCollection")[0].value;
|
||||
|
||||
aaconfig = {
|
||||
type: "arango",
|
||||
nodeCollection: ncol,
|
||||
edgeCollection: ecol,
|
||||
host: host
|
||||
};
|
||||
|
||||
$("#creationDialog").remove();
|
||||
ui = new GraphViewerUI(document.getElementById("content"), aaconfig);
|
||||
},
|
||||
|
||||
submitQuery: function() {
|
||||
// TODO!
|
||||
var self = this;
|
||||
//self.renderGraph("js/graph/testdata/friends.json");
|
||||
self.renderGraph("js/graph/testdata/big.json");
|
||||
/*
|
||||
var editor = ace.edit("aqlEditor");
|
||||
var data = {query: editor.getValue()};
|
||||
|
||||
var editor2 = ace.edit("queryOutput");
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/_api/cursor",
|
||||
data: JSON.stringify(data),
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
success: function(data) {
|
||||
editor2.setValue(self.FormatJSON(data.result));
|
||||
},
|
||||
error: function(data) {
|
||||
try {
|
||||
var temp = JSON.parse(data.responseText);
|
||||
editor2.setValue('[' + temp.errorNum + '] ' + temp.errorMessage);
|
||||
}
|
||||
catch (e) {
|
||||
editor2.setValue('ERROR');
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
},
|
||||
|
||||
renderGraph: function(jsonURL) {
|
||||
var self = this;
|
||||
if (self.force) {
|
||||
self.force.stop();
|
||||
}
|
||||
$('#graphSVG').empty();
|
||||
d3.json(jsonURL, function(error, graph) {
|
||||
var s = (typeof(self.scaleFactor) != "undefined" ? self.scaleFactor : 1);
|
||||
var r = s * self.NODERADIUS;
|
||||
var nodes = graph.nodes;
|
||||
var links = graph.links;
|
||||
var svg = d3.select("svg");
|
||||
|
||||
window.graph.startForcebasedLayout(self.force, nodes, links, self.LINKDIST * s, self.forceTick.bind(self));
|
||||
var edge = window.graph.drawEdgeWithSimpleArrowHead(svg, links, self.NODERADIUS, s);
|
||||
var edgeLabel = window.graph.appendLabelToEdges(svg, links, "label");
|
||||
var node = window.graph.drawNodes(svg, nodes);
|
||||
window.graph.makeNodesCircular(node, r);
|
||||
window.graph.makeNodesDragable(node, self.force);
|
||||
window.graph.makeNodesClickable(node, self.nodeClicked);
|
||||
window.graph.appendLabelToNodes(node, "name");
|
||||
|
||||
self.handles.edge = edge;
|
||||
self.handles.node = node;
|
||||
self.handles.edgeLabel = edgeLabel;
|
||||
self.handles.nodes = nodes;
|
||||
});
|
||||
},
|
||||
|
||||
forceTick: function() {
|
||||
var self = this;
|
||||
var changedDistance = window.graph.tick.nodePosition(self.handles.node, self.handles.nodes, self.x_scale);
|
||||
window.graph.tick.edgePosition(self.handles.edge);
|
||||
window.graph.tick.edgeLabelPosition(self.handles.edgeLabel, "label");
|
||||
if (changedDistance < 0.5) {
|
||||
self.force.stop();
|
||||
}
|
||||
},
|
||||
|
||||
nodeClicked: function(node) {
|
||||
console.log(node);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
$(this.el).html(this.template.text);
|
||||
var aqlEditor = ace.edit("aqlEditor");
|
||||
aqlEditor.getSession().setMode("ace/mode/javascript");
|
||||
aqlEditor.setTheme("ace/theme/merbivore_soft");
|
||||
aqlEditor.resize();
|
||||
|
||||
$('#graphOutput').resizable({
|
||||
handles: "s",
|
||||
ghost: true,
|
||||
stop: function () {
|
||||
|
||||
}
|
||||
});
|
||||
$('#aqlEditor').resizable({
|
||||
handles: "n, s",
|
||||
ghost: true,
|
||||
helper: "resizable-helper",
|
||||
stop: function () {
|
||||
var aqlEditor = ace.edit("aqlEditor");
|
||||
aqlEditor.resize();
|
||||
}
|
||||
});
|
||||
|
||||
$('#aqlEditor .ace_text-input').focus();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue