qgraph
Version:
A Graph Manipulation and Visualization Library
297 lines (282 loc) • 11.1 kB
HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>qgraph Test</title>
<script src="../node_modules/lodash/lodash.js"></script>
<script src="../lib/canvg.js"></script>
<script src="../lib/jscanvas.js"></script>
<script src="../lib/qgraph.js"></script>
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<!--canvas id="ycanvas"></canvas-->
<!--input type="button" value="Start Viewer" onclick="startViewer()"/>
<input type="button" value="Destroy Viewer" onclick="destroyViewer()"/-->
<input type="button" value="Save Image" onclick="testImageCapture()">
<div id="graph-demo"
style="position:absolute;border: 1px solid gray;left:10px;right:10px;top:20px;bottom:10px;margin-top:20px"></div>
<script type="text/javascript">
var qg = window["qgraph"].default;
// This is the configuration file for the graph. It specifies the possible types of nodes and edges and how display should happen.
// Also how the graph should be displayed.
var graphConfig = {
mode: 0,
// Types of edges possible. Different styles can be applied to different type of edge.
edgeTypes: [
{
name: 'Default',
style: "fill: none;stroke: rgb(134, 142, 142);stroke-width: 1;stroke-miterlimit: 10;",
// shape defines how the edges are displayed, availabel values are "direct", "bezier", "manahattan", "entityRelations" and is defined
// in src/Link.js
shape: {
type: 'bezier', round: 10, orthogonal: true
},
// labelConfig defines how the label is displayed on the edge.
labelConfig: {
align: 'center',
backgroundStyle: 'fill:white;stroke-width:0',
geometry: {x: 0.5}
},
endMarker: {
size: 15
}
},
{
name: 'Terminal',
endMarker: {
type: 'diamond',
size: 10
}
}
],
// Types of nodes possible.
nodeTypes: [
// Error node is the default to display in case cann't find the right type of node to display.
{name: "Error"},
{
name: 'Start',
shape: {
name: "Ellipse",
width: 60,
height: 60,
style: 'fill: #C5E7C4;stroke: #47B352;stroke-width: 2;'
},
labelConfig: {
ns: 'label',
align: "center",
fontSize: 12,
width: 0.9,
geometry: {y:0.5, anchorY: 0.5},
textStyle: 'fill:#888888;font-size: 12px;font-family: Arial;stroke-width: 0;'
}
},
{
name: 'Task',
shape: {
name: "Rectangle",
width: 80,
height: 60,
style: 'fill:#C5E7C4;stroke: #47B352;stroke-width:2'
},
labelConfig: {
ns: 'label',
align: "center",
fontSize: 12,
backgroundStyle: 'fill:none;stroke-width:0',
width: 0.9,
textStyle: 'fill:#888888;font-size: 12px;font-family: Arial;stroke-width: 0;'
}
},
{
name: 'Fork',
shape: {
name: "Rhombus",
width: 70,
height: 70,
style: 'fill: #FFD5BE;stroke: #FD8037;stroke-width: 2;'
},
labelConfig: {
ns: 'label',
align: "center",
fontSize: 12,
width: 0.9,
textStyle: 'fill:#888888;font-size: 12px;font-family: Arial;stroke-width: 0;'
}
},
{
name: 'End',
shape: {
name: "Ellipse",
width: 60,
height: 60,
style: 'fill: #F9BEBF;stroke: #EC3843;stroke-width: 2;'
},
labelConfig: {
ns: 'label',
align: "center",
fontSize: 12,
width: 0.9,
geometry: {x:0.5, anchorX: 0.5, offsetX: 5},
textStyle: 'fill:#888888;font-size: 12px;font-family: Arial;stroke-width: 0;'
}
},
{name: 'Annotation', resizable: true, htmlLabel: true}
]
};
var viewConfig = {
isDefault: true,
gridEnabled: true,
maskOpacity: 0
};
// This is the actual model of the graph.
var model = {
nodes: [
{type:'Start', label:'Start', id:'1', x:50, y:300},
{type: 'Fork', label: 'Fork', id: '2', x: 200, y: 300},
{type: 'Task', label: 'Task1', id: '3', x: 450, y: 200},
{type: 'Task', label: 'Task2', id: '4', x: 450, y: 400},
{type:'End', label:'End', id:'5', x:700, y:300}
],
edges: [
{from: '1', to: '2'},
{from: '2', to: '3'},
{from: '2', to: '4'},
{from: '3', to: '5', type: 'Terminal'},
{from: '4', to: '5', type: 'Terminal'},
]
};
qg.Utils.debug();
var graph, renderer;
function startViewer() {
graph = new qg.Graph('myGraph', graphConfig, model);
renderer = new qg.SVGRenderer('default', document.getElementById('graph-demo'), viewConfig, graph);
renderer.render();
}
function createTestModel(size) {
var model = {nodes: [], edges: []};
var gap = 20;
var x = gap, y = gap;
for (var i = 0; i < size; i++) {
model.nodes.push({
type: vertexTypes[_.random(0, vertexTypes.length - 1)].name,
label: "s" + (i + 1),
x: x,
y: y
});
x += 120 + gap;
if (x > 1000) {
x = gap;
y += 60 + gap;
}
}
return model;
}
function createShape(name, type, indicators) {
return {type: type, label: name, id: name, indicators: indicators};
}
function createChildren(model, node, size, level, maxlevel) {
if (level >= maxlevel) return;
var v1, id;
var fromid = _.isArray(node) ? node[0].id : node.id;
for (var i = 0; i < size; i++) {
id = fromid + "-" + level + ":" + i;
v1 = createShape(id, "Assignment", [{className: 'SLAModifier'}]);
model.nodes.push(v1);
model.edges.push({type: 'Transition', from: fromid, to: id, id: fromid + id});
createChildren(model, v1, size, level + 1, maxlevel);
}
}
function testUpdate() {
var model = {
nodes: [
{type: 'root', label: 'test1', id: 'Rule-Decision-Strategy'},
{
type: 'StrategySet',
label: 'Strategy Set',
id: 'StrategySet1',
tooltip: 'jji',
pathKey: 'RH_2.pyModelProcess.pyShapes(StrategySet1)',
indicators: [{className: 'summary', label: 'jji'}, {className: 'dataEnrichment'}],
x: 0.48,
y: 0.48
}
],
edges: []
};
ViewerManager.getViewer().update(model);
}
function drawCapturedImage() {
var ycanvas = document.getElementById('ycanvas');
var yctx = ycanvas.getContext('2d');
var cantest = new jscanvastest(yctx);
// we can get the natural size of the object from the instantiated
// object this way.
// alternatively, you can use inwidth/inheight to scale the output
// object to a given canvas size, eg:
// yctx.scale (200/cantest.inwidth, 200/cantest.inwidth);
ycanvas.width = cantest.inwidth;
ycanvas.height = cantest.inheight;
yctx.scale(1, 1);
// capture the sets to various fields in the 2d context
// this is good for changing the look of the generated object at run time.
// @override
cantest.setter = function (ctx, key, val) {
if (key == 'fillStyle') {
switch (val) {
case '#bbbbbb':
val = 'rgba(255, 0, 0, 1)';
break;
case '#aaaaaa':
val = ctx.createLinearGradient(0, 0, 0, 500);
val.addColorStop(0, 'rgb(255,0,0)');
val.addColorStop(1, 'rgb(0,255,0)');
break;
case '#eeeeee':
val = ctx.createPattern(document.getElementById('pattern'), 'repeat');
break;
default:
break; // keep original
}
} else if (key == 'strokeStyle' && val == 'rgba(0, 0, 0, 1)')
val = 'rgba(0, 0, 255, 1)';
ctx [key] = val;
};
// all set up, render away...
cantest.render();
}
function testImageCapture() {
/*var image = renderer.svg.toDataURL('javascript', { keepOutsideViewport: true, debug: true, padding: 20, callback: function(data) {
console.log(data);
eval(data);
drawCapturedImage();
}});*/
var image = renderer.svg.toDataURL('image/png', {keepOutsideViewport: true, debug: true, padding: 20});
qg.DomUtils.downloadFile('graph', image);
}
function toggleZoom() {
var graph = ViewerManager.currentViewer.graph;
var currentScale = graph.scale();
if (currentScale == 1.0)
ViewerManager.executeAction({name: "zoom", zoom: 2});
else
ViewerManager.executeAction({name: "zoom", zoom: 'actual'});
}
function testPerformance() {
var myClass = function (name) {
this.name = name;
};
myClass.prototype.sayName = function () {
console.log(this.name);
};
var classes = [];
var start = new Date().getTime();
for (var i = 0; i < 100000; i++)
classes.push(new myClass("name" + i));
var end = new Date().getTime();
alert((end - start) / 1000);
}
startViewer();
</script>
</body>
</html>