UNPKG

sigma

Version:

A JavaScript library dedicated to graph drawing.

163 lines (144 loc) 5.43 kB
;(function(undefined) { 'use strict'; var shapes = []; var register = function(name,drawShape,drawBorder) { shapes.push({ 'name': name, 'drawShape': drawShape, 'drawBorder': drawBorder }); } var enumerateShapes = function() { return shapes; } /** * For the standard closed shapes - the shape fill and border are drawn the * same, with some minor differences for fill and border. To facilitate this we * create the generic draw functions, that take a shape drawing func and * return a shape-renderer/border-renderer * ---------- */ var genericDrawShape = function(shapeFunc) { return function(node,x,y,size,color,context) { context.fillStyle = color; context.beginPath(); shapeFunc(node,x,y,size,context); context.closePath(); context.fill(); }; } var genericDrawBorder = function(shapeFunc) { return function(node,x,y,size,color,context) { context.strokeStyle = color; context.lineWidth = size / 5; context.beginPath(); shapeFunc(node,x,y,size,context); context.closePath(); context.stroke(); }; } /** * We now proced to use the generics to define our standard shape/border * drawers: square, diamond, equilateral (polygon), and star * ---------- */ var drawSquare = function(node,x,y,size,context) { var rotate = Math.PI*45/180; // 45 deg rotation of a diamond shape context.moveTo(x+size*Math.sin(rotate), y-size*Math.cos(rotate)); // first point on outer radius, dwangle 'rotate' for(var i=1; i<4; i++) { context.lineTo(x+Math.sin(rotate+2*Math.PI*i/4)*size, y-Math.cos(rotate+2*Math.PI*i/4)*size); } } register("square",genericDrawShape(drawSquare),genericDrawBorder(drawSquare)); var drawCircle = function(node,x,y,size,context) { context.arc(x,y,size,0,Math.PI*2,true); } register("circle",genericDrawShape(drawCircle),genericDrawBorder(drawCircle)); var drawDiamond = function(node,x,y,size,context) { context.moveTo(x-size, y); context.lineTo(x, y-size); context.lineTo(x+size, y); context.lineTo(x, y+size); } register("diamond",genericDrawShape(drawDiamond),genericDrawBorder(drawDiamond)); var drawCross = function(node,x,y,size,context) { var lineWeight = (node.cross && node.cross.lineWeight) || 5; context.moveTo(x-size, y-lineWeight); context.lineTo(x-size, y+lineWeight); context.lineTo(x-lineWeight, y+lineWeight); context.lineTo(x-lineWeight, y+size); context.lineTo(x+lineWeight, y+size); context.lineTo(x+lineWeight, y+lineWeight); context.lineTo(x+size, y+lineWeight); context.lineTo(x+size, y-lineWeight); context.lineTo(x+lineWeight, y-lineWeight); context.lineTo(x+lineWeight, y-size); context.lineTo(x-lineWeight, y-size); context.lineTo(x-lineWeight, y-lineWeight); } register("cross",genericDrawShape(drawCross),genericDrawBorder(drawCross)); var drawEquilateral = function(node,x,y,size,context) { var pcount = (node.equilateral && node.equilateral.numPoints) || 5; var rotate = ((node.equilateral && node.equilateral.rotate) || 0)*Math.PI/180; var radius = size; context.moveTo(x+radius*Math.sin(rotate), y-radius*Math.cos(rotate)); // first point on outer radius, angle 'rotate' for(var i=1; i<pcount; i++) { context.lineTo(x+Math.sin(rotate+2*Math.PI*i/pcount)*radius, y-Math.cos(rotate+2*Math.PI*i/pcount)*radius); } } register("equilateral",genericDrawShape(drawEquilateral),genericDrawBorder(drawEquilateral)); var starShape = function(node,x,y,size,context) { var pcount = (node.star && node.star.numPoints) || 5, inRatio = (node.star && node.star.innerRatio) || 0.5, outR = size, inR = size*inRatio, angleOffset = Math.PI/pcount; context.moveTo(x, y-size); // first point on outer radius, top for(var i=0; i<pcount; i++) { context.lineTo(x+Math.sin(angleOffset+2*Math.PI*i/pcount)*inR, y-Math.cos(angleOffset+2*Math.PI*i/pcount)*inR); context.lineTo(x+Math.sin(2*Math.PI*(i+1)/pcount)*outR, y-Math.cos(2*Math.PI*(i+1)/pcount)*outR); } } register("star",genericDrawShape(starShape),genericDrawBorder(starShape)); /** * An example of a non standard shape (pacman). Here we WILL NOT use the * genericDraw functions, but rather register a full custom node renderer for * fill, and skip the border renderer which is irrelevant for this shape * ---------- */ var drawPacman = function(node,x,y,size,color,context) { context.fillStyle = 'yellow'; context.beginPath(); context.arc(x,y,size,1.25*Math.PI,0,false); context.arc(x,y,size,0,0.75*Math.PI,false); context.lineTo(x,y); context.closePath(); context.fill(); context.fillStyle = 'white'; context.strokeStyle = 'black'; context.beginPath(); context.arc(x+size/3,y-size/3,size/4,0,2*Math.PI,false); context.closePath(); context.fill(); context.stroke(); context.fillStyle = 'black'; context.beginPath(); context.arc(x+4*size/9,y-size/3,size/8,0,2*Math.PI,false); context.closePath(); context.fill(); } register("pacman",drawPacman,null); /** * Exporting * ---------- */ this.ShapeLibrary = { // Functions enumerate: enumerateShapes, // add: addShape, // Version version: '0.1' }; }).call(this);