Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Thursday, 10 October 2013

Capture the moment...

Hey there,

So I have been working on this feature for PINV were you can share the exact configuration that you got while visualizing your interactions. This share URL can be by getting a url or by embedding PINV into your web site or blog. This makes me think in this blog, which I kind of unintentionally abandoned, so why not to write a post about the new feature demonstrating it on my blog and try to get me into the habit of writing again as a bonus.

Besides the capability of sharing a status, I have also worked in several other features, like resizing the nodes, linking to other services in the web, including legends for colors and sizes, what I'm saying is that there are a lot of new features there for you to explore, please play with the app and let me know any bugs, suggestions and comments on the forum: https://groups.google.com/group/pinv_biosual

So back to been able to include your visualization into your web, it is pretty easy and looks cool, just check it out here:

The idea behind this new feature is to allow to share and to collaborate in a simple way. Researchers can now explore their data using PINV and when they found something interesting, they can click into the share icon, copy the unique URL and send it to a collaborator who with this link can now open PINV and display all the features that the first researcher had used (e.g. queries, colors, zooming, re-location of nodes, etc.). For example you can go and check in PINV the configuration above by following this LINK.

The second scenario of the sharing feature is to included in your website and as you saw above is not only about the URL, but to include the whole PINV in the middle of your page, and yeah I know, there is nothing incredible new on it, I'm just following the same idea of things like google maps, you tube, prezi, etc. and actually following it a bit too close... the strategy of all of them, including PINV is to give the user a piece of HTML code that represents an iframe to include a compact version of the web content.
An iframe in HTML is an element to create a frame in your page where all its content is coming from a separate web page, it doesn't have to be in the same server, and therefore makes life easier at the moment of including a complete web application in the middle of another web page.
For instance, the youtube compact version doesn't include the side suggestions or the comments, it is limited to the video; and then when is included as an iframe in other page it looks like the video is part of the page.
Likewise PINV compact version only displays the graphic (network or circle layout) and hides any headers and side tools. Nonetheless those tools are still active, they have just been hidden, and if the link included in the iframe use any of this tools to get the final display it does it. For example, if the person sharing the visualization have used a rule to resize the nodes depending on a feature(e.g. closeness) this rule is executed on the iframe graphic, even when the panel of rules is not visible.

If you want to try it by yourself I'd suggest to go through this tutorial I made a month ago to get familiar with some other features in PINV. Once you get the final view, you can press on the share button, and get the link, I just did it and the link I got is this one: http://biosual.cbio.uct.ac.za/pinViewer.html?status=021f90c1e054674498cf87ecb9fb48b8.json, hopefully this result page looks similar to the one you created.

But if what you want is to included in your blog you can copy the HTML to Embed textfield content that should look similar to:
<iframe width="800" height="600" src="http://biosual.cbio.uct.ac.za/pinViewer.html?status=021f90c1e054674498cf87ecb9fb48b8.json&embedded=true" frameborder="0" allowfullscreen></iframe>

In blogger you can go to the HTML view and paste that, and that's it, your view is included in your blog, like here:
I'm going to avoid any technicalities right now, that's maybe material for another blog post.

As usual I'm looking forward to your comments, suggestions or bug reports, is the only way I really have to know if I'm on the right track.

Cheers!!

Monday, 28 January 2013

Biosual Viewer. First prototype.

Hello there!

So here is the first post of actual work of the year, although most of it was done last year. So, the last time I post here the status of the protein-protein interaction viewer looked like this: http://biosual.cbio.uct.ac.za/interactions/, and my efforts since november have been focused in making it look like this: http://biosual.cbio.uct.ac.za/biosual/tests/pinv/pinv.html Notice the difference?
No, I am not talking about the logo and new name. So try again, check both pages and see the difference! If you didn't notice a change its because I did my job well, in case you notice let me know and I will try to correct that.

Warning: I am going to start being quite technical so if you are not into web development you might get lost. Badly lost!

