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.
Files changed (144) hide show
  1. data/README.md +88 -0
  2. data/VERSION +1 -1
  3. data/bio-svgenes.gemspec +131 -8
  4. data/doc/classes/Bio.html +131 -0
  5. data/doc/classes/Bio/Graphics.html +142 -0
  6. data/doc/classes/Bio/Graphics/Glyph.html +987 -0
  7. data/doc/classes/Bio/Graphics/Glyph.src/M000001.html +26 -0
  8. data/doc/classes/Bio/Graphics/Glyph.src/M000002.html +27 -0
  9. data/doc/classes/Bio/Graphics/Glyph.src/M000003.html +32 -0
  10. data/doc/classes/Bio/Graphics/Glyph.src/M000004.html +27 -0
  11. data/doc/classes/Bio/Graphics/Glyph.src/M000005.html +25 -0
  12. data/doc/classes/Bio/Graphics/Glyph.src/M000006.html +29 -0
  13. data/doc/classes/Bio/Graphics/Glyph.src/M000007.html +107 -0
  14. data/doc/classes/Bio/Graphics/Glyph.src/M000008.html +51 -0
  15. data/doc/classes/Bio/Graphics/Glyph.src/M000009.html +23 -0
  16. data/doc/classes/Bio/Graphics/Glyph.src/M000010.html +18 -0
  17. data/doc/classes/Bio/Graphics/Glyph.src/M000011.html +75 -0
  18. data/doc/classes/Bio/Graphics/Glyph.src/M000012.html +51 -0
  19. data/doc/classes/Bio/Graphics/Glyph.src/M000013.html +23 -0
  20. data/doc/classes/Bio/Graphics/Glyph.src/M000014.html +26 -0
  21. data/doc/classes/Bio/Graphics/Glyph.src/M000015.html +27 -0
  22. data/doc/classes/Bio/Graphics/Glyph.src/M000016.html +32 -0
  23. data/doc/classes/Bio/Graphics/Glyph.src/M000017.html +27 -0
  24. data/doc/classes/Bio/Graphics/Glyph.src/M000018.html +25 -0
  25. data/doc/classes/Bio/Graphics/Glyph.src/M000019.html +29 -0
  26. data/doc/classes/Bio/Graphics/Glyph.src/M000020.html +107 -0
  27. data/doc/classes/Bio/Graphics/Glyph.src/M000021.html +51 -0
  28. data/doc/classes/Bio/Graphics/Glyph.src/M000022.html +23 -0
  29. data/doc/classes/Bio/Graphics/Glyph.src/M000023.html +18 -0
  30. data/doc/classes/Bio/Graphics/Glyph.src/M000024.html +75 -0
  31. data/doc/classes/Bio/Graphics/MiniFeature.html +243 -0
  32. data/doc/classes/Bio/Graphics/MiniFeature.src/M000001.html +25 -0
  33. data/doc/classes/Bio/Graphics/MiniFeature.src/M000003.html +25 -0
  34. data/doc/classes/Bio/Graphics/MiniFeature.src/M000024.html +25 -0
  35. data/doc/classes/Bio/Graphics/Page.html +705 -0
  36. data/doc/classes/Bio/Graphics/Page.src/M000010.html +35 -0
  37. data/doc/classes/Bio/Graphics/Page.src/M000011.html +83 -0
  38. data/doc/classes/Bio/Graphics/Page.src/M000012.html +24 -0
  39. data/doc/classes/Bio/Graphics/Page.src/M000013.html +29 -0
  40. data/doc/classes/Bio/Graphics/Page.src/M000014.html +24 -0
  41. data/doc/classes/Bio/Graphics/Page.src/M000015.html +20 -0
  42. data/doc/classes/Bio/Graphics/Page.src/M000016.html +20 -0
  43. data/doc/classes/Bio/Graphics/Page.src/M000017.html +18 -0
  44. data/doc/classes/Bio/Graphics/Page.src/M000018.html +18 -0
  45. data/doc/classes/Bio/Graphics/Page.src/M000019.html +18 -0
  46. data/doc/classes/Bio/Graphics/Page.src/M000020.html +18 -0
  47. data/doc/classes/Bio/Graphics/Page.src/M000021.html +18 -0
  48. data/doc/classes/Bio/Graphics/Page.src/M000022.html +18 -0
  49. data/doc/classes/Bio/Graphics/Page.src/M000023.html +18 -0
  50. data/doc/classes/Bio/Graphics/Page.src/M000024.html +18 -0
  51. data/doc/classes/Bio/Graphics/Page.src/M000025.html +35 -0
  52. data/doc/classes/Bio/Graphics/Page.src/M000026.html +83 -0
  53. data/doc/classes/Bio/Graphics/Page.src/M000027.html +24 -0
  54. data/doc/classes/Bio/Graphics/Page.src/M000028.html +29 -0
  55. data/doc/classes/Bio/Graphics/Page.src/M000029.html +24 -0
  56. data/doc/classes/Bio/Graphics/Page.src/M000030.html +20 -0
  57. data/doc/classes/Bio/Graphics/Page.src/M000031.html +20 -0
  58. data/doc/classes/Bio/Graphics/Page.src/M000032.html +18 -0
  59. data/doc/classes/Bio/Graphics/Page.src/M000033.html +18 -0
  60. data/doc/classes/Bio/Graphics/Page.src/M000034.html +18 -0
  61. data/doc/classes/Bio/Graphics/Page.src/M000035.html +18 -0
  62. data/doc/classes/Bio/Graphics/Page.src/M000036.html +18 -0
  63. data/doc/classes/Bio/Graphics/Page.src/M000037.html +18 -0
  64. data/doc/classes/Bio/Graphics/Page.src/M000038.html +18 -0
  65. data/doc/classes/Bio/Graphics/Page.src/M000039.html +18 -0
  66. data/doc/classes/Bio/Graphics/Page.src/M000040.html +107 -0
  67. data/doc/classes/Bio/Graphics/Page.src/M000041.html +18 -0
  68. data/doc/classes/Bio/Graphics/Page.src/M000042.html +23 -0
  69. data/doc/classes/Bio/Graphics/Page.src/M000043.html +18 -0
  70. data/doc/classes/Bio/Graphics/Page.src/M000044.html +18 -0
  71. data/doc/classes/Bio/Graphics/Primitive.html +204 -0
  72. data/doc/classes/Bio/Graphics/Primitive.src/M000001.html +21 -0
  73. data/doc/classes/Bio/Graphics/Primitive.src/M000002.html +20 -0
  74. data/doc/classes/Bio/Graphics/Primitive.src/M000008.html +21 -0
  75. data/doc/classes/Bio/Graphics/Primitive.src/M000009.html +20 -0
  76. data/doc/classes/Bio/Graphics/Primitive.src/M000022.html +21 -0
  77. data/doc/classes/Bio/Graphics/Primitive.src/M000023.html +20 -0
  78. data/doc/classes/Bio/Graphics/SVGEE.html +290 -0
  79. data/doc/classes/Bio/Graphics/SVGEE.src/M000002.html +24 -0
  80. data/doc/classes/Bio/Graphics/SVGEE.src/M000003.html +18 -0
  81. data/doc/classes/Bio/Graphics/SVGEE.src/M000004.html +24 -0
  82. data/doc/classes/Bio/Graphics/SVGEE.src/M000005.html +18 -0
  83. data/doc/classes/Bio/Graphics/SVGEE.src/M000006.html +18 -0
  84. data/doc/classes/Bio/Graphics/SVGEE.src/M000007.html +21 -0
  85. data/doc/classes/Bio/Graphics/SVGEE.src/M000008.html +27 -0
  86. data/doc/classes/Bio/Graphics/SVGEE.src/M000009.html +23 -0
  87. data/doc/classes/Bio/Graphics/SVGEE.src/M000016.html +24 -0
  88. data/doc/classes/Bio/Graphics/SVGEE.src/M000017.html +18 -0
  89. data/doc/classes/Bio/Graphics/SVGEE.src/M000018.html +18 -0
  90. data/doc/classes/Bio/Graphics/SVGEE.src/M000019.html +21 -0
  91. data/doc/classes/Bio/Graphics/SVGEE.src/M000020.html +27 -0
  92. data/doc/classes/Bio/Graphics/SVGEE.src/M000021.html +23 -0
  93. data/doc/classes/Bio/Graphics/Track.html +473 -0
  94. data/doc/classes/Bio/Graphics/Track.src/M000001.html +35 -0
  95. data/doc/classes/Bio/Graphics/Track.src/M000002.html +18 -0
  96. data/doc/classes/Bio/Graphics/Track.src/M000003.html +28 -0
  97. data/doc/classes/Bio/Graphics/Track.src/M000004.html +18 -0
  98. data/doc/classes/Bio/Graphics/Track.src/M000010.html +35 -0
  99. data/doc/classes/Bio/Graphics/Track.src/M000011.html +18 -0
  100. data/doc/classes/Bio/Graphics/Track.src/M000012.html +28 -0
  101. data/doc/classes/Bio/Graphics/Track.src/M000013.html +18 -0
  102. data/doc/created.rid +1 -9
  103. data/doc/files/lib/bio-svgenes_rb.html +131 -0
  104. data/doc/files/lib/bio/graphics/glyph_rb.html +101 -0
  105. data/doc/files/lib/bio/graphics/mini_feature_rb.html +101 -0
  106. data/doc/files/lib/bio/graphics/page_rb.html +111 -0
  107. data/doc/files/lib/bio/graphics/primitive_rb.html +101 -0
  108. data/doc/files/lib/bio/graphics/svgee_rb.html +101 -0
  109. data/doc/files/lib/bio/graphics/track_rb.html +101 -0
  110. data/doc/fr_class_index.html +34 -0
  111. data/doc/fr_file_index.html +33 -0
  112. data/doc/fr_method_index.html +70 -0
  113. data/doc/index.html +21 -91
  114. data/doc/manual/bootstrap/css/bootstrap-responsive.css +1109 -0
  115. data/doc/manual/bootstrap/css/bootstrap-responsive.min.css +9 -0
  116. data/doc/manual/bootstrap/css/bootstrap.css +6158 -0
  117. data/doc/manual/bootstrap/css/bootstrap.min.css +9 -0
  118. data/doc/manual/bootstrap/img/glyphicons-halflings-white.png +0 -0
  119. data/doc/manual/bootstrap/img/glyphicons-halflings.png +0 -0
  120. data/doc/manual/bootstrap/js/bootstrap.js +2276 -0
  121. data/doc/manual/bootstrap/js/bootstrap.min.js +6 -0
  122. data/doc/manual/img/circle.png +0 -0
  123. data/doc/manual/img/directed.png +0 -0
  124. data/doc/manual/img/down_triangle.png +0 -0
  125. data/doc/manual/img/histogram.png +0 -0
  126. data/doc/manual/img/span.png +0 -0
  127. data/doc/manual/img/transcript.png +0 -0
  128. data/doc/manual/img/up_triangle.png +0 -0
  129. data/doc/manual/manual.html +360 -0
  130. data/doc/manual/manual.md +307 -0
  131. data/doc/rdoc-style.css +208 -0
  132. data/examples/example.rb +12 -8
  133. data/examples/{make_example.rb → example2.rb} +5 -16
  134. data/lib/bio/graphics/glyph.rb +293 -126
  135. data/lib/bio/graphics/mini_feature.rb +24 -17
  136. data/lib/bio/graphics/page.rb +112 -54
  137. data/lib/bio/graphics/primitive.rb +12 -9
  138. data/lib/bio/graphics/svgee.rb +9 -11
  139. data/lib/bio/graphics/track.rb +92 -10
  140. metadata +132 -9
  141. data/README.rdoc +0 -19
  142. data/examples/annotate_snps.rb +0 -86
  143. data/examples/eg2.rb +0 -40
  144. 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
