// Mathieu Jacomy @ Sciences Po Médialab & WebAtlas // (requires sigma.js to be loaded) sigma.publicPrototype.parseGexf = function(gexfPath) { // Load XML file: var gexfhttp, gexf; var sigmaInstance = this; gexfhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); gexfhttp.overrideMimeType('text/xml'); gexfhttp.open('GET', gexfPath, false); gexfhttp.send(); gexf = gexfhttp.responseXML; var viz='http://www.gexf.net/1.2draft/viz'; // Vis namespace var i, j, k; // Parse Attributes // This is confusing, so I'll comment heavily var nodesAttributes = []; // The list of attributes of the nodes of the graph that we build in json var nodesAttributesDict = {}; var edgesAttributes = []; // The list of attributes of the edges of the graph that we build in json var edgesAttributesDict = {}; var attributesNodes = gexf.getElementsByTagName('attributes'); // In the gexf (that is an xml), the list of xml nodes 'attributes' (note the plural 's') for(i = 0; i<attributesNodes.length; i++){ var attributesNode = attributesNodes[i]; // attributesNode is each xml node 'attributes' (plural) if(attributesNode.getAttribute('class') == 'node'){ var attributeNodes = attributesNode.getElementsByTagName('attribute'); // The list of xml nodes 'attribute' (no 's') for(j = 0; j<attributeNodes.length; j++){ var attributeNode = attributeNodes[j]; // Each xml node 'attribute' var id = attributeNode.getAttribute('id'), title = attributeNode.getAttribute('title'), type = attributeNode.getAttribute('type'); var attribute = {id:id, title:title, type:type}; nodesAttributes.push(attribute); nodesAttributesDict[id] = title } } else if(attributesNode.getAttribute('class') == 'edge'){ var attributeNodes = attributesNode.getElementsByTagName('attribute'); // The list of xml nodes 'attribute' (no 's') for(j = 0; j<attributeNodes.length; j++){ var attributeNode = attributeNodes[j]; // Each xml node 'attribute' var id = attributeNode.getAttribute('id'), title = attributeNode.getAttribute('title'), type = attributeNode.getAttribute('type'); var attribute = {id:id, title:title, type:type}; edgesAttributes.push(attribute); edgesAttributesDict[id] = title } } } var nodes = []; // The nodes of the graph var nodesNodes = gexf.getElementsByTagName('nodes') // The list of xml nodes 'nodes' (plural) for(i=0; i<nodesNodes.length; i++){ var nodesNode = nodesNodes[i]; // Each xml node 'nodes' (plural) var nodeNodes = nodesNode.getElementsByTagName('node'); // The list of xml nodes 'node' (no 's') for(j=0; j<nodeNodes.length; j++){ var nodeNode = nodeNodes[j]; // Each xml node 'node' (no 's') window.NODE = nodeNode; var id = nodeNode.getAttribute('id'); var label = nodeNode.getAttribute('label') || id; //viz var size = 1; var x = 100 - 200*Math.random(); var y = 100 - 200*Math.random(); var color; var sizeNodes = nodeNode.getElementsByTagName('size'); sizeNodes = sizeNodes.length ? sizeNodes : nodeNode.getElementsByTagNameNS('*','size'); if(sizeNodes.length>0){ sizeNode = sizeNodes[0]; size = parseFloat(sizeNode.getAttribute('value')); } var positionNodes = nodeNode.getElementsByTagName('position'); positionNodes = positionNodes.length ? positionNodes : nodeNode.getElementsByTagNameNS('*','position'); if(positionNodes.length>0){ var positionNode = positionNodes[0]; x = parseFloat(positionNode.getAttribute('x')); y = parseFloat(positionNode.getAttribute('y')); } var colorNodes = nodeNode.getElementsByTagName('color'); colorNodes = colorNodes.length ? colorNodes : nodeNode.getElementsByTagNameNS('*','color'); if(colorNodes.length>0){ colorNode = colorNodes[0]; color = '#'+sigma.tools.rgbToHex(parseFloat(colorNode.getAttribute('r')), parseFloat(colorNode.getAttribute('g')), parseFloat(colorNode.getAttribute('b'))); } var colorsProcessed = {}; if (nodeJSON.colors) { for (var key in nodeJSON.colors) { if (nodeJSON.colors.hasOwnProperty(key)) { // Get the rgb string for this property, e.g., "rgb(198,116,255)" var rgbStr = nodeJSON.colors[key]; // Remove "rgb(" and ")" then split by comma to extract r, g, b values var rgbArr = rgbStr.replace(/rgb\(|\)/g, '').split(','); var r_val = parseInt(rgbArr[0].trim(), 10); var g_val = parseInt(rgbArr[1].trim(), 10); var b_val = parseInt(rgbArr[2].trim(), 10); // Convert to hex and store under the corresponding key colorsProcessed[key] = '#' + sigma.tools.rgbToHex(r_val, g_val, b_val); } } } // Create Node var node = {label:label, size:size, x:x, y:y, attributes:{}, color:color, colors: colorsProcessed}; // The graph node // Attribute values var attvalueNodes = nodeNode.getElementsByTagName('attvalue'); for(k=0; k<attvalueNodes.length; k++){ var attvalueNode = attvalueNodes[k]; var attr = attvalueNode.getAttribute('for'); var val = attvalueNode.getAttribute('value'); node.attributes[nodesAttributesDict[attr]] = val; } sigmaInstance.addNode(id,node); } } var edges = []; var edgeId = 0; var edgesNodes = gexf.getElementsByTagName('edges'); for(i=0; i<edgesNodes.length; i++){ var edgesNode = edgesNodes[i]; var edgeNodes = edgesNode.getElementsByTagName('edge'); for(j=0; j<edgeNodes.length; j++){ var edgeNode = edgeNodes[j]; var source = edgeNode.getAttribute('source'); var target = edgeNode.getAttribute('target'); var label = edgeNode.getAttribute('label'); var edge = { id: j, sourceID: source, targetID: target, label: label, attributes: {} }; var attrs = edgeNode.attributes; for(var i=0;i<attrs.length;i++) { var n = attrs[i].name; if(n == 'source' || n =='target' || n=='label') continue; edge.attributes[n]=attrs[i].value; } var weight = edgeNode.getAttribute('weight'); if(weight!=undefined){ edge['weight'] = weight; } var attvalueNodes = edgeNode.getElementsByTagName('attvalue'); for(k=0; k<attvalueNodes.length; k++){ var attvalueNode = attvalueNodes[k]; var attr = attvalueNode.getAttribute('for'); var val = attvalueNode.getAttribute('value'); edge.attributes[edgesAttributesDict[attr]] = val; } sigmaInstance.addEdge(edgeId++,source,target,edge); } } };