HyperTree – Converting JIT Examples to JQuery

2 Comments

Recently, while working on the Kiobo project with Lynn we stumbled across the JIT (JavaScript Information Visualization Toolkit) library. It is an amazing toolkit that has helped us see the future of JavaScript visualizations, which has previously been an area where only Flash/ActionScript has had the power to display highly animated and appealing client side visualization of data. On the current Kiobo site, you can see it is almost entirely written in Flash/ActionScript, but the future leads us in another direction.

The JIT is quite easy to integrate into your own site. Simply taking the examples and filling in your own JSON object with data can make quite an impression on people visiting your project. One issue that I ran into during implementation was that all the examples were written with the MooTools framework in mind. MooTools is a great framework, but Kiobo was already using the JQuery library for our JavaScript needs. I took on the task of converting the examples into JQuery to use them with Kiobo.

To implement JQuery with Kiobo I used the JRails plugin to replace all the Prototype methods. What follows won’t be a recreation of the entire tutorial, only the situations where you will need to change things.

First, rather than calling the MooTools library, we’ll call the JQuery library (and while we’re at it we’ll convert all the standard HTML to Rails).

So in the example you have this code:

<html>
<head>
<link type="text/css" rel="stylesheet" href="/static/css/example-hypertree.css" />

<!--[if IE]>
<script type="text/javascript" src="/static/js/excanvas.js"></script>
<![endif]-->
<script type="text/javascript" src="/static/js/mootools-1.2.js" ></script>
<script type="text/javascript" src="/static/js/hypertree/Hypertree.js" ></script>
<script type="text/javascript" src="/static/js/example/example-hypertree.js" ></script>

</head>
<body onload="init();">
<div id="infovis"></div>
</body>
</html>

Once you have converted everything and called your JQuery library it should look like this:

<html>
<head>

<!--[if IE]>
<%= javascript_include_tag 'excanvas' %>
<![endif]-->

<%= javascript_include_tag :defaults %>
<%= javascript_include_tag 'example/example-hypertree' %>
<%= javascript_include_tag 'Hypertree' %>
<%= stylesheet_link_tag 'example-hypertree' %>
</head>
<body onload="init();">
<div id="infovis"></div>
</body>
</html>

This will load the JQuery Library, as well as the Hypertree library, the example-hypertree library and the stylesheet example-hypertree.

At this point you will be able to continue the tutorial and see your first HyperTree. However, when you get to adding labels things once again diverge.

The example uses this code:

function init() {
var json = //json data mentioned above...
//Create a new canvas instance.
var canvas = new Canvas('mycanvas', {
//Where to inject the canvas. Any HTML container will do.
'injectInto':'infovis',
//Width and height of canvas, default's to 200.
'width': 900,
'height':500,
//Canvas styles.
'styles': {
'fillStyle': '#ddd',
'strokeStyle': '#dd00bb'
}
});
var ht= new Hypertree(canvas, {

onCreateLabel: function(domElement, node) {
$(domElement).set('html', node.name + " and text");
}

});

ht.loadTreeFromJSON(json);
ht.compute();
ht.plot();
}

This will not work the same with JQuery as it has some MooTools specific calls, particularly:
$(domElement).set(‘html’, node.name + ” and text”)
However this is an easy fix with JQuery
$(domElement).html(node.name + ” and text”)
So your entire file should look like

function init() {
var json = //json data mentioned above...
//Create a new canvas instance.
var canvas = new Canvas('mycanvas', {
//Where to inject the canvas. Any HTML container will do.
'injectInto':'infovis',
//Width and height of canvas, default's to 200.
'width': 900,
'height':500,
//Canvas styles.
'styles': {
'fillStyle': '#ddd',
'strokeStyle': '#dd00bb'
}
});
var ht= new Hypertree(canvas, {

onCreateLabel: function(domElement, node) {
$(domElement).html(node.name + " and text");
}

});

ht.loadTreeFromJSON(json);
ht.compute();
ht.plot();
}

When placing the labels you will also need to change the code a bit. I couldn’t find a similar method inside the JQuery core for the .toInt() method so we’ll fall back to parseInt.

function init() {
var json = //json data...
//Create a new canvas instance.
var canvas = new Canvas('mycanvas', {
//Where to inject the canvas. Any HTML container will do.
'injectInto':'infovis',
//Width and height of canvas, default's to 200.
'width': 900,
'height':500,
//Canvas styles.
'styles': {
'fillStyle': '#ddd',
'strokeStyle': '#dd00bb'
}
});
var ht= new Hypertree(canvas, {
onCreateLabel: function(domElement, node) {
$(domElement).html(node.name + " and text");
},

//Take the left style property and
// substract half of the label actual width.
onPlaceLabel: function(tag, node) {
var width = tag.offsetWidth;
var intX = tag.style.left.toInt();
intX -= width/2;
tag.style.left = intX + 'px';
}

});

ht.loadTreeFromJSON(json);
ht.compute();
ht.plot();
}

Use this example instead:

