$(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();
});
});
});