# HG changeset patch # User Yves-Marie Haussonne <1218002+ymph@users.noreply.github.com> # Date 1322577712 -3600 # Node ID 1ec7b057a8bdfc4d89989541b96c0fdf9119c1f9 # Parent aa445cd7300e4c265b624337e19aed003dc3866c# Parent 698e4280d2705a2c6720b40e9c15f26e27a0ad46 Merge with cbbb959fab4c21e240b9820354a8879db3969d55 diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/css/style.css --- a/tweetcast/nodejs-bis/client/css/style.css Tue Nov 29 15:41:15 2011 +0100 +++ b/tweetcast/nodejs-bis/client/css/style.css Tue Nov 29 15:41:52 2011 +0100 @@ -22,22 +22,169 @@ } body { - font-family: Helvetica, Arial, sans-serif; + font-family: Helvetica, Arial, sans-serif; background-color: #F7F6F6; background-image: url("../img/bgd.jpg"); background-repeat: repeat-x; +} + +b { + font-weight: bold; +} + +.highlight { + background: #ffff00; } #container { - margin: 20px; + width: 960px; margin: 0 auto; +} + +#colgauche { + float: left; width: 455px; margin-right: 13px; +} + +.barre { + float: left; width: 100%; +} + +.greyed { + color: #999; font-style: italic; +} + +.rechercheCourante { + background: #ffa0ff; font-weight: bold; color: #000080; +} + +/* Menu */ + +#headlogo { + float: left; margin-right: 10px; } -/* Barre */ -.barre { - float: left; width: 100%; +.menu { + border-left: 1px solid #C3C3C3; + float: left; + list-style: none; + font-size: 12px; + height: 62px; overflow: hidden; +} + +.menu li { + background: url("../img/menu_underline.gif") left bottom no-repeat; + padding: 3px 0 0 5px; + height: 18px; + min-width: 80px; +} + +.menu a { + color: #000000; text-decoration: none; +} + +.menu a:hover { + color: #0099FF; +} + +/* Formulaire */ + +#twwWrap { + float: left; width: 450px; background: #ffffff; padding: 1px; border-width: 1px; border-style: solid solid none solid; border-color: #ababab; margin-top: 6px; +} + +#tweetWriter { + width: 430px; padding: 10px; background: #efefef; } /* Liste de Tweets */ +#tweetviz { + float: left; width: 452px; border: 1px solid #999; +} + +/* Recherche */ + +#recherche { + position: relative; float: left; padding: 2px 0; width: 452px; border-bottom: 1px solid #999; +} + +#recherche input { + float: left; +} + +#inp_q { + width: 236px; border: none; padding: 1px; margin-left: 2px; height: 17px; font-size: 13px; +} + +#inp_submit, #inp_reset { + border: 0; padding: 0; width: 20px; height: 20px; overflow: hidden; text-indent: 800px; background: url(../img/searchcancel.png) +} + +#inp_submit:hover { + background-position: -20px 0; +} + +#inp_submit:active { + background-position: -40px 0; +} + +#inp_reset { + background-position: 0 -20px; +} + +#inp_reset:hover { + background-position: -20px -20px; +} + +#inp_reset:active { + background-position: -40px -20px; +} + +#time_legende { + float: left; margin-left: 30px; width: 30px; height: 20px; background: url(../img/scale.png) left; +} + +#time_scale { + float: left; font-size: 12px; margin: 3px 0 0; color: #666; width: 50px; text-align: center; +} + +#time_zoomout, #time_zoomin { + float: left; width: 12px; height: 20px; background: url(../img/scale.png); +} + +#time_zoomout { + background-position: -30px; +} + +#time_zoomout.inactive { + background-position: -54px; +} + +#time_zoomin { + background-position: -42px; +} + +#time_zoomin.inactive { + background-position: -66px; +} + +#recherche_annot { + position: absolute; top: 20px; z-index: 4; background: #ffffff; border: 1px solid #ccc; padding: 4px; font-size: 12px; + display: none; box-shadow: 2px 2px 2px rgba(0, 0, 0, .5) +} + +#recherche_annot a { + padding: 1px; line-height: 13px; margin: 1px; font-weight: bold; text-decoration: none; color: #000000; +} + +/* Liste des tweets */ + #tweetlist { - float: left; width: 280px; height: 450px; list-style: none; border: 1px solid #999; color: #585858; cursor: pointer; cursor: hand; + float: left; width: 280px; height: 480px; list-style: none; border-right: 1px solid #999; color: #585858; cursor: pointer; cursor: hand; background: #ffffff; +} + +#tweetlist a { + text-decoration: none; color: #1985B5; +} + +#tweetlist a:hover { + text-decoration: underline; color: #105060; } li.tweet, li.placeholder { @@ -49,7 +196,7 @@ } li.full { - width: 270px; height: 84px; border-right: 10px solid #ff0; + width: 270px; height: 117px; border-right: 10px solid #ff0; } li.half { @@ -69,7 +216,7 @@ } .full p.tweet_text { - font-size: 12px; margin: 5px 0 5px 58px; height: 75px; width: 207px; color: #000000; + font-size: 12px; margin: 5px 0 5px 58px; height: 108px; width: 207px; color: #000000; } .half p.tweet_text { @@ -92,14 +239,10 @@ margin: 2px; width: 16px; height: 16px; } -.full p.created_at { +p.created_at { font-size: 12px; text-align: center; font-style: italic; color: #999999; width: 58px; overflow: hidden; } -.half p.created_at, .icons p { - display: none -} - .annotations { position: absolute; margin: 0; padding: 0; top: 0; left: 0; width: 100%; height: 100%; } @@ -116,26 +259,28 @@ position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; overflow: hidden; } +div.tweet_actions { + position: absolute; bottom : 2px; right: 4px; font-size: 11px; +} + /* timeline */ #timeline { - float: left; height: 450px; width: 150px; border-width: 1px; border-style: solid solid solid none; border-color: #999; cursor: pointer; cursor: hand; + float: left; height: 480px; width: 150px; border-right: 1px solid #999; cursor: pointer; cursor: hand; } - - #scrollcont { - float: left; width: 20px; height: 452px; overflow: auto; + float: left; width: 20px; height: 480px; overflow: auto; } #scrollin { - width: 1px; height: 10000px; + width: 1px; height: 8000px; } /* hovertweet */ #hovertweet { - position: absolute; display: none; margin: -20px 0 0 15px; + position: absolute; display: none; margin: -20px 0 0 15px; z-index: 12; } div.full { @@ -146,8 +291,46 @@ position: absolute; width: 10px; height: 18px; left: -9px; top: 13px; background: url(../img/arrow.png); } +/* Colonne de droite */ + +#coldroite { + float: left; width: 492px; +} + +#vlWrap { + float: left; border: 5px solid #ffffff; background: #999999; padding: 1px; margin-top: 20px; +} + +#videoLivePlayer { + width: 480px; height: 320px; background: #000000; +} + +#out_fleche { + float: left; position: relative; width: 492px; height: 14px; background: url(../img/bgnoarrow.png); +} + +#in_fleche { + position: absolute; left: 10px; width: 27px; height: 15px; background: url(../img/arrowtop.png); +} + +#accordeon { + float: left; width: 492px; list-style: none; background: #777777; +} + +#accordeon li { + float: left; width: 480px; margin: 0 1px 1px 1px; padding: 4px; border: 1px solid #ffffff; background: #efefef; +} + +#accordeon li.deplie { + background: url(../img/bgdeplie.png) top repeat-x #efefef; +} + /* Tag Cloud */ #motscles { - float: left; width: 400px; height: 100px; text-align: center; border: 1px solid #999; margin: 0 20px; + text-align: center; } + +#motscles span { + padding: 2px; cursor: pointer; cursor: hand; +} diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/img/arrowtop.png Binary file tweetcast/nodejs-bis/client/img/arrowtop.png has changed diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/img/bgd.jpg Binary file tweetcast/nodejs-bis/client/img/bgd.jpg has changed diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/img/bgdeplie.png Binary file tweetcast/nodejs-bis/client/img/bgdeplie.png has changed diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/img/bgnoarrow.png Binary file tweetcast/nodejs-bis/client/img/bgnoarrow.png has changed diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/img/head_logo.gif Binary file tweetcast/nodejs-bis/client/img/head_logo.gif has changed diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/img/menu_underline.gif Binary file tweetcast/nodejs-bis/client/img/menu_underline.gif has changed diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/img/placeholder.png Binary file tweetcast/nodejs-bis/client/img/placeholder.png has changed diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/img/searchcancel.png Binary file tweetcast/nodejs-bis/client/img/searchcancel.png has changed diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/index.html --- a/tweetcast/nodejs-bis/client/index.html Tue Nov 29 15:41:15 2011 +0100 +++ b/tweetcast/nodejs-bis/client/index.html Tue Nov 29 15:41:52 2011 +0100 @@ -6,34 +6,78 @@ +
-
-
+
+
+ + +
+
+
+