@@ -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 =&gt; 800,
68
+ :height =&gt; 200,
69
+ :number_of_intervals =&gt; 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 =&gt; :generic,
81
+ :name =&gt; 'generic_features',
82
+ :label =&gt; 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 =&gt; 923,
94
+ :end =&gt; 2212,
95
+ :strand =&gt; '+',
96
+ :id =&gt; "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 =&gt; :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 =&gt; :circle
154
+ )
155
+
156
+ feature = Bio::Graphics::MiniFeature.new(
157
+ :start =&gt; 100,
158
+ :end =&gt; 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 =&gt; :circle
168
+ )
169
+
170
+ feature = Bio::Graphics::MiniFeature.new(
171
+ :start =&gt; 100,
172
+ :end =&gt; 200,
173
+ :strand =&gt; '-'
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 =&gt; :histogram
183
+ )
184
+
185
+ data_feature = Bio::Graphics::MiniFeature.new(
186
+ :start =&gt; 100,
187
+ :end =&gt; 200,
188
+ :segment_height =&gt; 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 =&gt; :transcript
200
+ )
201
+
202
+ feature = Bio::Graphics::MiniFeature.new(
203
+ :start =&gt; 100,
204
+ :end =&gt; 200,
205
+ :strand =&gt; '-',
206
+ :utrs =&gt; [100,110,90,200],
207
+ :exons =&gt; [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 =&gt; :directed,
223
+ :stroke_color =&gt; 'black',
224
+ :fill_color =&gt; 'gold',
225
+ :stroke_width =&gt; '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 =&gt; :transcript,
233
+ :exon_fill_color =&gt; 'green',
234
+ :utr_fill_color =&gt; 'blue',
235
+ :line_color =&gt; 'black',
236
+ :gap_marker =&gt; '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 =&gt; :directed,
251
+ :stroke_color =&gt; 'black',
252
+ :fill_color =&gt; :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 =&gt; "grad1",
261
+ :cx =&gt; 50,
262
+ :cy =&gt; 50,
263
+ :r =&gt; 50, :fx =&gt; 50, :
264
+ fy =&gt; 50,
265
+ :stops =&gt; [
266
+ {
267
+ :offset =&gt; 0,
268
+ :color =&gt; 'rgb(255,255,255)',
269
+ :opacity =&gt; 0
270
+ },
271
+ {
272
+ :offset =&gt; 100,
273
+ :color =&gt; 'rgb(0,0,255)',
274
+ :opacity =&gt; 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 =&gt; :directed,
284
+ :stroke_color =&gt; 'black',
285
+ :fill_color =&gt; 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 =&gt; :generic,
293
+ :style =&gt; "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 =&gt; :generic,
303
+ :feature_height =&gt; 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 =&gt; :histogram,
311
+ :max_y =&gt; 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`.