Visualizing our running progress

You’ve found a dinosaur, this post is only here for archiving purposes. The content is outdated and is not applicable anymore.

While I was running a couple of weeks back I was thinking about Nike’s new slogan for it’s Nike+ campaign. “Make it count!” it says, but for what? So I hacked up a little website that fetches all tweets send by the Nike+ app and bundles all our runs together per hour.

Make it count! is the result. It holds a realtime visualisation which displays all runs reported by Twitter as circles. Big circles are big runs, etc.. You can also see the top hour of today (since midnight GMT). Every hour get’s a score and our goal is to top that score every hour!

The site is built almost entirely in javascript, node.js catches all tweets and sends them over realtime by using web sockets (socket.io). You can read more about that in my previous blogpost.

The site does need some improvement in the design, I’ve already talked to some people about helping me out here. So stay tuned for even more awesomeness!

Storing tweets using nodejs

Since I have my own VPS I’m constantly trying out new stuff. After messing around with nodejs I have my own little script (just over 100 lines) that connects to Twitter using their streaming API, get’s all tweets that contain certain words, do a minimal amount of parsing and store it all in a SQL database.

Nodejs does not contain a lot of stuff out of the box which I need, the power lies in the huge amount of ‘modules’ (extenstions) for node. They even got their own package manager! In this example I use the modules node-mysql, ntwitter and forever.

Installing all those couldn’t be easier:

npm install mysql ntwitter forever

In my script I fetch all tweets by people who use nikeplus (app) to keep track of their running results. By storing all those tweets I can later create something cool with all the data. I use the streaming API to keep a connection open, to do this you need to register your own app at dev.twitter.com to get the required keys.

Setup:

var sys = require('util');

/* setup mysql connection */
var Client = require('mysql').Client;
var client = new Client();
client.user = 'sql username';
client.password = 'sql password';
console.log('Connected to MySQL');

Now we have a we have twit object for opening a Twitter stream and a client object for talking to our SQL server.

more

Getting started with Processing.js

Lately I’ve been reading a book about data visualization. The book goes into the thought process of visualizing data for humans and also talks a lot about visual coding. All code in the book is Processing code, an extremely easy and fast way to visualize.

Last night I started playing with the code and I’m amazed at how clean the code is. With Processing you only need to write stuff the gets on the screen in an elegant and clean way. I can imagine that if you want to take your animations to the next level (interaction wise) things would get a little difficult.

For example I haven’t crossed any type of event system yet. So you want to get the X position of the mouse? It’s stored in mouseX. This makes it extremely easy to use it but on the other hand it’s limited to the global vars Processing offers.

Here is the result of my playing last night (you should hover).

and here is the code.

// the arraylist that holds all the atoms
ArrayList atoms = new ArrayList();

// this function only runs on init
void setup() {
    size(584,500);
    frameRate(30);
    noStroke();

// create 250 atoms
for(int i = 0; i < 250; i++) {
    atoms.add(new Atom());  
}

}

// this function runs every frame
void draw() {
    background(100);

// loop through all atoms and update() and draw() them
for(int i = 0; i < atoms.size(); i++) {
    Atom a = (Atom)atoms.get(i);
    a.update();
    a.draw();
}

}

class Atom {
    // position
    int x, y, xV, yV;
    // filling
    int r, g, b, a;
    // size
    int size, xDiff, yDiff, diff, treshold;

// constructor of the class
Atom() {
    // create a random color
    r = random(50);
    g = random(255);
    b = random(255);

    x = random(width);
    y = random(height);

    // maximum distance from atom 
    // to mouse before bubbling
    treshold = width / 4;

    xV = random(-2, 2);
    yV = random(-2, 2);
}

// this function calcs
// and sets: x, y, a, size
void update() {

    x += xV;
    y += yV;

    // take care of borders right & bottom  
    x %= width;
    y %= height;

    // take care of borders left & top
    if(x < 0) {
        x += width;
    }
    if(y < 0) {
        y += height;
    }

    // determinse X and Y 
    // distance to mouse
    xDiff = mouseX - x;
    yDiff = mouseY - y;

    // if it's close enough
    if(
        xDiff < treshold && 
        xDiff > -treshold && 
        yDiff < treshold && 
        yDiff > -treshold
        ) {

        // determine distance to mouse
        // a2 + b2 = c2
        int diff = sqrt(sq(xDiff) + sq(yDiff));

        // make smaller diff always bigger
        if(diff < 0) {
            diff *= -1;
        }

        // make the size bigger
        size = treshold - diff + 20;
        if(size < 20) {
            size = 20;
        }

        // set alpha
        a = size * 1.5;

        if(a < 50) {
            a = 50;
        }

    } else {
        // it's not close enough
        size = 20;
        a = 50;
    }

}

void draw() {
    fill(r, g, b, a);
    ellipse(x, y, size, size);
}

You might notice some things being just simpler compared to languages like ActionScript (flash). For example:

  • Random is a much simpler

    random(40); VS Math.random() * 40;
    or random(-40, 40); VS Math.random() * 40 - 40;

  • drawing is much simpler

    If you want an ellipse you just call ellipse(), no need to add it to a display manager. You also just draw stuff in the order you want it, instead of needing to keep track of what items are drawn when.

  • Properties are just vars

if(y < 0) {
  y += height;
}

VS

if(this.y < 0) {
 // only accessible from certain places
 this.y += stage.stageHeight;
}

Ring a bell when someone visits your website

I love the new realtime Google Analytics. I love the fact how you can see what people are doing on your website right now. However I can’t stare at the interface all day, so why not play a little sound every time someone visits your website?

Note that this idea was inspired by bellbot, a website with the same functionality. My solution requires no signup or client side code (besides Google Aanalytics) though.

This is a little bookmarklet that you can run on your realtime Google Analytics page that plays a bell everytime a new visitor enters your website. The video below shows how it works.

It is now even easier to ring a bell, here are the updated steps to Ring a bell!

  1. Add Ring a bell! as bookmark to your browser.

  2. Get Google Analytics and make sure you have access to the realtime data.

  3. Navigate to the Realtime overview: Home – Realtime – Overview

  4. Click on the Ring a bell! bookmarklet.

For those curious, here is the javascript function.

(function( d, c ){
   var beep = new Audio( 'https://mikevanrossum.nl/stuff/doorbell.mp3' )
     , check = function( old ) {
      var visitors = parseInt( d.getElementById( 'ID-overviewCounterValue' ).innerHTML );
      // c.log('visitors: ' + visitors);
      // only try the second time and up
      if( old || old === 0 ) {
         //the difference between the old number and the new number
         var dif = visitors -- old;
         // if the new number is higher, we have new visitors
         if( dif > 0 ) {
            // play a sound & log for each visitor
            while( dif-- ) {
               c.log( 'Ding! New visitor!' );
               setTimeout( function() { beep.play(); }, 500 * i );
            }
         }
      }
      setTimeout( function() { check( visitors ); }, 2000 );
   }
   check();
}( document, console ));