js/startscreen.js
changeset 5 490e4d1b6fee
parent 4 26a901771957
child 6 14dd1980b0b9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/js/startscreen.js	Wed Mar 06 18:09:40 2013 +0100
@@ -0,0 +1,484 @@
+var topicPoubelle = 13;
+
+function showData() {
+    
+    var ordertag = 0;
+
+    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 = [];
+        for (var i = 0; i < nmmso; i++) {
+            topic.weights.push(0);
+        }
+    });
+    
+    data.segments.forEach(function(mmso, i) {
+        mmso.topics.forEach(function(t) {
+            data.topics[t.topic].weights[i] = t.weight;
+            data.topics[t.topic].score += t.weight;
+        });
+        mmso.tweet_rate = mmso.tweet_count / mmso.duration; 
+    });
+    
+    var sortedTopics = data.topics.filter(function(t) {
+        return t.index !== topicPoubelle;
+    }).sort(function(a,b) {
+        return b.score - a.score;
+    });
+    
+    var selectedWords = [], searchString = "";
+    
+    function wordFilter() {
+        var selectedLis = $(".topwords-list li.selected");
+        searchString = $(".keyword-search").val() || "",
+        selectedWords = [];
+        if (searchString.length) {
+            selectedWords.push(searchString);
+        }
+        selectedLis.each(function() {
+            selectedWords.push($(this).text().trim());
+        });
+        if (selectedWords.length) {
+        /*
+            var topiclist = data.topics.filter(function(topic) {
+                if (topic.index === topicPoubelle) {
+                    return false;
+                }
+                var found = false,
+                    relevance = 0;
+                var foundWords = selectedWords.map(function() { return false });
+                topic.words.forEach(function(topicword) {
+                    selectedWords.forEach(function(selectedword, k) {
+                        if (topicword.word.search(selectedword) !== -1) {
+                            found = true;
+                            relevance += (.5 + topicword.weight);
+                        }
+                    });
+                });
+                topic.relevance = relevance;
+                return found;
+            }).sort(function(a,b) {
+                return b.relevance - a.relevance;
+            });
+            */
+            TopicsBean.topicsForKeywords(selectedWords.join(","),{
+                callback: function(topicweights) {
+                    console.log(topicweights);
+                    var topiclist = data.topics.filter(function(topic) {
+                        return topicweights[topic.index] > .01 && topic.index !== topicPoubelle;
+                    });
+                    topiclist.sort(function(a,b) {
+                        return topicweights[b.index] - topicweights[b.index]
+                    });
+                    showTopics(topiclist);
+                }
+            });
+        } else {
+            showTopics(sortedTopics);
+        }
+    }
+    
+    function showTopics(topiclist) {
+        var topicHtmls = ["", "", ""];
+        if (searchString.length) {
+            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());
+            });
+        }
+        var replaceRx = new RegExp('(' + selectedWords.map(function(w) {
+            return w.replace(/(\W)/g,'\\$1')
+        }).join("|") + ')', "gim");
+        topiclist.forEach(function(topic,i) {
+            var wordsToShow = topic.words.slice(0,8),
+                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="999999"><ul class="topic-words">'
+                + wordsToShow.reduce(function(memwords, word) {
+                    return memwords
+                        + '<li style="font-size: '
+                        + ( 10 + scale * (word.weight - min) )
+                        + 'px;">'
+                        + ( selectedWords.length
+                            ? word.word.replace(replaceRx,'<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 globwords = {},
+        allwords = [];
+    
+    data.topics.forEach(function(topic) {
+        topic.words.forEach(function(word) {
+            globwords[word.word] = 1
+        });
+    });
+    
+    var ntw = data.topwords.length,
+        topwords = data.topwords.map(function(v, k) {
+        globwords[v] = 1;
+        return {
+            word: v,
+            weight: ntw - k
+        }
+    });
+    
+    for (var w in globwords) {
+        if (globwords.hasOwnProperty(w)) {
+            allwords.push(w);
+        }
+    }
+    allwords.sort();
+    
+    $(".keyword-search").autocomplete({
+        source: allwords
+    }).on("keyup change paste", wordFilter);
+ */
+
+    var wordsToShow = topwords.slice(0,80),
+        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 < sortedTopics.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.timestamp - b.timestamp ) || ( a.id - b.id );
+        });
+        topicBlocks.css("background","");
+        topicsAndColors.forEach(function(topic, i) {
+            topic.color = topic.hovered ? "#ffff00" : 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: .5 + .5 * 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.minutes.map(function(s) { return s.count})),
+        xscale = (pw - 50)/mx;
+    
+    var segmentrects = data.segments.map(function(mmso) {
+        var rect = paper.rect(0, yscale * mmso.start, pw - 50, 1+yscale * mmso.duration);
+        rect.attr({stroke: "none"});
+        return rect;
+    });
+    
+    var d = "M" + data.minutes.map(function(s) {
+            var x = xscale * s.count;
+            return x
+                + ","
+                + yscale * (s.from + 20)
+                + "L"
+                + x
+                + ","
+                + yscale * (s.from + 40);
+        }).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"
+    });
+    paper.text(0, ph - 14,"tweets/min.").attr({
+        "text-anchor": "start",
+        "fill": "#ffffff"
+    });
+    
+    for (var k = 2; k < 6; k++) {
+        var x = xscale * k * 1000;
+        paper.path("M" + x + ",0L" + x + "," + (ph - 10)).attr({
+            stroke: "#666"
+        });
+        
+        paper.text(x-2, ph - 14,k+"k").attr({
+            "fill": "#ffffff"
+        });
+    }
+    
+    wordFilter();
+    
+    $(".topics-block").on("mouseenter", ".topic", function() {
+        var el = $(this);
+        el.addClass("hover");
+        showTopicViz();
+    }).on("mouseleave", ".topic", function() {
+        $(this).removeClass("hover");
+        showTopicViz();
+    }).on("click", ".topic", function() {
+        var el = $(this);
+        $(this).toggleClass("selected");
+        el.attr("data-timestamp", el.hasClass("selected") ? ++ordertag : 999999);
+        showTopicViz();
+    });
+}
+
+var data = { duration: 10200, topics: [] },
+    colorset = ["#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00", "#A65628", "#F781BF"];
+
+$(function() {
+    
+    $(".topics-block").draggable({axis:"y"});
+    
+    var loadedSteps = 0,
+        stepsToFullyLoaded = 0;
+    
+    function checkIfLoaded() {
+        loadedSteps++;
+        if (loadedSteps >= stepsToFullyLoaded) {
+            console.log("Showing data");
+            setTimeout(showData,0);
+        }
+    }
+    
+    function loadJson(url, propname, callback) {
+        stepsToFullyLoaded++;
+        $.getJSON(url, function(d) {
+            if (callback) {
+                var res = callback(d);
+            } else {
+                var res = d;
+            }
+            if (propname) {
+                data[propname] = res;
+            }
+            checkIfLoaded();
+        });
+    }
+    
+    function solrUrl(table, params) {
+        return "http://159.217.144.101:8050/sia-solr/" + table + "/select?" + $.param(params) + "&wt=json&json.wrf=?";
+    }
+    
+    function loadFromTopicsBean(method, propname, args, callback) {
+        stepsToFullyLoaded++;
+        var arg = args || [],
+            cb = function(d) {
+                if (callback) {
+                    var res = callback(d);
+                } else {
+                    var res = d;
+                }
+                if (propname) {
+                    data[propname] = res;
+                }
+                checkIfLoaded();
+            }
+        arg.push({callback: cb});
+        TopicsBean[method].apply(TopicsBean,arg);
+    }
+    
+    loadJson("data/minutes.json", "minutes");
+    
+    loadJson(
+        solrUrl("MMSO", {q: "*:*", fl: "topic*,MMSO_id,multimediaSegment", rows: 250 }),
+        "segments",
+        function(d) {
+            return d.response.docs.map(function(mmso) {
+                var tc = mmso.multimediaSegment.match(/\d+/g),
+                    start = parseInt(tc[0]),
+                    end = parseInt(tc[1]),
+                    topics = [];
+                for (var k in mmso) {
+                    if (k.substr(0,5) === "topic" && mmso[k] > .01) {
+                        topics.push({
+                            topic: parseInt(k.substr(5)),
+                            weight: mmso[k]
+                        })
+                    }
+                }
+                topics.sort(function(a,b) {
+                    return b.weight - a.weight;
+                });
+/*                topics = topics.filter(function(t) {
+                    return t.topic !== topicPoubelle
+                }).slice(0,1);
+                topics[0].weight = 1; */
+                return {
+                    id: mmso.MMSO_id,
+                    start: start,
+                    end: end,
+                    duration: end - start,
+                    topics: topics,
+                    tweet_count: (end - start) * (35 + 3 * Math.random()) //TODO: dissociate tweet counts from segments
+                }
+            }).sort(function(a,b) {
+                return a.start - b.start;
+            });
+        })
+    
+    dwr.engine.setTimeout(60000);
+    TopicsBean._path = "http://159.217.144.101:8050/sia-solr/dwr";
+    
+    loadFromTopicsBean("getTopicsNumber",false,false,function(topic_count) {
+        for (var i = 0; i < topic_count; i++) {
+            data.topics.push(null);
+        }
+        data.topics.forEach(function(v, k) {
+            loadFromTopicsBean("getTopicDistribution",false,[k, 50, false],function(topic) {
+                var words = topic.match(/[^=,{]+=0.\d{0,8}/g);
+                data.topics[k] = {
+                    index: k,
+                    words: words.map(function(w) {
+                        var parts = w.split("=");
+                        return {
+                            word: parts[0].trim(),
+                            weight: parseFloat(parts[1])
+                        }
+                    })
+                }
+            });
+            
+        });
+        
+    });
+    
+    //loadFromTopicsBean("getTopWords","topwords",[400]);
+    
+});