var lineColor = "#172CAF"; var circleOutlineColor = "#0776A0"; var circleFillColor = "#62B1D0"; var textColorSource = "#FFFFFF"; var circleOutlineColorTarget = "#FFA340"; var circleFillColorTarget = "#FFBC73"; var textColorTarget = "#A65600"; var nodes = [{ id : "T0", name : "Target 0", type : "t", time : 0, strength : 1 }, { id : "T1", name : "Target 1", type : "t", time : 3, strength : 10 }, { id : "T2", name : "Target 2", type : "t", time : 5, strength : 2 }, { id : "T3", name : "Target 3", type : "t", time : 8, strength : 7 }, { id : "T4", name : "Target 4", type : "t", time : 6, strength : 7 }, { id : "S1", name : "Source 1", type : "s", time : 1, count : 2 }, { id : "S2", name : "Source 2", type : "s", time : 2, count : 1 }, { id : "S3", name : "Source 3", type : "s", time : 2, count : 4 }, { id : "S4", name : "Source 4", type : "s", time : 4, count : 2 }, { id : "S5", name : "Source 5", type : "s", time : 3, count : 2 } ]; var links = [{ source : "S1", target : "T1", strength : 0.05 }, { source : "S2", target : "T1", strength : 0.1 }, { source : "S3", target : "T1", strength : 0.3 }, { source : "S3", target : "T2", strength : 0.8 }, { source : "S1", target : "T2", strength : 0.05 }, { source : "S3", target : "T3", strength : 1.0 }, { source : "S4", target : "T4", strength : 1.0 }, { source : "S4", target : "T2", strength : 0.3 }, { source : "S5", target : "T3", strength : 1.0 }, { source : "S5", target : "T2", strength : 0.1 }, { source : "S3", target : "T4", strength : 1.0 } ]; var margin = { top : 20, right : 10, bottom : 20, left : 10 }, padding = { top : 60, right : 60, bottom : 60, left : 60 }, outerWidth = 500, outerHeight = 400, innerWidth = outerWidth - margin.left - margin.right, innerHeight = outerHeight - margin.top - margin.bottom, width = innerWidth - padding.left - padding.right, height = innerHeight - padding.top - padding.bottom, axisBand = 15; var x_max = d3.max(nodes, function(d) { return d.time; }); var x = d3.scale.linear() .domain([0, x_max]) .range([0, width]); var y = d3.scale.linear() .domain([0, 100]) .range([0, height]); var target_axis_position = y(50); mapNodes = function (nodes) { var nodesMap; nodesMap = d3.map(); nodes.forEach(function (n) { return nodesMap.set(n.id, n); }); return nodesMap; }; nodesMap = mapNodes(nodes); links.forEach(function (l) { l.source = nodesMap.get(l.source); l.target = nodesMap.get(l.target); }); var color = d3.scale.category20(); var force = d3.layout.force() .charge(-240) .gravity(0.2) .linkStrength(function (l, i) { return l.strength; }) .size([width, height]); var svg = d3.select("div.graph").append("svg") .attr("width", outerWidth) .attr("height", outerHeight) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var g = svg.append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); force.nodes(nodes) .links(links) .start(); g.append("rect") .attr("x", 0) .attr("y", y(50 - axisBand)) .attr("width", x(x_max)) .attr("height", y(2 * axisBand)) .attr("fill", "#EEE"); var link = g.selectAll(".link") .data(links) .enter().append("line") .attr("class", "link") .style("stroke-width", function (d) { return Math.sqrt(d.strength * 10); }); var node = g.selectAll(".node") .data(nodes) .enter().append("circle") .attr("class", "node") .attr("r", function (d) { if (d.type == "t") { return Math.sqrt(d.strength) * 5; } else if (d.type = "s") { return Math.sqrt(d.count) * 5; } else { return 5; } }) .classed("target", function (d) { return d.type == "t"; }) .classed("source", function (d) { return d.type == "s"; }) .call(force.drag); node.append("title") .text(function (d) { return d.name; }); // drag zoom adapted from http://bl.ocks.org/rmarimon/1179647 var downx = Math.NaN; var downscalex; var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); function dragX(d) { var p = d3.mouse(svg[0][0]); downx = x.invert(p[0]); downscalex = x; }; g.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + target_axis_position + ")") .call(xAxis) .on("mousedown", function (d) { dragX(d); }); svg.select('.x.axis text') .on("mousedown", function (d) { dragX(d); }); d3.select('body') .on("mousemove", function (d) { if (!isNaN(downx)) { var p = d3.mouse(svg[0][0]); var rupx = p[0]; if (rupx != 0) { x.domain([downscalex.domain()[0], width * (downx - downscalex.domain()[0]) / rupx + downscalex.domain()[0]]); } svg.select('.x.axis').call(xAxis); force.start(); } }) .on("mouseup", function (d) { downx = Math.NaN; }); var adjust_y = function(d) { if (d.type == "t") { return y(50); } else { if (Math.abs(y(50) - d.y) < y(axisBand)) { return d.y < y(50) ? y(50 - axisBand) : y(50 + axisBand); } else { return d.y; } } }; var adjust_x = function(d) { return x(d.time); }; force.on("tick", function () { link.attr("x1", function (d) { return adjust_x(d.source); }) .attr("y1", function (d) { return adjust_y(d.source); }) .attr("x2", function (d) { return adjust_x(d.target); }) .attr("y2", function (d) { return adjust_y(d.target); }); node.attr("cx", function (d) { return adjust_x(d); }) .attr("cy", function (d) { return adjust_y(d); }); }); $(function() { $( "#slider" ).slider({ range: "min", value: -240, min: -960, max: 0, slide: function( event, ui ) { $('#charge').text(ui.value); force.charge($('#charge').text()).start(); } }); });