meta data for this page
  •  

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

user:hevi:sun_lively_kernel_report [2011/09/02 12:04] (current)
Line 1: Line 1:
 +====== Delicious Tag Graph ======
 +[[#Code Camp]], Sun Lively Kernel Application\\
 +0035087 Petri Heinilä\\
 +2008-10-24 Lappeenranta\\
  
 +===== Application =====
 +Delicious Tag Graph allow user to visualize his bookmarks on http://​delicious.com . Delicious.com provides web based bookmarking service where bookmarks can be grouped and managed by tags. Tag is a simple name presenting some field. Bookmark can have multiple tags, so they can intersect each other field. With this information it is possible form relationships between tags. Delicious Tag Graph presents tags as graph nodes and relationships as edges. From edge user and then see a list of bookmarks involving to the relationship,​ and of course navigate along the bookmark link.
 +
 +[[#Sun Lively Kernel]] provides a way to dynamically modify browser side [[#SVG]] document object model (DOM), thus implementing very graphical oriented programming environment. Graph presentations benefit graphical implementation background the lively kernel is providing. ​
 +
 +{{ :​postgraduate:​hevi:​screenshot01.png }}
 +Delicious Tag Graph in Safari web browser
 +{{ :​postgraduate:​hevi:​screenshot02.png }}
 +Delicious Tag Graph in Firefox wen browser, reactivity was not so good than in safari.
 +
 +===== Design =====
 +Initial design consists of graph management objects. Classes are inherited from lively kernel graphical primitive classes. Morph is a graphical entity with shape and spatial space allocation. ClipMorph constrains sub-morph space allocation to given area. **TagGraph** manages the graph view. It contains the things and relationships between them. **Thing** presents the tag. Thing is able to be moved by the use so that relationships are following the movement. **Relationship** presents the edges in the graph. ​
 +{{ :​postgraduate:​hevi:​design01.png }}
 +
 +===== Implementation =====
 +Implementation status:
 +  * Presentation:​ Graph Creation and Management (done)
 +  * Communication:​ XMLHttpRequest to delicious.com (not done)
 +  * Logic: Bookmark information parsing and calculation (not done)
 +
 +On implementation the biggest problem was lack of reference manual. ​
 +The lively kernel source code work as primary functionality discovery
 +source, but it was very slow to find out relevant things out of it.
 +So time gone to find out functionality and no communication or logic
 +implementation were done.
 +
 +===== Running the application =====
 +  * Unzip delicious_tag_graph-<​REV>​-<​DATE>​.zip
 +  * Open delicious_tag_graph-<​REV>​-<​DATE>/​aa_test.xhtml with Safari web browser
 +
 +===== References =====
 +=== Code Camp ===
 +http://​opetus.it.lut.fi/​doku.php?​id=comlab:​ct30a9300:​start
 +=== SVG ===
 +http://​www.w3.org/​Graphics/​SVG/​
 +=== Sun Lively Kernel ===
 +http://​research.sun.com/​projects/​lively/​
 +
 +===== Code =====
 +<​code>​
 +/* Delicious Tag Graph
 +
 +Copyright (c) 2008 Petri Heinil�.
 +
 +Permission is hereby granted, free of charge, to any person
 +obtaining a copy of this software and associated documentation
 +files (the "​Software"​),​ to deal in the Software without
 +restriction,​ including without limitation the rights to use,
 +copy, modify, merge, publish, distribute, sublicense, and/or sell
 +copies of the Software, and to permit persons to whom the
 +Software is furnished to do so, subject to the following
 +conditions:
 +
 +The above copyright notice and this permission notice shall be
 +included in all copies or substantial portions of the Software.
 +
 +THE SOFTWARE IS PROVIDED "AS IS", IF THE SOFTWARE DRINKS YOUR BEER,
 +THEN IT IS WAY TOO BAD, WE COULD NOT CARE LESS.
 +*/
 +
 +/​****************************************************************************
 + * Create application with window.
 + */
 +var create_delicious_tag_graph = function() {
 +  var widget;
 +  var window; ​
 +  widget = new TestMorph(new Rectangle(20,​50,​500,​500));​
 +  window = new WindowMorph(widget,"​Delicious Tag Graph"​);​
 +  return window;
 +}
 +
 +/​****************************************************************************
 + * Thing
 + */
 +Morph.subclass("​Thing",​{
 +  initialize: function($super,​ctx,​rect,​text){
 + this.text = new TextMorph(new Rectangle(0,​0,​0,​0),​text);​
 +    this.text.beLabel();​
 + //​this.magic_thing = true;
 + this.relationships = [];
 + var nrect = new Rectangle(
 +   rect.x,​rect.y,​
 +   this.text.bounds().width,​
 + this.text.bounds().height
 + ); 
 +    $super(nrect,'​rect'​);​
 +    this.openForDragAndDrop = true;
 +    this.relayMouseEvents(this,​{ ​
 +   onMouseDown:​ "​thingMouseDown", ​
 + onMouseUp:​ "​thingMouseUp", ​
 + onMouseMove:​ "​thingMouseMove"​
 + });
 + this.addMorph(this.text);​
 + this.ctx = ctx;
 + return this;
 +  },
 + center: function() {
 + return this.bounds().center();​
 + },
 + thingMouseDown:​ function(evt) {
 + // console.log("​Thing.thingMouseDown " + evt);
 + return true;
 + },
 +  thingMouseUp:​ function(evt) {
 +    // console.log("​Thing.thingMouseUp"​);​
 + return true;
 +  },
 +  thingMouseMove:​ function(evt) {
 +    var cb = this.bounds();​ // current this morph bounds
 +    var cwp = this.owner.localize(evt.mousePoint);​
 +    var nb = new Rectangle(cwp.x,​ cwp.y,​cb.width,​cb.height);​
 +    this.setBounds(nb);​
 + this.update();​
 + return true;
 +  },
 + update: function() {
 + this.ctx.update();​
 + },
 +
 +}); // Thing
 +
 +/​****************************************************************************
 + * Relationship ​
 + */
 +Morph.subclass("​Relationship",​{
 + initialize:​ function($super,​ctx,​aThing,​bThing,​text) {
 + $super(pt(0,​0).asRectangle(),'​rect'​);​
 + this.ctx = ctx;
 + this.aThing = aThing;
 + this.bThing = bThing; ​
 +    this.applyStyle({
 + fill: null,
 + borderWidth:​ 1,
 + borderColor:​ Color.black,​
 + });
 + console.log("​LINE " + this.aThing.center() + " " + this.bThing.center());​
 + this.shape = new PolylineShape([this.aThing.center(),​this.bThing.center()],​
 + 1, Color.black);​
 +    this.morph = new Morph(pt(0,​0).asRectangle(),​ '​rect'​);​
 +    this.morph.applyStyle({
 +        fill: null,
 +        borderWidth:​ 1,
 +        borderColor:​ Color.black
 +    });
 +    this.morph.setShape(this.shape);​
 + this.update();​
 + },
 + update: function() {
 + // console.log("​Relationship.update"​);​
 + this.shape.setVertices([this.aThing.center(),​this.bThing.center()]);​
 + this.morph.changed();​
 +    this.morph.layoutChanged();​
 +    this.morph.setShape(this.shape);​
 + },
 + get_morph: function() {
 + return this.morph;
 + },
 +})
 +
 +/​****************************************************************************
 + * Tag Graph
 + */
 +ClipMorph.subclass("​TestMorph",​ {    ​
 + initialize:​ function($super,​ rect) {
 + $super(rect,​ "​rect"​);​
 + console.log("​TestMorph initialize"​); ​
 +    this.thing_num = 0;
 + this.relationship_num = 0;
 + this.things = [];
 + this.items = [];
 + this.relationships = [];
 + this.openForDragAndDrop = true;
 +    this.layout();​
 + //​this.setFill(Color.veryLightGray);​
 +    return this;
 +    },
 +
 +  update: function(evt) {
 +    var i;
 +    for(i = 0; i < this.relationships.length;​ i += 1) {
 +      var r = this.relationships[i];​
 +      r.update();
 +    }   
 +  },
 +
 +  create_Thing:​ function() {
 +    var name = "​thing-"​ + this.thing_num;​
 +    this.thing_num += 1;
 +    var cr = this.bounds();​
 +    var r = new Rectangle(0,​0,​100,​60);​
 +    r.x = (cr.width - r.width) / 2.0 + 
 +      Math.random() * (cr.width - r.width) - ((cr.width - r.width) / 2);
 +    r.y = (cr.height - r.height) / 2.0 + 
 +      Math.random() * (cr.height - r.height) - ((cr.width - r.width) / 2);
 +    var t = new Thing(this,​r,​name);​
 +    this.addMorph(t);​
 +    this.things.push(t);​
 +    this.items.push(t);​
 +    return t;
 +  },
 +  ​
 +  create_Relationship:​ function(aThing,​bThing) {
 +    var name = "​relationship-"​ + this.relationship_num;​
 +    this.relationship_num += 1;
 +    var r = new Relationship(this,​aThing,​bThing,​name);​
 +    r.update();
 +    // alert(r);
 +    this.addMorphBack(r.morph);​
 +    this.relationships.push(r);​
 +    this.items.push(r);​
 +    return r;
 +  },   
 +
 +
 + layout: function() {
 + this.test_layout3();​
 + },
 +
 + test_layout1:​ function() {
 +    var a = this.create_Thing();​
 +    var b = this.create_Thing();​
 +    var c = this.create_Thing();​
 +    var d = this.create_Thing();​
 +    var e = this.create_Thing();​
 +    var f = this.create_Thing();​
 +    this.create_Relationship(a,​b);​
 +    this.create_Relationship(a,​c);​
 +    this.create_Relationship(a,​d);​
 +    this.create_Relationship(a,​e);​
 +    this.create_Relationship(b,​c);​
 +    this.create_Relationship(c,​d);​
 +    this.create_Relationship(f,​d); ​   ​
 +    this.create_Relationship(f,​a); ​  
 + },
 +
 + test_layout2:​ function() {
 + var i;
 + for(i = 0;i < 50;i += 1) {
 +      var a = this.create_Thing();​
 + }
 + },
 +
 +  test_layout3:​ function() {
 +    var i;
 + var j;
 +    for(i = 0;i < 7;i += 1) {
 +      var a = this.create_Thing(); ​   ​
 +    }   
 + for(i=0;i < this.things.length;​i+=1) {
 + var it = this.things[i];​
 +      for(j=0;j < this.things.length;​j+=1) {
 +        var jt = this.things[j];​
 +        var r = this.create_Relationship(it,​jt); ​    
 +      };
 + };
 +  },
 +
 +}); // TestMorph
 +</​code>​