30 Jun 09

Animated Ajax Pageview Ticker

In my infinite quest to make everything better I found myself quite frustrated with the use of “plaintext” to display the number of pageviews on a MindTouch page .  Plaintext was clearly way too simple and I saw an opportunity to make it way more complex, quite possibly even confusing.

Using plain numbers is boring, they don’t move, shake, glide or slide.  Plaintext is not flashy enough and it doesn’t update.   If another ten billion people visit the page you’ll never know it’s true popularity, at least not until you refresh (so 90’s).  I know, all very pointless points but this is what I have to tell myself to justify such an endeavour.

counter_ticker_bg

To combat my frustration I decided to build an automated number ticker that updates using ajax to display the REAL-TIME pageviews of a MindTouch page.  The ajax utilizes the MindTouch API to retrieve the latest pageview data.  I used CSS to make the nice numbers which referenced this image.

The Number Ticker currently hits the API every 10 seconds.  This can be reduced to savor server resources and should be a major consideration when deciding to use this script or not.

Lastly, I consolidated it all into one MindTouch template so it can be included into multiple pages.  To create this template:

  1. copy the code below
  2. go to your template namespace (yourwiki.com/template:)
  3. create a new page
  4. view source
  5. paste and save.

Template Code

<h1>Template:AjaxCounterTicker</h1>
<input type="hidden" id="pgapi" value="{{page.api}}">
<div class="counter-wrap">
    <div class="counter-number">
        &nbsp;
    </div>
</div>
<div>
<style>
.counter-wrap {
    height:18px;
    overflow:hidden;
}
.counter-number {
    height:198px;
    width:12px;
    position:relative;
    background-image:url(http://developer.mindtouch.com/@api/deki/files/4548/=counter_ticker_bg.gif);
    float:left;
}
</style>
</div>
<script type="text/javascript">
Deki.$("body").ready( function() {
    getviewcount();
    setInterval("getviewcount()", 10000);
});
function getviewcount() {
    var pgapi = Deki.$("#pgapi").val();
    Deki.$.ajax({
        type: "GET",
        url: pgapi,
        async: false,
        dataType: "xml",
        success: function(xml) {
            var pgviewnum = Deki.$(xml).find("metric\\.views").text();
            loadticker(add_commas(pgviewnum));
        }
    });
}
Deki.$(".counter-number").each( function(i) {
    Deki.$(this).attr('id','num'+i);
});
function loadinput() {
    var newval = Deki.$("#numgo").val();
    loadticker(newval);
}
function loadticker(ticnum) {
    var numheight=18;
    addticker(ticnum);
    if (ticnum && ticnum != 0) {
        var s = String(ticnum);
        for (i=s.length;i>=0; i--)
        {
            var onum=s.charAt(i);
            Deki.$("#num"+i).attr('value',onum);
        }
        Deki.$(".counter-number").each( function() {
            var nval=Deki.$(this).attr("value");
            if (!isNaN(nval)) {
                var nheight = Number(nval)*numheight*-1;
                Deki.$(this).animate({ top: nheight+'px'}, 1500 );
            }
            if (nval==','){
                Deki.$(this).animate({ top: '-180px'}, 1500 );
            }
          });
    }
}
function addticker(newnum) {
    var digitcnt = Deki.$(".counter-number").size();
    var nnum = String(newnum).length;
    var digitdiff = Number(nnum - Number(digitcnt));
    if (digitdiff <0) {
        var ltdig = (Number(nnum)-1);
        Deki.$(".counter-number:gt(" + ltdig + ")").remove();
    }
    for(i=1;i<=digitdiff;i++) {
        Deki.$(".counter-wrap").append('<div class="counter-number" id="num' + (Number(digitcnt+i-1)) + '">&nbsp;</div>');
    }
}
function add_commas(nStr) {
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}
</script>

How to call the Template

{{AjaxCounterTicker();}}

If you have questions please post them as comments and I’ll be sure to respond.  Thank you for your time.

Damien Howley
@DamienH

6 Responses to “Animated Ajax Pageview Ticker”

  1. blakeh responds:

    Looks awesome! And it seems easy enough to add a parameter to that template to look at other pages’ # of views.
    For instance:

    instead of:

    would make:
    {{ AjaxCounterTicker(Wiki.GetPage(”/Dekiscript”).api); }}
    display pageviews on the /Dekiscript page.

  2. blakeh responds:

    Uh oh. Looks like html got the better of my comment. Look at http://developer.mindtouch.com/User:BlakeH/Templates/PageView

  3. bohappa responds:

    Very nice. Doesn’t appear to work. I see for columns of numbers 0-9. I suspect the overflow isn’t hidden. the numbers line up to indicate a page view that is probably right. I am using 9.0.2 commercial on Windows 2003.
    Any suggestions? Pretty cool widget I’d like to use.
    My view:
    0
    1
    2 1
    312
    423
    534
    645
    756
    867
    978
    ,89
    9,
    ,

  4. Bobby responds:

    Hi and many thanks for posting this sample. It seems that you’re using a library called Deki. Do you happen to have a sample code with just Jquery and CSS? I’m not sure if that’s possible to animate or what Deki’s role is but just wondering…

    Thanks in advance!

  5. Damien responds:

    Bohappa, what browser are you using? It very well may be an issue with overflow although I can confidently say I saw it working on IE6, IE7, Chrome and FF3.

    Damien

  6. Damien responds:

    Bobby, Deki is simply a jQuery alias that is used while developing on the MindTouch platform. Simply just replace the Deki.$ with $ and your jQuery will work just fine.

    Damien

Leave a Reply