/** * This component uses the D3 library and specifically its implementation of the bundle algorithm to * represent a network of protein interactions. * * @class * @extends Biojs * * @author Gustavo A. Salazar * @version 0.9.1_beta * @category 1 * * @requires jQuery Core 1.7.2 * @dependency * * @requires D3 * @dependency * * @requires InteractionsD3 CSS * @dependency * * @param {Object} options An object with the options for the InteractionsD3 component. * * @option {string} target * Identifier of the DIV tag where the component should be displayed. * @option {string} width * Width of the SVG element, if given in percentage, it will use it on proportion of the container * @option {string} height * Height of the SVG element, if given in percentage, it will use it on proportion of the container * @option {string} radius * Radius of the nodes representing the proteins * @option {string} textLength * Space in pixels to be reserved for the labels around the circle * * @example * var instance = new Biojs.InteractionsBundleD3({ * target: "YourOwnDivId", * }); * var pid=1; * for (var i=0;i<100;i++) * instance.addProtein({id:'p'+pid++,group:1,organism:"human"}); * for (var i=0;i<100;i++) * instance.addProtein({id:'p'+pid++,group:1,organism:"TB"}); * for (var i=1;i<200;i++){ * instance.addInteraction("p"+(i),"p"+(100+i),{id:"p"+(i)+"_p"+(100+i),feature1:"value"}); * instance.addInteraction("p"+(i),"p"+(i%17),{id:"p"+(i)+"_p"+(i%17),feature1:"value"}); * } * instance.restart(); */ Biojs.InteractionsBundleD3 = Biojs.extend ( /** @lends Biojs.InteractionsBundleD3# */ { cluster:null, bundle:null, vis:null, splines:[], model:{}, organisms:{}, proteins:[], interactions:[], interactionsA:{}, svg:null, //Transformation values tTranslate:null, tScale:null, constructor: function (options) { var self = this; self.cluster=null; self.bundle=null; self.vis=null; self.splines=[]; self.model={"name":"", "children":[] }; self.organisms={}; self.proteins=[]; self.interactions=[]; self.svg=null; self.interactionsA={}; this._container = $("#"+self.opt.target); this._container.empty(); $(this._container).addClass("graphCircle"); var w = $(this._container).width(), h = $(this._container).height(); w = (self.opt.width.indexOf("%")!=-1)?w*(self.opt.width.substring(0, self.opt.width.length-1)*1)/100.0:self.opt.width*1; self.opt.width=w; h = (self.opt.height.indexOf("%")!=-1)?h*(self.opt.height.substring(0, self.opt.height.length-1)*1)/100.0:self.opt.height*1; self.opt.height=h; var rx = w / 2, ry = h / 2; var tmpR=(rxb[1]){ return -1; }else return 1; return a[0]-b[0]; }); }, _paintLegend:function(legend,type){ var self = this; legend.filter(function(d) { return d[0]== "label" && d[1]==type; }).append("text") .attr("x", self.opt.width/2 - 6) .attr("y", 7-self.opt.height/2) .attr("dy", ".35em") .style("text-anchor", "end") .style("font-size", "1.2em") .text(type+":"); if (type.indexOf("Resize By")==0){ legend.filter(function(d) { return d[0]!="label" && d[1]==type; }).append("path") .attr("class", "figure") .attr("d", function(d) { var h=2*self.opt.radius*Math.sqrt(d[0][2]); return "M0,0L0,10M0,5L"+h+",5M"+h+",0L"+h+",10 "; }) .attr("transform", function(d) { return "translate(" + (self.opt.width/2 - 18 - 2*self.opt.radius*Math.sqrt(d[0][2])) + ", -" + self.opt.height/2 + ")"; }) .style("fill", "transparent") .style("stroke", "black"); legend.filter(function(d) { return d[0]!="label" && d[1]== type; }).append("text") .attr("x", function(d) { return (self.opt.width/2 - 22 - 5*self.opt.radius); }) .attr("y", 7-self.opt.height/2 ) .attr("dy", ".35em") .style("text-anchor", "end") .text(function(d) { return (d[0][1]*1.0).toFixed(2); }); }else{ legend.filter(function(d) { return d[0]!="label" && d[1]==type; }).append("rect") .attr("x", self.opt.width/2 - 18) .attr("y", -self.opt.height/2) .attr("width", 13) .attr("height", 13) .style("fill", function(d,i) { if (typeof d[2]== "undefined") return self.colors[i]; return d[2]; }); legend.filter(function(d) { return d[0]!="label" && d[1]== type; }).append("text") .attr("x", self.opt.width/2 - 24) .attr("y", 7-self.opt.height/2) .attr("dy", ".35em") .style("text-anchor", "end") .text(function(d) { return d[0]; }); } }, _paintLegends: function(){ var self = this; var w=18 + self.longestLegend*7 + 10; var legendBlock = self.svg.insert("g",".link") .attr("class", "legendBlock"); self._sortLegends(); legendBlock.append("rect") .attr("x", self.opt.width/2 -w) .attr("y", -self.opt.height/2) .attr("height", 6 + self.legends.length *16) .attr("width", w) .style("fill", "#ddd") .style("fill-opacity","0.4"); var legend = legendBlock.selectAll(".mainLegend") .data(self.legends) .enter().insert("g") .attr("class", "mainLegend") .attr("transform", function(d, i) { return "translate(0," + (3 + i * 16) + ")"; }); for (var i=0; i< self.legendTypes.length; i++) self._paintLegend(legend,self.legendTypes[i]); }, longestLegend:4, legendTypes:[], /** * Adds a legend to the graphic * * @example * instance.addLegends(["Legend red"],"Color","#FF0000"); * instance.restart(); */ addLegends:function(legends,type,color){ var self = this; if (self.legends==null) self.legends=[],self.legendTypes=[]; if (legends==null) { self.legends = null; self.legendTypes=[]; self.longestLegend=4; return; } if (type=="Resize By") type = type+ " "+legends[0]; if (self.legendTypes.indexOf(type)==-1) { self.legends.push(["label",type]); self.legendTypes.push(type); if (type.length>self.longestLegend) self.longestLegend=type.length; } if (type.indexOf("Resize By")==0){ //is a size label self.legends.push([legends,type]); } else //is a color label for (var i=0;iself.longestLegend) self.longestLegend=legends[i].length; } }, /** * Hides the elements on the graphic that match the selector. * Check the CSS3 selectors documentation to build a selector string * * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string * * @example * instance.hide('[id *="node-p1"]'); */ hide: function(selector){ var self=this; self.vis.selectAll(selector).attr("visibility", 'hidden'); self.vis.selectAll(selector).selectAll(" .legend").attr("visibility", 'hidden'); }, /** * Shows the elements on the graphic that match the selector. * Check the CSS3 selectors documentation to build a selector string * * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string * * @example * instance.show('[id *="node-p1"]'); */ show: function(selector){ var self=this; self.vis.selectAll(selector).attr("visibility", 'visible'); self.vis.selectAll(selector).selectAll(" .legend").attr("visibility",function(d) { return (d.showLegend)?"visible":"hidden";}); }, /** * Highlight the elements on the graphic that match the selector. * Check the CSS3 selectors documentation to build a selector string * * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string * * @example * instance.highlight(".figure"); */ highlight: function(selector){ var self=this; self.vis.selectAll(selector).style("stroke", '#0f0'); }, /** * Set the fill's color of the elements on the graphic that match the selector. * Check the CSS3 selectors documentation to build a selector string * * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string * @param {string} color a color in web format eg. #FF0000 * * @example * instance.setFillColor(".figure","#FF0000"); */ setFillColor: function(selector,color){ var self=this; self.vis.selectAll(selector).style("fill", color); }, /** * Set the stroke's color of the elements on the graphic that match the selector. * Check the CSS3 selectors documentation to build a selector string * * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string * @param {string} color a color in web format eg. #FF0000 * * @example * instance.setColor(".figure","#FF0000"); */ setColor: function(selector,color){ var self=this; self.vis.selectAll(selector).style("stroke", color); }, /** * Shows/Hide the legend(id) of the protein * * @param {string} protein the id of the protein to swap the visibility of the legend * * @example * instance.swapShowLegend("#node-p"+(pid-1)+" .legend"); */ showLegend: function(selector,typeLegend){ var self=this; self.vis.selectAll(selector).selectAll(".legend").attr("visibility", "visible").text(function(d) { d.typeLegend=typeLegend; if (d.typeLegend=="id") return d.id; // else if (d.typeLegend.indexOf("features.")==0) // return d.features[d.typeLegend.substr(9)]; else return d.features[d.typeLegend]; }); }, /** * Scales the area of a protein * * @param {string} protein the id of the protein to scale * @param {integer} scale value to scale a node * * @example * instance.setSizeScale("#figure_p188",4); */ setSizeScale: function(selector,scale){ var self=this; self.vis.selectAll(selector).attr("r", function(d) { d.size=scale; return self.opt.radius*Math.sqrt(d.size); }); }, /** * Scales the size of the proteins which value has been modify by other means * * @param {string} selector a CSS3 selector to choose the nodes to resize * * @example * var j=0; * for (var i in instance.proteins) * instance.proteins[i].size=1+(j++)%4; * instance.refreshSizeScale(".figure"); */ refreshSizeScale: function(selector){ var self=this; self.vis.selectAll(selector).attr("r", function(d) { return self.opt.radius*Math.sqrt(d.size); }); }, /** * Is the legend of the protein visible * * @param {string} selector a CSS3 selector to choose the legend * * @example * alert(instance.isLegendVisible("#node_5 .legend")); */ isLegendVisible: function(selector){ var self=this; return (self.vis.selectAll(selector).selectAll(".legend").attr("visibility")=="visible"); }, /** * Shows/Hide the legend(id) of the protein * * @param {string} protein the id of the protein to swap the visibility of the legend * * @example * instance.swapShowLegend("#node-p"+(pid-1)+" .legend"); */ hideLegend: function(selector){ var self=this; self.vis.selectAll(selector).selectAll(".legend").attr("visibility", "hidden"); }, /** * Shows/Hide the legend(id) of the protein * * @param {string} protein the id of the protein to swap the visibility of the legend * * @example * instance.swapShowLegend("#node-p"+(pid-1)+" .legend"); */ swapShowLegend: function(selector){ var self=this; self.vis.selectAll(selector).selectAll(".legend").attr("visibility", function(d) { d.showLegend = !d.showLegend; return (d.showLegend)?"visible":"hidden"; }); }, /** * * Resizing the graph depending on the size of the window. * * @param self */ _resize: function (self) { var width = window.innerWidth, height = window.innerHeight; self.vis.attr("width", width).attr("height", height); self.force.size([width, height]).resume(); }, colors: [ "#1f77b4", "#aec7e8", "#ff7f0e", "#ffbb78", "#2ca02c", "#98df8a", "#d62728", "#ff9896", "#9467bd", "#c5b0d5", "#8c564b", "#c49c94", "#e377c2", "#f7b6d2", "#7f7f7f", "#c7c7c7", "#bcbd22", "#dbdb8d", "#17becf", "#9edae5", "#0077b4", "#11c7e8", "#227f0e", "#33bb78", "#44a02c", "#55df8a", "#662728", "#779896", "#8867bd", "#99b0d5", "#AA564b", "#BB9c94", "#CC77c2", "#DDb6d2", "#EE7f7f", "#FFc7c7", "#00bd22", "#11db8d", "#22becf", "#33dae5", "#1f00b4", "#ae11e8", "#ff220e", "#ff3378", "#2c442c", "#98558a", "#d66628", "#ff7796", "#9488bd", "#c599d5", "#8cAA4b", "#c4BB94", "#e3CCc2", "#f7DDd2", "#7fEE7f", "#c7FFc7", "#bc0022", "#db118d", "#1722cf", "#9e33e5", "#1f7700", "#aec711", "#ff7f22", "#ffbb33", "#2ca044", "#98df55", "#d62766", "#ff9877", "#946788", "#c5b099", "#8c56AA", "#c49cBB", "#e377FC", "#f7b6FD", "#7f7fEE", "#c7c7FF", "#bcbd00", "#dbdb11", "#17be22", "#9eda33" ] });