function init() {
var json = //json data...
//Create a new canvas instance.
var canvas = new Canvas('mycanvas', {
//Where to inject the canvas. Any HTML container will do.
'injectInto':'infovis',
//Width and height of canvas, default's to 200.
'width': 900,
'height':500,
//Canvas styles.
'styles': {
'fillStyle': '#ddd',
'strokeStyle': '#dd00bb'
}
});
var ht= new Hypertree(canvas, {
onCreateLabel: function(domElement, node) {
$(domElement).html(node.name + " and text");
},

//Take the left style property and
// substract half of the label actual width.
onPlaceLabel: function(tag, node) {
var width = tag.offsetWidth;
var intX = parseInt(tag.style.left);
intX = intX-(width/2);
tag.style.left = intX + 'px';
},

});

ht.loadTreeFromJSON(json);
ht.compute();
ht.plot();
}

Finally, adding events to the HyperTree. This is actually completely different than the MooTools example
.addEvents({‘click’: function(e) {ht.onClick(node.id)}});
It will instead be replaced with click method
.click( function () {ht.onClick(node.id)} );

So your final code should look like this:

function init() {
var json = //some json data
//Create a new canvas instance.
var canvas = new Canvas('mycanvas', {
//Where to inject the canvas. Any HTML container will do.
'injectInto':'infovis',
//Width and height of canvas, default's to 200.
'width': 900,
'height':500,
//Canvas styles.
'styles': {
'fillStyle': '#ddd',
'strokeStyle': '#dd00bb'
}
});
var ht= new Hypertree(canvas, {
onCreateLabel: function(domElement, node) {
$(domElement).set('html', node.name + " and text").addEvents({
//Call the "onclick" method from
//the hypertree to move the hypertree
//correspondingly.
//This method takes the clicked node's id.
'click': function(e) {
ht.onClick(node.id);
}
});

},

//Take the left style property and
//substract half of the label actual width.
onPlaceLabel: function(tag, node) {
var width = tag.offsetWidth;
var intX = tag.style.left.toInt();
intX -= width/2;
tag.style.left = intX + 'px';
}

});

ht.loadTreeFromJSON(json);
ht.compute();
ht.plot();
}

Your code:

function init() {
var json = //some json data
//Create a new canvas instance.
var canvas = new Canvas('mycanvas', {
//Where to inject the canvas. Any HTML container will do.
'injectInto':'infovis',
//Width and height of canvas, default's to 200.
'width': 900,
'height':500,
//Canvas styles.
'styles': {
'fillStyle': '#ddd',
'strokeStyle': '#dd00bb'
}
});
var ht= new Hypertree(canvas, {
onCreateLabel: function(domElement, node) {
$(domElement).html(node.name + " and text").click( function () {ht.onClick(node.id)} );
},

//Take the left style property and
//substract half of the label actual width.
onPlaceLabel: function(tag, node) {
var width = tag.offsetWidth;
var intX = tag.style.left.toInt();
intX -= width/2;
tag.style.left = intX + 'px';
}
});

ht.loadTreeFromJSON(json);
ht.compute();
ht.plot();
}

The Whuffie Project

2 Comments

The latest Powered by Geek project isn’t a web application. It is a look into the process of turning a knowledgeable developer with no social footprint into a well connected social dynamo.  The first developer enjoying the luxury of this transformation is me, Dan Ahern.

This project is called http://thewhuffieproject.com and it is architected and executed by a group of the PBG team : Michael, Lynn, and myself.

If you are not familiar with the term Whuffie, don’t be ashamed, I
wasn’t either. In Cory Doctorow’s book Down and Out in the Magic Kingdom, he defines Whuffie as social capital, or reputation.  The Whuffie Project’s goal is to help me build up my reputation to the point at which the people who matter in my world know who I am as much as I know who they are.

I’ve been chosen for our maiden voyage for a few reasons :

1. I am engrossed in the social media landscape.  I specialize in digesting content from social media sites and processing it new and useful ways.
2. I want this.  I want to be more involved with the community that I love.  I want to be recognized for the work I’m doing in the community, and I want to be involved in the direction of the web.  I have talent, I have good ideas, and I believe that I can make the
world a better place through my work with social media.
3. I take direction well.  I have a sincere willingness to do whatever Michael, Lynn or the Internet at large have in mind to build social capital.

We recently did a preliminary interview between Lynn and myself regarding our expectations for The Whuffie Project, and discussed paths that I may follow in the beginning to achieve my goal.

Our first step is to introduce Dan Ahern to the web, officially.

I have been a Ruby on Rails developer for 3 years. I originally began my programming career working on a compiled (c++) cgi binary at the company where I met Lynn Wallenstein.  I had a natural affinity for procedural thought and problem solving, and in the years following I experimented with other programming languages like PHP and Python.  These are powerful languages, but they lacked the elegance and ease of use that I was searching for.  After a long conversation with Lynn, we decided on a new landscape: Ruby on Rails.  Since falling in love with the language, and falling back in love with programming, I’ve tamed Ruby to build social media sites LongTimeLost, iStalkr, Playericious and Kiobo.  I have contracted for major firms in the Ruby community like FiveRuns, and I’ve been involved in cutting edge work with social media APIs and other creative web services.