Annotations polémiques

+
+
+
+
+
+ + + +
+
+
+ + +
+
+ Recherche par annotation :
+
+
+
+
    +
    +
    +
    +
    +
    - -
    -
    -
    -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • Nuage de mots-clés

    • +
    • +
    -
    -
    -
    -
    -
    +
    +
    +
    +
    \ No newline at end of file diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/js/script.js --- a/tweetcast/nodejs-bis/client/js/script.js Tue Nov 29 15:41:15 2011 +0100 +++ b/tweetcast/nodejs-bis/client/js/script.js Tue Nov 29 15:41:52 2011 +0100 @@ -5,35 +5,37 @@ var socket, tlPaper, twCx = { - zoomLevel : 1, followLast : true, - position : 0, + position : "0", date_levels : [ + 3600 * 1000, 15 * 60 * 1000, 5 * 60 * 1000, - 60 * 1000, - 15 * 1000 + 60 * 1000 ], - timeLevel : 0, + timeLevel : 1, deltaX : 40, tlWidth : 150, - tlHeight : 450, + tlHeight : 480, globalWords : {}, refMouse : { x : 0, y : 0}, refPosTl : { x : 0, y : 0}, tlMouseMoved : false, - tlMouseClicked : false + tlMouseClicked : false, + filtre : null }, tlBuffer = '', relHover = [], wheelDelta = 0, + scrollEnabled = false, + scrollExtent = 8000 - 480, + lastScrollPos = 0, rx_url = /https?:\/\/[0-9a-zA-Z\.%\/-_]+/g, rx_word = /[^ \.&;,'"!\?\d\(\)\+\[\]\\\…\-«»:\/]{3,}/g, stop_list = [ 'and', 'avec', 'aux', 'car', 'comme', 'dans', 'donc', 'des', 'elle', 'est', 'être', 'eux', 'ils', 'les', 'leur', 'leurs', 'mes', 'mon', 'tes', 'ton', 'notre', 'nos', 'nous', 'ont', 'pas', 'que', 'qui', 'sont', 'the', 'une', 'votre', 'vos', 'vous' ]; function getColor(annotation, lum) { -// console.log(annotations[annotation].h, annotations[annotation].s, lum, Raphael.hsl(annotations[annotation].h, annotations[annotation].s, lum)) - return Raphael.hsl(annotations[annotation].colors.h, annotations[annotation].colors.s, lum); + return Raphael.hsl2rgb(annotations[annotation].colors.h, annotations[annotation].colors.s, lum); } function arc(source, target) { @@ -167,9 +169,16 @@ } function trimFDS() { - var slices = flattenDateStruct(twCx.timeline, twCx.timeLevel), + var slices = flattenDateStruct(twCx.timeline, twCx.timeLevel); + while (slices[0].tweets.length == 0) { + slices.splice(0,1); + } + while (slices[slices.length - 1].tweets.length == 0) { + slices.pop(); + } + var centralTweet = ( twCx.centralTweet ? twCx.centralTweet : twCx.tweets[twCx.tweets.length - 1] ), delta = 30 * twCx.date_levels[twCx.timeLevel], - centre = Math.min(slices[slices.length - 1].end - delta , Math.max(slices[0].start + delta, twCx.tweets[twCx.position].date_value)), + centre = Math.min(slices[slices.length - 1].end - delta , Math.max(slices[0].start + delta, centralTweet.date_value)), min = centre - delta, max = centre + delta; while (slices[0].start < min) { @@ -225,25 +234,27 @@ } function selectTweet(tweetid) { - var pos = twCx.idIndex.indexOf(tweetid); - if (pos != -1) { - twCx.position = pos; - twCx.followLast = (twCx.position == twCx.tweets.length - 1); - updateDisplay() - } + twCx.position = tweetid; + twCx.followLast = (twCx.position == twCx.idIndex[twCx.tweets.length - 1]); + updateDisplay(); } function goToPos(nPos) { - twCx.position = Math.min( twCx.tweets.length - 1, Math.max(0, nPos ) ); - twCx.followLast = (twCx.position == twCx.tweets.length - 1); + twCx.position = twCx.currentIdIndex[Math.min( twCx.currentIdIndex.length - 1, Math.max(0, nPos ) )]; + twCx.followLast = (!twCx.filtre && nPos == twCx.tweets.length - 1); updateDisplay(); } function movePos(delta) { - goToPos( delta + twCx.position ); + goToPos( delta + twCx.currentIdIndex.indexOf(twCx.position) ); } function tweetToHtml(tweet, className, elName) { + + function highlight(texte) { + return ( twCx.filtre ? texte.replace(twCx.filtre, '$1' ) : texte ); + } + if (!tweet) { return placeHolder(className); } @@ -260,12 +271,12 @@ if (tweet.annotations.length) { html += '
    '; for (var i in tweet.annotations) { - html += '
    '; + html += '
    '; } html += '
    '; } html += '
    '; - a_user = ''; + a_user = ''; html += '
    ' + a_user + ''; if (className == 'full') { html += '

    ' + new Date(tweet.date_value).toTimeString().substr(0,8) + '

    '; @@ -279,7 +290,8 @@ entities.push({ "start" : tweet.entities.hashtags[i].indices[0], "end" : tweet.entities.hashtags[i].indices[1], - "html" : '#' + tweet.entities.hashtags[i].text + '' + "link" : '', + "text" : '#' + tweet.entities.hashtags[i].text }); } for (var i in tweet.entities.urls) { @@ -291,23 +303,30 @@ entities.push({ "start" : tweet.entities.urls[i].indices[0], "end" : tweet.entities.urls[i].indices[1], - "html" : '' + dispurl + '' + "link" : '', + "text" : dispurl }); } for (var i in tweet.entities.user_mentions) { entities.push({ "start" : tweet.entities.user_mentions[i].indices[0], "end" : tweet.entities.user_mentions[i].indices[1], - "html" : '@' + tweet.entities.user_mentions[i].screen_name + '' + "link" : '', + "text" : '@' + tweet.entities.user_mentions[i].screen_name }); } entities.sort(function(a, b) { return a.start - b.start }); for (var i in entities) { - txt += tweet.text.substring(lastend, entities[i].start) + entities[i].html; + txt += highlight( tweet.text.substring(lastend, entities[i].start) ) + entities[i].link + highlight( entities[i].text ) + ''; lastend = entities[i].end; } - txt += tweet.text.substring(lastend); - html += '

    ' + a_user + '@' + tweet.user.screen_name + ': ' + txt + '

    '; + txt += highlight( tweet.text.substring(lastend) ); + html += '

    ' + a_user + highlight('@' + tweet.user.screen_name) + '' + ( className == 'full' ? ' (' + tweet.user.name + ')
    ' : ' : ') + txt + '

    '; + if (className == 'full' && el == 'li') { + html += '
    répondre · '; + html += 'retweeter · '; + html += 'favori
    '; + } } html += '
    '; return html; @@ -340,6 +359,9 @@ } function tlPosTweet(tweet, annotation) { + if (!twCx.tweets) { + return; + } var x, y, dt = tweet.date_value, @@ -436,33 +458,50 @@ } function updateDisplay() { - var p = twCx.position, - l = twCx.tweets.length, + if (!twCx.tweets) { + return; + } + if (twCx.filtre) { + var tweets = twCx.tweets.filter(function(tweet) { + var mention = '@' + tweet.user.screen_name; + return ( tweet.text.search(twCx.filtre) != -1 ) || ( mention.search(twCx.filtre) != -1 ); + }); + $("#inp_q").val(twCx.filtreTexte + ' (' + tweets.length + ' tweets)'); + if (tweets.length) { + var idIndex = tweets.map(function(tweet) { + return tweet.id; + }); + var p = idIndex.indexOf(twCx.position); + if (p == -1) { + for (p = idIndex.length - 1; p > 0 && idIndex[p] > twCx.position; p--) { + } + } + twCx.position = idIndex[p]; + twCx.currentIdIndex = idIndex; + } + + } else { + twCx.currentIdIndex = twCx.idIndex; + var tweets = twCx.tweets; + var p = twCx.idIndex.indexOf(twCx.position); + if (p == -1) { + p = (twCx.followLast ? twCx.idIndex.length - 1 : 0); + } + } + + var l = tweets.length, lines = 0, ppy = 0, html = '', tweetsOnDisplay = [], localWords = {}; - if (p == 0) { - $("#downbutton").addClass("inactive"); - } else { - $("#downbutton").removeClass("inactive"); - } - - if (p == l-1) { - $("#upbutton").addClass("inactive"); - } else { - $("#upbutton").removeClass("inactive"); - } - - function pushTweet(tp, className) { if (tp < l && tp >= 0) { - html += tweetToHtml(twCx.tweets[tp], className) + html += tweetToHtml(tweets[tp], className) tweetsOnDisplay.push(tp); - for (var i in twCx.tweets[tp].words) { - var w = twCx.tweets[tp].words[i]; + for (var i in tweets[tp].words) { + var w = tweets[tp].words[i]; if (localWords[w]) { localWords[w].freq++ } else { @@ -476,8 +515,8 @@ } } } - for (var j in twCx.tweets[tp].annotations) { - localWords[w].annotations[twCx.tweets[tp].annotations[j]]++; + for (var j in tweets[tp].annotations) { + localWords[w].annotations[tweets[tp].annotations[j]]++; } } } else { @@ -485,97 +524,123 @@ } } - if (l > p + 18) { - lines++; - ppy += 20; - for (var i = p + 31; i >= p + 18; i--) { - pushTweet(i, 'icons'); - } - } - if (l > p + 4) { - lines++; - ppy += 20; - for (var i = p + 17; i >= p + 4; i--) { - pushTweet(i, 'icons'); - } - } - for (var k = 3; k >= 1; k--) { - if (l > p + k) { - ppy += 47; + if (l) { + + lastScrollPos = Math.floor( scrollExtent * ( 1 - ( p / l ) ) ); + $("#scrollcont").scrollTop(lastScrollPos); + + if (l > p + 18) { lines++; - pushTweet(p + k, 'half'); - } - } - pushTweet(p, 'full'); - var n = p - 1; - for (var i = 0; i < Math.min(6, Math.max(3, 6 - lines)); i++) { - if (n < 0) { - break; - } - pushTweet(n, 'half'); - n--; - } - for (var i = 0; i < 14 * Math.min(4, Math.max(2, 7 - lines)); i++) { - if (n < 0) { - break; + ppy += 20; + for (var i = p + 31; i >= p + 18; i--) { + pushTweet(i, 'icons'); + } } - pushTweet(n, 'icons'); - n--; - } - if (html != tlBuffer) { - $("#tweetlist").html(html); - $(".tweet.full").fadeIn(); - tlBuffer = html; - } - - for (var j in localWords) { - if (localWords[j].freq < 2) delete localWords[j]; - } - var tab = []; - for (var j in localWords) { - tab.push({ - "word": j, - "freq" : localWords[j].freq, - "annotations" : localWords[j].annotations, - "score" : localWords[j].freq / Math.log(1+twCx.globalWords[j]) - }); - } - tab.sort( function(a,b){ return ( b.score - a.score ) }).splice(20); - var minfreq = tab[tab.length - 1].score, - maxfreq = Math.max(minfreq + .1, tab[0].score), - echfreq = 8 / Math.sqrt( maxfreq - minfreq ), - html = ''; - for (var j in tab) { - var maxann = 0, - ann = "default"; - for (var k in tab[j].annotations) { - if (tab[j].annotations[k] == maxann) { - ann = "default"; + if (l > p + 4) { + lines++; + ppy += 20; + for (var i = p + 17; i >= p + 4; i--) { + pushTweet(i, 'icons'); } - if (tab[j].annotations[k] > maxann) { - ann = k; - maxann = tab[j].annotations[k]; + } + for (var k = 3; k >= 1; k--) { + if (l > p + k) { + ppy += 47; + lines++; + pushTweet(p + k, 'half'); } } - var coul = (ann == "default" ? '' : ' background: ' + getColor(ann, 1 - .4 * ( tab[j].annotations[ann] / tab[j].freq ) ) + ';"'), - fontsize = Math.floor( ( 12 + Math.sqrt( tab[j].score - minfreq ) * echfreq ) ); - html += '' + tab[j].word + ' '; + pushTweet(p, 'full'); + var n = p - 1; + for (var i = 0; i < Math.min(6, Math.max(3, 6 - lines)); i++) { + if (n < 0) { + break; + } + pushTweet(n, 'half'); + n--; + } + for (var i = 0; i < 14 * Math.min(4, Math.max(2, 7 - lines)); i++) { + if (n < 0) { + break; + } + pushTweet(n, 'icons'); + n--; + } + if (html != tlBuffer) { + $("#tweetlist").html(html); + $(".tweet.full").fadeIn(); + tlBuffer = html; + } + + /* Recherche des mots pertinents correspondant à la sélection */ + + var tab = _(localWords).map(function(v, k) { + return { + "word": k, + "freq" : v.freq, + "annotations" : v.annotations, + "score" : v.freq / Math.log( 2 + twCx.globalWords[j] ) + }; + }).filter(function(v) { + return v.freq > 1; + }); + + if (tab.length) { + + tab = _(tab).sortBy( function(a) { return ( - a.score ) }).slice(0,20); + var minfreq = _(tab).min( function(a) { return a.freq} ).freq, + maxfreq = Math.max(minfreq + .1, _(tab).max( function(a) { return a.freq} ).freq), + echfreq = 8 / Math.sqrt( maxfreq - minfreq ), + html = ''; + for (var j in tab) { + var maxann = 0, + ann = "default"; + for (var k in tab[j].annotations) { + if (tab[j].annotations[k] == maxann) { + ann = "default"; + } + if (tab[j].annotations[k] > maxann) { + ann = k; + maxann = tab[j].annotations[k]; + } + } + if (ann == "default") { + var coul = ''; + } else { + var c = getColor(ann, .6), + coul = "background: rgba(" + [ Math.floor(c.r), Math.floor(c.g), Math.floor(c.b), ( tab[j].annotations[ann] / tab[j].freq )].join(',') + ")"; + } + var fontsize = Math.floor( ( 12 + Math.sqrt( tab[j].freq - minfreq ) * echfreq ) ); + html += '' + tab[j].word + ' '; + } + $("#motscles").html(html); + } else { + $("#motscles").html(''); + } + twCx.centralTweet = tweets[p]; + } else { + $("#tweetlist").html(''); + tlBuffer = ''; + $("#motscles").html(''); } - $("#motscles").html(html); twCx.tlOnDisplay = trimFDS(); twCx.scaleY = twCx.tlHeight / twCx.tlOnDisplay.length; var maxTweets = 0, startTl = 0, - endTl = twCx.tlOnDisplay.length - 1, - startTw = twCx.tweets[tweetsOnDisplay[tweetsOnDisplay.length - 1]].date_value, - endTw = twCx.tweets[tweetsOnDisplay[0]].date_value; + endTl = twCx.tlOnDisplay.length - 1; + if (l) { + var startTw = tweets[tweetsOnDisplay[tweetsOnDisplay.length - 1]].date_value, + endTw = tweets[tweetsOnDisplay[0]].date_value; + } for (var i = 0; i < twCx.tlOnDisplay.length; i++) { - if (startTw >= twCx.tlOnDisplay[i].start && startTw < twCx.tlOnDisplay[i].end) { - startTl = i; - } - if (endTw >= twCx.tlOnDisplay[i].start && endTw < twCx.tlOnDisplay[i].end) { - endTl = i; + if (l) { + if (startTw >= twCx.tlOnDisplay[i].start && startTw < twCx.tlOnDisplay[i].end) { + startTl = i; + } + if (endTw >= twCx.tlOnDisplay[i].start && endTw < twCx.tlOnDisplay[i].end) { + endTl = i; + } } var displayData = {}; for (var j in annotations) { @@ -607,31 +672,31 @@ relHover = null; // Dessin de la correspondance liste-timeline - - var startY = twCx.tlHeight - startTl * twCx.scaleY, - endY = twCx.tlHeight - ( endTl + 1 ) * twCx.scaleY, - path = "M0 " + twCx.tlHeight + "C" + .7*twCx.deltaX + " " + twCx.tlHeight + " " + .3*twCx.deltaX + " " + startY + " " + twCx.deltaX + " " + startY + "L" + twCx.tlWidth + " " + startY + "L" + twCx.tlWidth + " " + endY + "L" + twCx.deltaX + " " + endY + "C" + .3*twCx.deltaX + " " + endY + " " + .7*twCx.deltaX + " 0 0 0"; - tlPaper.path( path ).attr({ "stroke" : "none", "fill" : "#000080", "opacity" : .2 }); - + if (l) { + var startY = twCx.tlHeight - startTl * twCx.scaleY, + endY = twCx.tlHeight - ( endTl + 1 ) * twCx.scaleY, + path = "M0 " + twCx.tlHeight + "C" + .7*twCx.deltaX + " " + twCx.tlHeight + " " + .3*twCx.deltaX + " " + startY + " " + twCx.deltaX + " " + startY + "L" + twCx.tlWidth + " " + startY + "L" + twCx.tlWidth + " " + endY + "L" + twCx.deltaX + " " + endY + "C" + .3*twCx.deltaX + " " + endY + " " + .7*twCx.deltaX + " 0 0 0"; + tlPaper.path( path ).attr({ "stroke" : "none", "fill" : "#000080", "opacity" : .2 }); + } // dessin de la date de début - tlPaper.text(2, twCx.tlHeight - 7, new Date(twCx.tlOnDisplay[0].start).toTimeString().substr(0,5)) - .attr({ "text-anchor" : "start", "font-size": "9px" }); + tlPaper.text(twCx.deltaX / 2, twCx.tlHeight - 7, new Date(twCx.tlOnDisplay[0].start).toTimeString().substr(0,5)) + .attr({ "text-anchor" : "middle", "font-size": "9px" }); // dessin de la date de fin - tlPaper.text(2, 7, new Date(twCx.tlOnDisplay[twCx.tlOnDisplay.length - 1].end).toTimeString().substr(0,5)) - .attr({ "text-anchor" : "start", "font-size": "9px" }); + tlPaper.text(twCx.deltaX / 2, 7, new Date(twCx.tlOnDisplay[twCx.tlOnDisplay.length - 1].end).toTimeString().substr(0,5)) + .attr({ "text-anchor" : "middle", "font-size": "9px" }); for (var i = 0; i < twCx.tlOnDisplay.length; i++) { var n = 0, posY = twCx.tlHeight - ( i + 1 ) * twCx.scaleY; for (var j in twCx.tlOnDisplay[i].displayData) { - var l = twCx.tlOnDisplay[i].displayData[j].length; - if (l > 0) { - tlPaper.rect( twCx.deltaX + n * twCx.scaleX, posY, l * twCx.scaleX, twCx.scaleY ) - .attr({"stroke" : "none", "fill" : getColor(j, .4) }); - n += l; + var ll = twCx.tlOnDisplay[i].displayData[j].length; + if (ll > 0) { + tlPaper.rect( twCx.deltaX + n * twCx.scaleX, posY, ll * twCx.scaleX, twCx.scaleY ) + .attr({"stroke" : "none", "fill" : getColor(j, .4).hex }); + n += ll; } } @@ -639,27 +704,62 @@ if (i < twCx.tlOnDisplay.length - 1 && !(twCx.tlOnDisplay[i].end % 1800000)) { tlPaper.path("M0 "+posY+"L" + twCx.tlWidth +" "+posY).attr({"stroke":"#ccc"}); - tlPaper.text(2, posY, new Date(twCx.tlOnDisplay[i].end).toTimeString().substr(0,5)).attr({ "text-anchor" : "start", "font-size": "9px" }); + tlPaper.text(twCx.deltaX / 2, posY, new Date(twCx.tlOnDisplay[i].end).toTimeString().substr(0,5)).attr({ "text-anchor" : "middle", "font-size": "9px" }); } } // dessin du tweet courant - - var posp = tlPosTweet(twCx.tweets[p]); - if (posp) { + if (l) { + + if (twCx.filtre) { + for (var i = 0; i < tweets.length; i++) { + if (i != p) { + var pos = tlPosTweet(tweets[i]); + if (pos) { + drawTweetPos(pos, "#ffccff"); + } + } + } + + } - drawTweetPos(posp, "#ffff00"); - var yy = posp.y - .5 * twCx.scaleY, - path = "M0 " + ppy + "C" + ( .7 * twCx.deltaX ) + " " + ppy + " " + ( .2 * twCx.deltaX ) + " " + yy + " " + ( twCx.deltaX ) + " " + yy + "L" + ( posp.x - .5 * twCx.scaleX ) + " " + yy; - yy = posp.y + .5 * twCx.scaleY; - ppy += 84; - path += "L" + ( posp.x - .5 * twCx.scaleX ) + " " + yy + "L" + twCx.deltaX + " " + yy + "C" + ( .2 * twCx.deltaX ) + " " + yy + " " + ( .7 * twCx.deltaX ) + " " + ppy + " 0 " + ppy; - tlPaper.path( path ).attr({"stroke":"#ffff00", "fill" : "#ffff00", "fill-opacity" : .15}); - - drawTweetArcs(twCx.tweets[p], posp, '#800080'); + var posp = tlPosTweet(tweets[p]); + if (posp) { + + drawTweetPos(posp, "#ffff00"); + var yy = posp.y - .5 * twCx.scaleY, + path = "M0 " + ppy + "C" + ( .7 * twCx.deltaX ) + " " + ppy + " " + ( .2 * twCx.deltaX ) + " " + yy + " " + ( twCx.deltaX ) + " " + yy + "L" + ( posp.x - .5 * twCx.scaleX ) + " " + yy; + yy = posp.y + .5 * twCx.scaleY; + ppy += 117; + path += "L" + ( posp.x - .5 * twCx.scaleX ) + " " + yy + "L" + twCx.deltaX + " " + yy + "C" + ( .2 * twCx.deltaX ) + " " + yy + " " + ( .7 * twCx.deltaX ) + " " + ppy + " 0 " + ppy; + tlPaper.path( path ).attr({"stroke":"#ffff00", "fill" : "#ffff00", "fill-opacity" : .15}); + + drawTweetArcs(tweets[p], posp, '#800080'); + } } - +} + +function filtrerAnnotation(annotation) { + if (annotations[annotation]) { + effectuerFiltrage(annotations[annotation].display_name, + new RegExp( "(" + annotations[annotation].keywords.map(function(a) { return a.source }).join("|") + ")", "gi" ) ); + } else { + effectuerFiltrage('', null) + } +} + +function filtrerTexte(valeur) { + effectuerFiltrage( valeur, valeur ? new RegExp("(" + valeur.replace(/(\W)/g, '\\$1') + ")" ,'gi') : null ); +} + +function effectuerFiltrage(filtreTexte, tabRegexp) { + $("#recherche_annot").slideUp(); + $("#inp_q").val(filtreTexte).attr("class","rechercheCourante"); + twCx.filtreTexte = filtreTexte; + twCx.filtre = tabRegexp; + twCx.followLast = !tabRegexp && (twCx.position == twCx.idIndex[twCx.idIndex.length - 1]); + updateDisplay(); } function clicTl(evt) { @@ -694,11 +794,42 @@ addTweet(tweets[i]); } if (twCx.followLast) { - twCx.position = twCx.tweets.length - 1; + twCx.position = twCx.idIndex[twCx.tweets.length - 1]; } updateDisplay(); } +function focusOutRecherche() { + $("#recherche_annot").slideUp(); + var inpq = $("#inp_q"), + val = inpq.val(); + if (val == '' || val == twCx.filtreTexte) { + if (twCx.filtre) { + inpq.attr("class", "rechercheCourante").val(twCx.filtreTexte); + } else { + inpq.attr("class", "greyed").val("Rechercher"); + } + } +} + +function chaineTimeZoom() { + var chaine = "", + t = twCx.date_levels[twCx.timeLevel], + h = 3600*1000, + m = 60*1000, + s = 1000, + heures = Math.floor(t/h); + if (heures) { chaine += heures + ' h. ' }; + t -= (heures * h); + var minutes = Math.floor(t/m); + if (minutes) { chaine += minutes + ' min. ' }; + t -= (minutes * m); + if (t) { chaine += Math.floor(t/s) + ' sec.' } + $("#time_scale").html(chaine); + $("#time_zoomout").attr("class",(twCx.timeLevel == 0 ? "inactive" : "")); + $("#time_zoomin").attr("class",(twCx.timeLevel == twCx.date_levels.length - 1 ? "inactive" : "")); +} + $(document).ready(function() { tlPaper = Raphael("timeline", twCx.tlWidth, twCx.tlHeight); @@ -716,7 +847,7 @@ addTweet(data.new_tweets[i]); } if (twCx.followLast) { - twCx.position = twCx.tweets.length - 1; + twCx.position = twCx.idIndex[twCx.tweets.length - 1]; } updateDisplay(); }); @@ -724,6 +855,15 @@ $.getScript("tweetdata.js"); } + var html = ''; + for (var j in annotations) { + if (j != "default") { + html += '' + annotations[j].display_name + ' ' + } + } + $("#rech_list_annot").html(html); + + chaineTimeZoom(); $("#tweetlist").mousewheel(function(e, d) { wheelDelta += d; @@ -743,12 +883,27 @@ } if (tl != twCx.timeLevel) { twCx.timeLevel = tl; + chaineTimeZoom(); updateDisplay(); } wheelDelta = 0; } return false; }); + $("#time_zoomin").click(function() { + if (twCx.timeLevel < twCx.date_levels.length - 1) { + twCx.timeLevel++; + chaineTimeZoom(); + updateDisplay(); + } + }); + $("#time_zoomout").click(function() { + if (twCx.timeLevel > 0) { + twCx.timeLevel--; + chaineTimeZoom(); + updateDisplay(); + } + }); $("#timeline, #tweetlist").mouseout(function() { twCx.tlMouseClicked = false; twCx.tlMouseMoved = false; @@ -763,16 +918,50 @@ twCx.tlMouseMoved = false; var o = $(this).offset(); twCx.refMouse = { x : evt.pageX - o.left, y : evt.pageY - o.top }; - twCx.refPosTl = tlPosTweet(twCx.tweets[twCx.position]) || twCx.refMouse; + twCx.refPosTl = tlPosTweet(tweetById(twCx.position)) || twCx.refMouse; }); $("#timeline").mouseup(function(evt) { clicTl(evt); twCx.tlMouseClicked = false; twCx.tlMouseMoved = false; }); - $("#scrollcont").scroll(function(evt) { - var p = Math.floor( twCx.tweets.length * ( 1 - $(this).scrollTop() / 9548 ) ); - goToPos(p); + $("#inp_q").focus(function() { + $("#recherche_annot").slideDown(); + $(this).val($(this).val().replace(/ \(.+\)$/, '')) + if ($(this).hasClass("greyed")) { + $(this).val(""); + } + $(this).attr("class",""); + }); + $("#inp_q").focusout(function() { + focusOutRecherche(); + }); + $("#inp_reset").click(function() { + $("#inp_q").val(''); + if (twCx.filtre) { + twCx.filtre = null; + updateDisplay(); + } + twCx.filtreTexte = ''; + focusOutRecherche(); + return false; }) + $("#recherche").submit(function(evt) { + evt.preventDefault(); + if (!$("#inp_q").hasClass("greyed")) { + var valeur = $("#inp_q").val(); + filtrerTexte(valeur); + } + return false; + }); + + setInterval(function() { + var sc = $("#scrollcont"); + if (sc.scrollTop() != lastScrollPos && twCx.tweets) { + var p = Math.floor( twCx.currentIdIndex.length * ( 1 - sc.scrollTop() / scrollExtent ) ); + goToPos(p); + } + + }, 100) }); diff -r aa445cd7300e -r 1ec7b057a8bd tweetcast/nodejs-bis/client/js/underscore-min.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tweetcast/nodejs-bis/client/js/underscore-min.js Tue Nov 29 15:41:52 2011 +0100 @@ -0,0 +1,30 @@ +// Underscore.js 1.2.2 +// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore +(function(){function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(b.isFunction(a.isEqual))return a.isEqual(c);if(b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return String(a)==String(c);case "[object Number]":return a=+a,c=+c,a!=a?c!=c:a==0?1/a==1/c:a==c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== +c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&r(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(m.call(a,h)&&(f++,!(g=m.call(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c, +h)&&!f--)break;g=!f}}d.pop();return g}var s=this,F=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,G=k.unshift,l=p.toString,m=p.hasOwnProperty,v=k.forEach,w=k.map,x=k.reduce,y=k.reduceRight,z=k.filter,A=k.every,B=k.some,q=k.indexOf,C=k.lastIndexOf,p=Array.isArray,H=Object.keys,t=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&&define.amd? +define("underscore",function(){return b}):s._=b;b.VERSION="1.2.2";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(v&&a.forEach===v)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,f=a.length;e=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,c){var b=e(a,c);(d[b]||(d[b]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e< +f;){var g=e+f>>1;d(a[g])=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=H||function(a){if(a!== +Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)? +a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=l.call(arguments)=="[object Arguments]"?function(a){return l.call(a)=="[object Arguments]"}: +function(a){return!(!a||!m.call(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null}; +b.isUndefined=function(a){return a===void 0};b.noConflict=function(){s._=F;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),function(c){I(c,b[c]=a[c])})};var J=0;b.uniqueId=function(a){var b=J++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g, +interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g, +"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e(a,b)}};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var u=function(a,c){return c?b(a).chain():a},I=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);G.call(a,this._wrapped);return u(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){b.apply(this._wrapped, +arguments);return u(this._wrapped,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return u(b.apply(this._wrapped,arguments),this._chain)}});n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}}).call(this); diff -r aa445cd7300e -r 1ec7b057a8bd web/res/metadataplayer.polemic/src/js/polemic.js --- a/web/res/metadataplayer.polemic/src/js/polemic.js Tue Nov 29 15:41:15 2011 +0100 +++ b/web/res/metadataplayer.polemic/src/js/polemic.js Tue Nov 29 15:41:52 2011 +0100 @@ -524,7 +524,7 @@ } // DRAW UI :: resize border and bgd - heightOfChart = (yMax-(config.height-yMax)); + heightOfChart = (config.height-yMax); PaperBackground = paper.rect(0,yMax,config.width,heightOfChart).attr({fill:"#fff","stroke-width":0.1,opacity: 0.1}); PaperBorder = paper.rect(0,yMax,config.width,1).attr({fill:"#fff",stroke: "none",opacity: 1}); PaperSlider = paper.rect(0,20,1,heightOfChart).attr({fill:"#fc00ff",stroke: "none",opacity: 1});