Background: I'm a JS/NodeJS newb working through "NodeJS in 24 Hours". I'm at Hour 14 which is a real-time Twitter feed using socket.io. I decided to augment the exercise by using Express 3 and rickshaw for a real-time plot of # of tweets that include "Breaking Bad" versus "Game of Thrones". (code is below)
Question(s):
a) Even though the book example uses Express, it doesn't actually use Express to generate the Express directory structure. I'm assuming then that Express is just a library and that the project creation aspect eg $ express twitter_feed is not mandatory. Correct?
b) The reason I ask a) is, in my app.js file, I had to use app.use(express.static( __dirname + '/node_modules')); to configure express.static middleware so index.html could access the rickshaw scripts. Notice that I actually referred to the node_modules directory because I didn't have a /public or /static directory. Since rickshaw was installed as a dependency, why wasn't the rickshaw directory already visible?
c) Are there any good docs for rickshaw?
package.json
{
"name":"socket.io-twitter-example",
"version": "0.0.1",
"private": "true",
"dependencies": {
"express": ">=2.5.4",
"ntwitter": ">=0.2.10",
"socket.io": ">=0.8.7",
"rickshaw": ">=1.1.0"
}
}
index.html
<!DOCTYPE html>
<html lang="eng">
<head>
<meta charset="UTF-8" />
<title>Socket.IO Twitter Example</title>
</head>
<body>
<h1>Socket.IO Twitter Example</h1>
<ul class="percentage">
<li class = "love"></li>
<li class = "hate"></li>
</ul>
<style>
#chart_container {
position: relative;
font-family: Arial, Helvetica, sans-serif;
}
#chart {
position: relative;
left: 40px;
}
#y_axis {
position: absolute;
top: 0;
bottom: 0;
width: 40px;
}
#legend {
display: inline-block;
vertical-align: top;
margin: 0 0 0 10px;
}
</style>
<div id="chart_container">
<div id="y_axis"></div>
<div id="chart"></div>
</div>
<div id ="legend"></div>
<ul class="tweets"></ul>
<link type="text/css" rel="stylesheet" href="/rickshaw/rickshaw.min.css">
<script src="rickshaw/vendor/d3.min.js"></script>
<script type="text/javascript" src="/rickshaw/vendor/d3.v2.js"></script>
<script type="text/javascript" src="/rickshaw/rickshaw.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
// graph instantiation starts here
// instantiate the graph, y-axis, legend
var tv = 100;
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 500,
height: 250,
renderer: 'line',
series: new Rickshaw.Series.FixedDuration([{ name: 'Breaking Bad' }], undefined, {
timeInterval: tv,
maxDataPoints: 100,
timeBase: new Date().getTime() / 1000
})
} );
var y_axis = new Rickshaw.Graph.Axis.Y( {
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis'),
} );
var legend = new Rickshaw.Graph.Legend( {
element: document.querySelector('#legend'),
graph: graph
} );
graph.render();
// graphing instatiation ends here
var socket = io.connect();
jQuery(function ($) {
var tweetList = $('ul.tweets'),
loveCounter = $('li.love'),
hateCounter = $('li.hate');
socket.on('tweet', function (data) {
tweetList
.prepend('<li>' + data.user + ': ' + data.text + '</li>');
loveCounter
.text('B Bad: ' + data.love + '%');
hateCounter
.text('G o T: ' + data.hate + '%');
// graph update script starts here
var gdata = {
one : data.love,
two : data.hate
};
graph.series.addData(gdata);
graph.update();
// graph update script stops here
});
});
</script>
</body>
</html>
app.js
var express = require('express'),
app = express(),
twitter = require('ntwitter'),
socket = require('socket.IO'),
http = require('http'),
server = http.createServer(app),
io = socket.listen(server),
love = 0,
hate = 0;
total = 0;
server.listen(3000);
app.use(express.static( __dirname + '/node_modules'));
var twit = new twitter({
consumer_key: 'xxx',
consumer_secret: 'xxx',
access_token_key: 'xxx',
access_token_secret: 'xxx'
});
twit.stream('statuses/filter', { track: ['breaking bad', 'thrones'] }, function(stream){
stream.on('data', function (data) {
io.set('log level', 0); //stops debug messages completely?
var text = data.text.toLowerCase();
if (text.indexOf('breaking bad') !== -1) {
love++;
total++;
}
if (text.indexOf('game of thrones') !== -1) {
hate++;
total++;
}
io.sockets.volatile.emit('tweet', {
user: data.user.screen_name,
text: data.text,
love: Math.round((love/total)*100),
hate: Math.round((hate/total)*100)
});
//console.log(data.user.screen_name + ': ' + data.text );
});
});