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