The thing is what i did was to change the way Ajax-Solr (the library I'm using to get the data) includes its widgets so they can be loaded from a config file, I also make sure all those widgets are now completely agnostic of the other widgets, and I also create some PHP scripting in order to generate a single javascript that contains all the Ajax-Solr files, all the widgets and its dependencies, so pretty much I change hell of a lot in the background with the goal of having a single config file indicating which visual components should be included in the page. It is still in a work on progress stage, but the fact that I'm getting something as close to the application with the original version of AjaxSolr, makes me thing I'm in a good path!

You may be asking why to change so many things if at the end it is going to look almost the same. Well that has to be with the big picture of my project. The viewer has to be dynamic enough to display different setups that users can configure, so what im doing here is been able to create a runnable javascript that include all the required code to show the different graphic components by just passing few parameters.

The key is the configuration file, which is saved in the installation of biosual, then retrieved identifying it by its id. this separation allows me to in future develop a tool to create that configuration file. I'm sure there are lots of requirements i have to go through to get that authoring tool, however the process of this development help me to identify lots of them.

So lets explain some details of this whole thing. I'll start for the PHP script, mainly because it kind of works as the controller of the whole thing and in that way it gives me the chance to have some sort of order in the descriptions. The idea is to have a single point to ask for the resources of a viewer instance. A html page that wants to include an instance of the viewer requires to have an empty [div] component that will be the container of it, and to include as a javascript the path to the PHP script sending as parameters: (i)the id of the instance to create, (ii)the target id, and (iii) the type of data.
There are 3 types of data so far: json returns the MDC configuration file,that indicates which widgets/components are part of this viewer instance; js to get a bundle of all the java scripts files associated with the given id; the third option is css to get a single file with all the css files from the different widgets, dependencies etc.

So the basic HTML file that includes a viewer instance is like follows:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>PINV - Biosual Architecture</title>
  <link href="../../include.php?id=pinv&type=css" media="screen" rel="stylesheet" type="text/css"></link>
  <script src="../../include.php?id=pinv&target=here&type=js" type="text/javascript"></script>
  <link href="http://fonts.googleapis.com/css?family=Jura" rel="stylesheet" type="text/css"></link>
 </head>
 <body>
  <div id="here">
</div>
</body>


Notice that there is just a single javascript tag in this code, the PHP script will create a unified resource that includes the dependencies, the whole Ajax-Solr library, the selected widgets ant its own dependencies. The order to include all this files is key to make the whole thing to work, so here is a high level view of this, and below some explanations of each step.


  1. Add a list of mandatory dependencies, which in the current version is composed by jquery, jquery-ui, ajax-solr and biojs. This dependencies can be located in the same machine where the script is located or somewhere accessible via Web.
  2. The configuration file is loaded through the id parameter passed in the URL.
  3. One of the options in the config file is to assign a template. this is basically a HTML piece of code that works as layout for the components. In this step the PHP script creates a variable in the javascript code containing the selected template, and them a piece of executable js is added to inject the template into the target div.
  4. There are scripts that are associated with a configuration in particular (eg. making 2 widgets to work together) in this case those scripts are listed in the configuration option js and the PHP script adds them in to the response here.
  5. And here is the core of a viewer configuration: the widgets. A widget should be a component that can be executed by itself in the biosual framework, and follow the idea of ajax-solr iwgets, having functions that will be caled at the initialization of the widget and whenever new data is been captured for the Viewer. The way a widget is defined in biosual(at least for now) is as a sub-folder in the folder widgets, it requires a file there called widget.json, the file follows a JSON format and allows to specify the javascript file of the widget, any dependencies a style file on CSS format, and a HTML snippet of code that will be injected whenever the MDC file indicates. An example of the widget configuration below.
    {
        "name": "Search with Autocomplete",
        "description": "a text based widget to start a search",
        "dependencies":["jquery.autocomplete.js"],
        "dependenciesCSS":["jquery.autocomplete.css"],
        "js": "AutocompleteWidget.js",
        "html": "AutocompleteWidget.html",
        "css": "AutocompleteWidget.css"
    }
    

    This configuration indicates the widget is in the file "AutocompleteWidget.js", but that it requires the file "jquery.autocomplete.js". it also contains the CSSs, HTML and some metadata for the widget.
    A widget can be created but never been used, it is just when is part of a MDC file, that is included, starting for including all its dependencies, then the widget file itself, and in last the HTML to be included in the target explicitly indicated in the MDC file.
  6. A subset of the MDC file is included: widgets, parameters and server
  7. Finally the loader.js is included. This is a piece of software that uses the previous parameters and scripts to create an instance of the Ajax-Solr manager that includes all the widgets and starts the page.
  8. The final resource is included in the web page. The loader.js is executed once the page has been loaded.
There are implementation details that I will post in a future post but for now this one is long enough. By the way, if anybody is interested enough in checking put the code I have a git repository with it: https://github.com/4ndr01d3/biosual/tree/ajaxSolrFromPHP

So let me know any opinions!!
Cheerio!!!

Monday, 13 August 2012

Back into interacting!

WOW, is been a while!!

I'm the first one to be sorry of no having post recently. I've been busy with the paper I mentioned before and is going to get publish pretty soon! :-) Also, the things I have worked on recently are more improvements than anything else and all around the Interaction Viewer(See this post), so I had the feeling it wasn't enough for a post, however now that i checked there are several things I have to talk about, so this might be a long post, or to be split in several. So let's stop of excuses...

