js/startscreen-fake.js
changeset 2 0d947d167ec5
parent 1 1f574d93e195
child 3 7fa607ed7e82
--- a/js/startscreen-fake.js	Mon Feb 04 18:54:17 2013 +0100
+++ b/js/startscreen-fake.js	Thu Feb 07 17:14:46 2013 +0100
@@ -1,85 +1,327 @@
+PATH_MODE = false;
+
 $(function() {
     
-    var colorset = ["#1f77b4 ", "#aec7e8 ", "#ff7f0e ", "#ffbb78 ", "#2ca02c ", "#98df8a ", "#d62728 ", "#ff9896 ", "#9467bd ", "#c5b0d5 ", "#8c564b ", "#c49c94 ", "#e377c2 ", "#f7b6d2 ", "#7f7f7f ", "#c7c7c7 ", "#bcbd22 ", "#dbdb8d ", "#17becf ", "#9edae5"]
+    var colorset_pastel = ["#FBB4AE", "#B3CDE3", "#CCEBC5", "#DECBE4", "#FED9A6", "#E5D8BD", "#FDDAEC"];
+    var colorset_vivid = ["#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00", "#A65628", "#F781BF"];
+    
+    $(".topics-block").draggable({axis:"y"})
     
     $.getJSON("fakedata/data.json", function(data) {
-        $(".topwords-block").html(data.top_words.reduce(function(mem, d) {
-            return mem + '<li>' + d.word + '</li>'
-        },""));
+        
+        function secsToString(seconds) {
+            var hours = Math.floor(seconds/3600),
+                minutes = Math.floor(seconds/60) % 60,
+                secs = Math.floor(seconds % 60);
+            function pad(n) {
+                var r = n.toString();
+                while (r.length < 2) {
+                    r = "0" + r;
+                }
+                return r;
+            }
+            return (hours ? (hours + ":") : "") + pad(minutes) + ":" + pad(secs);
+        }
+        
+        $(".duration").text(secsToString(data.duration));
+        
+        $(".topwords-block").on("click", "li", function() {
+            var el = $(this).toggleClass("selected");
+            wordFilter();
+        });
         
         var nmmso = data.segments.length;
         
         data.topics.forEach(function(topic) {
             topic.score = 0;
-            topic.curve = [];
+            topic.weights = [];
+            topic.scores = [];
             for (var i = 0; i < nmmso; i++) {
-                topic.curve.push(0);
+                topic.weights.push(0);
+                topic.scores.push(0);
             }
         });
         
         data.segments.forEach(function(mmso, i) {
             mmso.topics.forEach(function(t) {
                 var score = t.weight * mmso.tweet_count;
-                data.topics[t.topic].curve[i] = score;
+                data.topics[t.topic].weights[i] = t.weight;
+                data.topics[t.topic].scores[i] = score;
                 data.topics[t.topic].score += score;
             });
+            mmso.tweet_rate = mmso.tweet_count / mmso.duration; 
         });
         
-        data.topics = data.topics.sort(function(a,b) {
+        var sortedTopics = data.topics.slice().sort(function(a,b) {
             return b.score - a.score;
         });
         
-        var topicHtmls = ["", "", ""]
+        var selectedWords = [];
+        
+        function wordFilter() {
+            var selectedLis = $(".topwords-block li.selected");
+            selectedWords = [];
+            selectedLis.each(function() {
+                selectedWords.push($(this).text().trim());
+            });
+            console.log(selectedWords);
+            if (selectedWords.length) {
+                showTopics(data.topics.filter(function(topic) {
+                    var foundWords = selectedWords.map(function() { return false });
+                    topic.words.forEach(function(topicword) {
+                        selectedWords.forEach(function(selectedword, k) {
+                            if (!foundWords[k] && selectedword === topicword.word) {
+                                foundWords[k] = true;
+                            }
+                        })
+                    });
+                    return foundWords.reduce(function(mem, w) { return mem && w}, true);
+                }).sort(function(a,b) {
+                    return b.score - a.score;
+                }));
+            } else {
+                showTopics(sortedTopics);
+            }
+        }
         
-        data.topics.forEach(function(topic,i) {
-            var li = '<li class="shadow-block topic" style="background:'
-                + colorset[topic.index % colorset.length]
-                + '" data-topic-id="'
-                + topic.index
-                + '"><ul class="topic-words">'
-                + topic.words.reduce(function(memwords, word) {
-                    return memwords + '<li>' + word.word + '</li>';
-                },"")
-                + '</ul></li>';
-            topicHtmls[i % 3] += li;
-        });
-        console.log(topicHtmls);
-        $(".topics-block").html(topicHtmls.reduce(function(mem,html) {
-           return mem + '<ul class="topic-column">' + html + '</ul>' 
-        },""));
+        function showTopics(topiclist) {
+            var topicHtmls = ["", "", ""],
+                globwords = {},
+                topwords = [];
+            topiclist.forEach(function(topic,i) {
+                var wordsToShow = topic.words.slice(0,5),
+                    max = wordsToShow[0].weight,
+                    min = Math.min(wordsToShow[wordsToShow.length - 1].weight, max - .01),
+                    scale = 10 / (max - min);
+                var li = '<li class="shadow-block topic" data-topic-id="'
+                    + topic.index
+                    + '" data-viz-color="'
+                    + Raphael.hsl(topic.index / data.topics.length, .8, .5) //colorset_vivid[topic.index % colorset_vivid.length] //colorset_vivid[i % colorset_vivid.length]
+                    + '"" data-li-color="'
+                    + Raphael.hsl(topic.index / data.topics.length, .7, .8) //colorset_pastel[topic.index % colorset_pastel.length] //colorset_pastel[i % colorset_pastel.length]
+                    + '"><ul class="topic-words">'
+                    + wordsToShow.reduce(function(memwords, word) {
+                        return memwords
+                            + '<li style="font-size: '
+                            + ( 10 + scale * (word.weight - min) )
+                            + 'px;">'
+                            + word.word
+                            + '</li>';
+                    },"")
+                    + '</ul></li>';
+                topicHtmls[i % 3] += li;
+                topic.words.forEach(function(word) {
+                    globwords[word.word] = word.weight + (globwords[word.word] || 0)
+                });
+            });
+            var tb = $(".topics-block");
+            tb.html(topicHtmls.reduce(function(mem,html) {
+               return mem + '<ul class="topic-column">' + html + '</ul>' 
+            },""));
+            tb.css("top",0);
+            
+            for (var w in globwords) {
+                topwords.push({
+                    word : w,
+                    weight : globwords[w]
+                });
+            }
+            topwords.sort(function(a, b) {
+                return b.weight - a.weight;
+            });
+            
+            var wordsToShow = topwords.slice(0,30),
+                max = wordsToShow[0].weight,
+                min = Math.min(wordsToShow[wordsToShow.length - 1].weight, max - .01),
+                scale = 10 / (max - min);
+            
+            $(".topwords-block").html(wordsToShow.reduce(function(mem, d) {
+                return mem
+                    + '<li style="font-size: '
+                    + ( 10 + scale * (d.weight - min) )
+                    + 'px;"'
+                    + (selectedWords.indexOf(d.word) !== -1 ? ' class="selected"' : '')
+                    + '>'
+                    + d.word
+                    + '</li>'
+            },""));
+            
+            showTopicViz();
+        }
         
-        $(".topic").mouseenter(function() {
-            var datavizheight = $(".start-dataviz").height(),
-                scale = datavizheight / data.duration,
-                topicid = parseInt($(this).attr("data-topic-id")),
-                topic;
-            for (var i = 0; i < data.topics.length; i++) {
-                if (data.topics[i].index == topicid) {
-                    topic = data.topics[i];
-                    break;
+        function showTopicViz() {
+            var selectedBlocks = $(".topic.selected, .topic.hover"),
+                sbl = selectedBlocks.length;
+            if (!sbl) {
+                selectedBlocks = $(".topic");
+                sbl = selectedBlocks.length;
+            }
+            if (sbl) {
+                $(".topic").css("background","");
+                selectedBlocks.each(function() {
+                    var el = $(this);
+                    el.css("background",el.attr("data-li-color"));
+                });
+            } else {
+                $(".topic").each(function() {
+                    var el = $(this);
+                    el.css("background",el.attr("data-li-color"));
+                });
+            }
+            var topicsAndColors = selectedBlocks.map(function() {
+                var el = $(this),
+                    topicid = parseInt(el.attr("data-topic-id")),
+                    vizcolor = el.attr("data-viz-color");
+                return {
+                    topic: data.topics[topicid],
+                    id: topicid,
+                    color: vizcolor
+                };
+            });
+            if (PATH_MODE) {
+                topicpaths.forEach(function(p) {
+                    p.hide();
+                });
+                topicsAndColors.each(function(j, t) {
+                    var p = topicpaths[t.id];
+                    p.attr({
+                        stroke: t.color,
+                        fill: t.color,
+                        "fill-opacity": .25
+                    });
+                    p.show();
+                });
+                if (sbl > 1 && sbl < data.topics.length) {
+                    var d = "M0,0L" + data.segments.map(function(mmso, i) {
+                        var tweets = 0;
+                        for (var j = 0; j < sbl; j++) {
+                            tweets += topicsAndColors[j].topic.scores[i]
+                        }
+                        x = xscale * tweets / mmso.duration;
+                    return x
+                        + ","
+                        + yscale * (mmso.start + mmso.duration / 3)
+                        + "L"
+                        + x
+                        + ","
+                        + yscale * (mmso.start + 2 * mmso.duration / 3);
+                    }).join("L") + "L0,"+(yscale * data.duration);
+                    sumpath.attr({
+                        path: d
+                    });
+                    sumpath.show();
+                } else {
+                    sumpath.hide();
+                }
+            } else {
+                for (var i = 0; i < nmmso; i++) {
+                    var opacity = 0,
+                        rgb = [0,0,0];
+                    for (var j = 0; j < sbl; j++) {
+                        var c = Raphael.getRGB(topicsAndColors[j].color),
+                            o = topicsAndColors[j].topic.weights[i];
+                        rgb[0] += c.r * o;
+                        rgb[1] += c.g * o;
+                        rgb[2] += c.b * o;
+                        opacity += o;
+                    }
+                    if (opacity) {
+                        color = Raphael.rgb.apply(Raphael, rgb.map(function(c) {
+                            return c/opacity;
+                        }));
+                        segmentrects[i].show();
+                        segmentrects[i].attr({
+                            fill: color,
+                            opacity: .2 + .8 * opacity
+                        });
+                    } else {
+                        segmentrects[i].hide();
+                    }
                 }
             }
-            if (!topic) {
-                return;
-            }
-            var color = colorset[topicid % colorset.length];
-            $(".start-dataviz").html(topic.curve.reduce(function(mem, c, i) {
-                if (!c) {
-                    return mem;
-                } else {
-                    var mmso = data.segments[i];
-                    return mem + '<div style="position: absolute; background: '
-                        + color
-                        +'; opacity: '
-                        + c
-                        +'; left: 0; ; top: '
-                        + scale * mmso.start
-                        +'px; height: '
-                        + scale * mmso.duration
-                        +'px; width: 266px"></div>'
-                }
-            },""));
-        })//.mouseleave(function() {$(".start-dataviz").empty(); });
+            
+        }
+        
+        var jqsvg = $(".start-svg");
+            paper = new Raphael(jqsvg[0]),
+            ph = jqsvg.height(),
+            pw = jqsvg.width(),
+            yscale = ph / data.duration,
+            mx = Math.max.apply(Math, data.segments.map(function(s) { return s.tweet_rate})),
+            xscale = (pw - 10)/mx;
+        
+        if (PATH_MODE) {
+            var sumpath = paper.path();
+            sumpath.attr({
+                fill: "#f0f0f0",
+                stroke: "#666666",
+                "stroke-width": 2
+            });
+            var topicpaths = data.topics.map(function(topic) {
+                var d = "M0,0L" + topic.scores.map(function(s, i) {
+                    var mmso = data.segments[i],
+                        x = xscale * s / mmso.duration;
+                    return x
+                        + ","
+                        + yscale * (mmso.start + mmso.duration / 3)
+                        + "L"
+                        + x
+                        + ","
+                        + yscale * (mmso.start + 2 * mmso.duration / 3);
+                }).join("L") + "L0,"+(yscale * data.duration);
+                return paper.path(d);
+            });
+        } else {
+            var segmentrects = data.segments.map(function(mmso) {
+                var rect = paper.rect(0, yscale * mmso.start, pw - 50, yscale * mmso.duration);
+                rect.attr({stroke: "none"});
+                return rect;
+            });
+        }
+        
+        var d = "M" + data.segments.map(function(s) {
+                var x = xscale * s.tweet_rate;
+                return x
+                    + ","
+                    + yscale * (s.start + s.duration / 3)
+                    + "L"
+                    + x
+                    + ","
+                    + yscale * (s.start + 2 * s.duration / 3);
+            }).join("L");
+            
+        paper.path(d);
+        
+        
+        for (var i=0; i < data.duration; i += 1800) {
+            var y = yscale * i;
+            paper.path("M0," + y + "L" + pw + "," + y).attr({
+                stroke: "#666"
+            });
+            paper.text(pw - 2, y + 6, secsToString(i)).attr({
+                "text-anchor": "end"
+            });
+        }
+        paper.text(pw-2, ph-6, secsToString(data.duration)).attr({
+            "text-anchor": "end"
+        });
+        
+        wordFilter();
+        
+        $(".topics-block").on("mouseenter", ".topic", function() {
+            var topicid = parseInt($(this).attr("data-topic-id")),
+                color = $(this).attr("data-viz-color"),
+                topic = data.topics[topicid];
+            $(this).addClass("hover");
+            showTopicViz();
+        }).on("mouseleave", ".topic", function() {
+            $(this).removeClass("hover");
+            showTopicViz();
+        }).on("click", ".topic", function() {
+            $(this).toggleClass("selected");
+            showTopicViz();
+        });
+        
         
     });
 });