about summary refs log tree commit diff
path: root/sourcecodes/graph-creator.js
diff options
context:
space:
mode:
authorziejd22019-06-27 13:58:58 -0500
committerziejd22019-06-27 13:58:58 -0500
commit5310fa747a6a46a0e96dc649cbca863e2c44aeb4 (patch)
tree3d4ba8a8a8a6f50b4877d1153e0fb390bbf86564 /sourcecodes/graph-creator.js
parent2be4664d4ef668feee3d1e8972c7fd0813aea7e8 (diff)
downloadBNW-5310fa747a6a46a0e96dc649cbca863e2c44aeb4.tar.gz
Version 1.22
Adding new visualization options
Diffstat (limited to 'sourcecodes/graph-creator.js')
-rw-r--r--sourcecodes/graph-creator.js275
1 files changed, 275 insertions, 0 deletions
diff --git a/sourcecodes/graph-creator.js b/sourcecodes/graph-creator.js
new file mode 100644
index 00000000..d9764d46
--- /dev/null
+++ b/sourcecodes/graph-creator.js
@@ -0,0 +1,275 @@
+var colors = d3.scaleOrdinal(d3.schemeCategory10);
+
+var svg = d3.select("svg"),
+    width = +svg.attr("width"),
+    height = +svg.attr("height"),
+    node,
+    link;
+
+svg.append('defs').append('marker')
+    .attrs({'id':'arrowhead',
+		'viewBox':'-0 -5 10 10',
+		'refX':13,
+		'refY':0,
+		'orient':'auto',
+		'markerWidth':13,
+		'markerHeight':13,
+		'xoverflow':'visible',
+		'stroke-width':'4px',
+		'stroke-opacity':0.8})
+    .append('svg:path')
+    .attr('d', 'M 0,-5 L 10 ,0 L 0,5')
+    .attr('fill', '#999')
+    .style('stroke','none');
+
+var simulation = d3.forceSimulation()
+    .force("link", d3.forceLink().id(function (d) {return d.id;}).distance(400).strength(0))
+    //    .force("charge", d3.forceManyBody())
+    //.force("center", d3.forceCenter(width / 2, height / 2));
+
+d3.json("graph.json", function (error, graph) {
+        if (error) throw error;
+        update(graph.links, graph.nodes);
+    })
+
+    function update(links, nodes) {
+    link = svg.selectAll(".link")
+	.data(links)
+	.enter()
+	.append("line")
+	.attr("class", "link")
+	.attr('marker-end','url(#arrowhead)')
+    .attr('stroke',"#999")
+    .attr('stroke-opacity',.8)
+    .attr('stroke-width',"1px");
+
+    link.append("title")
+	.text(function (d) {return d.type;});
+
+    edgepaths = svg.selectAll(".edgepath")
+	.data(links)
+	.enter()
+	.append('path')
+	.attrs({
+                'class': 'edgepath',
+                'fill-opacity': 0,
+                'stroke-opacity': 0,
+                'id': function (d, i) {return 'edgepath' + i}
+            })
+	.style("pointer-events", "none");
+
+    edgelabels = svg.selectAll(".edgelabel")
+	.data(links)
+	.enter()
+	.append('text')
+	.style("pointer-events", "none")
+	.attrs({
+                'class': 'edgelabel',
+                'id': function (d, i) {return 'edgelabel' + i},
+                'font-size': 17,
+                'fill': '#aaa',
+		'dx': 0,
+		'dy': -4
+            });
+
+    edgelabels.append('textPath')
+	.attr('xlink:href', function (d, i) {return '#edgepath' + i})
+	.style("text-anchor", "middle")
+	.style("pointer-events", "none")
+	.attr("startOffset", "50%")
+	.attr("startOffset", "50%")
+	.text(function (d) {return d.type});
+
+    node = svg.selectAll(".node")
+	.data(nodes)
+	.enter()
+	.append("g")
+	.attr("class", "node")
+	.call(d3.drag()
+	      .on("start", dragstarted)
+	      .on("drag", dragged)
+	      //.on("end", dragended)
+	      );
+
+    node.append("circle")
+	.attr("r", 5)
+        .style("fill","#999");
+    //	.attr("r", 5)
+    //	.style("fill", function (d, i) {return colors(i);})
+
+    node.append("title")
+	.text(function (d) {return d.name;});
+
+    node.append("text")
+       .text(function (d) {return d.name;})
+       .attr("x",10)
+       .attr("dy", ".35em")
+       .attr("font","20px")
+       .attr("font-size",20)
+    //.attr("dy", -3)
+    //	.text(function (d) {return d.name+":"+d.label;});
+
+    simulation
+        .nodes(nodes)
+        .on("tick", ticked);
+
+    simulation.force("link")
+        .links(links);
+}
+
+function ticked() {
+        link
+            .attr("x1", function (d) {return d.source.x;})
+            .attr("y1", function (d) {return d.source.y;})
+            .attr("x2", function (d) {return d.target.x;})
+            .attr("y2", function (d) {return d.target.y;});
+
+        node
+            .attr("transform", function (d) {return "translate(" + d.x + ", " + d.y + ")";});
+
+        edgepaths.attr('d', function (d) {
+		return 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y;
+	    });
+
+        edgelabels.attr('transform', function (d) {
+		if (d.target.x < d.source.x) {
+		    var bbox = this.getBBox();
+
+		    rx = bbox.x + bbox.width / 2;
+		    ry = bbox.y + bbox.height / 2;
+		    return 'rotate(180 ' + rx + ' ' + ry + ')';
+		}
+		else {
+		    return 'rotate(0)';
+		}
+	    });
+}
+
+function dragstarted(d) {
+    if (!d3.event.active) simulation.alphaTarget(0.3).restart()
+			      d.fx = d.x;
+    d.fy = d.y;
+}
+
+function dragged(d) {
+    d.fx = d3.event.x;
+    d.fy = d3.event.y;
+}
+
+//    function dragended(d) {
+//        if (!d3.event.active) simulation.alphaTarget(0);
+//        d.fx = undefined;
+//        d.fy = undefined;
+//    }
+
+
+
+d3.select('#saveButton').on('click', function(){
+	var svgString = getSVGString(svg.node());
+	svgString2Image( svgString, 2*width, 2*height, 'png', save ); // passes Blob and filesize String to the callback
+
+	function save( dataBlob, filesize ){
+	    saveAs( dataBlob, 'D3 vis exported to PNG.png' ); // FileSaver.js function
+	}
+    });
+
+// Below are the functions that handle actual exporting:
+// getSVGString ( svgNode ) and svgString2Image( svgString, width, height, format, callback )
+function getSVGString( svgNode ) {
+    svgNode.setAttribute('xlink', 'http://www.w3.org/1999/xlink');
+    var cssStyleText = getCSSStyles( svgNode );
+    appendCSS( cssStyleText, svgNode );
+
+    var serializer = new XMLSerializer();
+    var svgString = serializer.serializeToString(svgNode);
+    svgString = svgString.replace(/(\w+)?:?xlink=/g, 'xmlns:xlink='); // Fix root xlink without namespace
+    svgString = svgString.replace(/NS\d+:href/g, 'xlink:href'); // Safari NS namespace fix
+
+    return svgString;
+
+    function getCSSStyles( parentElement ) {
+	var selectorTextArr = [];
+
+	// Add Parent element Id and Classes to the list
+	selectorTextArr.push( '#'+parentElement.id );
+	for (var c = 0; c < parentElement.classList.length; c++)
+	    if ( !contains('.'+parentElement.classList[c], selectorTextArr) )
+		selectorTextArr.push( '.'+parentElement.classList[c] );
+
+	// Add Children element Ids and Classes to the list
+	var nodes = parentElement.getElementsByTagName("*");
+	for (var i = 0; i < nodes.length; i++) {
+	    var id = nodes[i].id;
+	    if ( !contains('#'+id, selectorTextArr) )
+		selectorTextArr.push( '#'+id );
+
+	    var classes = nodes[i].classList;
+	    for (var c = 0; c < classes.length; c++)
+		if ( !contains('.'+classes[c], selectorTextArr) )
+		    selectorTextArr.push( '.'+classes[c] );
+	}
+
+	// Extract CSS Rules
+	var extractedCSSText = "";
+	for (var i = 0; i < document.styleSheets.length; i++) {
+	    var s = document.styleSheets[i];
+	    
+	    try {
+		if(!s.cssRules) continue;
+	    } catch( e ) {
+		if(e.name !== 'SecurityError') throw e; // for Firefox
+		continue;
+	    }
+
+	    var cssRules = s.cssRules;
+	    for (var r = 0; r < cssRules.length; r++) {
+		if ( contains( cssRules[r].selectorText, selectorTextArr ) )
+		    extractedCSSText += cssRules[r].cssText;
+	    }
+	}
+	
+
+	return extractedCSSText;
+
+	function contains(str,arr) {
+	    return arr.indexOf( str ) === -1 ? false : true;
+	}
+
+    }
+
+    function appendCSS( cssText, element ) {
+	var styleElement = document.createElement("style");
+	styleElement.setAttribute("type","text/css"); 
+	styleElement.innerHTML = cssText;
+	var refNode = element.hasChildNodes() ? element.children[0] : null;
+	element.insertBefore( styleElement, refNode );
+    }
+}
+
+
+function svgString2Image( svgString, width, height, format, callback ) {
+    var format = format ? format : 'png';
+
+    var imgsrc = 'data:image/svg+xml;base64,'+ btoa( unescape( encodeURIComponent( svgString ) ) ); // Convert SVG string to data URL
+
+    var canvas = document.createElement("canvas");
+    var context = canvas.getContext("2d");
+
+    canvas.width = width;
+    canvas.height = height;
+
+    var image = new Image();
+    image.onload = function() {
+	context.clearRect ( 0, 0, width, height );
+	context.drawImage(image, 0, 0, width, height);
+
+	canvas.toBlob( function(blob) {
+		var filesize = Math.round( blob.length/1024 ) + ' KB';
+		if ( callback ) callback( blob, filesize );
+	    });
+
+	
+    };
+
+    image.src = imgsrc;
+}