From ab78f3a7d64f012d4bd8d31ac9f648abd7e34c18 Mon Sep 17 00:00:00 2001 From: Elijah meeks Date: Mon, 15 Sep 2014 11:51:19 -0700 Subject: [PATCH 1/6] Expose raw array --- hexbin/hexbin.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hexbin/hexbin.js b/hexbin/hexbin.js index 8076834..fb049ab 100644 --- a/hexbin/hexbin.js +++ b/hexbin/hexbin.js @@ -68,6 +68,11 @@ d3.hexbin = function() { return "m" + hexagon(radius).join("l") + "z"; }; + hexbin.hexagonArray = function(radius) { + if (arguments.length < 1) radius = r; + return hexagon(radius); + }; + hexbin.centers = function() { var centers = []; for (var y = 0, odd = false, j = 0; y < height + r; y += dy, odd = !odd, ++j) { From cc584a8958e0a7299de407a95ae79110ef9d71a6 Mon Sep 17 00:00:00 2001 From: Elijah Meeks Date: Fri, 22 May 2015 10:21:13 -0700 Subject: [PATCH 2/6] Link as area and adjusted links --- sankey/sankey.js | 70 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/sankey/sankey.js b/sankey/sankey.js index abe137b..04fa16a 100644 --- a/sankey/sankey.js +++ b/sankey/sankey.js @@ -50,6 +50,40 @@ d3.sankey = function() { return sankey; }; + sankey.linkAdjusted = function() { + var curvature = .5; + + function link(d, adjustment, segmentOffset) { + var x0 = d.source.x + d.source.dx, + x1 = d.target.x, + xi = d3.interpolateNumber(x0, x1), + x2 = xi(curvature), + x3 = xi(1 - curvature), + y0 = d.source.y + d.sy + segmentOffset, + y1 = d.target.y + d.ty + segmentOffset, + y2 = d.target.y + d.ty + (d.dy * adjustment) + segmentOffset, + y3 = d.source.y + d.sy + (d.dy * adjustment) + segmentOffset; + + return "M" + x0 + "," + y0 + + "C" + x2 + "," + y0 + + " " + x3 + "," + y1 + + " " + x1 + "," + y1 + + "L" + x1 + "," + y2 + + "C" + x3 + "," + y2 + + " " + x2 + "," + y3 + + " " + x0 + "," + y3 + + "Z"; + } + + link.curvature = function(_) { + if (!arguments.length) return curvature; + curvature = +_; + return link; + }; + + return link; + }; + sankey.link = function() { var curvature = .5; @@ -59,12 +93,38 @@ d3.sankey = function() { xi = d3.interpolateNumber(x0, x1), x2 = xi(curvature), x3 = xi(1 - curvature), - y0 = d.source.y + d.sy + d.dy / 2, - y1 = d.target.y + d.ty + d.dy / 2; + y0 = d.source.y + d.sy, + y1 = d.target.y + d.ty, + y2 = d.target.y + d.ty + d.dy, + y3 = d.source.y + d.sy + d.dy; + + if (y3 - y0 < 30000) { + return "M" + x0 + "," + y0 + "C" + x2 + "," + y0 + " " + x3 + "," + y1 - + " " + x1 + "," + y1; + + " " + x1 + "," + y1 + + "L" + x1 + "," + y2 + + "C" + x3 + "," + y2 + + " " + x2 + "," + y3 + + " " + x0 + "," + y3 + + "Z"; + } + else { + + var offset = (x1 - x0) /4; + return "M" + x0 + "," + y0 + + "C" + x2 + "," + y0 + + " " + x3 + "," + (y1) + + " " + (x1 - offset) + "," + (y1 + 0) + + "L" + (x1 - 6) + "," + ((y2 + y1)/2) + + "L" + (x1 - offset) + "," + (y2 + 0) + + "C" + x3 + "," + (y2) + + " " + x2 + "," + y3 + + " " + x0 + "," + y3 + + "Z"; + + } } link.curvature = function(_) { @@ -108,6 +168,7 @@ d3.sankey = function() { // nodes with no incoming links are assigned breadth zero, while // nodes with no outgoing links are assigned the maximum breadth. function computeNodeBreadths() { + var remainingNodes = nodes, nextNodes, x = 0; @@ -127,7 +188,6 @@ d3.sankey = function() { ++x; } - // moveSinksRight(x); scaleNodeBreadths((size[0] - nodeWidth) / (x - 1)); } @@ -291,4 +351,4 @@ d3.sankey = function() { } return sankey; -}; +}; \ No newline at end of file From d56179f73ae5a45082480a596c40d908483883c6 Mon Sep 17 00:00:00 2001 From: Elijah Meeks Date: Thu, 4 Jun 2015 13:15:44 -0700 Subject: [PATCH 3/6] A simple adjacency matrix --- adjacencyMatrix/d3.layout.adjacencyMatrix.js | 151 +++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 adjacencyMatrix/d3.layout.adjacencyMatrix.js diff --git a/adjacencyMatrix/d3.layout.adjacencyMatrix.js b/adjacencyMatrix/d3.layout.adjacencyMatrix.js new file mode 100644 index 0000000..d25b966 --- /dev/null +++ b/adjacencyMatrix/d3.layout.adjacencyMatrix.js @@ -0,0 +1,151 @@ +(function() { + d3.layout.adjacencyMatrix = function() { + var directed = true, + size = [1,1], + nodes = [], + edges = [], + edgeWeight = function (d) {return 1}, + nodeID = function (d) {return d.id}; + + function matrix() { + var width = size[0], + height = size[1], + nodeWidth = width / nodes.length, + nodeHeight = height / nodes.length, + constructedMatrix = [], + matrix = [], + edgeHash = {}, + xScale = d3.scale.linear().domain([0,nodes.length]).range([0,width]), + yScale = d3.scale.linear().domain([0,nodes.length]).range([0,height]); + + nodes.forEach(function(node, i) { + node.sortedIndex = i; + }) + + edges.forEach(function(edge) { + var constructedEdge = {source: edge.source, target: edge.target, weight: edgeWeight(edge)}; + if (typeof edge.source == "number") { + constructedEdge.source = nodes[edge.source]; + } + if (typeof edge.target == "number") { + constructedEdge.target = nodes[edge.target]; + } + var id = nodeID(constructedEdge.source) + "-" + nodeID(constructedEdge.target); + + if (directed === false && constructedEdge.source.sortedIndex < constructedEdge.target.sortedIndex) { + id = nodeID(constructedEdge.target) + "-" + nodeID(constructedEdge.source); + } + if (!edgeHash[id]) { + edgeHash[id] = constructedEdge; + } + else { + edgeHash[id].weight = edgeHash[id].weight + constructedEdge.weight; + } + }); + + nodes.forEach(function (sourceNode, a) { + nodes.forEach(function (targetNode, b) { + var grid = {id: nodeID(sourceNode) + "-" + nodeID(targetNode), x: xScale(b), y: yScale(a), weight: 0, height: nodeHeight, width: nodeWidth}; + var edgeWeight = 0; + if (edgeHash[grid.id]) { + edgeWeight = edgeHash[grid.id].weight; + grid.weight = edgeWeight; + }; + if (directed === true || grid.x < grid.y) { + matrix.push(grid); + if (directed === false) { + var mirrorGrid = {id: nodeID(sourceNode) + "-" + nodeID(targetNode), x: xScale(a), y: yScale(b), weight: 0, height: nodeHeight, width: nodeWidth}; + mirrorGrid.weight = edgeWeight; + matrix.push(mirrorGrid); + } + } + }); + }); + + return matrix; + } + + matrix.directed = function(x) { + if (!arguments.length) return directed; + directed = x; + return matrix; + } + + matrix.size = function(x) { + if (!arguments.length) return size; + size = x; + return matrix; + } + + matrix.width = function(x) { + if (!arguments.length) return width; + width = x; + return matrix; + } + + matrix.nodes = function(x) { + if (!arguments.length) return nodes; + nodes = x; + return matrix; + } + + matrix.links = function(x) { + if (!arguments.length) return edges; + edges = x; + return matrix; + } + + matrix.edgeWeight = function(x) { + if (!arguments.length) return edgeWeight; + if (typeof x === "function") { + edgeWeight = x; + } + else { + edgeWeight = function () {return x}; + } + return matrix; + } + + matrix.nodeID = function(x) { + if (!arguments.length) return nodeID; + if (typeof x === "function") { + nodeID = x; + } + return matrix; + } + + matrix.xAxis = function(calledG) { + var nameScale = d3.scale.ordinal() + .domain(nodes.map(nodeID)) + .rangePoints([0,size[0]],1); + + var xAxis = d3.svg.axis().scale(nameScale).orient("top").tickSize(4); + + calledG + .append("g") + .attr("class", "am-xAxis am-axis") + .call(xAxis) + .selectAll("text") + .style("text-anchor", "end") + .attr("transform", "translate(-10,-10) rotate(90)"); + + } + + matrix.yAxis = function(calledG) { + var nameScale = d3.scale.ordinal() + .domain(nodes.map(nodeID)) + .rangePoints([0,size[1]],1); + + yAxis = d3.svg.axis().scale(nameScale) + .orient("left") + .tickSize(4); + + calledG.append("g") + .attr("class", "am-yAxis am-axis") + .call(yAxis); + } + + return matrix; + } + +})(); \ No newline at end of file From 02c059525a88ea411474ad72129b7140587263f0 Mon Sep 17 00:00:00 2001 From: Elijah Meeks Date: Thu, 4 Jun 2015 13:32:37 -0700 Subject: [PATCH 4/6] Save source and target information --- adjacencyMatrix/d3.layout.adjacencyMatrix.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adjacencyMatrix/d3.layout.adjacencyMatrix.js b/adjacencyMatrix/d3.layout.adjacencyMatrix.js index d25b966..f8bc8df 100644 --- a/adjacencyMatrix/d3.layout.adjacencyMatrix.js +++ b/adjacencyMatrix/d3.layout.adjacencyMatrix.js @@ -45,7 +45,7 @@ nodes.forEach(function (sourceNode, a) { nodes.forEach(function (targetNode, b) { - var grid = {id: nodeID(sourceNode) + "-" + nodeID(targetNode), x: xScale(b), y: yScale(a), weight: 0, height: nodeHeight, width: nodeWidth}; + var grid = {id: nodeID(sourceNode) + "-" + nodeID(targetNode), source: sourceNode, target: targetNode, x: xScale(b), y: yScale(a), weight: 0, height: nodeHeight, width: nodeWidth}; var edgeWeight = 0; if (edgeHash[grid.id]) { edgeWeight = edgeHash[grid.id].weight; @@ -54,7 +54,7 @@ if (directed === true || grid.x < grid.y) { matrix.push(grid); if (directed === false) { - var mirrorGrid = {id: nodeID(sourceNode) + "-" + nodeID(targetNode), x: xScale(a), y: yScale(b), weight: 0, height: nodeHeight, width: nodeWidth}; + var mirrorGrid = {id: nodeID(sourceNode) + "-" + nodeID(targetNode), source: sourceNode, target: targetNode, x: xScale(a), y: yScale(b), weight: 0, height: nodeHeight, width: nodeWidth}; mirrorGrid.weight = edgeWeight; matrix.push(mirrorGrid); } From e2f3ac7f7b5b6814d029f57479aa18c7abebe805 Mon Sep 17 00:00:00 2001 From: Elijah Meeks Date: Thu, 4 Jun 2015 13:46:16 -0700 Subject: [PATCH 5/6] A readme --- adjacencyMatrix/readme.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 adjacencyMatrix/readme.md diff --git a/adjacencyMatrix/readme.md b/adjacencyMatrix/readme.md new file mode 100644 index 0000000..0029e7e --- /dev/null +++ b/adjacencyMatrix/readme.md @@ -0,0 +1,20 @@ +# Adjacency Matrix + +[Demo](http://bl.ocks.org/emeeks/15c005cba60aad26e11a). + +**#matrix.size** An array of [width, height] that is used to calculate grid x, y, height and width. + +**#matrix.nodes** An array of the nodes of your network. + +**#matrix.links** An array of the edges of your network. As with other D3 network layouts, if the source and target properties are numbers, they are assumed to be array position within the nodes array, otherwise objects are assumed. + +**#matrix.edgeWeight** The function to return the weight of the edges of your links, if any. Defaults to returning 1. + +**#matrix.nodeID** The function to return the id value of a node, defaults to returning #node.id. The id is used to build the matrix and drive the axes. + +**#matrix.xAxis** Cannot be set. Call this from the same place where you've put your matrix cells and it will build a simple horizontal axis with labels from your node id. + +**#matrix.yAxis** Cannot be set. Call this from the same place where you've put your matrix cells and it will build a simple vertical axis with labels from your node id. + +**#matrix.directed** Set to false if you want to mirror undirected networks. + From d23fc8088fc6c0c08bf54ed5faa5eb12d76bdea1 Mon Sep 17 00:00:00 2001 From: Elijah Meeks Date: Thu, 4 Jun 2015 14:05:47 -0700 Subject: [PATCH 6/6] d3brokeandmadeart --- adjacencyMatrix/d3.layout.adjacencyMatrix.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/adjacencyMatrix/d3.layout.adjacencyMatrix.js b/adjacencyMatrix/d3.layout.adjacencyMatrix.js index f8bc8df..79dfbab 100644 --- a/adjacencyMatrix/d3.layout.adjacencyMatrix.js +++ b/adjacencyMatrix/d3.layout.adjacencyMatrix.js @@ -43,6 +43,8 @@ } }); + console.log("nodes", nodes, nodes.length) + nodes.forEach(function (sourceNode, a) { nodes.forEach(function (targetNode, b) { var grid = {id: nodeID(sourceNode) + "-" + nodeID(targetNode), source: sourceNode, target: targetNode, x: xScale(b), y: yScale(a), weight: 0, height: nodeHeight, width: nodeWidth}; @@ -51,7 +53,7 @@ edgeWeight = edgeHash[grid.id].weight; grid.weight = edgeWeight; }; - if (directed === true || grid.x < grid.y) { + if (directed === true || b < a) { matrix.push(grid); if (directed === false) { var mirrorGrid = {id: nodeID(sourceNode) + "-" + nodeID(targetNode), source: sourceNode, target: targetNode, x: xScale(a), y: yScale(b), weight: 0, height: nodeHeight, width: nodeWidth}; @@ -62,6 +64,8 @@ }); }); + console.log("matrix", matrix, matrix.length) + return matrix; } @@ -77,12 +81,6 @@ return matrix; } - matrix.width = function(x) { - if (!arguments.length) return width; - width = x; - return matrix; - } - matrix.nodes = function(x) { if (!arguments.length) return nodes; nodes = x;