"use strict"; function initGraph(url, corpus) { // VAR var loc = window.location.pathname, dir = loc.substring(0, loc.lastIndexOf('/')), corpus = JSON.parse(corpus); d3.json(url, function(error, graph) { if (error) throw error; var canvas = document.querySelector("#container"), d3Canvas = d3.select("#container"), color = d3.scaleOrdinal(d3.schemeCategory20), width = +d3Canvas.attr("width"), height = +d3Canvas.attr("height"), radius = 2.5, context = canvas.getContext("2d"); var simulation = d3.forceSimulation() .force("link", d3.forceLink().id(function(d) { return d.id; })) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width / 2, height / 2)); // FILTER & COMMUNITY var edges = [], nodes = []; for (var i = 0; i < graph.nodes.length; i++) { nodes.push(i); } for (var i = 0; i < graph.links.length; i++) { var edge = graph.links[i]; edge.weight = edge.value; edges.push(edge); } // Create the "community" var community = jLouvain().nodes(nodes).edges(edges), res = community(); // Affect community for each node for (var key in res) { graph.nodes[nodes[key]].group = res[key]; } var deleted_links = {}, selectedLinks = graph.links.filter(function(d) { var res = (d.value >= 10); if (!res) { deleted_links[d.source] = deleted_links[d.source] + 1 || 1; deleted_links[d.target] = deleted_links[d.target] + 1 || 1; } return res; }), selectedNodes = graph.nodes.filter(function(d) { d.value = d.value - (deleted_links[d.id] || 0); var res = (d.value > 0); return res; }); // FILL CANVAS simulation .nodes(selectedNodes) .on("tick", draw); simulation.force("link") .links(selectedLinks); function draw() { context.save(); context.clearRect(0, 0, width, height); context.translate(transform.x, transform.y); context.scale(transform.k, transform.k); // draw links context.strokeStyle = "#546e7a"; context.beginPath(); graph.links.forEach(function(d) { context.moveTo(d.source.x, d.source.y); context.lineTo(d.target.x, d.target.y); }); context.stroke(); // draw nodes graph.nodes.forEach(function(d) { context.beginPath(); //for each node do begin path as context fill style and stroke are different. context.strokeStyle = "#fff"; context.fillStyle = color(d.group); context.moveTo(d.x + radius, d.y); context.arc(d.x, d.y, radius, 0, 2 * Math.PI); context.fill(); context.stroke(); }); context.restore(); } // ZOOM var transform = d3.zoomIdentity; d3Canvas .call(d3.drag().subject(dragsubject) .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)) .call(d3.zoom().scaleExtent([-100, 100]).on("zoom", zoomed)) .call(draw); function zoomed() { transform = d3.event.transform; draw(); } function dragsubject() { var selectedNode, i, n, x = transform.invertX(d3.event.x), y = transform.invertY(d3.event.y), dx, dy; for (i = selectedNodes.length - 1; i >= 0; --i) { selectedNode = selectedNodes[i]; dx = x - selectedNode.x; dy = y - selectedNode.y; if (dx * dx + dy * dy < radius * radius) { selectedNode.x = transform.applyX(selectedNode.x); selectedNode.y = transform.applyY(selectedNode.y); return selectedNode; } } } // function dragged() { // d3.event.subject.x = transform.invertX(d3.event.x); // d3.event.subject.y = transform.invertY(d3.event.y); // draw(); // } function dragstarted() { if (!d3.event.active) simulation.alphaTarget(0.3).restart(); d3.event.subject.fx = transform.invertX(d3.event.subject.x); d3.event.subject.fy = transform.invertY(d3.event.subject.y); } function dragged() { d3.event.subject.fx = transform.invertX(d3.event.x); d3.event.subject.fy = transform.invertY(d3.event.y); } function dragended() { if (!d3.event.active) simulation.alphaTarget(0); d3.event.subject.fx = null; d3.event.subject.fy = null; } }); }