First thing I did was to add the Ruler Component (See previous post) into the Interactions Viewer . The initial step is to define the rules for the component, this has to be in a JSON format. Here the rules defined then:

rules: {
  "location": [ ],
  "action": ["Highlight", "Show", "Hide", "Color" ],
  "target": [ {
   "name": "Proteins",
   "conditions": [ {
    "name": "interactions with",
    "type": "selects",
    "amount": 1,
    "values": [ ]
   }, {
    "name": "number of interactions",
    "type": "numeric_comparison"
   }, {
    "name": "accession number",
    "type": "text_comparison"
   } ]
  }, {
   "name": "Interactions",
   "conditions": [ {
    "name": "protein",
    "type": "selects",
    "amount": 1,
    "values": [ ]
   }, {
    "name": "proteins",
    "type": "selects",
    "amount": 2,
    "values": [ ]
   }, {
    "name": "score",
    "type": "numeric_comparison"
   }, {
    "name": "type of evidence",
    "type": "selects",
    "amount": 1,
    "values": [ 
      "neighborhood",
      "fusion", 
      "cooccurrence", 
      "txt_mining",  
      "microarray",  
      "similarity",  
      "domain",  
      "experimental",  
      "knowledge",  
      "pdb",  
      "interlogs" 
    ]
   }
   ]
  } ]
}

As you might noticed some of the values are empty arrays, those will be populated once a Solr response is obtained. What I'm trying to say is, if a rule requires a set of protein to select from, that field is dynamically filled with the proteins presented in the graphic.

The Ruler component triggers events when a rule is added, removed or re-ordered. Is then the interactions app, who applies the existing rules into the graphic, so all this events are going to call the same function:
self.ruler.onRuleCreated(function( objEvent ) {
 self.manager.widgets["graph"].applyRules();
}); 
self.ruler.onRuleRemoved(function( objEvent ) {
 self.manager.widgets["graph"].applyRules();
}); 
self.ruler.onOrderChanged(function( objEvent ) {
 self.manager.widgets["graph"].applyRules();
}); 

The actions defined in the rules where completely related with displaying options: Show, Hide, Highlight and Color. So my strategy for the applyRules method was to create selectors that operate over the interactions graphic(SVG) to filter the elements that pass certain rule, and then operate the respective action on all of them. The full method is rather long so I wont put the whole thing here (You can check it in the repository), instead here are some important snippets of that code.

