mirror of https://gitee.com/bigwinds/arangodb
graph testing
This commit is contained in:
parent
a2b9919a6f
commit
84be68b6e6
|
@ -1,6 +1,6 @@
|
|||
/*jshint browser: true */
|
||||
/*jshint unused: false */
|
||||
/*jshint maxlen: 99999999 */
|
||||
/*jshint maxlen: 999999 */
|
||||
/*global Backbone, $, _, window, templateEngine, arangoHelper, GraphViewerUI, require, Viva*/
|
||||
|
||||
(function() {
|
||||
|
@ -34,7 +34,7 @@
|
|||
graph.addNode(self.jsonNodes[i]._id, self.jsonNodes[i]);
|
||||
}
|
||||
for (i = 0; i < self.jsonEdges.length; ++i) {
|
||||
graph.addLink(self.jsonEdges[i]._id, self.jsonEdges[i]);
|
||||
graph.addLink(self.jsonEdges[i]._from, self.jsonEdges[i]._to, null);
|
||||
}
|
||||
|
||||
var layout = Viva.Graph.Layout.forceDirected(graph, {
|
||||
|
@ -44,28 +44,200 @@
|
|||
gravity : -1.2
|
||||
});
|
||||
|
||||
var nodeColor = 0x8aa249, // hex rrggbb
|
||||
nodeSize = 40;
|
||||
|
||||
var graphics = Viva.Graph.View.webglGraphics();
|
||||
var circleNode = this.buildCircleNodeShader();
|
||||
graphics.setNodeProgram(circleNode);
|
||||
|
||||
graphics.node(function (node) {
|
||||
return new self.WebglCircle(nodeSize, nodeColor);
|
||||
});
|
||||
|
||||
var renderer = Viva.Graph.View.renderer(graph, {
|
||||
layout : layout,
|
||||
graphics : graphics,
|
||||
container: document.getElementById(this.graphContainer)
|
||||
});
|
||||
layout : layout,
|
||||
graphics : graphics,
|
||||
container : document.getElementById(this.graphContainer)
|
||||
});
|
||||
|
||||
// I'm not quite happy with how events are currently implemented
|
||||
// in the library and I'm planning to refactor it. But for the
|
||||
// time beings this is how you track webgl-based input events:
|
||||
var events = Viva.Graph.webglInputEvents(graphics, graph);
|
||||
|
||||
events.mouseEnter(function (node) {
|
||||
}).mouseLeave(function (node) {
|
||||
//console.log(node);
|
||||
}).dblClick(function (node) {
|
||||
// console.log('Double click on node: ' + node.id);
|
||||
}).click(function (node) {
|
||||
// console.log('Single click on node: ' + node.id);
|
||||
});
|
||||
|
||||
renderer.run();
|
||||
|
||||
// add live nodes example
|
||||
window.setTimeout(function() {
|
||||
graph.beginUpdate();
|
||||
for (var i = 0; i < self.jsonNodes.length; ++i) {
|
||||
graph.addNode(self.jsonNodes[i]._key, self.jsonNodes[i]);
|
||||
}
|
||||
graph.endUpdate();
|
||||
}, 2000);
|
||||
|
||||
},
|
||||
|
||||
WebglCircle: function (size, color) {
|
||||
this.size = size;
|
||||
this.color = color;
|
||||
},
|
||||
|
||||
buildCircleNodeShader: function () {
|
||||
// For each primitive we need 4 attributes: x, y, color and size.
|
||||
var ATTRIBUTES_PER_PRIMITIVE = 4,
|
||||
nodesFS = [
|
||||
'precision mediump float;',
|
||||
'varying vec4 color;',
|
||||
|
||||
'void main(void) {',
|
||||
' if ((gl_PointCoord.x - 0.5) * (gl_PointCoord.x - 0.5) + (gl_PointCoord.y - 0.5) * (gl_PointCoord.y - 0.5) < 0.25) {',
|
||||
' gl_FragColor = color;',
|
||||
' } else {',
|
||||
' gl_FragColor = vec4(0);',
|
||||
' }',
|
||||
'}'].join('\n'),
|
||||
nodesVS = [
|
||||
'attribute vec2 a_vertexPos;',
|
||||
// Pack clor and size into vector. First elemnt is color, second - size.
|
||||
// Since it's floating point we can only use 24 bit to pack colors...
|
||||
// thus alpha channel is dropped, and is always assumed to be 1.
|
||||
'attribute vec2 a_customAttributes;',
|
||||
'uniform vec2 u_screenSize;',
|
||||
'uniform mat4 u_transform;',
|
||||
'varying vec4 color;',
|
||||
|
||||
'void main(void) {',
|
||||
' gl_Position = u_transform * vec4(a_vertexPos/u_screenSize, 0, 1);',
|
||||
' gl_PointSize = a_customAttributes[1] * u_transform[0][0];',
|
||||
' float c = a_customAttributes[0];',
|
||||
' color.b = mod(c, 256.0); c = floor(c/256.0);',
|
||||
' color.g = mod(c, 256.0); c = floor(c/256.0);',
|
||||
' color.r = mod(c, 256.0); c = floor(c/256.0); color /= 255.0;',
|
||||
' color.a = 1.0;',
|
||||
'}'].join('\n');
|
||||
|
||||
var program,
|
||||
gl,
|
||||
buffer,
|
||||
locations,
|
||||
utils,
|
||||
nodes = new Float32Array(64),
|
||||
nodesCount = 0,
|
||||
canvasWidth, canvasHeight, transform,
|
||||
isCanvasDirty,
|
||||
self = this;
|
||||
|
||||
return {
|
||||
/**
|
||||
* Called by webgl renderer to load the shader into gl context.
|
||||
*/
|
||||
load : function (glContext) {
|
||||
gl = glContext;
|
||||
self.webglUtils = Viva.Graph.webgl(glContext);
|
||||
|
||||
program = self.webglUtils.createProgram(nodesVS, nodesFS);
|
||||
gl.useProgram(program);
|
||||
locations = self.webglUtils.getLocations(program, ['a_vertexPos', 'a_customAttributes', 'u_screenSize', 'u_transform']);
|
||||
|
||||
gl.enableVertexAttribArray(locations.vertexPos);
|
||||
gl.enableVertexAttribArray(locations.customAttributes);
|
||||
|
||||
buffer = gl.createBuffer();
|
||||
},
|
||||
|
||||
/**
|
||||
* Called by webgl renderer to update node position in the buffer array
|
||||
*
|
||||
* @param nodeUI - data model for the rendered node (WebGLCircle in this case)
|
||||
* @param pos - {x, y} coordinates of the node.
|
||||
*/
|
||||
position : function (nodeUI, pos) {
|
||||
var idx = nodeUI.id;
|
||||
nodes[idx * ATTRIBUTES_PER_PRIMITIVE] = pos.x;
|
||||
nodes[idx * ATTRIBUTES_PER_PRIMITIVE + 1] = pos.y;
|
||||
nodes[idx * ATTRIBUTES_PER_PRIMITIVE + 2] = nodeUI.color;
|
||||
nodes[idx * ATTRIBUTES_PER_PRIMITIVE + 3] = nodeUI.size;
|
||||
},
|
||||
|
||||
/**
|
||||
* Request from webgl renderer to actually draw our stuff into the
|
||||
* gl context. This is the core of our shader.
|
||||
*/
|
||||
render : function() {
|
||||
gl.useProgram(program);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, nodes, gl.DYNAMIC_DRAW);
|
||||
|
||||
if (isCanvasDirty) {
|
||||
isCanvasDirty = false;
|
||||
gl.uniformMatrix4fv(locations.transform, false, transform);
|
||||
gl.uniform2f(locations.screenSize, canvasWidth, canvasHeight);
|
||||
}
|
||||
|
||||
gl.vertexAttribPointer(locations.vertexPos, 2, gl.FLOAT, false, ATTRIBUTES_PER_PRIMITIVE * Float32Array.BYTES_PER_ELEMENT, 0);
|
||||
gl.vertexAttribPointer(locations.customAttributes, 2, gl.FLOAT, false, ATTRIBUTES_PER_PRIMITIVE * Float32Array.BYTES_PER_ELEMENT, 2 * 4);
|
||||
|
||||
gl.drawArrays(gl.POINTS, 0, nodesCount);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called by webgl renderer when user scales/pans the canvas with nodes.
|
||||
*/
|
||||
updateTransform : function (newTransform) {
|
||||
transform = newTransform;
|
||||
isCanvasDirty = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called by webgl renderer when user resizes the canvas with nodes.
|
||||
*/
|
||||
updateSize : function (newCanvasWidth, newCanvasHeight) {
|
||||
canvasWidth = newCanvasWidth;
|
||||
canvasHeight = newCanvasHeight;
|
||||
isCanvasDirty = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called by webgl renderer to notify us that the new node was created in the graph
|
||||
*/
|
||||
createNode : function (node) {
|
||||
nodes = self.webglUtils.extendArray(nodes, nodesCount, ATTRIBUTES_PER_PRIMITIVE);
|
||||
nodesCount += 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called by webgl renderer to notify us that the node was removed from the graph
|
||||
*/
|
||||
removeNode : function (node) {
|
||||
if (nodesCount > 0) { nodesCount -=1; }
|
||||
|
||||
if (node.id < nodesCount && nodesCount > 0) {
|
||||
// we do not really delete anything from the buffer.
|
||||
// Instead we swap deleted node with the "last" node in the
|
||||
// buffer and decrease marker of the "last" node. Gives nice O(1)
|
||||
// performance, but make code slightly harder than it could be:
|
||||
self.webglUtils.copyArrayPart(nodes, node.id*ATTRIBUTES_PER_PRIMITIVE, nodesCount*ATTRIBUTES_PER_PRIMITIVE, ATTRIBUTES_PER_PRIMITIVE);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This method is called by webgl renderer when it changes parts of its
|
||||
* buffers. We don't use it here, but it's needed by API (see the comment
|
||||
* in the removeNode() method)
|
||||
*/
|
||||
replaceProperties : function(replacedNode, newNode) {},
|
||||
};
|
||||
},
|
||||
|
||||
parseResultOfTraversal: function (result, callback) {
|
||||
|
||||
var self = this;
|
||||
|
|
Loading…
Reference in New Issue