1var zoom = {}; 2 var drag = {}; 3 var svg = {}; 4 5 6 function showSankey(energy) 7 { 8 9 $('.d3-tip-nodes').remove(); //clear olds tips 10 // var chartBox = d3.select("#sankey").node().getBoundingClientRect(); 11 var margin = {top: 10, right: 10, bottom: 10, left: 20}; 12 var width = 800; 13 var height = 300; 14 15 var linkTooltipOffset = 72, 16 nodeTooltipOffset = 130; 17 18 //Tooltip function: 19 //D3 sankey diagram with view options (Austin Czarneckiâs Block cc6371af0b726e61b9ab) 20 //https://bl.ocks.org/austinczarnecki/cc6371af0b726e61b9ab 21 var tipLinks = d3.tip() 22 .attr('class', 'd3-tip') 23 .attr('id', 'transferTips') 24 .offset([-10,0]); 25 26 var tipNodes = d3.tip() 27 .attr('class', 'd3-tip d3-tip-nodes') 28 .attr('id', 'transferTips') 29 .offset([-10, 0]); 30 31 32 function formatAmount(val) { 33 //return val.toLocaleString("en-US", {style: 'currency', currency: "USD"}).replace(/\.[0-9]+/, ""); 34 return parseFloat(val).toFixed(0) + " votes"; 35 }; 36 37 // "â¡" 38 tipLinks.html(function(d) { 39 var title, candidate; 40 if (energy.links.indexOf(d.source.name) > -1) { 41 candidate = d.source.name; 42 title = d.target.name; 43 } else { 44 candidate = d.target.name; 45 title = d.source.name; 46 } 47 var html = '<div class="table-wrapper">'+ 48 '<h1>'+title+'</h1>'+ 49 '<table>'+ 50 '<tr>'+ 51 '<td class="col-left">'+candidate+'</td>'+ 52 '<td align="right">'+formatAmount(d.value)+'</td>'+ 53 '</tr>'+ 54 '</table>'+ 55 '</div>'; 56 return html; 57 }); 58 59 tipNodes.html(function(d) { 60 var object = d3.entries(d), 61 nodeName = object[1].value, 62 linksTo = object[3].value, 63 linksFrom = object[4].value, 64 html; 65 66 html = '<div class="table-wrapper">'+ 67 '<h1>'+nodeName+'</h1>'+ 68 '<table>'; 69 if (linksFrom.length > 0 & linksTo.length > 0) { 70 html+= '<tr><td><h2>Input:</h2></td><td></td></tr>' 71 } 72 for (i = 0; i < linksFrom.length; ++i) { 73 html += '<tr>'+ 74 '<td class="col-left">'+linksFrom[i].source.name+'</td>'+ 75 '<td align="right">'+formatAmount(linksFrom[i].value)+'</td>'+ 76 '</tr>'; 77 } 78 if (linksFrom.length > 0 & linksTo.length > 0) { 79 html+= '<tr><td><h2>Output:</h2></td><td></td></tr>' 80 } 81 for (i = 0; i < linksTo.length; ++i) { 82 html += '<tr>'+ 83 '<td class="col-left">'+linksTo[i].target.name+'</td>'+ 84 '<td align="right">'+formatAmount(linksTo[i].value)+'</td>'+ 85 '</tr>'; 86 } 87 html += '</table></div>'; 88 return html; 89 }); 90 91 // function zoomed() { 92 // svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); 93 // } 94 95 function dragstarted(d) { 96 d3.select(this).classed("dragging", true); 97 } 98 99 function dragged(d) { 100 d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y); 101 } 102 103 function dragended(d) { 104 d3.select(this).classed("dragging", false); 105 } 106 107 drag = d3.drag() 108 .subject(function(d) { return d; }) 109 .on("drag", dragged) 110 .on("start", dragstarted) 111 .on("end", dragended); 112 113 // zoom = d3.behavior.zoom() 114 // .scaleExtent([0, 5]) 115 // .center([width / 2, height / 2]) 116 // .on("zoom", zoomed); 117 118 var formatNumber = d3.format(",.0f"), 119 format = function(d) { return formatNumber(d) + " votes transfered"; }, 120 color = "#000000" 121 122 svg = d3.select("#sankey").append("svg") 123 .attr("id", "snakeysvg") 124 .attr("width", width + 40) 125 .attr("height", height + 40) 126 .call(tipLinks) 127 .call(tipNodes) 128 .append("g") 129 .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 130 131 var sankey = d3.sankey() 132 .nodeWidth(40) 133 .nodePadding(15) 134 .size([width, height]); 135 136 var path = sankey.link(); 137 sankey 138 .nodes(energy.nodes) 139 .links(energy.links) 140 .layout(32); 141 142 var fontScale = d3.scaleLinear().domain(d3.extent(energy.nodes, function(d) { return d.value })).range([18, 30]); 143 144 var link = svg.append("g").selectAll(".link") 145 .data(energy.links) 146 .enter().append("path") 147 .attr("class", "link") 148 .attr("d", path) 149 .style("stroke", function(d){ return d.source.color; }) 150 .style("stroke-width", function(d) { return Math.max(1, d.dy); }) 151 .sort(function(a, b) { return b.dy - a.dy; }) 152 .on('mousemove', function(event) { 153 tipLinks 154 .style("top", (d3.event.pageY - linkTooltipOffset) + "px") 155 .style("left", function () { 156 var left = (Math.max(d3.event.pageX - linkTooltipOffset, 10)); 157 left = Math.min(left, window.innerWidth - $('.d3-tip').width() - 20) 158 return left + "px"; }) 159 }) 160 .on('mouseover', tipLinks.show) 161 .on('mouseout', tipLinks.hide); 162 163 var node = svg.append("g").selectAll(".node") 164 .data(energy.nodes) 165 .enter().append("g") 166 .attr("class", "node") 167 .attr("transform", function(d) { 168 return "translate(" + d.x + "," + d.y + ")"; 169 }) 170 .on('mousemove', function(event) { 171 tipNodes 172 .style("top", (d3.event.pageY - $('.d3-tip-nodes').height() - 20) + "px") 173 .style("left", function () { 174 var left = d3.event.pageX - 150; 175 // left = Math.max(left, window.innerWidth - $('.d3-tip').width() - 20) 176 return left + "px"; }) 177 }) 178 .on('mouseover', tipNodes.show) 179 .on('mouseout', tipNodes.hide) 180 .call(d3.drag() 181 .subject(function(d) { return d; }) 182 .on("start", function() { 183 d3.event.sourceEvent.stopPropagation();
183 //Disable drag sankey on node select 184 this.parentNode.appendChild(this); }) 185 .on("drag", dragmove)); 186 187 node.append("rect") 188 .attr("height", function(d) { return d.dy; }) 189 .attr("width", sankey.nodeWidth()) 190 .style("fill", function(d) { 191 if (d.color == undefined) 192 return d.color = color(d.name.replace(/ .*/, "")); //get new color if node.color is null 193 return d.color; 194 }) 195 .style("stroke", function(d) { return d3.rgb(d.color).darker(2); }); 196 197 node.append("text") 198 .attr("class","nodeValue") 199 .text(function(d) { return d.name + "\n" + format(d.value); }); 200 201 node.selectAll("text.nodeValue") 202 .attr("x", sankey.nodeWidth() / 2) 203 .attr("y", function (d) { return (d.dy / 2) }) 204 .text(function (d) { return formatNumber(d.value); }) 205 .attr("dy", 5) 206 .attr("text-anchor", "middle"); 207 208 node.append("text") 209 .attr("class","nodeLabel") 210 .style("fill", function(d) { 211 return d3.rgb(d.color).darker(2.4); 212 }) 213 .style("font-size", function(d) { 214 return fontScale(d.value) + "px"; 215 }); 216 217 node.selectAll("text.nodeLabel") 218 .attr("x", -6) 219 .attr("y", function(d) { return d.dy / 2; }) 220 .attr("dy", ".35em") 221 .attr("text-anchor", "end") 222 .attr("transform", null) 223 .text(function(d) { return d.name; }) 224 .filter(function(d) { return d.x < width / 2; }) 225 .attr("x", 6 + sankey.nodeWidth()) 226 .attr("text-anchor", "start"); 227 function dragmove(d) { 228 d3.select(this) 229 .attr("transform", "translate(" + d.x + "," + 230 (d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))) + ")"); 231 sankey.relayout(); 232 link.attr("d", path); 233 }; 234 235 // fitZoom(); 236 } 237 238 function getData() { 239 return { 240 "nodes": [{ 241 "node": 0, 242 "name": "Yellow Party", 243 color: "#faa71a" 244 }, { 245 "node": 1, 246 "name": "Red Party", 247 color:"#ed2224" 248 }, { 249 "node": 2, 250 "name": "Coral Party", 251 color: "#ff7f50" 252 }, { 253 "node": 3, 254 "name": "Blue Party", 255 color: "#4a82b5" 256 }, { 257 "node": 4, 258 "name": "Pink Party", 259 color: "#bd4289" 260 }, { 261 "node": 5, 262 "name": "Yellow Party", 263 color: "#faa71a" 264 }, { 265 "node": 6, 266 "name": "Red Party", 267 color: "#ed2224" 268 }, { 269 "node": 7, 270 "name": "Coral Party", 271 color: "#ff7f50" 272 },{ 273 "node": 8, 274 "name": "Blue Party", 275 color: "#4a82b5" 276 },{ 277 "node": 9, 278 "name": "Pink Party", 279 color: "#bd4289" 280 } 281 282 ], 283 284 285 286 287 "links":[ 288{"source":2,"target":5,"value":22}, 289{"source":1,"target":5,"value":114}, 290{"source":0,"target":9,"value":146}, 291{"source":3,"target":7,"value":201}, 292{"source":1,"target":7,"value":147}, 293{"source":1,"target":9,"value":122}, 294{"source":1,"target":8,"value":129}, 295{"source":2,"target":8,"value":140}, 296{"source":3,"target":9,"value":25}, 297{"source":3,"target":6,"value":30}, 298{"source":2,"target":9,"value":25}, 299{"source":0,"target":8,"value":25}, 300{"source":0,"target":6,"value":25}, 301{"source":3,"target":5,"value":26}, 302{"source":4,"target":7,"value":21}, 303{"source":4,"target":5,"value":135}, 304{"source":4,"target":6,"value":19}, 305{"source":4,"target":8,"value":21}, 306{"source":2,"target":6,"value":22}, 307{"source":0,"target":7,"value":22}] 308 309 310 311 312 313 314 315 316 }; 317 }; 318 319 320
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.