js/startscreen-fake.js
author veltr
Fri, 15 Feb 2013 18:34:43 +0100
changeset 4 26a901771957
parent 3 7fa607ed7e82
permissions -rw-r--r--
Black Background

$(function() {
    
    var colorset = ["#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00", "#A65628", "#F781BF"];
    
    $(".topics-block").draggable({axis:"y"})
    
    $.getJSON("fakedata/data.json", function(data) {
        
        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-list").on("click", "li", function() {
            var el = $(this).toggleClass("selected");
            wordFilter();
        });
        
        var nmmso = data.segments.length;
        
        data.topics.forEach(function(topic) {
            topic.score = 0;
            topic.weights = [];
            topic.scores = [];
            for (var i = 0; i < nmmso; i++) {
                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].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; 
        });
        
        var sortedTopics = data.topics.slice().sort(function(a,b) {
            return b.score - a.score;
        });
        
        function wordFilter() {
            var selectedLis = $(".topwords-list li.selected"),
                searchString = $(".keyword-search").val() || "",
                useSearchString = (searchString.length > 1),
                selectedWords = [];
            selectedLis.each(function() {
                selectedWords.push($(this).text().trim());
            });
            if (selectedWords.length || useSearchString) {
                var topiclist = data.topics.filter(function(topic) {
                    var found = false,
                        relevance = 0;
                    var foundWords = selectedWords.map(function() { return false });
                    topic.words.forEach(function(topicword) {
                        selectedWords.forEach(function(selectedword, k) {
                            if (selectedword === topicword.word) {
                                found = true;
                                relevance += (.5 + topicword.weight);
                            }
                        });
                        if (useSearchString && topicword.word.search(searchString) !== -1) {
                            found = true;
                            relevance += (.5 + topicword.weight);
                        }
                    });
                    topic.relevance = relevance;
                    return found;
                }).sort(function(a,b) {
                    return b.relevance - a.relevance;
                });
            } else {
                var topiclist = sortedTopics;
            }
            var topicHtmls = ["", "", ""];
            if (useSearchString) {
                var searchStringRx = new RegExp('(' + searchString.replace(/(\W)/g,'\\$1') + ')', "gim");
                $(".topwords-list li").each(function() {
                    var el = $(this);
                    el.html(el.text().replace(searchStringRx,'<span class="highlight">$1</span>'));
                });
            } else {
                $(".topwords-list li").each(function() {
                    var el = $(this);
                    el.text(el.text());
                });
            }
            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-timestamp="'
                    + new Date().valueOf()
                    + '"><ul class="topic-words">'
                    + wordsToShow.reduce(function(memwords, word) {
                        return memwords
                            + '<li style="font-size: '
                            + ( 10 + scale * (word.weight - min) )
                            + 'px;"'
                            + ( selectedWords.indexOf(word.word) == -1 ? '' : ' class="selected"')
                            + '>'
                            + ( useSearchString
                                ? word.word.replace(searchStringRx,'<span class="highlight">$1</span>')
                                : word.word )
                            + '</li>';
                    },"")
                    + '</ul></li>';
                topicHtmls[i % 3] += li;
            });
            var tb = $(".topics-block");
            tb.html(topicHtmls.reduce(function(mem,html) {
               return mem + '<ul class="topic-column">' + html + '</ul>' 
            },""));
            tb.css("top",0);
            
            showTopicViz();
        }
        
        var topwords = [], globwords = {};
        
        data.topics.forEach(function(topic) {
            topic.words.forEach(function(word) {
                globwords[word.word] = word.weight + (globwords[word.word] || 0)
            });
        })
        
        for (var w in globwords) {
            topwords.push({
                word : w,
                weight : globwords[w]
            });
        }
        topwords.sort(function(a, b) {
            return b.weight - a.weight;
        });
        
        $(".keyword-search").autocomplete({
            source: topwords.map(function(w) { return w.word })
        }).on("keyup change paste", wordFilter);
        
        var wordsToShow = topwords.slice(0,40),
            max = wordsToShow[0].weight,
            min = Math.min(wordsToShow[wordsToShow.length - 1].weight, max - .01),
            scale = 10 / (max - min);
        
        $(".topwords-list").html(wordsToShow.reduce(function(mem, d) {
            return mem
                + '<li style="font-size: '
                + ( 10 + scale * (d.weight - min) )
                + 'px;">'
                + d.word
                + '</li>'
        },""));
        
        function showTopicViz() {
            var selectedBlocks = $(".topic.selected, .topic.hover"),
                sbl = selectedBlocks.length,
                topicBlocks = $(".topic");
            if (!sbl && topicBlocks.length !== data.topics.length) {
                topicBlocks.each(function() {
                    
                })
                selectedBlocks = topicBlocks;
                sbl = selectedBlocks.length;
            }
            var topicsAndColors = [];
            selectedBlocks.map(function() {
                var el = $(this),
                    topicid = parseInt(el.attr("data-topic-id"));
                topicsAndColors.push({
                    "$": el,
                    timestamp: parseInt(el.attr("data-timestamp")),
                    hovered: el.hasClass("hover"),
                    id: topicid,
                    topic: data.topics[topicid]
                });
            });
            topicsAndColors.sort(function(a,b) {
               return (a.hovered
                   ? 1
                   : ( b.hovered
                       ? -1
                       : ( a.timestamp - b.timestamp ) || ( a.id - b.id )
                   )
               )
            });
            topicBlocks.css("background","");
            topicsAndColors.forEach(function(topic, i) {
                topic.color = colorset[i % colorset.length];
                topic.$.css("background", topic.color);
            });
            
            for (var i = 0; i < nmmso; i++) {
                var opacity = 0,
                    rgb = [0,0,0];
                topicsAndColors.forEach(function(topic) {
                    var c = Raphael.getRGB(topic.color),
                        o = topic.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();
                }
            }
            
        }
        
        var jqsvg = $(".start-svg");
            paper = new Raphael(jqsvg[0]),
            ph = jqsvg.height(),
            pw = jqsvg.width(),
            yscale = (ph - 20) / data.duration,
            mx = Math.max.apply(Math, data.segments.map(function(s) { return s.tweet_rate})),
            xscale = (pw - 50)/mx;
        console.log(mx);
        
        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).attr({
            "stroke-width": 4,
            "stroke": "#000000",
            opacity: .5
        });
        paper.path(d).attr({
            "stroke-width": 1,
            "stroke": "#ffffff"
        });
        
        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",
                "fill": "#ffffff"
            });
        }
        paper.text(pw-2, ph-14, secsToString(data.duration)).attr({
            "text-anchor": "end",
            "fill": "#ffffff"
        });
        paper.path("M0," + (ph-20) + "L" + pw + "," + (ph-20)).attr({
            stroke: "#666"
        });
        
        var x = xscale * 1000 / 60;
        paper.path("M" + x + ",0L" + x + "," + (ph - 10)).attr({
            stroke: "#666"
        });
        
        paper.text(x-2, ph - 14,"1000 tweets/minute").attr({
            "text-anchor": "end",
            "fill": "#ffffff"
        });
        
        wordFilter();
        
        $(".topics-block").on("mouseenter", ".topic", function() {
            var el = $(this);
            if (!el.hasClass("selected")) {
                el.addClass("hover");
                showTopicViz();
            }
        }).on("mouseleave", ".topic", function() {
            $(this).removeClass("hover");
            showTopicViz();
        }).on("click", ".topic", function() {
            var el = $(this);
            $(this).toggleClass("selected");
            if (el.hasClass("selected")) {
                el.attr("data-timestamp", new Date().valueOf())
            }
            showTopicViz();
        });
        
        
    });
});