Graph database Analysis of the Steam Network
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

236 lines
7.6 KiB

;(function(undefined) {
'use strict';
if (typeof sigma === 'undefined')
throw 'sigma is not declared';
if (typeof ShapeLibrary === 'undefined')
throw 'ShapeLibrary is not declared';
// Initialize package:
sigma.utils.pkg('sigma.canvas.nodes');
sigma.utils.pkg('sigma.svg.nodes');
var sigInst = undefined;
var imgCache = {};
var initPlugin = function(inst) {
sigInst = inst;
}
var drawImage = function (node,x,y,size,context) {
if(sigInst && node.image && node.image.url) {
var url = node.image.url;
var ih = node.image.h || 1; // 1 is arbitrary, anyway only the ratio counts
var iw = node.image.w || 1;
var scale = node.image.scale || 1;
var clip = node.image.clip || 1;
// create new IMG or get from imgCache
var image = imgCache[url];
if(!image) {
image = document.createElement('IMG');
image.src = url;
image.status = 'loading';
image.onerror = function() {
console.log("error loading", url);
image.status = 'error';
};
image.onload = function(){
// TODO see how we redraw on load
// need to provide the siginst as a parameter to the library
console.log("redraw on image load", url);
image.status = 'ok';
sigInst.refresh();
};
imgCache[url] = image;
}
// calculate position and draw
var xratio = (iw<ih) ? (iw/ih) : 1;
var yratio = (ih<iw) ? (ih/iw) : 1;
var r = size*scale;
// Draw the clipping disc:
context.save(); // enter clipping mode
context.beginPath();
context.arc(x,y,size*clip,0,Math.PI*2,true);
context.closePath();
context.clip();
if(image.status === 'ok') {
// Draw the actual image
context.drawImage(image,
x+Math.sin(-3.142/4)*r*xratio,
y-Math.cos(-3.142/4)*r*yratio,
r*xratio*2*Math.sin(-3.142/4)*(-1),
r*yratio*2*Math.cos(-3.142/4));
}
context.restore(); // exit clipping mode
}
}
var drawSVGImage = function (node, group, settings) {
if(sigInst && node.image && node.image.url) {
var clipCircle = document.createElementNS(settings('xmlns'), 'circle'),
clipPath = document.createElementNS(settings('xmlns'), 'clipPath'),
clipPathId = settings('classPrefix') + '-clip-path-' + node.id,
def = document.createElementNS(settings('xmlns'), 'defs'),
image = document.createElementNS(settings('xmlns'), 'image'),
url = node.image.url;
clipPath.setAttributeNS(null, 'id', clipPathId);
clipPath.appendChild(clipCircle);
def.appendChild(clipPath);
// angular's base tag will change the relative fragment id, so
// #<clipPathId> doesn't work
// HACKHACK: IE <=9 does not respect the HTML base element in SVG.
// They don't need the current URL in the clip path reference.
var absolutePath = /MSIE [5-9]/.test(navigator.userAgent) ?
"" : document.location.href;
// To fix cases where an anchor tag was used
absolutePath = absolutePath.split("#")[0];
image.setAttributeNS(null, 'class',
settings('classPrefix') + '-node-image');
image.setAttributeNS(null, 'clip-path',
'url(' + absolutePath + '#' + clipPathId + ')');
image.setAttributeNS(null, 'pointer-events', 'none');
image.setAttributeNS('http://www.w3.org/1999/xlink', 'href',
node.image.url);
group.appendChild(def);
group.appendChild(image);
}
}
var register = function(name,drawShape,drawBorder) {
sigma.canvas.nodes[name] = function(node, context, settings) {
var args = arguments,
prefix = settings('prefix') || '',
size = node[prefix + 'size'],
color = node.color || settings('defaultNodeColor'),
borderColor = node.borderColor || color,
x = node[prefix + 'x'],
y = node[prefix + 'y'];
context.save();
if(drawShape) {
drawShape(node,x,y,size,color,context);
}
if(drawBorder) {
drawBorder(node,x,y,size,borderColor,context);
}
drawImage(node,x,y,size,context);
context.restore();
};
sigma.svg.nodes[name] = {
create: function(node, settings) {
var group = document.createElementNS(settings('xmlns'), 'g'),
circle = document.createElementNS(settings('xmlns'), 'circle');
group.setAttributeNS(null, 'class',
settings('classPrefix') + '-node-group');
group.setAttributeNS(null, 'data-node-id', node.id);
// Defining the node's circle
circle.setAttributeNS(null, 'data-node-id', node.id);
circle.setAttributeNS(null, 'class',
settings('classPrefix') + '-node');
circle.setAttributeNS(null, 'fill',
node.color || settings('defaultNodeColor'));
group.appendChild(circle);
drawSVGImage(node, group, settings);
return group;
},
update: function(node, group, settings) {
var classPrefix = settings('classPrefix'),
clip = node.image.clip || 1,
// 1 is arbitrary, anyway only the ratio counts
ih = node.image.h || 1,
iw = node.image.w || 1,
prefix = settings('prefix') || '',
scale = node.image.scale || 1,
size = node[prefix + 'size'],
x = node[prefix + 'x'],
y = node[prefix + 'y'];
var r = scale * size,
xratio = (iw<ih) ? (iw/ih) : 1,
yratio = (ih<iw) ? (ih/iw) : 1;
for(var i = 0, childNodes = group.childNodes; i < childNodes.length; i ++) {
var className = childNodes[i].getAttribute('class');
switch (className) {
case classPrefix + '-node':
childNodes[i].setAttributeNS(null, 'cx', x);
childNodes[i].setAttributeNS(null, 'cy', y);
childNodes[i].setAttributeNS(null, 'r', size);
// // Updating only if not freestyle
if (!settings('freeStyle')) {
childNodes[i].setAttributeNS(
null,
'fill',
node.color || settings('defaultNodeColor'));
}
break;
case classPrefix + '-node-image':
childNodes[i].setAttributeNS(null, 'x',
x+Math.sin(-3.142/4)*r*xratio);
childNodes[i].setAttributeNS(null, 'y',
y-Math.cos(-3.142/4)*r*yratio);
childNodes[i].setAttributeNS(null, 'width',
r*xratio*2*Math.sin(-3.142/4)*(-1));
childNodes[i].setAttributeNS(null, 'height',
r*yratio*2*Math.cos(-3.142/4));
break;
default:
// no class name, must be the clip-path
var clipPath = childNodes[i].firstChild;
if (clipPath != null) {
var clipPathId = classPrefix + '-clip-path-' + node.id;
if (clipPath.getAttribute('id') === clipPathId) {
clipPath.firstChild.setAttributeNS(null, 'cx', x);
clipPath.firstChild.setAttributeNS(null, 'cy', y);
clipPath.firstChild.setAttributeNS(null, 'r',
clip * size);
}
}
break;
}
}
// showing
group.style.display = '';
}
}
}
ShapeLibrary.enumerate().forEach(function(shape) {
register(shape.name,shape.drawShape,shape.drawBorder);
});
/**
* Exporting
* ----------
*/
this.CustomShapes = {
// Functions
init: initPlugin,
// add pre-cache images
// Version
version: '0.1'
};
}).call(this);