|
1 PATH_MODE = false; |
|
2 |
1 $(function() { |
3 $(function() { |
2 |
4 |
3 var colorset = ["#1f77b4 ", "#aec7e8 ", "#ff7f0e ", "#ffbb78 ", "#2ca02c ", "#98df8a ", "#d62728 ", "#ff9896 ", "#9467bd ", "#c5b0d5 ", "#8c564b ", "#c49c94 ", "#e377c2 ", "#f7b6d2 ", "#7f7f7f ", "#c7c7c7 ", "#bcbd22 ", "#dbdb8d ", "#17becf ", "#9edae5"] |
5 var colorset_pastel = ["#FBB4AE", "#B3CDE3", "#CCEBC5", "#DECBE4", "#FED9A6", "#E5D8BD", "#FDDAEC"]; |
|
6 var colorset_vivid = ["#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00", "#A65628", "#F781BF"]; |
|
7 |
|
8 $(".topics-block").draggable({axis:"y"}) |
4 |
9 |
5 $.getJSON("fakedata/data.json", function(data) { |
10 $.getJSON("fakedata/data.json", function(data) { |
6 $(".topwords-block").html(data.top_words.reduce(function(mem, d) { |
11 |
7 return mem + '<li>' + d.word + '</li>' |
12 function secsToString(seconds) { |
8 },"")); |
13 var hours = Math.floor(seconds/3600), |
|
14 minutes = Math.floor(seconds/60) % 60, |
|
15 secs = Math.floor(seconds % 60); |
|
16 function pad(n) { |
|
17 var r = n.toString(); |
|
18 while (r.length < 2) { |
|
19 r = "0" + r; |
|
20 } |
|
21 return r; |
|
22 } |
|
23 return (hours ? (hours + ":") : "") + pad(minutes) + ":" + pad(secs); |
|
24 } |
|
25 |
|
26 $(".duration").text(secsToString(data.duration)); |
|
27 |
|
28 $(".topwords-block").on("click", "li", function() { |
|
29 var el = $(this).toggleClass("selected"); |
|
30 wordFilter(); |
|
31 }); |
9 |
32 |
10 var nmmso = data.segments.length; |
33 var nmmso = data.segments.length; |
11 |
34 |
12 data.topics.forEach(function(topic) { |
35 data.topics.forEach(function(topic) { |
13 topic.score = 0; |
36 topic.score = 0; |
14 topic.curve = []; |
37 topic.weights = []; |
|
38 topic.scores = []; |
15 for (var i = 0; i < nmmso; i++) { |
39 for (var i = 0; i < nmmso; i++) { |
16 topic.curve.push(0); |
40 topic.weights.push(0); |
|
41 topic.scores.push(0); |
17 } |
42 } |
18 }); |
43 }); |
19 |
44 |
20 data.segments.forEach(function(mmso, i) { |
45 data.segments.forEach(function(mmso, i) { |
21 mmso.topics.forEach(function(t) { |
46 mmso.topics.forEach(function(t) { |
22 var score = t.weight * mmso.tweet_count; |
47 var score = t.weight * mmso.tweet_count; |
23 data.topics[t.topic].curve[i] = score; |
48 data.topics[t.topic].weights[i] = t.weight; |
|
49 data.topics[t.topic].scores[i] = score; |
24 data.topics[t.topic].score += score; |
50 data.topics[t.topic].score += score; |
25 }); |
51 }); |
26 }); |
52 mmso.tweet_rate = mmso.tweet_count / mmso.duration; |
27 |
53 }); |
28 data.topics = data.topics.sort(function(a,b) { |
54 |
|
55 var sortedTopics = data.topics.slice().sort(function(a,b) { |
29 return b.score - a.score; |
56 return b.score - a.score; |
30 }); |
57 }); |
31 |
58 |
32 var topicHtmls = ["", "", ""] |
59 var selectedWords = []; |
33 |
60 |
34 data.topics.forEach(function(topic,i) { |
61 function wordFilter() { |
35 var li = '<li class="shadow-block topic" style="background:' |
62 var selectedLis = $(".topwords-block li.selected"); |
36 + colorset[topic.index % colorset.length] |
63 selectedWords = []; |
37 + '" data-topic-id="' |
64 selectedLis.each(function() { |
38 + topic.index |
65 selectedWords.push($(this).text().trim()); |
39 + '"><ul class="topic-words">' |
66 }); |
40 + topic.words.reduce(function(memwords, word) { |
67 console.log(selectedWords); |
41 return memwords + '<li>' + word.word + '</li>'; |
68 if (selectedWords.length) { |
42 },"") |
69 showTopics(data.topics.filter(function(topic) { |
43 + '</ul></li>'; |
70 var foundWords = selectedWords.map(function() { return false }); |
44 topicHtmls[i % 3] += li; |
71 topic.words.forEach(function(topicword) { |
45 }); |
72 selectedWords.forEach(function(selectedword, k) { |
46 console.log(topicHtmls); |
73 if (!foundWords[k] && selectedword === topicword.word) { |
47 $(".topics-block").html(topicHtmls.reduce(function(mem,html) { |
74 foundWords[k] = true; |
48 return mem + '<ul class="topic-column">' + html + '</ul>' |
75 } |
49 },"")); |
76 }) |
50 |
77 }); |
51 $(".topic").mouseenter(function() { |
78 return foundWords.reduce(function(mem, w) { return mem && w}, true); |
52 var datavizheight = $(".start-dataviz").height(), |
79 }).sort(function(a,b) { |
53 scale = datavizheight / data.duration, |
80 return b.score - a.score; |
54 topicid = parseInt($(this).attr("data-topic-id")), |
81 })); |
55 topic; |
82 } else { |
56 for (var i = 0; i < data.topics.length; i++) { |
83 showTopics(sortedTopics); |
57 if (data.topics[i].index == topicid) { |
84 } |
58 topic = data.topics[i]; |
85 } |
59 break; |
86 |
|
87 function showTopics(topiclist) { |
|
88 var topicHtmls = ["", "", ""], |
|
89 globwords = {}, |
|
90 topwords = []; |
|
91 topiclist.forEach(function(topic,i) { |
|
92 var wordsToShow = topic.words.slice(0,5), |
|
93 max = wordsToShow[0].weight, |
|
94 min = Math.min(wordsToShow[wordsToShow.length - 1].weight, max - .01), |
|
95 scale = 10 / (max - min); |
|
96 var li = '<li class="shadow-block topic" data-topic-id="' |
|
97 + topic.index |
|
98 + '" data-viz-color="' |
|
99 + Raphael.hsl(topic.index / data.topics.length, .8, .5) //colorset_vivid[topic.index % colorset_vivid.length] //colorset_vivid[i % colorset_vivid.length] |
|
100 + '"" data-li-color="' |
|
101 + Raphael.hsl(topic.index / data.topics.length, .7, .8) //colorset_pastel[topic.index % colorset_pastel.length] //colorset_pastel[i % colorset_pastel.length] |
|
102 + '"><ul class="topic-words">' |
|
103 + wordsToShow.reduce(function(memwords, word) { |
|
104 return memwords |
|
105 + '<li style="font-size: ' |
|
106 + ( 10 + scale * (word.weight - min) ) |
|
107 + 'px;">' |
|
108 + word.word |
|
109 + '</li>'; |
|
110 },"") |
|
111 + '</ul></li>'; |
|
112 topicHtmls[i % 3] += li; |
|
113 topic.words.forEach(function(word) { |
|
114 globwords[word.word] = word.weight + (globwords[word.word] || 0) |
|
115 }); |
|
116 }); |
|
117 var tb = $(".topics-block"); |
|
118 tb.html(topicHtmls.reduce(function(mem,html) { |
|
119 return mem + '<ul class="topic-column">' + html + '</ul>' |
|
120 },"")); |
|
121 tb.css("top",0); |
|
122 |
|
123 for (var w in globwords) { |
|
124 topwords.push({ |
|
125 word : w, |
|
126 weight : globwords[w] |
|
127 }); |
|
128 } |
|
129 topwords.sort(function(a, b) { |
|
130 return b.weight - a.weight; |
|
131 }); |
|
132 |
|
133 var wordsToShow = topwords.slice(0,30), |
|
134 max = wordsToShow[0].weight, |
|
135 min = Math.min(wordsToShow[wordsToShow.length - 1].weight, max - .01), |
|
136 scale = 10 / (max - min); |
|
137 |
|
138 $(".topwords-block").html(wordsToShow.reduce(function(mem, d) { |
|
139 return mem |
|
140 + '<li style="font-size: ' |
|
141 + ( 10 + scale * (d.weight - min) ) |
|
142 + 'px;"' |
|
143 + (selectedWords.indexOf(d.word) !== -1 ? ' class="selected"' : '') |
|
144 + '>' |
|
145 + d.word |
|
146 + '</li>' |
|
147 },"")); |
|
148 |
|
149 showTopicViz(); |
|
150 } |
|
151 |
|
152 function showTopicViz() { |
|
153 var selectedBlocks = $(".topic.selected, .topic.hover"), |
|
154 sbl = selectedBlocks.length; |
|
155 if (!sbl) { |
|
156 selectedBlocks = $(".topic"); |
|
157 sbl = selectedBlocks.length; |
|
158 } |
|
159 if (sbl) { |
|
160 $(".topic").css("background",""); |
|
161 selectedBlocks.each(function() { |
|
162 var el = $(this); |
|
163 el.css("background",el.attr("data-li-color")); |
|
164 }); |
|
165 } else { |
|
166 $(".topic").each(function() { |
|
167 var el = $(this); |
|
168 el.css("background",el.attr("data-li-color")); |
|
169 }); |
|
170 } |
|
171 var topicsAndColors = selectedBlocks.map(function() { |
|
172 var el = $(this), |
|
173 topicid = parseInt(el.attr("data-topic-id")), |
|
174 vizcolor = el.attr("data-viz-color"); |
|
175 return { |
|
176 topic: data.topics[topicid], |
|
177 id: topicid, |
|
178 color: vizcolor |
|
179 }; |
|
180 }); |
|
181 if (PATH_MODE) { |
|
182 topicpaths.forEach(function(p) { |
|
183 p.hide(); |
|
184 }); |
|
185 topicsAndColors.each(function(j, t) { |
|
186 var p = topicpaths[t.id]; |
|
187 p.attr({ |
|
188 stroke: t.color, |
|
189 fill: t.color, |
|
190 "fill-opacity": .25 |
|
191 }); |
|
192 p.show(); |
|
193 }); |
|
194 if (sbl > 1 && sbl < data.topics.length) { |
|
195 var d = "M0,0L" + data.segments.map(function(mmso, i) { |
|
196 var tweets = 0; |
|
197 for (var j = 0; j < sbl; j++) { |
|
198 tweets += topicsAndColors[j].topic.scores[i] |
|
199 } |
|
200 x = xscale * tweets / mmso.duration; |
|
201 return x |
|
202 + "," |
|
203 + yscale * (mmso.start + mmso.duration / 3) |
|
204 + "L" |
|
205 + x |
|
206 + "," |
|
207 + yscale * (mmso.start + 2 * mmso.duration / 3); |
|
208 }).join("L") + "L0,"+(yscale * data.duration); |
|
209 sumpath.attr({ |
|
210 path: d |
|
211 }); |
|
212 sumpath.show(); |
|
213 } else { |
|
214 sumpath.hide(); |
60 } |
215 } |
61 } |
216 } else { |
62 if (!topic) { |
217 for (var i = 0; i < nmmso; i++) { |
63 return; |
218 var opacity = 0, |
64 } |
219 rgb = [0,0,0]; |
65 var color = colorset[topicid % colorset.length]; |
220 for (var j = 0; j < sbl; j++) { |
66 $(".start-dataviz").html(topic.curve.reduce(function(mem, c, i) { |
221 var c = Raphael.getRGB(topicsAndColors[j].color), |
67 if (!c) { |
222 o = topicsAndColors[j].topic.weights[i]; |
68 return mem; |
223 rgb[0] += c.r * o; |
69 } else { |
224 rgb[1] += c.g * o; |
70 var mmso = data.segments[i]; |
225 rgb[2] += c.b * o; |
71 return mem + '<div style="position: absolute; background: ' |
226 opacity += o; |
72 + color |
227 } |
73 +'; opacity: ' |
228 if (opacity) { |
74 + c |
229 color = Raphael.rgb.apply(Raphael, rgb.map(function(c) { |
75 +'; left: 0; ; top: ' |
230 return c/opacity; |
76 + scale * mmso.start |
231 })); |
77 +'px; height: ' |
232 segmentrects[i].show(); |
78 + scale * mmso.duration |
233 segmentrects[i].attr({ |
79 +'px; width: 266px"></div>' |
234 fill: color, |
|
235 opacity: .2 + .8 * opacity |
|
236 }); |
|
237 } else { |
|
238 segmentrects[i].hide(); |
|
239 } |
80 } |
240 } |
81 },"")); |
241 } |
82 })//.mouseleave(function() {$(".start-dataviz").empty(); }); |
242 |
|
243 } |
|
244 |
|
245 var jqsvg = $(".start-svg"); |
|
246 paper = new Raphael(jqsvg[0]), |
|
247 ph = jqsvg.height(), |
|
248 pw = jqsvg.width(), |
|
249 yscale = ph / data.duration, |
|
250 mx = Math.max.apply(Math, data.segments.map(function(s) { return s.tweet_rate})), |
|
251 xscale = (pw - 10)/mx; |
|
252 |
|
253 if (PATH_MODE) { |
|
254 var sumpath = paper.path(); |
|
255 sumpath.attr({ |
|
256 fill: "#f0f0f0", |
|
257 stroke: "#666666", |
|
258 "stroke-width": 2 |
|
259 }); |
|
260 var topicpaths = data.topics.map(function(topic) { |
|
261 var d = "M0,0L" + topic.scores.map(function(s, i) { |
|
262 var mmso = data.segments[i], |
|
263 x = xscale * s / mmso.duration; |
|
264 return x |
|
265 + "," |
|
266 + yscale * (mmso.start + mmso.duration / 3) |
|
267 + "L" |
|
268 + x |
|
269 + "," |
|
270 + yscale * (mmso.start + 2 * mmso.duration / 3); |
|
271 }).join("L") + "L0,"+(yscale * data.duration); |
|
272 return paper.path(d); |
|
273 }); |
|
274 } else { |
|
275 var segmentrects = data.segments.map(function(mmso) { |
|
276 var rect = paper.rect(0, yscale * mmso.start, pw - 50, yscale * mmso.duration); |
|
277 rect.attr({stroke: "none"}); |
|
278 return rect; |
|
279 }); |
|
280 } |
|
281 |
|
282 var d = "M" + data.segments.map(function(s) { |
|
283 var x = xscale * s.tweet_rate; |
|
284 return x |
|
285 + "," |
|
286 + yscale * (s.start + s.duration / 3) |
|
287 + "L" |
|
288 + x |
|
289 + "," |
|
290 + yscale * (s.start + 2 * s.duration / 3); |
|
291 }).join("L"); |
|
292 |
|
293 paper.path(d); |
|
294 |
|
295 |
|
296 for (var i=0; i < data.duration; i += 1800) { |
|
297 var y = yscale * i; |
|
298 paper.path("M0," + y + "L" + pw + "," + y).attr({ |
|
299 stroke: "#666" |
|
300 }); |
|
301 paper.text(pw - 2, y + 6, secsToString(i)).attr({ |
|
302 "text-anchor": "end" |
|
303 }); |
|
304 } |
|
305 paper.text(pw-2, ph-6, secsToString(data.duration)).attr({ |
|
306 "text-anchor": "end" |
|
307 }); |
|
308 |
|
309 wordFilter(); |
|
310 |
|
311 $(".topics-block").on("mouseenter", ".topic", function() { |
|
312 var topicid = parseInt($(this).attr("data-topic-id")), |
|
313 color = $(this).attr("data-viz-color"), |
|
314 topic = data.topics[topicid]; |
|
315 $(this).addClass("hover"); |
|
316 showTopicViz(); |
|
317 }).on("mouseleave", ".topic", function() { |
|
318 $(this).removeClass("hover"); |
|
319 showTopicViz(); |
|
320 }).on("click", ".topic", function() { |
|
321 $(this).toggleClass("selected"); |
|
322 showTopicViz(); |
|
323 }); |
|
324 |
83 |
325 |
84 }); |
326 }); |
85 }); |
327 }); |