function addEvent(obj, type, fn) {
    if (obj.addEventListener) obj.addEventListener(type, fn, false);
    else obj.attachEvent('on' + type, fn);
}

function initSpaceTree(project, json){
    var infovis = document.getElementById('infovis');
    var w = infovis.offsetWidth, h = infovis.offsetHeight;

    //init canvas
    //Create a new canvas instance.
    var canvas = new Canvas('mycanvas', {
        //Where to append the canvas widget
        'injectInto': 'infovis',
        'width': w,
        'height': h,
    
        //Optional: create a background canvas and plot
        //concentric circles in it.
        'backgroundCanvas': {
            'styles': {
                'strokeStyle': '#555'
            },
        
            'impl': {
                'init': function(){},
                'plot': function(canvas, ctx){
                    var times = 6, d = 100;
                    var pi2 = Math.PI * 2;
                    for (var i = 1; i <= times; i++) {
                        ctx.beginPath();
                        ctx.arc(0, 0, i * d, 0, pi2, true);
                        ctx.stroke();
                        ctx.closePath();
                    }
                }
            }
        }
    });
    //end

    var rgraph = new RGraph(canvas, {
        //Set Node and Edge colors.
        Node: {
            color: '#ccddee'
        },
        
        Edge: {
            color: '#772277'
        },
        
        transition: Trans.Elastic.easeOut,
        duration: 1050,
        
        onBeforeCompute: function(node) {
          function pathify(str) { return str.replace('::', '/'); }
          function capitalize(str) { 
            return str.replace(/^(.)/, function(a) { 
              return a.charAt(0).toUpperCase(); 
            }); 
          }
          
          var url = "http://yardoc.org/docs/" + project + "/" + escape(pathify(node.id));
          var html = "<h4>" + node.data.type.small() + "<br/>" + node.id + "</h4>";
          html += ("View " + node.data.type + " docs").link(url).small().italics();
          for (var type in {'class':0, 'instance':1}) {
            if (node.data[type + '_methods'].length > 0) {
              html += "<h5>" + capitalize(type) + " Methods</h5><ul>"
              for (var idx in node.data[type + '_methods']) {
                var meth = node.data[type + '_methods'][idx];
                var path = pathify(node.id) + (type == 'instance' ? ':' : '.') + escape(meth);
                var url = "http://yardoc.org/docs/" + project + "/" + path;
                html += "<li>" + meth.link(url) + "</li>";
              }
              html += "</ul>"
            }
          }
          document.getElementById('data').innerHTML = html;
        },
        //Add the name of the node in the correponding label
        //and a click handler to move the graph.
        //This method is called once, on label creation.
        onCreateLabel: function(domElement, node){
            domElement.innerHTML = node.name;
            domElement.onclick = function(){
                rgraph.onClick(node.id);
            };
        },
        //Change some label dom properties.
        //This method is called each time a label is plotted.
        onPlaceLabel: function(domElement, node){
            var style = domElement.style;
            style.display = '';
            style.cursor = 'pointer';

            if (node._depth <= 1) {
                style.fontSize = "0.8em";
                style.color = "#ddd";
            
            } else if(node._depth == 2){
                style.fontSize = "0.7em";
                style.color = "#777";
            
            } else {
                style.display = 'none';
            }

            var left = parseInt(style.left);
            var w = domElement.offsetWidth;
            style.left = (left - w / 2) + 'px';
        }
    });
    
    //load JSON data
    rgraph.loadJSON(json);
    //compute positions and make the first plot
    rgraph.refresh();
    //end
}