The method start by getting the active rules and restarting the graphic to get ride of any previous display changes cause by old rules. Then it loops trough the active rules and built the string selector depending on each case. The only rule evaluated in the following code is Proteins Interacting with a specific protein. The selector is an string containing all the IDs of the nodes that represent proteins interacting with the one selected by the user. This is quite easy because when displaying the graphic, a structure with this info was created: self.graph.interactionsA.



applyRules: function(){
 var self =this;
 var rules = self.manager.widgets["ruler"].ruler.getActiveRules();
 var model = self.manager.widgets["ruler"].rules;
 //Reseting the graph 
 self.graph.vis.selectAll("circle").attr("visibility", 'visible').attr("class", 'node').style("stroke","#fff");
 self.graph.vis.selectAll("line").attr("visibility", 'visible').attr("class", 'link').style("stroke","#999");
 
 var selector ="";
 for (var i=0;i<rules.length;i++){
  selector ="";
  var rule=rules[i];
  if (rule.target==model.target[0].name){ //Proteins
   switch (rule.condition){
    case model.target[0].conditions[0].name: // interactions with
     for (var j=0;j<self.graph.interactionsA[rule.parameters[0]].length;j++){
      selector +="[id =node_"+self.graph.interactionsA[rule.parameters[0]][j].name+"],";
     }
     selector = selector.substring(0, selector.length-1);
     break;



If for example i had 3 proteins in my graphic: p1, p2 and p3. And assuming there are interaction between all of them, a rule like Proteins Interacting with a P1 would generate a selector string like [id =node_p2],[id =node_p3]. All the missing logic in this code deals with the creation of the selector for all the combinations for the defined rules. Some of the generated selectors are explicitly listing the id nodes, such as in this first case, and in other cases the selector uses some wildcards to select several nodes with a simpler string.

Once the selector is created an action is executed with it, so for instance if the action is to highlight, the code self.graph.highlight(selector); is invoked. And that method in the interactions component is defined as:

  highlight: function(selector){
   var self=this;
   self.vis.selectAll(selector).style("stroke", '#3d6');
  },


I decided that actions won't really change the color of the node, but instead the color of the border, this with the purpose of conserving the color that relates a protein with the queried protein.

And all that, to be able to display an interaction like this:

All the nteractions of the proteins O05300 and Q7D8M9, highlighting the proteins interacting with O05300.
You can play with all the rules in the live version of this app at http://biosual.cbio.uct.ac.za/interactions/. And you might notice a lot of other details that I haven't talked here yet, but that's material for a next post. Promise to do it quicker than this time!

Chau Gente!

Friday, 22 June 2012

Ruling the world!!

Hey guys,

Is been a while eh! As I have said, my goal is to write a post per week, but you might notice that I skiped the last 3 weeks. I was busy with the edition of a paper, I wish writing formal academic documents was as easy as writing for this blog, but is not, specially with several authors, plus reviewers, etc.

Anyways, the paper is about MyDas and I hope this version get publish, I promise to put a link here whenever that happen(if does happen). I still have to work in one more section of it, but is mainly done, so I decide to be back to do some sketching, developing components, using them somewhere! Much more fun!

Remember that interaction component? Well, I though the next step of it was to make that graph more dynamic, so the user can highlight proteins that is interested on, and hide those that are just causing noise in the view. So that requires the user to define some rules for it.

That made me think that the definition of rules for filtering, selection, execution, etc. is a common task in many different scopes, but a lot of them can be written following the same structure:

In [a location in the page] do [an action] to [the target] when [a condition]

So, I thought that it would be useful to have a component to deal with the common tasks of creating, removing displaying and sorting rules. As usual I started by doing a sketch of my idea:

Sketch for a component to define rules

The idea is that the options for the rules are the input of the component, and then, the component should create the forms, lists and will control the look and feel of the rules. The execution of the rules is then responsibility of the one using the "ruler".

So in my idea of the standard rule, conditions can use different type of parameters (text, selects, etc.). And a condition is applicable to a specific target, which then creates the hierarchy Target>Condition>Parmeter. This information should be the input of the component as a JSON  document

{
 "location": [ "Some part of the page" ],
 "action": ["Action 1", "Action 2", "Action 3" ],
 "target": [ {
  "name": "First Target",
  "conditions": [ {
   "name": "Select from",
   "type": "selects",
   "amount": 1,
   "values": ["An Option","another option"  ]
  }, {
   "name": "number",
   "type": "numeric_comparison"
  }, {
   "name": "some text",
   "type": "text_comparison"
  } ]
 } ]
}

So a condition has a type, and the Ruler component will generate the different form components depending on the type, for example a 'selects' type creates a select with the options in the array of values, and the numeric comparison, creates a select with the comparison operandos ('==', '>', etc.) plus a textfield where the user can input a number.

So I implemented this idea using again Biojs. In reality is something simple: When the user clicks in [Add Rule] the component creates a DIV with the text of the rule and generates Select elements for the different parts of the rule. It also visualize/hide the conditions depending of which target is selected, and does the same for the parameters.

When the rule is added, is move to the top list and an event is triggered to inform which ever component is interest about the new rule. Rules can be removed and that also is informed by events, and the order of the rules can be adjusted. Other components can always ask for the current active rules through a method provided.

And I think the key factor is to make it look nice with CSS! So here is how it looks:

Snapshot of the sample view of the Ruler component


And you can play with it Here. I haven't updated the component to the BioJs registry because is not yet documented. Once I do it, I'll edit this post so you can download the component on BioJs. Here is the link in the BioJs registry.

And just to mention this, I did implemented in the protein interaction viewer, you can have a look Here. But this blog is getting long so I will describe what i did there in the next post.

Thanks for reading, and as usual please give me your feedback I do appreciate any ideas/comments about this!

Hasta la proxima!!

Tuesday, 15 May 2012

Update to the chromosome component

Hello people,

I know the previous post was quite technical, but this one in contrast is even more technical :-p Not really, I think i have to put this technical details here. So take this as a warning and if you are not into HTML5 programming, you might want to skip this port, and just check this link to see what im working on, I promise other posts no so techy!

So for those few that made it here this post to show you how I used the AreaSelector component to interact with the Chromosome one, so read those post if you haven't yet!

Firstly, the selector is optional for the chromosome component, so there is a new option in the constructor called includeSelector (true by default) and when all the bands have been loaded the selector is added. Then, every time the selector changes, the chromosome listen that event, refresh the corresponding coordinates and generates its own event telling the outside world that the selection have change. The last part of the code below is to insure that if the container DIV changes its size or position, the changes get propagated to the selector. So here is that piece of code:


//Setting up the selector in case is included
if (self.opt.includeSelector){
  //The selector just allows horizontal interaction and is preseted in the first band
  self.opt.selector = new Biojs.AreaSelector({
    target: self.opt.target+'_chr',
    resize_top: false,
    resize_bottom: false,
    area:[0,-5,$('#'+firstid).width(),20]
  });
  //Creating attributes in the object to save chromosome coordinates where is visible, starting in the first band   self.opt.selector.from = 0;    self.opt.selector.to = firstW;    self.opt.selector.fromWatcher=false;
  //When the selector change its position the chromosome coordinates have to be updated   self.opt.selector.onRegionChanged(function( objEvent ) {     if (!self.opt.selector.fromWatcher){       self.opt.selector.from = self._getCoordinateFromLeft(objEvent.region[0]);       self.opt.selector.to = self._getCoordinateFromLeft(objEvent.region[2]);       self.raiseEvent('onSelectorChanged', {         chromosome_id : self.opt.model.id,         selector_start: self.opt.selector.from,         selector_stop: self.opt.selector.to       });     }   });
  //if the div containing the chromosome is resized or moved the selector is modified with   $("#"+self.opt.target).watch("left,top,width,height,display", function() {     self.opt.selector.fromWatcher=true;     if (self.opt.selector.from!=null && self.opt.selector.to!=null )       self.moveSelectorToCoordinates(self.opt.selector.from,self.opt.selector.to);     self.opt.selector.fromWatcher=false;   }, 100, "_containerMove");
}


Other methods were implemented, mostly to handle conversion between the DIV coordinates and its coresponding chromosome coordinate. A method to directly change the position of the selector was added, so other components can interact with the chromosome view. Lastly 3 more events are associated with this component:  onModelLoaded to indicate that the DAS model has been succesfully loaded, onDASLoadFail in  the case the DAS source have any problem to be loaded, and onSelectorChanged for any position change on the selector.

The final result looks like the image below, and the code is now in the biojs registry here so you can play with it and use it whenever you want.

14 - Chromosome + AreaSelector component


Another part I worked on, came from a comment of a friend in this blog, and is that when displaying all the chromosomes, they were draw in the same size, which is not a good representation, each chromosome have a different number of nucleotides, and therefore its dimension vary.

The component was developed to auto-adjust to the assigned size of the container DIV, meaning that if we create DIV that are proportional to the size of the chromosomes, the representation will be more accurate.

The only problem is that a to be abe to calculate the proportions i need to know the size of all the chromosome, and because the info is geting asynchronous, is not something that we can just loop.

So what I did was to use the event onModelLoaded, to know when the component has finished loading the model, and in this way externally capture the size of that component, to adjust the width of the DIVs every time another chromosome is completed.
The DIV sizes, are then calculated with respect of the longest chromosome represented, this one has a width of 100% and all the other percentages are just proportion of it... Wow, thats a lot of words for just this piece of code:


  inst[i].onModelLoaded(function( objEvent ) {
    $("#holder_"+objEvent.model.id).data("size",1*objEvent.model.stop);
    adjustSizes(1*objEvent.model.stop)
  }); 

...

var maxSize=0;
var adjustSizes= function(size){   if (maxSize<size)     maxSize=size;   for (var i in chromosomes){     var chr=chromosomes[i];     if($("#holder_"+chr).data("size") != undefined){       var size = $("#holder_" + chr).data("size");       $("#holder_"+chr).width( (size/maxSize)*100 +"%");     }   } }


Below you can find a screenshot of this running, but if you want is to watch it in your browser just go to this LINK.

15 - Chromosome X and Y in proportion.

And that's me for now... Thanks for reading this, and please give me some feedback about it, I would like to know if someone is reading this and if is making any sense.

Hasta la vista!!!

Saturday, 12 May 2012

Area Selector and Chromosome Component

.position() .offset() .left . top .width() .height() .parent()

Those are the 'words' that I have written the most during the last few days. And the ones that I have spoken I had better avoid mentioning, in case it causes my blog to be censored.

Here is the story: after having finished the Chromosome component, I thought it would be cool to freely select and adjust areas in the chromosome, and not just select the bands as it was doing. I thought that a semi-transparent div at the top of the chromosome could do the trick, so it was just a matter of some styling and I have a div that shows what's selected in the chromosome. Then it's just javascript playing with the DOM to modify position, and size.

Simple! So let's start with a static HTML and its CSS. The Div is going to contain other divs that will work as the points to scale the div:

<div class='selector'>
  <div class='scaler top'></div>
  <div class='scaler bottom'></div>
  <div class='scaler left'></div>
  <div class='scaler right'></div>
</div>


So I defined a couple of styles in the CSS, defining the transparency, the position and size:

.selector {
  border: 1px solid #FF0000;
  position: absolute;
  margin-left: 0px;
  margin-top: -5px;
  height: 25px;
  width: 30px;
  z-index: 10;
  background-color: rgb(100%, 75%, 75%);
  opacity:0.4;
  filter:alpha(opacity=40); /* For IE8 and earlier */
}

.scaler {
  position: absolute;
  height: 5px;
  width: 5px;
  background-color: white;
  border: 1px solid red;
}



You can check the fully working code here. It looks like this:

12- Snapshot of the chromosome component with a overlapping div

So how hard could it be to make that div fully dynamic as an independent component? Easy peasy!
How wrong I was!! Well I'm not trying to say that it's incredibly complicated, but something that I estimated doing in one day took me the whole week. Hope that this is not going to be the rule in the rest of this project.

In reality the whole thing is not complicated, it's just a matter of transforming coordinates from the HTML document to the Chromosome space, and vice-versa. Plus having control of events to drag&drop the scalers to modify the size, location of the selector div. And saying it in that way makes me think again that it was something easy.

So, I tried to do the trick with mousedown() mouseup() events recalculating coordinates and redrawing things, but this didn't work because if you move your mouse too quickly you will move out of the scaler div, and it wont recognise the mouseup() event.

Then I realised that I was committing the classic mistake of reinventing the wheel. I mean that above is the description of a Draggable component in jquery UI, and for a moment I even thought that the whole thing could it be done by the Resizable component. But this one just modifies the size from the bottom-right corner, and what I want is something I can change from any side, conclusion back to my idea, but now using a jqueryui.

Here is the code for the draggable actions of the right scaler, the other scalers are pretty much the same, although the left and top required modifying the position of the div and not just increasing the width or height.


$("#"+self.opt.target+" .selector .right").draggable({
  axis: "x",
  start :function(event) {
    self.updateScalers();
    $(this).parent().css('border-right-width',"0px");
  },
  stop :function(event) {
    $("#"+self.opt.target+" .selector").width(self._removePx($(this).css('left'))+5);
    $(this).parent().css('border-right-width',"1px");
    self.updateScalers();
    self.raiseEvent('onRegionChanged', {
      region : self.getCoveredArea()
    });
  }
});


Obviously there is a lot more code than this, but this pretty much describes the task. The function updateScalers, repositions the divs that I used to create the effect. It also recalculates the limits of the enclosing div.

Another thing that I did for this component was to make sure that if the container changes its position, the constrains get automatically updated. In order to do that i found a plugin for jquery to watch a DOM element and react in that case. You can read some details here.

So this is how the Area Selector looks, I also created some methods and triggered some events in this component, so it can really interact with other elements.

13- Snapshot of the Area Selector component

You can play with it here, and soon it will be on the repository. I will update this post once it is online.
I just finished the interaction between this and the chromosome component and I will post about it at the beginning of the week.
For now, I'll be back to my super-lazy weekend, hope you guys are enjoying yours. :-)


EDIT: Here is the link of the AreaSelector in the registry (LINK)

Friday, 4 May 2012

A chromosome component

Hello People!

So, it have to happened, took me a while before falling in the temptation of starting to code. If you are a developer you know that until you have something running you dont feel like you have progress, no matter how much documentation, design, architecture or any of that so-called work have you done, the only progress is in code running, am I right??

So my lame excuse to start coding this time was about getting familiar with Biojs, I have mentioned before, this is the javascript library of web components that a friend is developing, I though about using this as the base of the Registry component of BIOsual, and the only way to really understand a library is to develop with it, isn't it?

And where else to start that by a 'Hello World' Tutorial. Biojs is as agnostic as me, although in javascript that term is not related with religions, what it means is that it doesn't know or even better, it doesn't care if you are using a framework (eg. jquery, YUI, prototype), so the developer can choose to use whatever works better for him/her, which in my case is jquery, so the tutorial uses it, but it could it be done using any other library or by no using any, but just plain js.

Anyways, in an attempt of learning by been productive I decided to do a mini-project with Biojs, and develop a small component, that help me to understand completely the library, but that it could be used as uno of the components for BIOsual, and then I though in a chromosome, displaying its bands. Here a  little of biology about the chromosome bands.

The Idea


I am starting to enjoy the idea of sketching, so here is the sketch of the visual component that I was developing:

9 -  Bands of a chromosome.
Inspired in the way that myKaryoView displays the chromosome, I decide to display a chromosome based on html elements, myKarioView does it with <a> but i decide to go with <div> just to avoid the '#' in the URL when you use those elements to trigger an click event instead of a normal link.

Then I though that getting that is something that can be done by plain HTML with some CSS styling, and then I literally came out of bed with the idea of doing some HTML+CSS that represents a chromosome, with the idea of doing the HTML as simple as posible, and this is how the code looks:



<html>
<head>
    <link rel="stylesheet" type="text/css" href="biojs.chromosome.css" media="screen" />
  </head>   <body>     <h1>Basic html example for a chromosome
    <div id='Chrmosome:8' class='chromosome' style='min-width: 480px;'>       <div id='p11.22' class='band gpos25 first' style='width: 25%;'></div>       <div id='p11.21' class='band gneg' style='width: 15%;'></div>       <div id='p11.1' class='band q_acen' style='width: 10%;'></div>       <div id='p11.1' class='band p_acen' style='width: 30%;'></div>       <div id='p11.1' class='band gpos75' style='width: 12%;'></div>       <div id='p11.1' class='band gpos50 last' style='width: 6%;'></div>     </div>   </body> </html>




In this way the html just have the structure of the chromosome, and all the looks resides in the CSS:


.band {
   position: relative;
   z-index: 3;
   height: 15px;    border: 1px solid #333;    border-right: 0px;    border-left: 0px;    border-image: initial;    cursor: pointer;    float:left; }
.q_acen, .first{    border-left: 1px solid #333;    border-top-left-radius: 4px;    border-bottom-left-radius: 4px;    -webkit-top-bottom-left-radius: 4px;
   -moz-border-radius-bottomright: 4px;    -moz-border-radius-topleft: 4px;
}
.p_acen,.q_acen {    background-color: #DDD; }


There is more in the CSS but is pretty much copy/paste of what you seen here to create the rest of the borders, and the different colours for the band's types, so it looks like the image below, and you can check that HTML here.

10 - HTML test for displaying a chromosome

The implementation

It looks cool, but the whole point is that it should be generated from real data, and here is where the javascript became important. Firstly I'm gonna take the information from this Ensemble DAS source, and for this example I am using the chromosome 8 of the human data set, but it apply to any organism with a chromosome based genome, and in the URL just change the segment to get a different chromosome.

For the parsing of the DAS response I'm using JsDAS, a library that allows me to do the ajax query to a das server and gave me the response as a javascript model, you can check the tutorial and see how easy is to work with this library.

From there is just a matter of create a DIV element for each feature in that response. As I mentioned before I'm using jquery here, it really makes my life easier to deal with the DOM of the page, and the whole point is to use BioJS. Following the rules of Biojs, or any framework in particular, feels like you are doing more work than need it, but in the case of Biojs, the benefits really are worth.

To begin with, you have to document with javadoc style, and for those like me, that love java, documenting in this way takes out part of the tediousness of the documenting task, not completely, but anything that helps there is welcome!

BioJs has a mvn file to facilitate the generation via maven of the documentation, reorganize the code, but most importantly, it creates a web registry, where based on the created documentation is able to visualize, important information of the module, for instance, methods, events, dependencies, and even a live example of the component, so whoever is having a look to the available components, can always see a demo of the components.

Creating a full registry of your components in your machine is nice, but the whole point is to create a community, and to do that the components have to be web visible, meaning having a central repository.  For now the repository is based on the components that have been sync in the source repository of the library, but the main developer confirmed that there is work in progress to create a repository similar to the jquery one,  exciting news from there!

So without more talking here is my chromosome component in the BioJs repository, so anyone can use it! but in a more selfish point of view, the firs component that can be used for BIOsual, given the good experience with it I think i should keep thinking in the visual components using it, and in doing the registry of BIOsual based on BioJs.

Lastly, here is a page displaying all the human chromosomes that looks like this:

11- snapshot of the chromosome component

Cheers!!