index.htmlView |
---|
5 | 5 … | <title>ssb-activity</title> |
6 | 6 … | <script src=common.js></script> |
7 | 7 … | </head> |
8 | 8 … | <body> |
| 9 … | + |
9 | 10 … | <div style="text-align:center"> |
10 | 11 … | <h2>Daily active users</h2> |
11 | 12 … | <img id=graph src=day.png alt="Graph of daily active feeds"> |
12 | 13 … | </div> |
13 | 14 … | |
| 15 … | +<div id="user-info" style="visibility:hidden"> |
| 16 … | + <div>User: <a id="user-link"><code id="user-id"> </code></a></div> |
| 17 … | +</div> |
| 18 … | + |
14 | 19 … | <script> |
15 | | - |
| 20 … | +var feedBase = 'https://viewer.scuttlebot.io/' |
| 21 … | +var ids, idColors, idsByColor = {} |
16 | 22 … | var img = document.getElementById('graph') |
17 | 23 … | var imgData, origImgData |
18 | 24 … | var width, height |
| 25 … | +var userInfo = document.getElementById('user-info') |
| 26 … | +var userLink = document.getElementById('user-link') |
| 27 … | +var userIdText = document.getElementById('user-id').firstChild |
19 | 28 … | |
20 | 29 … | var colors = { |
21 | 30 … | yellow: [255, 255, 0, 255], |
22 | 31 … | red: [255, 0, 0, 255], |
25 | 34 … | bg: [255, 255, 255, 0], |
26 | 35 … | highlight: [0, 0, 0, 255] |
27 | 36 … | } |
28 | 37 … | |
| 38 … | +function getJSON(url, cb) { |
| 39 … | + var req = new XMLHttpRequest() |
| 40 … | + req.open('GET', url, true) |
| 41 … | + req.onload = function () { |
| 42 … | + if (req.readyState !== 4) return |
| 43 … | + if (req.status >= 200 && req.status < 400) |
| 44 … | + cb(null, JSON.parse(req.responseText)) |
| 45 … | + else |
| 46 … | + return cb(req) |
| 47 … | + } |
| 48 … | + req.onerror = cb |
| 49 … | + req.send(null) |
| 50 … | +} |
| 51 … | + |
| 52 … | +function printError(err) { |
| 53 … | + var pre = document.createElement('pre') |
| 54 … | + document.body.appendChild(pre) |
| 55 … | + pre.appendChild(document.createTextNode(err.stack)) |
| 56 … | +} |
| 57 … | + |
| 58 … | +getJSON('ids.json', function (err, _ids) { |
| 59 … | + if (err) return printError(err) |
| 60 … | + ids = _ids |
| 61 … | + idColors = common.computeIdColors(ids) |
| 62 … | + for (var i = 0; i < ids.length; i++) { |
| 63 … | + var id = ids[i] |
| 64 … | + var color = idColors[id] |
| 65 … | + idsByColor[color] = id |
| 66 … | + } |
| 67 … | +}) |
| 68 … | + |
29 | 69 … | var canvas = document.createElement('canvas') |
30 | 70 … | var ctx |
31 | 71 … | function onImageLoad() { |
32 | 72 … | width = canvas.width = img.width |
50 | 90 … | } |
51 | 91 … | |
52 | 92 … | function colorEquals(a, b) { |
53 | 93 … | return a && b |
54 | | - && a[0] === b[0] |
55 | | - && a[1] === b[1] |
56 | | - && a[2] === b[2] |
| 94 … | + && a[3] === b[3] |
| 95 … | + && (a[3] === 0 || ( |
| 96 … | + a[0] === b[0] |
| 97 … | + && a[1] === b[1] |
| 98 … | + && a[2] === b[2] |
| 99 … | + )) |
57 | 100 … | } |
58 | 101 … | |
59 | 102 … | function getPixel(x, y) { |
60 | 103 … | var i = (y * width + x) << 2 |
75 | 118 … | data[i+2] = color[2] |
76 | 119 … | data[i+3] = 255 |
77 | 120 … | } |
78 | 121 … | |
79 | | -var prevColor |
80 | | - |
81 | 122 … | function replaceColor(oldColor, newColor) { |
82 | 123 … | for (var x = 0; x < width; x++) { |
83 | 124 … | for (var y = height-1; y > 0; y--) { |
84 | 125 … | var c = getPixel(x, y) |
90 | 131 … | } |
91 | 132 … | } |
92 | 133 … | } |
93 | 134 … | |
|
94 | | -canvas.addEventListener('mousemove', function (e) { |
95 | | - var point = getPoint(e) |
96 | | - var color = getPixel(point[0], point[1]) |
97 | | - if (colorEquals(color, colors.black) |
98 | | - || colorEquals(color, colors.bg) |
99 | | - || colorEquals(color, prevColor)) return |
100 | | - if (prevColor) replaceColor(prevColor, prevColor) |
| 135 … | +function pointEquals(a, b) { |
| 136 … | + return a ? b && a[0] === b[0] && a[1] === b[1] : !b |
| 137 … | +} |
| 138 … | + |
| 139 … | +var hoverColor, hoverPoint |
| 140 … | +var clickedColor, clickedPoint |
| 141 … | + |
| 142 … | +function highlight(color, point) { |
| 143 … | + if (colorEquals(color, hoverColor)) return |
| 144 … | + if (!color) { |
| 145 … | + if (hoverColor) replaceColor(hoverColor, hoverColor) |
| 146 … | + ctx.putImageData(imgData, 0, 0) |
| 147 … | + hoverColor = null |
| 148 … | + userInfo.style.visibility = 'hidden' |
| 149 … | + return |
| 150 … | + } |
| 151 … | + if (colorEquals(color, colors.black)) return |
| 152 … | + if (colorEquals(color, colors.bg)) return |
| 153 … | + if (hoverColor) replaceColor(hoverColor, hoverColor) |
101 | 154 … | replaceColor(color, colors.highlight) |
102 | | - prevColor = color |
| 155 … | + hoverColor = color |
103 | 156 … | ctx.putImageData(imgData, 0, 0) |
| 157 … | + var id = idsByColor[color] |
| 158 … | + if (!id) { |
| 159 … | + userInfo.style.visibility = 'hidden' |
| 160 … | + return |
| 161 … | + } |
| 162 … | + userIdText.nodeValue = id |
| 163 … | + userLink.href = feedBase + encodeURIComponent(id) |
| 164 … | + userInfo.style.visibility = 'visible' |
| 165 … | +} |
| 166 … | + |
| 167 … | +function clearHoverPoint() { |
| 168 … | + highlight(clickedColor, clickedPoint) |
| 169 … | +} |
| 170 … | + |
| 171 … | +function setHoverPoint(point) { |
| 172 … | + if (pointEquals(point, hoverPoint)) return |
| 173 … | + hoverPoint = point |
| 174 … | + var color = getPixel(point[0], point[1]) |
| 175 … | + highlight(color, point) |
| 176 … | +} |
| 177 … | + |
| 178 … | +function setClickedPoint(point) { |
| 179 … | + if (pointEquals(point, clickedPoint)) return |
| 180 … | + var color |
| 181 … | + if (point) { |
| 182 … | + color = getPixel(point[0], point[1]) |
| 183 … | + if (colorEquals(color, colors.bg)) { |
| 184 … | + color = null |
| 185 … | + point = null |
| 186 … | + } |
| 187 … | + } |
| 188 … | + clickedPoint = point |
| 189 … | + clickedColor = color |
| 190 … | + highlight(color, point) |
| 191 … | +} |
| 192 … | + |
| 193 … | +canvas.addEventListener('mousemove', function (e) { |
| 194 … | + setHoverPoint(getPoint(e)) |
104 | 195 … | }, false) |
105 | 196 … | |
| 197 … | + |
| 198 … | +canvas.addEventListener('mousedown', function (e) { |
| 199 … | + setClickedPoint(getPoint(e)) |
| 200 … | +}, false) |
| 201 … | + |
106 | 202 … | canvas.addEventListener('mouseout', function (e) { |
107 | | - if (prevColor) replaceColor(prevColor, prevColor) |
108 | | - ctx.putImageData(imgData, 0, 0) |
109 | | - prevColor = null |
| 203 … | + clearHoverPoint() |
110 | 204 … | }, false) |
111 | 205 … | |
112 | 206 … | </script> |
113 | 207 … | </body> |