bio-svgenes 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +88 -0
- data/VERSION +1 -1
- data/bio-svgenes.gemspec +131 -8
- data/doc/classes/Bio.html +131 -0
- data/doc/classes/Bio/Graphics.html +142 -0
- data/doc/classes/Bio/Graphics/Glyph.html +987 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000001.html +26 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000002.html +27 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000003.html +32 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000004.html +27 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000005.html +25 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000006.html +29 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000007.html +107 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000008.html +51 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000009.html +23 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000010.html +18 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000011.html +75 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000012.html +51 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000013.html +23 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000014.html +26 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000015.html +27 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000016.html +32 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000017.html +27 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000018.html +25 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000019.html +29 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000020.html +107 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000021.html +51 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000022.html +23 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000023.html +18 -0
- data/doc/classes/Bio/Graphics/Glyph.src/M000024.html +75 -0
- data/doc/classes/Bio/Graphics/MiniFeature.html +243 -0
- data/doc/classes/Bio/Graphics/MiniFeature.src/M000001.html +25 -0
- data/doc/classes/Bio/Graphics/MiniFeature.src/M000003.html +25 -0
- data/doc/classes/Bio/Graphics/MiniFeature.src/M000024.html +25 -0
- data/doc/classes/Bio/Graphics/Page.html +705 -0
- data/doc/classes/Bio/Graphics/Page.src/M000010.html +35 -0
- data/doc/classes/Bio/Graphics/Page.src/M000011.html +83 -0
- data/doc/classes/Bio/Graphics/Page.src/M000012.html +24 -0
- data/doc/classes/Bio/Graphics/Page.src/M000013.html +29 -0
- data/doc/classes/Bio/Graphics/Page.src/M000014.html +24 -0
- data/doc/classes/Bio/Graphics/Page.src/M000015.html +20 -0
- data/doc/classes/Bio/Graphics/Page.src/M000016.html +20 -0
- data/doc/classes/Bio/Graphics/Page.src/M000017.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000018.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000019.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000020.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000021.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000022.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000023.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000024.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000025.html +35 -0
- data/doc/classes/Bio/Graphics/Page.src/M000026.html +83 -0
- data/doc/classes/Bio/Graphics/Page.src/M000027.html +24 -0
- data/doc/classes/Bio/Graphics/Page.src/M000028.html +29 -0
- data/doc/classes/Bio/Graphics/Page.src/M000029.html +24 -0
- data/doc/classes/Bio/Graphics/Page.src/M000030.html +20 -0
- data/doc/classes/Bio/Graphics/Page.src/M000031.html +20 -0
- data/doc/classes/Bio/Graphics/Page.src/M000032.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000033.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000034.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000035.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000036.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000037.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000038.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000039.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000040.html +107 -0
- data/doc/classes/Bio/Graphics/Page.src/M000041.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000042.html +23 -0
- data/doc/classes/Bio/Graphics/Page.src/M000043.html +18 -0
- data/doc/classes/Bio/Graphics/Page.src/M000044.html +18 -0
- data/doc/classes/Bio/Graphics/Primitive.html +204 -0
- data/doc/classes/Bio/Graphics/Primitive.src/M000001.html +21 -0
- data/doc/classes/Bio/Graphics/Primitive.src/M000002.html +20 -0
- data/doc/classes/Bio/Graphics/Primitive.src/M000008.html +21 -0
- data/doc/classes/Bio/Graphics/Primitive.src/M000009.html +20 -0
- data/doc/classes/Bio/Graphics/Primitive.src/M000022.html +21 -0
- data/doc/classes/Bio/Graphics/Primitive.src/M000023.html +20 -0
- data/doc/classes/Bio/Graphics/SVGEE.html +290 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000002.html +24 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000003.html +18 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000004.html +24 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000005.html +18 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000006.html +18 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000007.html +21 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000008.html +27 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000009.html +23 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000016.html +24 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000017.html +18 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000018.html +18 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000019.html +21 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000020.html +27 -0
- data/doc/classes/Bio/Graphics/SVGEE.src/M000021.html +23 -0
- data/doc/classes/Bio/Graphics/Track.html +473 -0
- data/doc/classes/Bio/Graphics/Track.src/M000001.html +35 -0
- data/doc/classes/Bio/Graphics/Track.src/M000002.html +18 -0
- data/doc/classes/Bio/Graphics/Track.src/M000003.html +28 -0
- data/doc/classes/Bio/Graphics/Track.src/M000004.html +18 -0
- data/doc/classes/Bio/Graphics/Track.src/M000010.html +35 -0
- data/doc/classes/Bio/Graphics/Track.src/M000011.html +18 -0
- data/doc/classes/Bio/Graphics/Track.src/M000012.html +28 -0
- data/doc/classes/Bio/Graphics/Track.src/M000013.html +18 -0
- data/doc/created.rid +1 -9
- data/doc/files/lib/bio-svgenes_rb.html +131 -0
- data/doc/files/lib/bio/graphics/glyph_rb.html +101 -0
- data/doc/files/lib/bio/graphics/mini_feature_rb.html +101 -0
- data/doc/files/lib/bio/graphics/page_rb.html +111 -0
- data/doc/files/lib/bio/graphics/primitive_rb.html +101 -0
- data/doc/files/lib/bio/graphics/svgee_rb.html +101 -0
- data/doc/files/lib/bio/graphics/track_rb.html +101 -0
- data/doc/fr_class_index.html +34 -0
- data/doc/fr_file_index.html +33 -0
- data/doc/fr_method_index.html +70 -0
- data/doc/index.html +21 -91
- data/doc/manual/bootstrap/css/bootstrap-responsive.css +1109 -0
- data/doc/manual/bootstrap/css/bootstrap-responsive.min.css +9 -0
- data/doc/manual/bootstrap/css/bootstrap.css +6158 -0
- data/doc/manual/bootstrap/css/bootstrap.min.css +9 -0
- data/doc/manual/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/doc/manual/bootstrap/img/glyphicons-halflings.png +0 -0
- data/doc/manual/bootstrap/js/bootstrap.js +2276 -0
- data/doc/manual/bootstrap/js/bootstrap.min.js +6 -0
- data/doc/manual/img/circle.png +0 -0
- data/doc/manual/img/directed.png +0 -0
- data/doc/manual/img/down_triangle.png +0 -0
- data/doc/manual/img/histogram.png +0 -0
- data/doc/manual/img/span.png +0 -0
- data/doc/manual/img/transcript.png +0 -0
- data/doc/manual/img/up_triangle.png +0 -0
- data/doc/manual/manual.html +360 -0
- data/doc/manual/manual.md +307 -0
- data/doc/rdoc-style.css +208 -0
- data/examples/example.rb +12 -8
- data/examples/{make_example.rb → example2.rb} +5 -16
- data/lib/bio/graphics/glyph.rb +293 -126
- data/lib/bio/graphics/mini_feature.rb +24 -17
- data/lib/bio/graphics/page.rb +112 -54
- data/lib/bio/graphics/primitive.rb +12 -9
- data/lib/bio/graphics/svgee.rb +9 -11
- data/lib/bio/graphics/track.rb +92 -10
- metadata +132 -9
- data/README.rdoc +0 -19
- data/examples/annotate_snps.rb +0 -86
- data/examples/eg2.rb +0 -40
- data/examples/get_coverage_in_windows.rb +0 -176
@@ -0,0 +1,6 @@
|
|
1
|
+
/*!
|
2
|
+
* Bootstrap.js by @fat & @mdo
|
3
|
+
* Copyright 2012 Twitter, Inc.
|
4
|
+
* http://www.apache.org/licenses/LICENSE-2.0.txt
|
5
|
+
*/
|
6
|
+
!function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||s.toggleClass("open"),n.focus(),!1},keydown:function(n){var r,s,o,u,a,f;if(!/(38|40|27)/.test(n.keyCode))return;r=e(this),n.preventDefault(),n.stopPropagation();if(r.is(".disabled, :disabled"))return;u=i(r),a=u.hasClass("open");if(!a||a&&n.keyCode==27)return n.which==27&&u.find(t).focus(),r.click();s=e("[role=menu] li:not(.divider):visible a",u);if(!s.length)return;f=s.index(s.filter(":focus")),n.keyCode==38&&f>0&&f--,n.keyCode==40&&f<s.length-1&&f++,~f||(f=0),s.eq(f).focus()}};var s=e.fn.dropdown;e.fn.dropdown=function(t){return this.each(function(){var r=e(this),i=r.data("dropdown");i||r.data("dropdown",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.dropdown.Constructor=n,e.fn.dropdown.noConflict=function(){return e.fn.dropdown=s,this},e(document).on("click.dropdown.data-api",r).on("click.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("click.dropdown-menu",function(e){e.stopPropagation()}).on("click.dropdown.data-api",t,n.prototype.toggle).on("keydown.dropdown.data-api",t+", [role=menu]",n.prototype.keydown)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=n,this.$element=e(t).delegate('[data-dismiss="modal"]',"click.dismiss.modal",e.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};t.prototype={constructor:t,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var t=this,n=e.Event("show");this.$element.trigger(n);if(this.isShown||n.isDefaultPrevented())return;this.isShown=!0,this.escape(),this.backdrop(function(){var n=e.support.transition&&t.$element.hasClass("fade");t.$element.parent().length||t.$element.appendTo(document.body),t.$element.show(),n&&t.$element[0].offsetWidth,t.$element.addClass("in").attr("aria-hidden",!1),t.enforceFocus(),n?t.$element.one(e.support.transition.end,function(){t.$element.focus().trigger("shown")}):t.$element.focus().trigger("shown")})},hide:function(t){t&&t.preventDefault();var n=this;t=e.Event("hide"),this.$element.trigger(t);if(!this.isShown||t.isDefaultPrevented())return;this.isShown=!1,this.escape(),e(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),e.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal()},enforceFocus:function(){var t=this;e(document).on("focusin.modal",function(e){t.$element[0]!==e.target&&!t.$element.has(e.target).length&&t.$element.focus()})},escape:function(){var e=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(t){t.which==27&&e.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var t=this,n=setTimeout(function(){t.$element.off(e.support.transition.end),t.hideModal()},500);this.$element.one(e.support.transition.end,function(){clearTimeout(n),t.hideModal()})},hideModal:function(){var e=this;this.$element.hide(),this.backdrop(function(){e.removeBackdrop(),e.$element.trigger("hidden")})},removeBackdrop:function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},backdrop:function(t){var n=this,r=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var i=e.support.transition&&r;this.$backdrop=e('<div class="modal-backdrop '+r+'" />').appendTo(document.body),this.$backdrop.click(this.options.backdrop=="static"?e.proxy(this.$element[0].focus,this.$element[0]):e.proxy(this.hide,this)),i&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in");if(!t)return;i?this.$backdrop.one(e.support.transition.end,t):t()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),e.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(e.support.transition.end,t):t()):t&&t()}};var n=e.fn.modal;e.fn.modal=function(n){return this.each(function(){var r=e(this),i=r.data("modal"),s=e.extend({},e.fn.modal.defaults,r.data(),typeof n=="object"&&n);i||r.data("modal",i=new t(this,s)),typeof n=="string"?i[n]():s.show&&i.show()})},e.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},e.fn.modal.Constructor=t,e.fn.modal.noConflict=function(){return e.fn.modal=n,this},e(document).on("click.modal.data-api",'[data-toggle="modal"]',function(t){var n=e(this),r=n.attr("href"),i=e(n.attr("data-target")||r&&r.replace(/.*(?=#[^\s]+$)/,"")),s=i.data("modal")?"toggle":e.extend({remote:!/#/.test(r)&&r},i.data(),n.data());t.preventDefault(),i.modal(s).one("hide",function(){n.focus()})})}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("tooltip",e,t)};t.prototype={constructor:t,init:function(t,n,r){var i,s,o,u,a;this.type=t,this.$element=e(n),this.options=this.getOptions(r),this.enabled=!0,o=this.options.trigger.split(" ");for(a=o.length;a--;)u=o[a],u=="click"?this.$element.on("click."+this.type,this.options.selector,e.proxy(this.toggle,this)):u!="manual"&&(i=u=="hover"?"mouseenter":"focus",s=u=="hover"?"mouseleave":"blur",this.$element.on(i+"."+this.type,this.options.selector,e.proxy(this.enter,this)),this.$element.on(s+"."+this.type,this.options.selector,e.proxy(this.leave,this)));this.options.selector?this._options=e.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(t){return t=e.extend({},e.fn[this.type].defaults,this.$element.data(),t),t.delay&&typeof t.delay=="number"&&(t.delay={show:t.delay,hide:t.delay}),t},enter:function(t){var n=e.fn[this.type].defaults,r={},i;this._options&&e.each(this._options,function(e,t){n[e]!=t&&(r[e]=t)},this),i=e(t.currentTarget)[this.type](r).data(this.type);if(!i.options.delay||!i.options.delay.show)return i.show();clearTimeout(this.timeout),i.hoverState="in",this.timeout=setTimeout(function(){i.hoverState=="in"&&i.show()},i.options.delay.show)},leave:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);this.timeout&&clearTimeout(this.timeout);if(!n.options.delay||!n.options.delay.hide)return n.hide();n.hoverState="out",this.timeout=setTimeout(function(){n.hoverState=="out"&&n.hide()},n.options.delay.hide)},show:function(){var t,n,r,i,s,o,u=e.Event("show");if(this.hasContent()&&this.enabled){this.$element.trigger(u);if(u.isDefaultPrevented())return;t=this.tip(),this.setContent(),this.options.animation&&t.addClass("fade"),s=typeof this.options.placement=="function"?this.options.placement.call(this,t[0],this.$element[0]):this.options.placement,t.detach().css({top:0,left:0,display:"block"}),this.options.container?t.appendTo(this.options.container):t.insertAfter(this.$element),n=this.getPosition(),r=t[0].offsetWidth,i=t[0].offsetHeight;switch(s){case"bottom":o={top:n.top+n.height,left:n.left+n.width/2-r/2};break;case"top":o={top:n.top-i,left:n.left+n.width/2-r/2};break;case"left":o={top:n.top+n.height/2-i/2,left:n.left-r};break;case"right":o={top:n.top+n.height/2-i/2,left:n.left+n.width}}this.applyPlacement(o,s),this.$element.trigger("shown")}},applyPlacement:function(e,t){var n=this.tip(),r=n[0].offsetWidth,i=n[0].offsetHeight,s,o,u,a;n.offset(e).addClass(t).addClass("in"),s=n[0].offsetWidth,o=n[0].offsetHeight,t=="top"&&o!=i&&(e.top=e.top+i-o,a=!0),t=="bottom"||t=="top"?(u=0,e.left<0&&(u=e.left*-2,e.left=0,n.offset(e),s=n[0].offsetWidth,o=n[0].offsetHeight),this.replaceArrow(u-r+s,s,"left")):this.replaceArrow(o-i,o,"top"),a&&n.offset(e)},replaceArrow:function(e,t,n){this.arrow().css(n,e?50*(1-e/t)+"%":"")},setContent:function(){var e=this.tip(),t=this.getTitle();e.find(".tooltip-inner")[this.options.html?"html":"text"](t),e.removeClass("fade in top bottom left right")},hide:function(){function i(){var t=setTimeout(function(){n.off(e.support.transition.end).detach()},500);n.one(e.support.transition.end,function(){clearTimeout(t),n.detach()})}var t=this,n=this.tip(),r=e.Event("hide");this.$element.trigger(r);if(r.isDefaultPrevented())return;return n.removeClass("in"),e.support.transition&&this.$tip.hasClass("fade")?i():n.detach(),this.$element.trigger("hidden"),this},fixTitle:function(){var e=this.$element;(e.attr("title")||typeof e.attr("data-original-title")!="string")&&e.attr("data-original-title",e.attr("title")||"").attr("title","")},hasContent:function(){return this.getTitle()},getPosition:function(){var t=this.$element[0];return e.extend({},typeof t.getBoundingClientRect=="function"?t.getBoundingClientRect():{width:t.offsetWidth,height:t.offsetHeight},this.$element.offset())},getTitle:function(){var e,t=this.$element,n=this.options;return e=t.attr("data-original-title")||(typeof n.title=="function"?n.title.call(t[0]):n.title),e},tip:function(){return this.$tip=this.$tip||e(this.options.template)},arrow:function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(t){var n=t?e(t.currentTarget)[this.type](this._options).data(this.type):this;n.tip().hasClass("in")?n.hide():n.show()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}};var n=e.fn.tooltip;e.fn.tooltip=function(n){return this.each(function(){var r=e(this),i=r.data("tooltip"),s=typeof n=="object"&&n;i||r.data("tooltip",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.tooltip.Constructor=t,e.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},e.fn.tooltip.noConflict=function(){return e.fn.tooltip=n,this}}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("popover",e,t)};t.prototype=e.extend({},e.fn.tooltip.Constructor.prototype,{constructor:t,setContent:function(){var e=this.tip(),t=this.getTitle(),n=this.getContent();e.find(".popover-title")[this.options.html?"html":"text"](t),e.find(".popover-content")[this.options.html?"html":"text"](n),e.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var e,t=this.$element,n=this.options;return e=(typeof n.content=="function"?n.content.call(t[0]):n.content)||t.attr("data-content"),e},tip:function(){return this.$tip||(this.$tip=e(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}});var n=e.fn.popover;e.fn.popover=function(n){return this.each(function(){var r=e(this),i=r.data("popover"),s=typeof n=="object"&&n;i||r.data("popover",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.popover.Constructor=t,e.fn.popover.defaults=e.extend({},e.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),e.fn.popover.noConflict=function(){return e.fn.popover=n,this}}(window.jQuery),!function(e){"use strict";function t(t,n){var r=e.proxy(this.process,this),i=e(t).is("body")?e(window):e(t),s;this.options=e.extend({},e.fn.scrollspy.defaults,n),this.$scrollElement=i.on("scroll.scroll-spy.data-api",r),this.selector=(this.options.target||(s=e(t).attr("href"))&&s.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=e("body"),this.refresh(),this.process()}t.prototype={constructor:t,refresh:function(){var t=this,n;this.offsets=e([]),this.targets=e([]),n=this.$body.find(this.selector).map(function(){var n=e(this),r=n.data("target")||n.attr("href"),i=/^#\w/.test(r)&&e(r);return i&&i.length&&[[i.position().top+(!e.isWindow(t.$scrollElement.get(0))&&t.$scrollElement.scrollTop()),r]]||null}).sort(function(e,t){return e[0]-t[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},process:function(){var e=this.$scrollElement.scrollTop()+this.options.offset,t=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,n=t-this.$scrollElement.height(),r=this.offsets,i=this.targets,s=this.activeTarget,o;if(e>=n)return s!=(o=i.last()[0])&&this.activate(o);for(o=r.length;o--;)s!=i[o]&&e>=r[o]&&(!r[o+1]||e<=r[o+1])&&this.activate(i[o])},activate:function(t){var n,r;this.activeTarget=t,e(this.selector).parent(".active").removeClass("active"),r=this.selector+'[data-target="'+t+'"],'+this.selector+'[href="'+t+'"]',n=e(r).parent("li").addClass("active"),n.parent(".dropdown-menu").length&&(n=n.closest("li.dropdown").addClass("active")),n.trigger("activate")}};var n=e.fn.scrollspy;e.fn.scrollspy=function(n){return this.each(function(){var r=e(this),i=r.data("scrollspy"),s=typeof n=="object"&&n;i||r.data("scrollspy",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.scrollspy.Constructor=t,e.fn.scrollspy.defaults={offset:10},e.fn.scrollspy.noConflict=function(){return e.fn.scrollspy=n,this},e(window).on("load",function(){e('[data-spy="scroll"]').each(function(){var t=e(this);t.scrollspy(t.data())})})}(window.jQuery),!function(e){"use strict";var t=function(t){this.element=e(t)};t.prototype={constructor:t,show:function(){var t=this.element,n=t.closest("ul:not(.dropdown-menu)"),r=t.attr("data-target"),i,s,o;r||(r=t.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,""));if(t.parent("li").hasClass("active"))return;i=n.find(".active:last a")[0],o=e.Event("show",{relatedTarget:i}),t.trigger(o);if(o.isDefaultPrevented())return;s=e(r),this.activate(t.parent("li"),n),this.activate(s,s.parent(),function(){t.trigger({type:"shown",relatedTarget:i})})},activate:function(t,n,r){function o(){i.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),t.addClass("active"),s?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu")&&t.closest("li.dropdown").addClass("active"),r&&r()}var i=n.find("> .active"),s=r&&e.support.transition&&i.hasClass("fade");s?i.one(e.support.transition.end,o):o(),i.removeClass("in")}};var n=e.fn.tab;e.fn.tab=function(n){return this.each(function(){var r=e(this),i=r.data("tab");i||r.data("tab",i=new t(this)),typeof n=="string"&&i[n]()})},e.fn.tab.Constructor=t,e.fn.tab.noConflict=function(){return e.fn.tab=n,this},e(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(t){t.preventDefault(),e(this).tab("show")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.typeahead.defaults,n),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.source=this.options.source,this.$menu=e(this.options.menu),this.shown=!1,this.listen()};t.prototype={constructor:t,select:function(){var e=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(e)).change(),this.hide()},updater:function(e){return e},show:function(){var t=e.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return this.$menu.insertAfter(this.$element).css({top:t.top+t.height,left:t.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(t){var n;return this.query=this.$element.val(),!this.query||this.query.length<this.options.minLength?this.shown?this.hide():this:(n=e.isFunction(this.source)?this.source(this.query,e.proxy(this.process,this)):this.source,n?this.process(n):this)},process:function(t){var n=this;return t=e.grep(t,function(e){return n.matcher(e)}),t=this.sorter(t),t.length?this.render(t.slice(0,this.options.items)).show():this.shown?this.hide():this},matcher:function(e){return~e.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(e){var t=[],n=[],r=[],i;while(i=e.shift())i.toLowerCase().indexOf(this.query.toLowerCase())?~i.indexOf(this.query)?n.push(i):r.push(i):t.push(i);return t.concat(n,r)},highlighter:function(e){var t=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return e.replace(new RegExp("("+t+")","ig"),function(e,t){return"<strong>"+t+"</strong>"})},render:function(t){var n=this;return t=e(t).map(function(t,r){return t=e(n.options.item).attr("data-value",r),t.find("a").html(n.highlighter(r)),t[0]}),t.first().addClass("active"),this.$menu.html(t),this},next:function(t){var n=this.$menu.find(".active").removeClass("active"),r=n.next();r.length||(r=e(this.$menu.find("li")[0])),r.addClass("active")},prev:function(e){var t=this.$menu.find(".active").removeClass("active"),n=t.prev();n.length||(n=this.$menu.find("li").last()),n.addClass("active")},listen:function(){this.$element.on("focus",e.proxy(this.focus,this)).on("blur",e.proxy(this.blur,this)).on("keypress",e.proxy(this.keypress,this)).on("keyup",e.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",e.proxy(this.keydown,this)),this.$menu.on("click",e.proxy(this.click,this)).on("mouseenter","li",e.proxy(this.mouseenter,this)).on("mouseleave","li",e.proxy(this.mouseleave,this))},eventSupported:function(e){var t=e in this.$element;return t||(this.$element.setAttribute(e,"return;"),t=typeof this.$element[e]=="function"),t},move:function(e){if(!this.shown)return;switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()},keydown:function(t){this.suppressKeyPressRepeat=~e.inArray(t.keyCode,[40,38,9,13,27]),this.move(t)},keypress:function(e){if(this.suppressKeyPressRepeat)return;this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},focus:function(e){this.focused=!0},blur:function(e){this.focused=!1,!this.mousedover&&this.shown&&this.hide()},click:function(e){e.stopPropagation(),e.preventDefault(),this.select(),this.$element.focus()},mouseenter:function(t){this.mousedover=!0,this.$menu.find(".active").removeClass("active"),e(t.currentTarget).addClass("active")},mouseleave:function(e){this.mousedover=!1,!this.focused&&this.shown&&this.hide()}};var n=e.fn.typeahead;e.fn.typeahead=function(n){return this.each(function(){var r=e(this),i=r.data("typeahead"),s=typeof n=="object"&&n;i||r.data("typeahead",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.typeahead.defaults={source:[],items:8,menu:'<ul class="typeahead dropdown-menu"></ul>',item:'<li><a href="#"></a></li>',minLength:1},e.fn.typeahead.Constructor=t,e.fn.typeahead.noConflict=function(){return e.fn.typeahead=n,this},e(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(t){var n=e(this);if(n.data("typeahead"))return;n.typeahead(n.data())})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=e.extend({},e.fn.affix.defaults,n),this.$window=e(window).on("scroll.affix.data-api",e.proxy(this.checkPosition,this)).on("click.affix.data-api",e.proxy(function(){setTimeout(e.proxy(this.checkPosition,this),1)},this)),this.$element=e(t),this.checkPosition()};t.prototype.checkPosition=function(){if(!this.$element.is(":visible"))return;var t=e(document).height(),n=this.$window.scrollTop(),r=this.$element.offset(),i=this.options.offset,s=i.bottom,o=i.top,u="affix affix-top affix-bottom",a;typeof i!="object"&&(s=o=i),typeof o=="function"&&(o=i.top()),typeof s=="function"&&(s=i.bottom()),a=this.unpin!=null&&n+this.unpin<=r.top?!1:s!=null&&r.top+this.$element.height()>=t-s?"bottom":o!=null&&n<=o?"top":!1;if(this.affixed===a)return;this.affixed=a,this.unpin=a=="bottom"?r.top-n:null,this.$element.removeClass(u).addClass("affix"+(a?"-"+a:""))};var n=e.fn.affix;e.fn.affix=function(n){return this.each(function(){var r=e(this),i=r.data("affix"),s=typeof n=="object"&&n;i||r.data("affix",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.affix.Constructor=t,e.fn.affix.defaults={offset:0},e.fn.affix.noConflict=function(){return e.fn.affix=n,this},e(window).on("load",function(){e('[data-spy="affix"]').each(function(){var t=e(this),n=t.data();n.offset=n.offset||{},n.offsetBottom&&(n.offset.bottom=n.offsetBottom),n.offsetTop&&(n.offset.top=n.offsetTop),t.affix(n)})})}(window.jQuery);
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,360 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
2
|
+
"http://www.w3.org/TR/html4/strict.dtd">
|
3
|
+
|
4
|
+
<html lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
7
|
+
<title>bio-svgenes Manual</title>
|
8
|
+
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
|
9
|
+
<meta name="generator" content="TextMate http://macromates.com/">
|
10
|
+
<meta name="author" content="Dan MacLean (TSL)">
|
11
|
+
<!-- Date: 2013-04-09 -->
|
12
|
+
</head>
|
13
|
+
<body>
|
14
|
+
<div style="padding : 2em;">
|
15
|
+
<h1>bio-svgenes</h1>
|
16
|
+
|
17
|
+
<h2>A Ruby gem for rendering genomic features quickly and easily in SVG format</h2>
|
18
|
+
|
19
|
+
<p>SVGenes is a Ruby-language library that uses SVG primitives to render typical genomic glyphs through a simple and flexible Ruby interface. </p>
|
20
|
+
|
21
|
+
<h2>Installation</h2>
|
22
|
+
|
23
|
+
<p>This should be easy - the package is available as a gem. If you have an internet connection try:</p>
|
24
|
+
|
25
|
+
<pre><code>gem install bio-svgenes
|
26
|
+
</code></pre>
|
27
|
+
|
28
|
+
<p>If this doesn't work try,</p>
|
29
|
+
|
30
|
+
<pre><code>sudo gem install bio-svgenes
|
31
|
+
</code></pre>
|
32
|
+
|
33
|
+
<h2>Basic use</h2>
|
34
|
+
|
35
|
+
<ol>
|
36
|
+
<li>Design</li>
|
37
|
+
<li>Setting up a page</li>
|
38
|
+
<li>Adding a track</li>
|
39
|
+
<li>Creating and adding features</li>
|
40
|
+
<li>Writing the resulting SVG</li>
|
41
|
+
<li>Styling features
|
42
|
+
<ol>
|
43
|
+
<li>Available glyphs</li>
|
44
|
+
<li>Setting basic styles: colours and outlines</li>
|
45
|
+
<li>Setting advanced styles: gradients and arbitrary styles
|
46
|
+
4 . Height options for tracks</li>
|
47
|
+
</ol></li>
|
48
|
+
<li>Generating SVG from JSON configuration files</li>
|
49
|
+
<li>File formats</li>
|
50
|
+
</ol>
|
51
|
+
|
52
|
+
<h3>1. Design</h3>
|
53
|
+
|
54
|
+
<p>The library implements a simple Page object (a Bio::Graphics::Page object) that defines the whole drawing area. It carries the horizontal track objects (Bio::Graphics::Track objects). Tracks are the level at which visual information is supplied providing the full styling capability of the SVG standard.
|
55
|
+
A glyph type is chosen for each track and all features in a track are rendered with the same glyph any of a selection of defined glyphs. The feature model within SVGenes is simple but flexible and not dependent on particular existing gene feature formats meaning graphics for any existing datasets can easily be created without need for conversion.</p>
|
56
|
+
|
57
|
+
<p>To bring the code into your script, load in the gem</p>
|
58
|
+
|
59
|
+
<pre><code>require 'bio-svgenes'
|
60
|
+
</code></pre>
|
61
|
+
|
62
|
+
<h3>2. Setting up a page</h3>
|
63
|
+
|
64
|
+
<p>The first thing we need to do is set up the page object, a <code>Bio::Graphics::Page</code> instance. This defines the attributes of the page into which our features will be drawn.</p>
|
65
|
+
|
66
|
+
<pre><code>p = Bio::Graphics::Page.new(
|
67
|
+
:width => 800,
|
68
|
+
:height => 200,
|
69
|
+
:number_of_intervals => 10
|
70
|
+
)
|
71
|
+
</code></pre>
|
72
|
+
|
73
|
+
<p>The <code>:width</code> attribute specifies the minimum width of the page and the <code>:height</code> attribute specifies the minimum height. Each of these will be increased if successful rendering requires more room than specified. The <code>:number_of_intervals</code> attributes specifies the number of segments to divide the scale into. A scale is always drawn.</p>
|
74
|
+
|
75
|
+
<h3>3. Add a track to the page</h3>
|
76
|
+
|
77
|
+
<p>Next, we need to add a track to the page. We do this with the <code>Bio::Graphics::Page#add_track</code> method. Glyphs are rendered within tracks and tracks define how those glyphs will be styled. In this example we create a <code>generic</code> block glyph.</p>
|
78
|
+
|
79
|
+
<pre><code>generic_track = p.add_track(
|
80
|
+
:glyph => :generic,
|
81
|
+
:name => 'generic_features',
|
82
|
+
:label => true
|
83
|
+
)
|
84
|
+
</code></pre>
|
85
|
+
|
86
|
+
<p>The <code>:name</code> attribute allows us to define a name for the track and the <code>:label</code> attribute explicitly states whether the name should be written onto the track.</p>
|
87
|
+
|
88
|
+
<h3>4. Create a MiniFeature object</h3>
|
89
|
+
|
90
|
+
<p>Each of the features is represented by a <code>Bio::Graphics::MiniFeature</code> object. This is easily created:</p>
|
91
|
+
|
92
|
+
<pre><code>mini_feature = Bio::Graphics::MiniFeature.new(
|
93
|
+
:start => 923,
|
94
|
+
:end => 2212,
|
95
|
+
:strand => '+',
|
96
|
+
:id => "MyFeature"
|
97
|
+
)
|
98
|
+
</code></pre>
|
99
|
+
|
100
|
+
<p>The minimum information you need to provide for a feature is the start and end. In this example, we add a strand and an id for the feature.</p>
|
101
|
+
|
102
|
+
<h4>Add the feature to the track</h4>
|
103
|
+
|
104
|
+
<p>The feature now needs to be added to the track object to be considered during rendering, we use <code>Bio::Graphics::Track#add</code> for this.</p>
|
105
|
+
|
106
|
+
<pre><code>generic_track.add(mini_feature)
|
107
|
+
</code></pre>
|
108
|
+
|
109
|
+
<h3>5. Write the output to a file</h3>
|
110
|
+
|
111
|
+
<p>This process is repeated for all the features and tracks you want to show in the final rendered figure. We then tell the page to render itself to a file.</p>
|
112
|
+
|
113
|
+
<pre><code>p.write("output.svg")
|
114
|
+
</code></pre>
|
115
|
+
|
116
|
+
<h3>6. Styling features</h3>
|
117
|
+
|
118
|
+
<p>Selecting a style for the features in a track is done when you create the Bio::Graphics::Track object. The style information is applied to all features that appear in that track. </p>
|
119
|
+
|
120
|
+
<h4>Available glyphs</h4>
|
121
|
+
|
122
|
+
<p>A range of glyphs for features are used, namely</p>
|
123
|
+
|
124
|
+
<pre><code>:generic, :directed, :transcript, :histogram, :circle, :down_triangle, :up_triangle, :span
|
125
|
+
</code></pre>
|
126
|
+
|
127
|
+
<p>These look like this</p>
|
128
|
+
|
129
|
+
<ul>
|
130
|
+
<li><code>:generic</code> <img src="img/generic.png" alt="generic glyph" title="" /></li>
|
131
|
+
<li><code>:directed</code> <img src="img/directed.png" alt="directed glyph" title="" /></li>
|
132
|
+
<li><code>:transcript</code> <img src="img/transcript.png" alt="transcript glyph" title="" /></li>
|
133
|
+
<li><code>:histogram</code> <img src="img/histogram.png" alt="histogram glyph" title="" /></li>
|
134
|
+
<li><code>:circle</code> <img src="img/circle.png" alt="circle glyph" title="" /></li>
|
135
|
+
<li><code>:down_triangle</code> <img src="img/down_triangle.png" alt="down triangle glyph" title="" /></li>
|
136
|
+
<li><code>:up_triangle</code> <img src="img/up_triangle.png" alt="up triangle glyph" title="" /></li>
|
137
|
+
<li><code>:span</code> <img src="img/span.png" alt="span glyph" title="" /></li>
|
138
|
+
</ul>
|
139
|
+
|
140
|
+
<p>You can specify the glyph to use in the <code>add_track()</code> method for the page</p>
|
141
|
+
|
142
|
+
<pre><code>track = page.add_track(
|
143
|
+
:glyph => :generic
|
144
|
+
)
|
145
|
+
</code></pre>
|
146
|
+
|
147
|
+
<h4>Providing enough feature information for the glyph</h4>
|
148
|
+
|
149
|
+
<p>Different types of glyphs need different types of information to render the feature fully.
|
150
|
+
<code>:generic, :circle, :up_triangle, :down_triangle, :span</code> glyphs need the minimum feature information, just a start and a stop. Start and end can be the same number if you want to specify a single nucleotide feature.</p>
|
151
|
+
|
152
|
+
<pre><code>track = page.add_track(
|
153
|
+
:glyph => :circle
|
154
|
+
)
|
155
|
+
|
156
|
+
feature = Bio::Graphics::MiniFeature.new(
|
157
|
+
:start => 100,
|
158
|
+
:end => 200
|
159
|
+
)
|
160
|
+
|
161
|
+
track.add(feature)
|
162
|
+
</code></pre>
|
163
|
+
|
164
|
+
<p>In addition, the 'stranded' glyphs <code>:directed</code> and <code>:transcript</code> need a strand (+ will be assumed if none is provided).</p>
|
165
|
+
|
166
|
+
<pre><code>track = page.add_track(
|
167
|
+
:glyph => :circle
|
168
|
+
)
|
169
|
+
|
170
|
+
feature = Bio::Graphics::MiniFeature.new(
|
171
|
+
:start => 100,
|
172
|
+
:end => 200,
|
173
|
+
:strand => '-'
|
174
|
+
)
|
175
|
+
|
176
|
+
track.add(feature)
|
177
|
+
</code></pre>
|
178
|
+
|
179
|
+
<p>The <code>:histogram</code> feature is a bit more complicated. Each bar in the histogram is a feature. It's width on the x-axis is specified by it's <code>:start</code> and <code>:end</code> as for the other features, but it has a <code>:segment_height</code> that specifies the bar-height</p>
|
180
|
+
|
181
|
+
<pre><code>data_track = page.add_track(
|
182
|
+
:glyph => :histogram
|
183
|
+
)
|
184
|
+
|
185
|
+
data_feature = Bio::Graphics::MiniFeature.new(
|
186
|
+
:start => 100,
|
187
|
+
:end => 200,
|
188
|
+
:segment_height => 30
|
189
|
+
)
|
190
|
+
|
191
|
+
data_track.add(data_feature)
|
192
|
+
</code></pre>
|
193
|
+
|
194
|
+
<p>Histogram bars can have overlapping or gapped start and end positions if needed. </p>
|
195
|
+
|
196
|
+
<p>Features to be rendered with the <code>:transcript</code> glyph need extra information. The exons and utrs are specified as even-numbered lists of start and stop positions. </p>
|
197
|
+
|
198
|
+
<pre><code>track = page.add_track(
|
199
|
+
:glyph => :transcript
|
200
|
+
)
|
201
|
+
|
202
|
+
feature = Bio::Graphics::MiniFeature.new(
|
203
|
+
:start => 100,
|
204
|
+
:end => 200,
|
205
|
+
:strand => '-',
|
206
|
+
:utrs => [100,110,90,200],
|
207
|
+
:exons => [120,140,160,180]
|
208
|
+
)
|
209
|
+
|
210
|
+
track.add(feature)
|
211
|
+
</code></pre>
|
212
|
+
|
213
|
+
<h4>Setting fill and outline colours</h4>
|
214
|
+
|
215
|
+
<p>Fill and outline colours are specified when creating the track. Any HTML/SVG compatible colour string can be used, so <code>rgb(125,123,0)</code> or <code>#ffff11</code> or <code>goldenrod</code> are all acceptable for each of the following attributes</p>
|
216
|
+
|
217
|
+
<p><code>:stroke_color</code> is the outline colour of the glyph
|
218
|
+
<code>:stroke_width</code> is the width of the outline of the glyph
|
219
|
+
<code>:fill_color</code> is the fill colour of the glyph</p>
|
220
|
+
|
221
|
+
<pre><code>track = page.add_track(
|
222
|
+
:glyph => :directed,
|
223
|
+
:stroke_color => 'black',
|
224
|
+
:fill_color => 'gold',
|
225
|
+
:stroke_width => '1',
|
226
|
+
)
|
227
|
+
</code></pre>
|
228
|
+
|
229
|
+
<p>Transcript glyphs can have separate colours for the exons and utrs, using <code>:exon_fill_color</code> and <code>:utr_fill_color</code>. The line joining them can be coloured with <code>:line_color</code> and you can decide to have an angled line by setting <code>:gap_marker</code> to "angled"</p>
|
230
|
+
|
231
|
+
<pre><code>transcript_track = page.add_track(
|
232
|
+
:glyph => :transcript,
|
233
|
+
:exon_fill_color => 'green',
|
234
|
+
:utr_fill_color => 'blue',
|
235
|
+
:line_color => 'black',
|
236
|
+
:gap_marker => 'angled'
|
237
|
+
)
|
238
|
+
</code></pre>
|
239
|
+
|
240
|
+
<h4>Setting gradients and arbitrary styles</h4>
|
241
|
+
|
242
|
+
<p>A number of gradient styles are built-in and can be easily used as a fill colour for glyphs. Two basic types <code>radial</code> (which start from a white centre and fade to a colour) and <code>horizontal</code> (which start from white along the bottom edge and fade to a colour) are available in red, blue, yellow and green. The symbols for the attributes are</p>
|
243
|
+
|
244
|
+
<pre><code>:red_white_radial, :green_white_radial, :blue_white_radial, :yellow_white_radial, :red_white_h, :green_white_h, :blue_white, :yellow_white_h
|
245
|
+
</code></pre>
|
246
|
+
|
247
|
+
<p>and are set as</p>
|
248
|
+
|
249
|
+
<pre><code>track = page.add_track(
|
250
|
+
:glyph => :directed,
|
251
|
+
:stroke_color => 'black',
|
252
|
+
:fill_color => :red_white_h
|
253
|
+
)
|
254
|
+
</code></pre>
|
255
|
+
|
256
|
+
<p>Arbitrary gradients can be built according to the SVG gradient rules (see <a href="http://www.w3schools.com/svg/svg_grad_linear.asp">SVG gradient linear</a> and <a href="http://www.w3schools.com/svg/svg_grad_radial.asp">SVG gradient radial</a> ) using a ruby-ish attributes hash.</p>
|
257
|
+
|
258
|
+
<pre><code>my_gradient = {
|
259
|
+
|
260
|
+
:radial => "grad1",
|
261
|
+
:cx => 50,
|
262
|
+
:cy => 50,
|
263
|
+
:r => 50, :fx => 50, :
|
264
|
+
fy => 50,
|
265
|
+
:stops => [
|
266
|
+
{
|
267
|
+
:offset => 0,
|
268
|
+
:color => 'rgb(255,255,255)',
|
269
|
+
:opacity => 0
|
270
|
+
},
|
271
|
+
{
|
272
|
+
:offset => 100,
|
273
|
+
:color => 'rgb(0,0,255)',
|
274
|
+
:opacity => 1
|
275
|
+
}
|
276
|
+
]
|
277
|
+
}
|
278
|
+
</code></pre>
|
279
|
+
|
280
|
+
<p>simply pass this to the track <code>:fill_color</code> attribute.</p>
|
281
|
+
|
282
|
+
<pre><code>track = page.add_track(
|
283
|
+
:glyph => :directed,
|
284
|
+
:stroke_color => 'black',
|
285
|
+
:fill_color => my_gradient
|
286
|
+
)
|
287
|
+
</code></pre>
|
288
|
+
|
289
|
+
<p>The <code>:style</code> attribute can accept and use any arbitrarily complex SVG compliant style tag (see <a href="http://www.w3.org/TR/SVG/styling.html">SVG styling</a> ). A common use is to modify the opacity of glyphs</p>
|
290
|
+
|
291
|
+
<pre><code>track = page.add_track(
|
292
|
+
:glyph => :generic,
|
293
|
+
:style => "fill-opacity:0.4;"
|
294
|
+
)
|
295
|
+
</code></pre>
|
296
|
+
|
297
|
+
<h4>Height options for tracks</h4>
|
298
|
+
|
299
|
+
<p>The height of the glyphs may also be specified. Do this by setting the <code>:feature_height</code> attribute</p>
|
300
|
+
|
301
|
+
<pre><code>track = page.add_track(
|
302
|
+
:glyph => :generic,
|
303
|
+
:feature_height => 123
|
304
|
+
)
|
305
|
+
</code></pre>
|
306
|
+
|
307
|
+
<p>In data tracks (with the <code>:histogram</code> glyph) a maximum value for the y-scale can be specified that will be enforced and prevent the scale from being auto-calculated. This allows for easy comparison between multiple data tracks, use <code>:max_y</code>.</p>
|
308
|
+
|
309
|
+
<pre><code>track = page.add_track(
|
310
|
+
:glyph => :histogram,
|
311
|
+
:max_y => 1000
|
312
|
+
)
|
313
|
+
</code></pre>
|
314
|
+
|
315
|
+
<h3>6. Generating SVG from JSON configuration files</h3>
|
316
|
+
|
317
|
+
<p>It is also possible to generate the SVG from a <a href="http://en.wikipedia.org/wiki/JSON">JSON</a> file containing the track information and a reference to file of features in <a href="http://www.sequenceontology.org/gff3.shtml">GFF</a> format or histogram data in a tab-delimited file. The following sample specifies the page and two tracks, one for features one for data. The new attributes <code>file</code> and <code>file_type</code> specify the file and file format respectively. </p>
|
318
|
+
|
319
|
+
<pre><code>{
|
320
|
+
"Page":{"width":800, "height":800, "intervals":15},
|
321
|
+
"Tracks": [
|
322
|
+
{
|
323
|
+
"glyph":"generic",
|
324
|
+
"name":"Genes",
|
325
|
+
"label":true,
|
326
|
+
"file":"gene.gff",
|
327
|
+
"file_type":"gff",
|
328
|
+
"fill_color":"red",
|
329
|
+
"stroke_width":1,
|
330
|
+
"x_round":4,
|
331
|
+
"y_round":4
|
332
|
+
},
|
333
|
+
{
|
334
|
+
"glyph":"histogram",
|
335
|
+
"name":"Data",
|
336
|
+
"label":true,
|
337
|
+
"file":"data.txt",
|
338
|
+
"file_type":"data",
|
339
|
+
"track_height":100,
|
340
|
+
"fill_color":"yellow_white_radial",
|
341
|
+
"stroke_width":1
|
342
|
+
}
|
343
|
+
]
|
344
|
+
}
|
345
|
+
</code></pre>
|
346
|
+
|
347
|
+
<p>The data file has a simple format, for each bar of the histogram specify one row with three columns</p>
|
348
|
+
|
349
|
+
<pre><code>start, end, height
|
350
|
+
</code></pre>
|
351
|
+
|
352
|
+
<p>To generate the file, run the provided accessory script <code>draw_from_json.rb</code> which is found in the package examples folder. Find the folder the gem installed into with <code>gem which bio-svgenes</code>. You can then run the script with the following
|
353
|
+
|
354
|
+
<pre><code>ruby draw_from_json.rb --json_file json_config_file --svg_file svg_outfile.svg</code></pre>
|
355
|
+
|
356
|
+
where <code>json_config_file</code> is the name of the file with the JSON in and <code>svg_outfile.svg</code> is the name of the file into which the SVG is written.
|
357
|
+
</p>
|
358
|
+
</div>
|
359
|
+
</body>
|
360
|
+
</html>
|
@@ -0,0 +1,307 @@
|
|
1
|
+
# bio-svgenes
|
2
|
+
|
3
|
+
## A Ruby gem for rendering genomic features quickly and easily in SVG format
|
4
|
+
SVGenes is a Ruby-language library that uses SVG primitives to render typical genomic glyphs through a simple and flexible Ruby interface.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
This should be easy - the package is available as a gem. If you have an internet connection try:
|
9
|
+
|
10
|
+
gem install bio-svgenes
|
11
|
+
|
12
|
+
If this doesn't work try,
|
13
|
+
|
14
|
+
sudo gem install bio-svgenes
|
15
|
+
|
16
|
+
## Basic use
|
17
|
+
0. Design
|
18
|
+
1. Setting up a page
|
19
|
+
2. Adding a track
|
20
|
+
3. Creating and adding features
|
21
|
+
4. Writing the resulting SVG
|
22
|
+
5. Styling features
|
23
|
+
1. Available glyphs
|
24
|
+
2. Setting basic styles: colours and outlines
|
25
|
+
3. Setting advanced styles: gradients and arbitrary styles
|
26
|
+
4 . Height options for tracks
|
27
|
+
6. Generating SVG from JSON configuration files
|
28
|
+
7. File formats
|
29
|
+
|
30
|
+
|
31
|
+
### 1. Design
|
32
|
+
The library implements a simple Page object (a Bio::Graphics::Page object) that defines the whole drawing area. It carries the horizontal track objects (Bio::Graphics::Track objects). Tracks are the level at which visual information is supplied providing the full styling capability of the SVG standard.
|
33
|
+
A glyph type is chosen for each track and all features in a track are rendered with the same glyph any of a selection of defined glyphs. The feature model within SVGenes is simple but flexible and not dependent on particular existing gene feature formats meaning graphics for any existing datasets can easily be created without need for conversion.
|
34
|
+
|
35
|
+
|
36
|
+
To bring the code into your script, load in the gem
|
37
|
+
|
38
|
+
require 'bio-svgenes'
|
39
|
+
|
40
|
+
### 2. Setting up a page
|
41
|
+
|
42
|
+
The first thing we need to do is set up the page object, a `Bio::Graphics::Page` instance. This defines the attributes of the page into which our features will be drawn.
|
43
|
+
|
44
|
+
p = Bio::Graphics::Page.new(
|
45
|
+
:width => 800,
|
46
|
+
:height => 200,
|
47
|
+
:number_of_intervals => 10
|
48
|
+
)
|
49
|
+
|
50
|
+
The `:width` attribute specifies the minimum width of the page and the `:height` attribute specifies the minimum height. Each of these will be increased if successful rendering requires more room than specified. The `:number_of_intervals` attributes specifies the number of segments to divide the scale into. A scale is always drawn.
|
51
|
+
|
52
|
+
### 3. Add a track to the page
|
53
|
+
Next, we need to add a track to the page. We do this with the `Bio::Graphics::Page#add_track` method. Glyphs are rendered within tracks and tracks define how those glyphs will be styled. In this example we create a `generic` block glyph.
|
54
|
+
|
55
|
+
generic_track = p.add_track(
|
56
|
+
:glyph => :generic,
|
57
|
+
:name => 'generic_features',
|
58
|
+
:label => true
|
59
|
+
)
|
60
|
+
|
61
|
+
The `:name` attribute allows us to define a name for the track and the `:label` attribute explicitly states whether the name should be written onto the track.
|
62
|
+
|
63
|
+
### 4. Create a MiniFeature object
|
64
|
+
Each of the features is represented by a `Bio::Graphics::MiniFeature` object. This is easily created:
|
65
|
+
|
66
|
+
mini_feature = Bio::Graphics::MiniFeature.new(
|
67
|
+
:start => 923,
|
68
|
+
:end => 2212,
|
69
|
+
:strand => '+',
|
70
|
+
:id => "MyFeature"
|
71
|
+
)
|
72
|
+
|
73
|
+
The minimum information you need to provide for a feature is the start and end. In this example, we add a strand and an id for the feature.
|
74
|
+
|
75
|
+
#### Add the feature to the track
|
76
|
+
|
77
|
+
The feature now needs to be added to the track object to be considered during rendering, we use `Bio::Graphics::Track#add` for this.
|
78
|
+
|
79
|
+
generic_track.add(mini_feature)
|
80
|
+
|
81
|
+
|
82
|
+
### 5. Write the output to a file
|
83
|
+
This process is repeated for all the features and tracks you want to show in the final rendered figure. We then tell the page to render itself to a file.
|
84
|
+
|
85
|
+
p.write("output.svg")
|
86
|
+
|
87
|
+
|
88
|
+
### 6. Styling features
|
89
|
+
|
90
|
+
Selecting a style for the features in a track is done when you create the Bio::Graphics::Track object. The style information is applied to all features that appear in that track.
|
91
|
+
|
92
|
+
#### Available glyphs
|
93
|
+
|
94
|
+
A range of glyphs for features are used, namely
|
95
|
+
|
96
|
+
:generic, :directed, :transcript, :histogram, :circle, :down_triangle, :up_triangle, :span
|
97
|
+
|
98
|
+
These look like this
|
99
|
+
|
100
|
+
+ `:generic` ![generic glyph](img/generic.png)
|
101
|
+
+ `:directed` ![directed glyph](img/directed.png)
|
102
|
+
+ `:transcript` ![transcript glyph](img/transcript.png)
|
103
|
+
+ `:histogram` ![histogram glyph](img/histogram.png)
|
104
|
+
+ `:circle` ![circle glyph](img/circle.png)
|
105
|
+
+ `:down_triangle` ![down triangle glyph](img/down_triangle.png)
|
106
|
+
+ `:up_triangle` ![up triangle glyph](img/up_triangle.png)
|
107
|
+
+ `:span` ![span glyph](img/span.png)
|
108
|
+
|
109
|
+
You can specify the glyph to use in the `add_track()` method for the page
|
110
|
+
|
111
|
+
track = page.add_track(
|
112
|
+
:glyph => :generic
|
113
|
+
)
|
114
|
+
|
115
|
+
#### Providing enough feature information for the glyph
|
116
|
+
|
117
|
+
Different types of glyphs need different types of information to render the feature fully.
|
118
|
+
`:generic, :circle, :up_triangle, :down_triangle, :span` glyphs need the minimum feature information, just a start and a stop. Start and end can be the same number if you want to specify a single nucleotide feature.
|
119
|
+
|
120
|
+
track = page.add_track(
|
121
|
+
:glyph => :circle
|
122
|
+
)
|
123
|
+
|
124
|
+
feature = Bio::Graphics::MiniFeature.new(
|
125
|
+
:start => 100,
|
126
|
+
:end => 200
|
127
|
+
)
|
128
|
+
|
129
|
+
track.add(feature)
|
130
|
+
|
131
|
+
|
132
|
+
In addition, the 'stranded' glyphs `:directed` and `:transcript` need a strand (+ will be assumed if none is provided).
|
133
|
+
|
134
|
+
track = page.add_track(
|
135
|
+
:glyph => :circle
|
136
|
+
)
|
137
|
+
|
138
|
+
feature = Bio::Graphics::MiniFeature.new(
|
139
|
+
:start => 100,
|
140
|
+
:end => 200,
|
141
|
+
:strand => '-'
|
142
|
+
)
|
143
|
+
|
144
|
+
track.add(feature)
|
145
|
+
|
146
|
+
The `:histogram` feature is a bit more complicated. Each bar in the histogram is a feature. It's width on the x-axis is specified by it's `:start` and `:end` as for the other features, but it has a `:segment_height` that specifies the bar-height
|
147
|
+
|
148
|
+
data_track = page.add_track(
|
149
|
+
:glyph => :histogram
|
150
|
+
)
|
151
|
+
|
152
|
+
data_feature = Bio::Graphics::MiniFeature.new(
|
153
|
+
:start => 100,
|
154
|
+
:end => 200,
|
155
|
+
:segment_height => 30
|
156
|
+
)
|
157
|
+
|
158
|
+
data_track.add(data_feature)
|
159
|
+
|
160
|
+
Histogram bars can have overlapping or gapped start and end positions if needed.
|
161
|
+
|
162
|
+
Features to be rendered with the `:transcript` glyph need extra information. The exons and utrs are specified as even-numbered lists of start and stop positions.
|
163
|
+
|
164
|
+
track = page.add_track(
|
165
|
+
:glyph => :transcript
|
166
|
+
)
|
167
|
+
|
168
|
+
feature = Bio::Graphics::MiniFeature.new(
|
169
|
+
:start => 100,
|
170
|
+
:end => 200,
|
171
|
+
:strand => '-',
|
172
|
+
:utrs => [100,110,90,200],
|
173
|
+
:exons => [120,140,160,180]
|
174
|
+
)
|
175
|
+
|
176
|
+
track.add(feature)
|
177
|
+
|
178
|
+
#### Setting fill and outline colours
|
179
|
+
|
180
|
+
Fill and outline colours are specified when creating the track. Any HTML/SVG compatible colour string can be used, so `rgb(125,123,0)` or `#ffff11` or `goldenrod` are all acceptable for each of the following attributes
|
181
|
+
|
182
|
+
`:stroke_color` is the outline colour of the glyph
|
183
|
+
`:stroke_width` is the width of the outline of the glyph
|
184
|
+
`:fill_color` is the fill colour of the glyph
|
185
|
+
|
186
|
+
track = page.add_track(
|
187
|
+
:glyph => :directed,
|
188
|
+
:stroke_color => 'black',
|
189
|
+
:fill_color => 'gold',
|
190
|
+
:stroke_width => '1',
|
191
|
+
)
|
192
|
+
|
193
|
+
Transcript glyphs can have separate colours for the exons and utrs, using `:exon_fill_color` and `:utr_fill_color`. The line joining them can be coloured with `:line_color` and you can decide to have an angled line by setting `:gap_marker` to "angled"
|
194
|
+
|
195
|
+
transcript_track = page.add_track(
|
196
|
+
:glyph => :transcript,
|
197
|
+
:exon_fill_color => 'green',
|
198
|
+
:utr_fill_color => 'blue',
|
199
|
+
:line_color => 'black',
|
200
|
+
:gap_marker => 'angled'
|
201
|
+
)
|
202
|
+
|
203
|
+
#### Setting gradients and arbitrary styles
|
204
|
+
|
205
|
+
A number of gradient styles are built-in and can be easily used as a fill colour for glyphs. Two basic types `radial` (which start from a white centre and fade to a colour) and `horizontal` (which start from white along the bottom edge and fade to a colour) are available in red, blue, yellow and green. The symbols for the attributes are
|
206
|
+
|
207
|
+
:red_white_radial, :green_white_radial, :blue_white_radial, :yellow_white_radial, :red_white_h, :green_white_h, :blue_white, :yellow_white_h
|
208
|
+
|
209
|
+
and are set as
|
210
|
+
|
211
|
+
track = page.add_track(
|
212
|
+
:glyph => :directed,
|
213
|
+
:stroke_color => 'black',
|
214
|
+
:fill_color => :red_white_h
|
215
|
+
)
|
216
|
+
|
217
|
+
Arbitrary gradients can be built according to the SVG gradient rules (see [SVG gradient linear](http://www.w3schools.com/svg/svg_grad_linear.asp) and [SVG gradient radial](http://www.w3schools.com/svg/svg_grad_radial.asp) ) using a ruby-ish attributes hash.
|
218
|
+
|
219
|
+
my_gradient = {
|
220
|
+
|
221
|
+
:radial => "grad1",
|
222
|
+
:cx => 50,
|
223
|
+
:cy => 50,
|
224
|
+
:r => 50, :fx => 50, :
|
225
|
+
fy => 50,
|
226
|
+
:stops => [
|
227
|
+
{
|
228
|
+
:offset => 0,
|
229
|
+
:color => 'rgb(255,255,255)',
|
230
|
+
:opacity => 0
|
231
|
+
},
|
232
|
+
{
|
233
|
+
:offset => 100,
|
234
|
+
:color => 'rgb(0,0,255)',
|
235
|
+
:opacity => 1
|
236
|
+
}
|
237
|
+
]
|
238
|
+
}
|
239
|
+
|
240
|
+
|
241
|
+
simply pass this to the track `:fill_color` attribute.
|
242
|
+
|
243
|
+
track = page.add_track(
|
244
|
+
:glyph => :directed,
|
245
|
+
:stroke_color => 'black',
|
246
|
+
:fill_color => my_gradient
|
247
|
+
)
|
248
|
+
|
249
|
+
The `:style` attribute can accept and use any arbitrarily complex SVG compliant style tag (see [SVG styling](http://www.w3.org/TR/SVG/styling.html) ). A common use is to modify the opacity of glyphs
|
250
|
+
|
251
|
+
track = page.add_track(
|
252
|
+
:glyph => :generic,
|
253
|
+
:style => "fill-opacity:0.4;"
|
254
|
+
)
|
255
|
+
|
256
|
+
#### Height options for tracks
|
257
|
+
|
258
|
+
The height of the glyphs may also be specified. Do this by setting the `:feature_height` attribute
|
259
|
+
|
260
|
+
track = page.add_track(
|
261
|
+
:glyph => :generic,
|
262
|
+
:feature_height => 123
|
263
|
+
)
|
264
|
+
|
265
|
+
In data tracks (with the `:histogram` glyph) a maximum value for the y-scale can be specified that will be enforced and prevent the scale from being auto-calculated. This allows for easy comparison between multiple data tracks, use `:max_y`.
|
266
|
+
|
267
|
+
track = page.add_track(
|
268
|
+
:glyph => :histogram,
|
269
|
+
:max_y => 1000
|
270
|
+
)
|
271
|
+
|
272
|
+
### 6. Generating SVG from JSON configuration files
|
273
|
+
|
274
|
+
It is also possible to generate the SVG from a [JSON](http://en.wikipedia.org/wiki/JSON) file containing the track information and a reference to file of features in [GFF](http://www.sequenceontology.org/gff3.shtml) format or histogram data in a tab-delimited file. The following sample specifies the page and two tracks, one for features one for data. The new attributes `file` and `file_type` specify the file and file format respectively.
|
275
|
+
|
276
|
+
{
|
277
|
+
"Page":{"width":800, "height":800, "intervals":15},
|
278
|
+
"Tracks": [
|
279
|
+
{
|
280
|
+
"glyph":"generic",
|
281
|
+
"name":"Genes",
|
282
|
+
"label":true,
|
283
|
+
"file":"gene.gff",
|
284
|
+
"file_type":"gff",
|
285
|
+
"fill_color":"red",
|
286
|
+
"stroke_width":1,
|
287
|
+
"x_round":4,
|
288
|
+
"y_round":4
|
289
|
+
},
|
290
|
+
{
|
291
|
+
"glyph":"histogram",
|
292
|
+
"name":"Data",
|
293
|
+
"label":true,
|
294
|
+
"file":"data.txt",
|
295
|
+
"file_type":"data",
|
296
|
+
"track_height":100,
|
297
|
+
"fill_color":"yellow_white_radial",
|
298
|
+
"stroke_width":1
|
299
|
+
}
|
300
|
+
]
|
301
|
+
}
|
302
|
+
|
303
|
+
The data file has a simple format, for each bar of the histogram specify one row with three columns
|
304
|
+
|
305
|
+
start, end, height
|
306
|
+
|
307
|
+
To generate the file, run the provided accessory script `draw_from_json.rb` which is found in the package examples folder. Find the folder the gem installed into with `gem which bio-svgenes`.
|