@cryptotaxi247 / kubo / commits / b9f828e1e

diagnostics: added chord viewer

Juan Batiz-Benet committed Jan 14, 2015 at 09:18 UTC b9f828e1e3e04ca9f4bb8f38a6be1e66d40b43d9
1 file changed +166
diagnostics/d3/chord.html new
+166
@@ -0,0 +1,166 @@
1 +<!DOCTYPE html>
2 +<meta charset="utf-8">
3 +<style>
4 +
5 +.node {
6 + font: 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
7 +}
8 +
9 +.link {
10 + stroke: steelblue;
11 + stroke-opacity: .4;
12 + fill: none;
13 +}
14 +
15 +</style>
16 +<body>
17 +<script src="http://d3js.org/d3.v3.min.js"></script>
18 +<script>
19 +var hash = window.location.hash.substring(1)
20 +
21 +var diameter = 1400,
22 + radius = diameter / 2,
23 + innerRadius = radius - 200
24 + rotate = 145;
25 +
26 +var color = d3.scale.category10()
27 +
28 +var diagonal = d3.svg.diagonal.radial()
29 + .projection(function(d) { return [d.y, d.x / 180 * Math.PI]; });
30 +
31 +var svg = d3.select("body").append("svg")
32 + .attr("width", "100%")
33 + .attr("height", "100%")
34 + .attr("viewBox", "0 0 " + diameter + " " + diameter )
35 + .attr("preserveAspectRatio", "xMidYMid meet")
36 + .append("g")
37 + .attr("transform", "translate(" + radius + "," + radius + ")");
38 +
39 +d3.json(hash, function(error, data) {
40 +
41 + graph = parseGraph(data)
42 +
43 + var node = svg.selectAll(".node")
44 + .data(graph.nodes)
45 + .enter().append("g")
46 + .attr("class", "node")
47 + .attr("transform", function(d) { return "rotate(" + (d.x - 90 + rotate) + ")translate(" + d.y + ")"; })
48 +
49 + node.append("svg:circle")
50 + .attr("r", function(d) { return 4; })
51 + .style("fill", function(d, i) { return color(i % 3); })
52 +
53 + node.append("text")
54 + .attr("dx", function(d) { return 8; })
55 + .attr("dy", ".31em")
56 + // .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
57 + // .attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; })
58 + .text(function(d) { return truncate(d.name, 16); });
59 +
60 + var p = projection
61 + var link = svg.selectAll(".link")
62 + .data(graph.paths)
63 + .enter().append("path")
64 + .attr("class", "link")
65 + .attr("d", function(d) {
66 + return "M" + p(d[0])[0] + "," + p(d[0])[1]
67 + + "S" + p(d[1])[0] + "," + p(d[1])[1]
68 + + " " + p(d[2])[0] + "," + p(d[2])[1];
69 + })
70 +
71 + // var mid = svg.selectAll(".node-mid")
72 + // .data(graph.mids)
73 + // .enter().append("g")
74 + // .attr("class", "node-mid")
75 + // .attr("transform", function(d) { return "rotate(" + (d.x + rotate) + ")translate(" + d.y + ")"; })
76 +
77 + // mid.append("svg:circle")
78 + // .attr("r", function(d) { return 4; })
79 + // .style("fill", function(d, i) { return color(i % 3); })
80 +
81 + console.log(graph.paths)
82 +});
83 +
84 +
85 +function parseGraph(graph2) {
86 + graph = {}
87 + graph.nodes = []
88 + graph.links = []
89 + graph.paths = []
90 + graph.byName = {}
91 + graph.mids = []
92 +
93 + graph2.nodes.sort(function(a, b) {
94 + if (a.name > b.name) return 1;
95 + if (a.name < b.name) return -1;
96 + return 0;
97 + })
98 +
99 + graph2.nodes.forEach(function(data, i) {
100 + data.y = innerRadius
101 + data.x = ((360 / graph2.nodes.length) * i)
102 + graph.nodes.push(data)
103 + graph.byName[data.name] = data
104 + })
105 +
106 + graph2.links.forEach(function(link) {
107 + var source = graph2.nodes[link.source]
108 + var target = graph2.nodes[link.target]
109 +
110 + var mid = curveNode(source, target)
111 + graph.mids.push(mid)
112 +
113 + var link1 = {source: source, target: mid, value: link.value || 3}
114 + var link2 = {source: mid, target: target, value: link.value || 3}
115 + graph.links.push(link1)
116 + graph.links.push(link2)
117 +
118 + var path = [source, mid, target]
119 + graph.paths.push(path)
120 + })
121 +
122 + return graph
123 +}
124 +
125 +function curveNode(source, target) {
126 + var d = circleDistance(source.x, target.x)
127 + var h = ((1-(d/180)) * innerRadius) * 0.7
128 + var x = circleMidpoint(source.x, target.x)
129 + return {x: x, y: h}
130 +}
131 +
132 +function circleMidpoint(x, y) {
133 + var x2 = x > y ? x : y
134 + var y2 = x > y ? y : x
135 + var a = (x2-y2)
136 + if (a > 180) {
137 + a = 360 - a
138 + return (x2 + a/2) % 360
139 + } else {
140 + return (y2 + a/2) % 360
141 + }
142 +}
143 +
144 +function circleDistance(x, y) {
145 + var a = abs(x-y)
146 + return (a > 180) ? 360 - a : a
147 +}
148 +
149 +function abs(x) {
150 + return x < 0 ? -x : x
151 +}
152 +
153 +function projection(d) {
154 + var r = d.y, a = (d.x - 90 + rotate) / 180 * Math.PI;
155 + return [r * Math.cos(a), r * Math.sin(a)];
156 +}
157 +
158 +function truncate(name, limit) {
159 + return name.substring(0, limit)
160 +}
161 +
162 +
163 +d3.select(self.frameElement).style("height", "100%");
164 +d3.select(self.frameElement).style("width", "100%");
165 +
166 +</script>