reportbuilder 1.2.5 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.txt +6 -0
  3. data/Manifest.txt +377 -0
  4. data/data/flot/API.txt +1024 -0
  5. data/data/flot/FAQ.txt +71 -0
  6. data/data/flot/LICENSE.txt +22 -0
  7. data/data/flot/Makefile +15 -0
  8. data/data/flot/NEWS.txt +340 -0
  9. data/data/flot/PLUGINS.txt +105 -0
  10. data/data/flot/README.txt +81 -0
  11. data/data/flot/examples/ajax.html +143 -0
  12. data/data/flot/examples/annotating.html +75 -0
  13. data/data/flot/examples/arrow-down.gif +0 -0
  14. data/data/flot/examples/arrow-left.gif +0 -0
  15. data/data/flot/examples/arrow-right.gif +0 -0
  16. data/data/flot/examples/arrow-up.gif +0 -0
  17. data/data/flot/examples/basic.html +38 -0
  18. data/data/flot/examples/data-eu-gdp-growth-1.json +4 -0
  19. data/data/flot/examples/data-eu-gdp-growth-2.json +4 -0
  20. data/data/flot/examples/data-eu-gdp-growth-3.json +4 -0
  21. data/data/flot/examples/data-eu-gdp-growth-4.json +4 -0
  22. data/data/flot/examples/data-eu-gdp-growth-5.json +4 -0
  23. data/data/flot/examples/data-eu-gdp-growth.json +4 -0
  24. data/data/flot/examples/data-japan-gdp-growth.json +4 -0
  25. data/data/flot/examples/data-usa-gdp-growth.json +4 -0
  26. data/data/flot/examples/dual-axis.html +39 -0
  27. data/data/flot/examples/graph-types.html +75 -0
  28. data/data/flot/examples/hs-2004-27-a-large_web.jpg +0 -0
  29. data/data/flot/examples/image.html +45 -0
  30. data/data/flot/examples/index.html +43 -0
  31. data/data/flot/examples/interacting.html +93 -0
  32. data/data/flot/examples/layout.css +6 -0
  33. data/data/flot/examples/navigate.html +118 -0
  34. data/data/flot/examples/selection.html +114 -0
  35. data/data/flot/examples/setting-options.html +65 -0
  36. data/data/flot/examples/stacking.html +77 -0
  37. data/data/flot/examples/thresholding.html +54 -0
  38. data/data/flot/examples/time.html +71 -0
  39. data/data/flot/examples/tracking.html +95 -0
  40. data/data/flot/examples/turning-series.html +98 -0
  41. data/data/flot/examples/visitors.html +90 -0
  42. data/data/flot/examples/zooming.html +98 -0
  43. data/data/flot/excanvas.js +1427 -0
  44. data/data/flot/excanvas.min.js +1 -0
  45. data/data/flot/jquery.colorhelpers.js +174 -0
  46. data/data/flot/jquery.colorhelpers.min.js +1 -0
  47. data/data/flot/jquery.flot.crosshair.js +156 -0
  48. data/data/flot/jquery.flot.crosshair.min.js +1 -0
  49. data/data/flot/jquery.flot.image.js +237 -0
  50. data/data/flot/jquery.flot.image.min.js +1 -0
  51. data/data/flot/jquery.flot.js +2119 -0
  52. data/data/flot/jquery.flot.min.js +1 -0
  53. data/data/flot/jquery.flot.navigate.js +272 -0
  54. data/data/flot/jquery.flot.navigate.min.js +1 -0
  55. data/data/flot/jquery.flot.selection.js +299 -0
  56. data/data/flot/jquery.flot.selection.min.js +1 -0
  57. data/data/flot/jquery.flot.stack.js +152 -0
  58. data/data/flot/jquery.flot.stack.min.js +1 -0
  59. data/data/flot/jquery.flot.threshold.js +103 -0
  60. data/data/flot/jquery.flot.threshold.min.js +1 -0
  61. data/data/flot/jquery.js +4376 -0
  62. data/data/flot/jquery.min.js +19 -0
  63. data/data/jqplot/MIT-LICENSE.txt +21 -0
  64. data/data/jqplot/README.txt +73 -0
  65. data/data/jqplot/changes.txt +261 -0
  66. data/data/jqplot/copyright.txt +33 -0
  67. data/data/jqplot/docs/files/MIT-LICENSE-txt.html +39 -0
  68. data/data/jqplot/docs/files/changes-txt.html +39 -0
  69. data/data/jqplot/docs/files/gpl-2-0-txt.html +39 -0
  70. data/data/jqplot/docs/files/images/background.jpg +0 -0
  71. data/data/jqplot/docs/files/images/basicline.png +0 -0
  72. data/data/jqplot/docs/files/images/basiclogaxis.png +0 -0
  73. data/data/jqplot/docs/files/images/basiclogoptions.png +0 -0
  74. data/data/jqplot/docs/files/images/basicoptions.png +0 -0
  75. data/data/jqplot/docs/files/images/dualaxis.png +0 -0
  76. data/data/jqplot/docs/files/images/logo.jpg +0 -0
  77. data/data/jqplot/docs/files/images/navdocs.png +0 -0
  78. data/data/jqplot/docs/files/images/navdocsover.png +0 -0
  79. data/data/jqplot/docs/files/images/navdownload.png +0 -0
  80. data/data/jqplot/docs/files/images/navdownloadover.png +0 -0
  81. data/data/jqplot/docs/files/images/navexamples.png +0 -0
  82. data/data/jqplot/docs/files/images/navexamplesover.png +0 -0
  83. data/data/jqplot/docs/files/images/navhome.png +0 -0
  84. data/data/jqplot/docs/files/images/navhomeover.png +0 -0
  85. data/data/jqplot/docs/files/images/new.png +0 -0
  86. data/data/jqplot/docs/files/images/sample3.png +0 -0
  87. data/data/jqplot/docs/files/images/samplesm.png +0 -0
  88. data/data/jqplot/docs/files/jqPlotCssStyling-txt.html +39 -0
  89. data/data/jqplot/docs/files/jqPlotOptions-txt.html +292 -0
  90. data/data/jqplot/docs/files/jqplot-axisLabelRenderer-js.html +47 -0
  91. data/data/jqplot/docs/files/jqplot-axisTickRenderer-js.html +69 -0
  92. data/data/jqplot/docs/files/jqplot-canvasGridRenderer-js.html +39 -0
  93. data/data/jqplot/docs/files/jqplot-core-js.html +353 -0
  94. data/data/jqplot/docs/files/jqplot-divTitleRenderer-js.html +39 -0
  95. data/data/jqplot/docs/files/jqplot-lineRenderer-js.html +53 -0
  96. data/data/jqplot/docs/files/jqplot-linearAxisRenderer-js.html +39 -0
  97. data/data/jqplot/docs/files/jqplot-markerRenderer-js.html +65 -0
  98. data/data/jqplot/docs/files/jqplot-shadowRenderer-js.html +61 -0
  99. data/data/jqplot/docs/files/jqplot-shapeRenderer-js.html +63 -0
  100. data/data/jqplot/docs/files/jqplot-themeEngine-js.html +190 -0
  101. data/data/jqplot/docs/files/optionsTutorial-txt.html +119 -0
  102. data/data/jqplot/docs/files/plugins/jqplot-BezierCurveRenderer-js.html +45 -0
  103. data/data/jqplot/docs/files/plugins/jqplot-barRenderer-js.html +67 -0
  104. data/data/jqplot/docs/files/plugins/jqplot-blockRenderer-js.html +53 -0
  105. data/data/jqplot/docs/files/plugins/jqplot-bubbleRenderer-js.html +71 -0
  106. data/data/jqplot/docs/files/plugins/jqplot-canvasAxisLabelRenderer-js.html +63 -0
  107. data/data/jqplot/docs/files/plugins/jqplot-canvasAxisTickRenderer-js.html +79 -0
  108. data/data/jqplot/docs/files/plugins/jqplot-categoryAxisRenderer-js.html +46 -0
  109. data/data/jqplot/docs/files/plugins/jqplot-cursor-js.html +91 -0
  110. data/data/jqplot/docs/files/plugins/jqplot-dateAxisRenderer-js.html +93 -0
  111. data/data/jqplot/docs/files/plugins/jqplot-donutRenderer-js.html +98 -0
  112. data/data/jqplot/docs/files/plugins/jqplot-dragable-js.html +45 -0
  113. data/data/jqplot/docs/files/plugins/jqplot-enhancedLegendRenderer-js.html +49 -0
  114. data/data/jqplot/docs/files/plugins/jqplot-funnelRenderer-js.html +87 -0
  115. data/data/jqplot/docs/files/plugins/jqplot-highlighter-js.html +80 -0
  116. data/data/jqplot/docs/files/plugins/jqplot-logAxisRenderer-js.html +45 -0
  117. data/data/jqplot/docs/files/plugins/jqplot-mekkoAxisRenderer-js.html +49 -0
  118. data/data/jqplot/docs/files/plugins/jqplot-mekkoRenderer-js.html +62 -0
  119. data/data/jqplot/docs/files/plugins/jqplot-meterGaugeRenderer-js.html +103 -0
  120. data/data/jqplot/docs/files/plugins/jqplot-ohlcRenderer-js.html +65 -0
  121. data/data/jqplot/docs/files/plugins/jqplot-pieRenderer-js.html +93 -0
  122. data/data/jqplot/docs/files/plugins/jqplot-pointLabels-js.html +72 -0
  123. data/data/jqplot/docs/files/plugins/jqplot-trendline-js.html +67 -0
  124. data/data/jqplot/docs/files/usage-txt.html +58 -0
  125. data/data/jqplot/docs/index.html +1 -0
  126. data/data/jqplot/docs/index/Classes.html +58 -0
  127. data/data/jqplot/docs/index/Files.html +34 -0
  128. data/data/jqplot/docs/index/Functions.html +66 -0
  129. data/data/jqplot/docs/index/General.html +46 -0
  130. data/data/jqplot/docs/index/General2.html +46 -0
  131. data/data/jqplot/docs/index/General3.html +46 -0
  132. data/data/jqplot/docs/index/General4.html +50 -0
  133. data/data/jqplot/docs/index/General5.html +34 -0
  134. data/data/jqplot/docs/index/General6.html +58 -0
  135. data/data/jqplot/docs/index/Hooks.html +46 -0
  136. data/data/jqplot/docs/index/Properties.html +50 -0
  137. data/data/jqplot/docs/index/Properties2.html +50 -0
  138. data/data/jqplot/docs/index/Properties3.html +50 -0
  139. data/data/jqplot/docs/index/Properties4.html +34 -0
  140. data/data/jqplot/docs/index/Properties5.html +58 -0
  141. data/data/jqplot/docs/javascript/main.js +836 -0
  142. data/data/jqplot/docs/javascript/searchdata.js +182 -0
  143. data/data/jqplot/docs/search/ClassesA.html +20 -0
  144. data/data/jqplot/docs/search/ClassesG.html +20 -0
  145. data/data/jqplot/docs/search/ClassesJ.html +20 -0
  146. data/data/jqplot/docs/search/ClassesL.html +20 -0
  147. data/data/jqplot/docs/search/ClassesS.html +20 -0
  148. data/data/jqplot/docs/search/ClassesSymbols.html +20 -0
  149. data/data/jqplot/docs/search/ClassesT.html +20 -0
  150. data/data/jqplot/docs/search/FilesJ.html +20 -0
  151. data/data/jqplot/docs/search/FunctionsC.html +20 -0
  152. data/data/jqplot/docs/search/FunctionsD.html +20 -0
  153. data/data/jqplot/docs/search/FunctionsG.html +20 -0
  154. data/data/jqplot/docs/search/FunctionsI.html +20 -0
  155. data/data/jqplot/docs/search/FunctionsM.html +20 -0
  156. data/data/jqplot/docs/search/FunctionsN.html +20 -0
  157. data/data/jqplot/docs/search/FunctionsR.html +20 -0
  158. data/data/jqplot/docs/search/FunctionsS.html +20 -0
  159. data/data/jqplot/docs/search/FunctionsZ.html +20 -0
  160. data/data/jqplot/docs/search/GeneralA.html +20 -0
  161. data/data/jqplot/docs/search/GeneralB.html +20 -0
  162. data/data/jqplot/docs/search/GeneralC.html +20 -0
  163. data/data/jqplot/docs/search/GeneralD.html +20 -0
  164. data/data/jqplot/docs/search/GeneralE.html +20 -0
  165. data/data/jqplot/docs/search/GeneralF.html +20 -0
  166. data/data/jqplot/docs/search/GeneralG.html +20 -0
  167. data/data/jqplot/docs/search/GeneralH.html +20 -0
  168. data/data/jqplot/docs/search/GeneralI.html +20 -0
  169. data/data/jqplot/docs/search/GeneralJ.html +20 -0
  170. data/data/jqplot/docs/search/GeneralL.html +20 -0
  171. data/data/jqplot/docs/search/GeneralM.html +20 -0
  172. data/data/jqplot/docs/search/GeneralN.html +20 -0
  173. data/data/jqplot/docs/search/GeneralO.html +20 -0
  174. data/data/jqplot/docs/search/GeneralP.html +20 -0
  175. data/data/jqplot/docs/search/GeneralR.html +20 -0
  176. data/data/jqplot/docs/search/GeneralS.html +20 -0
  177. data/data/jqplot/docs/search/GeneralSymbols.html +20 -0
  178. data/data/jqplot/docs/search/GeneralT.html +20 -0
  179. data/data/jqplot/docs/search/GeneralU.html +20 -0
  180. data/data/jqplot/docs/search/GeneralV.html +20 -0
  181. data/data/jqplot/docs/search/GeneralW.html +20 -0
  182. data/data/jqplot/docs/search/GeneralX.html +20 -0
  183. data/data/jqplot/docs/search/GeneralY.html +20 -0
  184. data/data/jqplot/docs/search/GeneralZ.html +20 -0
  185. data/data/jqplot/docs/search/HooksA.html +20 -0
  186. data/data/jqplot/docs/search/HooksE.html +20 -0
  187. data/data/jqplot/docs/search/HooksJ.html +20 -0
  188. data/data/jqplot/docs/search/HooksP.html +20 -0
  189. data/data/jqplot/docs/search/NoResults.html +15 -0
  190. data/data/jqplot/docs/search/PropertiesA.html +20 -0
  191. data/data/jqplot/docs/search/PropertiesB.html +20 -0
  192. data/data/jqplot/docs/search/PropertiesC.html +20 -0
  193. data/data/jqplot/docs/search/PropertiesD.html +20 -0
  194. data/data/jqplot/docs/search/PropertiesE.html +20 -0
  195. data/data/jqplot/docs/search/PropertiesF.html +20 -0
  196. data/data/jqplot/docs/search/PropertiesG.html +20 -0
  197. data/data/jqplot/docs/search/PropertiesH.html +20 -0
  198. data/data/jqplot/docs/search/PropertiesI.html +20 -0
  199. data/data/jqplot/docs/search/PropertiesL.html +20 -0
  200. data/data/jqplot/docs/search/PropertiesM.html +20 -0
  201. data/data/jqplot/docs/search/PropertiesN.html +20 -0
  202. data/data/jqplot/docs/search/PropertiesO.html +20 -0
  203. data/data/jqplot/docs/search/PropertiesP.html +20 -0
  204. data/data/jqplot/docs/search/PropertiesR.html +20 -0
  205. data/data/jqplot/docs/search/PropertiesS.html +20 -0
  206. data/data/jqplot/docs/search/PropertiesT.html +20 -0
  207. data/data/jqplot/docs/search/PropertiesU.html +20 -0
  208. data/data/jqplot/docs/search/PropertiesV.html +20 -0
  209. data/data/jqplot/docs/search/PropertiesW.html +20 -0
  210. data/data/jqplot/docs/search/PropertiesX.html +20 -0
  211. data/data/jqplot/docs/search/PropertiesY.html +20 -0
  212. data/data/jqplot/docs/search/PropertiesZ.html +20 -0
  213. data/data/jqplot/docs/styles/1.css +767 -0
  214. data/data/jqplot/docs/styles/2.css +174 -0
  215. data/data/jqplot/docs/styles/main.css +2 -0
  216. data/data/jqplot/examples/.htaccess +1 -0
  217. data/data/jqplot/examples/OHLC.html +333 -0
  218. data/data/jqplot/examples/OHLC2.html +193 -0
  219. data/data/jqplot/examples/area.html +107 -0
  220. data/data/jqplot/examples/axisLabel.html +117 -0
  221. data/data/jqplot/examples/axisLabelsRotatedText.html +131 -0
  222. data/data/jqplot/examples/axisLabelsRotatedText2.html +155 -0
  223. data/data/jqplot/examples/barLinePieStack.html +198 -0
  224. data/data/jqplot/examples/barMissingValues.html +64 -0
  225. data/data/jqplot/examples/barTest.html +283 -0
  226. data/data/jqplot/examples/barTest2.html +74 -0
  227. data/data/jqplot/examples/bezierCurve.html +96 -0
  228. data/data/jqplot/examples/blockPlot.html +149 -0
  229. data/data/jqplot/examples/bubbleChart2.html +253 -0
  230. data/data/jqplot/examples/bubblechart.html +69 -0
  231. data/data/jqplot/examples/catchError.html +53 -0
  232. data/data/jqplot/examples/categoryHorizontalBar.html +81 -0
  233. data/data/jqplot/examples/categoryVsLinearAxes.html +74 -0
  234. data/data/jqplot/examples/chartInTable.html +33 -0
  235. data/data/jqplot/examples/customHighlighterCursorTrendline.html +72 -0
  236. data/data/jqplot/examples/customPieTests.html +73 -0
  237. data/data/jqplot/examples/dataLabels.html +192 -0
  238. data/data/jqplot/examples/dataTracking.html +91 -0
  239. data/data/jqplot/examples/donutTest.html +89 -0
  240. data/data/jqplot/examples/donutTest.js +96 -0
  241. data/data/jqplot/examples/examples.css +19 -0
  242. data/data/jqplot/examples/fillToZero.html +126 -0
  243. data/data/jqplot/examples/filledLine.html +78 -0
  244. data/data/jqplot/examples/filledLineCategoryAxis.html +80 -0
  245. data/data/jqplot/examples/funnelTest.html +82 -0
  246. data/data/jqplot/examples/funnelTest.js +74 -0
  247. data/data/jqplot/examples/gridCustomization.html +56 -0
  248. data/data/jqplot/examples/hiddenPlot.html +216 -0
  249. data/data/jqplot/examples/highlighter.html +95 -0
  250. data/data/jqplot/examples/highlighter2.html +63 -0
  251. data/data/jqplot/examples/horizontalLine.html +51 -0
  252. data/data/jqplot/examples/intticks.html +178 -0
  253. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  254. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  255. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
  256. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  257. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  258. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  259. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  260. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  261. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  262. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
  263. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
  264. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ef8c08_256x240.png +0 -0
  265. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
  266. data/data/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
  267. data/data/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui-1.8.1.custom.css +486 -0
  268. data/data/jqplot/examples/jquery-ui/js/jquery-1.4.2.min.js +154 -0
  269. data/data/jqplot/examples/jquery-ui/js/jquery-ui-1.8.1.custom.min.js +756 -0
  270. data/data/jqplot/examples/legendLabels.html +205 -0
  271. data/data/jqplot/examples/legendLabels2.html +228 -0
  272. data/data/jqplot/examples/liz.zip +0 -0
  273. data/data/jqplot/examples/markerStyles.html +44 -0
  274. data/data/jqplot/examples/mekkoChart.html +217 -0
  275. data/data/jqplot/examples/meterGauge.html +132 -0
  276. data/data/jqplot/examples/meterGauge2.html +158 -0
  277. data/data/jqplot/examples/minMaxLines.html +61 -0
  278. data/data/jqplot/examples/missingValues.html +119 -0
  279. data/data/jqplot/examples/multiAxesRotatedText.html +70 -0
  280. data/data/jqplot/examples/multipleBarColors.html +149 -0
  281. data/data/jqplot/examples/multipleLines.html +47 -0
  282. data/data/jqplot/examples/multipleYAxes.html +85 -0
  283. data/data/jqplot/examples/nav.inc +35 -0
  284. data/data/jqplot/examples/pieTest.html +77 -0
  285. data/data/jqplot/examples/pieTest2.html +87 -0
  286. data/data/jqplot/examples/pieTest2.js +80 -0
  287. data/data/jqplot/examples/pieTest3.html +100 -0
  288. data/data/jqplot/examples/pointLabels.html +94 -0
  289. data/data/jqplot/examples/pointLabels2.html +47 -0
  290. data/data/jqplot/examples/prefix.html +90 -0
  291. data/data/jqplot/examples/resizablePlot.html +150 -0
  292. data/data/jqplot/examples/rotatedTickLabels.html +61 -0
  293. data/data/jqplot/examples/rotatedTickLabelsZoom.html +68 -0
  294. data/data/jqplot/examples/seriesCanvasReorder.html +93 -0
  295. data/data/jqplot/examples/seriesUpdate.html +123 -0
  296. data/data/jqplot/examples/shadowTests.html +133 -0
  297. data/data/jqplot/examples/singlePoint.html +70 -0
  298. data/data/jqplot/examples/sparkLine.html +48 -0
  299. data/data/jqplot/examples/stackedBar2.html +104 -0
  300. data/data/jqplot/examples/stackedBar3.html +76 -0
  301. data/data/jqplot/examples/stackedBarCategoryVsLinearAxes.html +121 -0
  302. data/data/jqplot/examples/stackedCategoryAxis.html +89 -0
  303. data/data/jqplot/examples/stackedFilledLine.html +77 -0
  304. data/data/jqplot/examples/stackedLine.html +56 -0
  305. data/data/jqplot/examples/test2.html +64 -0
  306. data/data/jqplot/examples/theming.html +483 -0
  307. data/data/jqplot/examples/trendlineDragableCustomization.html +79 -0
  308. data/data/jqplot/examples/verticalLine.html +52 -0
  309. data/data/jqplot/examples/waterfall.html +135 -0
  310. data/data/jqplot/examples/zoom1.html +125 -0
  311. data/data/jqplot/examples/zoom2.html +73 -0
  312. data/data/jqplot/examples/zoom3.html +69 -0
  313. data/data/jqplot/examples/zoomOptions.html +101 -0
  314. data/data/jqplot/examples/zoomProxy.html +108 -0
  315. data/data/jqplot/excanvas.js +1416 -0
  316. data/data/jqplot/excanvas.min.js +35 -0
  317. data/data/jqplot/gpl-2.0.txt +280 -0
  318. data/data/jqplot/jqPlotCssStyling.txt +53 -0
  319. data/data/jqplot/jqPlotOptions.txt +276 -0
  320. data/data/jqplot/jquery-1.4.1.min.js +152 -0
  321. data/data/jqplot/jquery-1.4.2.min.js +154 -0
  322. data/data/jqplot/jquery.jqplot.css +212 -0
  323. data/data/jqplot/jquery.jqplot.js +7004 -0
  324. data/data/jqplot/jquery.jqplot.min.css +1 -0
  325. data/data/jqplot/jquery.jqplot.min.js +34 -0
  326. data/data/jqplot/optionsTutorial.txt +239 -0
  327. data/data/jqplot/plugins/jqplot.BezierCurveRenderer.js +300 -0
  328. data/data/jqplot/plugins/jqplot.BezierCurveRenderer.min.js +34 -0
  329. data/data/jqplot/plugins/jqplot.barRenderer.js +629 -0
  330. data/data/jqplot/plugins/jqplot.barRenderer.min.js +34 -0
  331. data/data/jqplot/plugins/jqplot.blockRenderer.js +221 -0
  332. data/data/jqplot/plugins/jqplot.blockRenderer.min.js +34 -0
  333. data/data/jqplot/plugins/jqplot.bubbleRenderer.js +724 -0
  334. data/data/jqplot/plugins/jqplot.bubbleRenderer.min.js +34 -0
  335. data/data/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js +187 -0
  336. data/data/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js +34 -0
  337. data/data/jqplot/plugins/jqplot.canvasAxisTickRenderer.js +226 -0
  338. data/data/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js +34 -0
  339. data/data/jqplot/plugins/jqplot.canvasTextRenderer.js +408 -0
  340. data/data/jqplot/plugins/jqplot.canvasTextRenderer.min.js +34 -0
  341. data/data/jqplot/plugins/jqplot.categoryAxisRenderer.js +630 -0
  342. data/data/jqplot/plugins/jqplot.categoryAxisRenderer.min.js +34 -0
  343. data/data/jqplot/plugins/jqplot.cursor.js +952 -0
  344. data/data/jqplot/plugins/jqplot.cursor.min.js +34 -0
  345. data/data/jqplot/plugins/jqplot.dateAxisRenderer.js +313 -0
  346. data/data/jqplot/plugins/jqplot.dateAxisRenderer.min.js +34 -0
  347. data/data/jqplot/plugins/jqplot.donutRenderer.js +876 -0
  348. data/data/jqplot/plugins/jqplot.donutRenderer.min.js +34 -0
  349. data/data/jqplot/plugins/jqplot.dragable.js +206 -0
  350. data/data/jqplot/plugins/jqplot.dragable.min.js +34 -0
  351. data/data/jqplot/plugins/jqplot.enhancedLegendRenderer.js +186 -0
  352. data/data/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js +34 -0
  353. data/data/jqplot/plugins/jqplot.funnelRenderer.js +918 -0
  354. data/data/jqplot/plugins/jqplot.funnelRenderer.min.js +34 -0
  355. data/data/jqplot/plugins/jqplot.highlighter.js +374 -0
  356. data/data/jqplot/plugins/jqplot.highlighter.min.js +34 -0
  357. data/data/jqplot/plugins/jqplot.logAxisRenderer.js +434 -0
  358. data/data/jqplot/plugins/jqplot.logAxisRenderer.min.js +34 -0
  359. data/data/jqplot/plugins/jqplot.mekkoAxisRenderer.js +595 -0
  360. data/data/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js +34 -0
  361. data/data/jqplot/plugins/jqplot.mekkoRenderer.js +419 -0
  362. data/data/jqplot/plugins/jqplot.mekkoRenderer.min.js +34 -0
  363. data/data/jqplot/plugins/jqplot.meterGaugeRenderer.js +1112 -0
  364. data/data/jqplot/plugins/jqplot.meterGaugeRenderer.min.js +34 -0
  365. data/data/jqplot/plugins/jqplot.ohlcRenderer.js +343 -0
  366. data/data/jqplot/plugins/jqplot.ohlcRenderer.min.js +34 -0
  367. data/data/jqplot/plugins/jqplot.pieRenderer.js +749 -0
  368. data/data/jqplot/plugins/jqplot.pieRenderer.min.js +34 -0
  369. data/data/jqplot/plugins/jqplot.pointLabels.js +325 -0
  370. data/data/jqplot/plugins/jqplot.pointLabels.min.js +34 -0
  371. data/data/jqplot/plugins/jqplot.trendline.js +208 -0
  372. data/data/jqplot/plugins/jqplot.trendline.min.js +34 -0
  373. data/data/jqplot/usage.txt +119 -0
  374. data/examples/graph.rb +17 -0
  375. data/lib/reportbuilder.rb +21 -2
  376. data/lib/reportbuilder/builder.rb +31 -3
  377. data/lib/reportbuilder/builder/html.rb +39 -5
  378. data/lib/reportbuilder/graph.rb +252 -0
  379. data/lib/reportbuilder/graph/html_flot.rb +149 -0
  380. data/lib/reportbuilder/graph/html_jqplot.rb +145 -0
  381. data/lib/reportbuilder/image.rb +178 -78
  382. data/lib/reportbuilder/table/rtfbuilder.rb +2 -2
  383. data/test/helper_test.rb +6 -7
  384. data/test/test_graph.rb +44 -0
  385. data/test/test_graph_html_flot.rb +36 -0
  386. data/test/test_graph_html_jqplot.rb +36 -0
  387. data/test/test_html.rb +4 -7
  388. data/test/test_image.rb +35 -7
  389. data/test/test_reportbuilder.rb +4 -6
  390. data/test/test_table.rb +0 -2
  391. metadata +402 -7
  392. metadata.gz.sig +4 -2
@@ -0,0 +1,149 @@
1
+ class ReportBuilder
2
+ class Graph
3
+ # Flot Wrapper
4
+ class HtmlFlot < ElementBuilder
5
+ def generate()
6
+ @builder.js(ReportBuilder::DATA_DIR+"/flot/excanvas.min.js")
7
+
8
+ @builder.js(ReportBuilder::DATA_DIR+"/flot/jquery.min.js")
9
+ @builder.js(ReportBuilder::DATA_DIR+"/flot/jquery.flot.min.js")
10
+
11
+ anchor=@builder.graph_entry(@element.name)
12
+ out="<a name='#{anchor}'></a><div id='graph_#{anchor}' style='width:#{@element.width}px; height:#{@element.height}px'> </div>"
13
+ out << "<script>\n$.plot($('#graph_#{anchor}'),"
14
+ out << @builder.parse_js(flot_series)+",\n"
15
+ out << @builder.parse_js(flot_options)+"\n);"
16
+ out+="</script>"
17
+
18
+ @builder.html(out)
19
+ end
20
+ def set_type(opt,v)
21
+ case v
22
+ when :line
23
+ opt[:lines][:show]=true
24
+ when :pie
25
+ raise "doesn't supported on flot"
26
+ when :scatter
27
+ opt[:lines][:show]=false
28
+ opt[:points][:show]=true
29
+ when :bar
30
+ opt[:lines][:show]=false
31
+ opt[:bars][:show]=true
32
+ when :histogram
33
+ opt[:lines][:show]=false
34
+ opt[:bars][:show]=true
35
+ opt[:bars][:align]="center"
36
+ else
37
+ raise "Type doesn't exists"
38
+ end
39
+ end
40
+
41
+
42
+ def hash_to_camel(h)
43
+ out=Hash.new
44
+ h.each do |k,v|
45
+ out[to_camel(k)]=v
46
+ end
47
+ out
48
+ end
49
+ def to_camel(k)
50
+ k.to_s.gsub(/_([a-z])/) {|s| s.upcase[1]}.to_sym
51
+ end
52
+
53
+ def flot_options
54
+ opts=Hash.new
55
+ opts[:title]=@element.title
56
+ opts[:axesDefaults]=axes_defaults if @element.axes_defaults.size>0
57
+ opts[:xaxis]=xaxis
58
+ opts[:yaxis]=yaxis
59
+ opts[:series]= series_defaults if @element.series_defaults.size>0
60
+ opts[:legend]=legend if @element.legend.size>0
61
+ opts[:grid]=grid if @element.grid.size>0
62
+ opts
63
+ end
64
+
65
+
66
+
67
+ def axes_defaults
68
+ hash_to_camel(@element.axes_defaults)
69
+ end
70
+ def xaxis
71
+ hash_to_camel(@element.xaxis)
72
+ end
73
+ def yaxis
74
+ hash_to_camel(@element.yaxis)
75
+ end
76
+ def legend
77
+ lo=@element.legend
78
+ lo.delete(:position) if lo[:position] and !["ne","nw","se","sw"].include? lo[:position]
79
+ hash_to_camel(lo)
80
+ end
81
+ def series_defaults
82
+ series_js(@element.series_defaults)
83
+ end
84
+ def grid
85
+ replace={}
86
+ out=Hash.new
87
+ @element.grid.each do |k,v|
88
+ if replace.include? k
89
+ out[replace[k]]=v
90
+ else
91
+ out[to_camel(k)]=v
92
+ end
93
+ end
94
+ out
95
+ end
96
+
97
+ def process_type(out_opt, k,v)
98
+ out_opt[:color]=v[:color] if !out_opt[:color]
99
+ out_opt[:shadowSize]=v[:shadow_depth] if v[:shadow_depth]
100
+ prev=out_opt[k]
101
+ if prev and prev.is_a? Hash
102
+ out_opt[k]=out_opt[k].merge(hash_to_camel(v))
103
+ else
104
+ out_opt[k]=hash_to_camel(v)
105
+ end
106
+ end
107
+ def series_js(in_opt)
108
+ out_opt=Hash.new
109
+ out_opt[:lines]=Hash.new
110
+ out_opt[:points]=Hash.new
111
+ out_opt[:bars]=Hash.new
112
+ in_opt.each_pair do |k,v|
113
+ case k
114
+ when :type
115
+ set_type(out_opt, v)
116
+ when :bars
117
+ v.delete(:width) # Uses width as number of ticks
118
+ process_type(out_opt, k,v)
119
+ when :markers
120
+ process_type(out_opt, k,v)
121
+ out_opt[:points]=out_opt.delete(:markers)
122
+ when :lines
123
+ v[:line_width]=v[:width] if v[:width]
124
+ process_type(out_opt, k,v)
125
+ else
126
+ out_opt[to_camel(k)]=v
127
+ end
128
+ end
129
+ [:lines, :points, :bars].each do |v|
130
+ out_opt.delete(v) if out_opt[v].size==0
131
+ end
132
+ out_opt
133
+ end
134
+ # Transform data options on jqPlot ones
135
+ def flot_series
136
+ dv=@element.series_data
137
+ i=0
138
+ own_options=@element.series_options.map do |in_opt|
139
+ out_opt=Hash.new
140
+ out_opt[:data]=dv[i]
141
+ i+=1
142
+ out_opt.merge(series_js(in_opt))
143
+ end
144
+ own_options
145
+ end
146
+
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,145 @@
1
+ class ReportBuilder
2
+ class Graph
3
+ # @element and @builder
4
+ class HtmlJqplot < ElementBuilder
5
+ def generate()
6
+ @builder.js(ReportBuilder::DATA_DIR+"/jqplot/excanvas.min.js")
7
+
8
+ @builder.js(ReportBuilder::DATA_DIR+"/jqplot/jquery-1.4.2.min.js")
9
+ @builder.js(ReportBuilder::DATA_DIR+"/jqplot/jquery.jqplot.min.js")
10
+ @builder.css(ReportBuilder::DATA_DIR+"/jqplot/jquery.jqplot.css")
11
+ anchor=@builder.graph_entry(@element.name)
12
+ out="<a name='#{anchor}'></a><div id='graph_#{anchor}' style='width:#{@element.width}px; height:#{@element.height}px'> </div>"
13
+ out+="
14
+ <script>
15
+ $.jqplot('graph_#{anchor}', #{@builder.parse_js(@element.series_data)},
16
+ "+@builder.parse_js(jqplot_options)+");
17
+ </script>"
18
+
19
+ @builder.html(out)
20
+ end
21
+ def jqplot_options
22
+ opts=Hash.new
23
+ opts[:title]=@element.title
24
+ opts[:series]=series_options
25
+ opts[:axesDefaults]=axes_defaults if @element.axes_defaults.size>0
26
+ if @element.xaxis.size>0 or @element.yaxis.size>0
27
+ opts[:axes]={:xaxis=>xaxis, :yaxis=>yaxis}
28
+ end
29
+ opts[:seriesDefaults]= series_defaults if @element.series_defaults.size>0
30
+ opts[:legend]=legend if @element.legend.size>0
31
+ opts[:grid]=grid if @element.grid.size>0
32
+ opts
33
+ end
34
+
35
+ def set_type(opt,v)
36
+ case v
37
+ when :line
38
+ when :pie
39
+ @builder.js(ReportBuilder::DATA_DIR+"/jqplot/plugins/jqplot.pieRenderer.min.js")
40
+ opt[:renderer]="$.jqplot.PieRenderer".to_sym
41
+ when :scatter
42
+ opt[:showLine]=false
43
+ opt[:showMarker]=true
44
+ when :bar
45
+ @builder.js(ReportBuilder::DATA_DIR+"/jqplot/plugins/jqplot.categoryAxisRenderer.min.js")
46
+ @builder.js(ReportBuilder::DATA_DIR+"/jqplot/plugins/jqplot.barRenderer.min.js")
47
+ opt[:renderer]="$.jqplot.BarRenderer".to_sym
48
+ else
49
+ raise "Type doesn't exists"
50
+ end
51
+ end
52
+ def axes_defaults
53
+ hash_to_camel(@element.axes_defaults)
54
+ end
55
+ def xaxis
56
+ hash_to_camel(@element.xaxis)
57
+ end
58
+ def yaxis
59
+ hash_to_camel(@element.yaxis)
60
+ end
61
+ def legend
62
+ lo=@element.legend
63
+ lo[:location]=lo.delete(:position) if lo[:position]
64
+ hash_to_camel(lo)
65
+ end
66
+ def series_defaults
67
+ series_js(@element.series_defaults)
68
+ end
69
+ def grid
70
+ replace={:show=>:drawGridLine, :color=>:gridLineColor, :background_color=>:background}
71
+ out=Hash.new
72
+ @element.grid.each do |k,v|
73
+ if replace.include? k
74
+ out[replace[k]]=v
75
+ else
76
+ out[to_camel(k)]=v
77
+ end
78
+ end
79
+ out
80
+ end
81
+ def hash_to_camel(h)
82
+ out=Hash.new
83
+ h.each do |k,v|
84
+ out[to_camel(k)]=v
85
+ end
86
+ out
87
+ end
88
+ def to_camel(k)
89
+ k.to_s.gsub(/_([a-z])/) {|s| s.upcase[1,1]}.to_sym
90
+ end
91
+ def series_js(in_opt)
92
+ out_opt=Hash.new
93
+ out_opt[:markerOptions]=Hash.new
94
+ out_opt[:rendererOptions]=Hash.new
95
+ in_opt.each_pair do |k,v|
96
+ case k
97
+ when :type
98
+ set_type(out_opt, v)
99
+ when :lines
100
+ out_opt[:showLines]=v[:show] if v[:show]
101
+ v.each do |k1,v1|
102
+ out_opt[to_camel(k1)]=v1
103
+ end
104
+ when :markers
105
+ out_opt[:showMarker]=v[:show] if v[:show]
106
+ v.each do |k1,v1|
107
+ out_opt[:markerOptions][to_camel(k1)]=v1
108
+ end
109
+ when :bars
110
+ v.each do |k1,v1|
111
+ k1=("bar_"+k1.to_s) if [:padding, :margin, :direction, :width].include? k1
112
+ out_opt[:rendererOptions][to_camel(k1)]=v1
113
+ end
114
+ when :color
115
+ if in_opt[:type]
116
+ set_color(in_opt[:type], out_opt,v)
117
+ else
118
+ out_opt[k]=v
119
+ end
120
+ else
121
+ out_opt[k]=v
122
+ end
123
+ end
124
+ out_opt
125
+ end
126
+ def set_color(t,out_opt,v)
127
+ case t
128
+ when :line
129
+ out_opt[:color]=v
130
+ when :scatter
131
+ out_opt[:markerOptions][:color]=v
132
+ when :bar
133
+ out_opt[:rendererOptions][:color]=v
134
+ end
135
+ end
136
+
137
+ # Transform data options on jqPlot ones
138
+ def series_options
139
+ @element.series_options.map do |in_opt|
140
+ series_js(in_opt)
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -1,89 +1,189 @@
1
- # Creates an Image
2
- #
3
- class ReportBuilder::Image
4
- @@n=1
5
- attr_reader :name
6
- def initialize(filename, options={})
7
- if !options.has_key? :name
8
- @name="Image #{@@n}"
9
- @@n+=1
10
- else
11
- @name=options[:name]
12
- end
13
- default_options={
14
- :alt=>@name,
15
- :chars => [ 'W', 'M', '$', '@', '#', '%', '^', 'x', '*', 'o', '=', '+',
16
- ':', '~', '.', ' ' ],
17
- :font_rows => 8,
18
- :font_cols => 4
19
- }
20
- @options=default_options.merge(options)
21
- @filename=filename
22
- end
23
- # Based on http://rubyquiz.com/quiz50.html
24
- def report_building_text(builder)
25
-
26
- require 'RMagick'
27
-
28
- img = Magick::Image.read(@filename).first
29
-
30
- # Resize too-large images. The resulting image is going to be
31
- # about twice the size of the input, so if the original image is too
32
- # large we need to make it smaller so the ASCII version won't be too
33
- # big. The `change_geometry' method computes new dimensions for an
34
- # image based on the geometry argument. The '320x320>' argument says
35
- # "If the image is too big to fit in a 320x320 square, compute the
36
- # dimensions of an image that will fit, but retain the original aspect
37
- # ratio. If the image is already smaller than 320x320, keep the same
38
- # dimensions."
39
- img.change_geometry('320x320>') do |cols, rows|
40
- img.resize!(cols, rows) if cols != img.columns || rows != img.rows
1
+ require 'digest/md5'
2
+ class ReportBuilder
3
+ # Abstract class for an image
4
+ class Image
5
+ @@n=1
6
+ attr_accessor :name
7
+ attr_accessor :alt
8
+ attr_accessor :chars
9
+ attr_accessor :font_rows
10
+ attr_accessor :font_cols
11
+ attr_accessor :width
12
+ attr_accessor :height
13
+ attr_accessor :type
14
+ attr_reader :filename
15
+ attr_reader :url
16
+ attr_reader :id
17
+
18
+ def initialize(options=Hash.new)
19
+ @id=Digest::MD5.hexdigest(Time.new.to_f.to_s)
20
+ @type=nil
21
+ if !options.has_key? :name
22
+ @name="Image #{@@n}"
23
+ @@n+=1
24
+ else
25
+ @name=options[:name]
26
+ end
27
+
28
+ default_options={
29
+ :alt=>@name,
30
+ :chars => [ 'W', 'M', '$', '@', '#', '%', '^', 'x', '*', 'o', '=', '+',
31
+ ':', '~', '.', ' ' ],
32
+ :font_rows => 8,
33
+ :font_cols => 4,
34
+ :width=>400,
35
+ :height=>300
36
+ }
37
+ @options=default_options.merge(options)
38
+ @options.each {|k,v|
39
+ self.send("#{k}=",v) if self.respond_to? k
40
+ }
41
+ end
42
+ # Get image_magick version of the image
43
+ def image_magick
44
+ raise "Must be implemented"
41
45
  end
42
-
43
- # Compute the image size in ASCII "pixels" and resize the image to have
44
- # those dimensions. The resulting image does not have the same aspect
45
- # ratio as the original, but since our "pixels" are twice as tall as
46
- # they are wide we'll get our proportions back (roughly) when we render.
47
- pr = img.rows / @options[:font_rows]
48
- pc = img.columns / @options[:font_cols]
49
- img.resize!(pc, pr)
50
-
51
- img = img.quantize(@options[:chars].size, Magick::GRAYColorspace)
52
- img = img.normalize
53
-
54
- out=""
55
- # Draw the image surrounded by a border. The `view' method is slow but
56
- # it makes it easy to address individual pixels. In grayscale images,
57
- # all three RGB channels have the same value so the red channel is as
58
- # good as any for choosing which character to represent the intensity of
59
- # this particular pixel.
60
- border = '+' + ('-' * pc) + '+'
61
- out += border+"\n"
62
- img.view(0, 0, pc, pr) do |view|
63
- pr.times do |i|
64
- out+= '|'
65
- pc.times do |j|
66
- out+= @options[:chars][view[i][j].red / (2**16/@options[:chars].size)]
46
+ # Based on http://rubyquiz.com/quiz50.html
47
+ def report_building_text(builder)
48
+ if ReportBuilder.has_rmagick?
49
+ # get image_magick version of image
50
+ img = image_magick
51
+ # Resize too-large images. The resulting image is going to be
52
+ # about twice the size of the input, so if the original image is too
53
+ # large we need to make it smaller so the ASCII version won't be too
54
+ # big. The `change_geometry' method computes new dimensions for an
55
+ # image based on the geometry argument. The '320x320>' argument says
56
+ # "If the image is too big to fit in a 320x320 square, compute the
57
+ # dimensions of an image that will fit, but retain the original aspect
58
+ # ratio. If the image is already smaller than 320x320, keep the same
59
+ # dimensions."
60
+ img.change_geometry('320x320>') do |cols, rows|
61
+ img.resize!(cols, rows) if cols != img.columns || rows != img.rows
67
62
  end
68
- out+= '|'+"\n"
63
+
64
+ # Compute the image size in ASCII "pixels" and resize the image to have
65
+ # those dimensions. The resulting image does not have the same aspect
66
+ # ratio as the original, but since our "pixels" are twice as tall as
67
+ # they are wide we'll get our proportions back (roughly) when we render.
68
+ pr = img.rows / font_rows
69
+ pc = img.columns / font_cols
70
+ img.resize!(pc, pr)
71
+
72
+ img = img.quantize(chars.size, Magick::GRAYColorspace)
73
+ img = img.normalize
74
+
75
+ out=""
76
+ # Draw the image surrounded by a border. The `view' method is slow but
77
+ # it makes it easy to address individual pixels. In grayscale images,
78
+ # all three RGB channels have the same value so the red channel is as
79
+ # good as any for choosing which character to represent the intensity of
80
+ # this particular pixel.
81
+ border = '+' + ('-' * pc) + '+'
82
+ out += border+"\n"
83
+ img.view(0, 0, pc, pr) do |view|
84
+ pr.times do |i|
85
+ out+= '|'
86
+ pc.times do |j|
87
+ out+= chars[view[i][j].red / (2**16 / chars.size)]
88
+ end
89
+ out+= '|'+"\n"
90
+ end
91
+ end
92
+ out+= border
93
+ builder.preformatted(out)
94
+ else
95
+ raise "Requires RMagick"
96
+ end
97
+ end
98
+ # Generate the code for images on html
99
+ def generate_tag_html(builder)
100
+ if @type=='svg'
101
+ builder.html("
102
+ <div class='image'>
103
+ <!--[if IE]>
104
+ <embed class='svg' height='#{@options[:height]}' src='#{@url}' width='#{@options[:width]}'></embed>
105
+ <![endif]-->
106
+ <object class='svg' data='#{@url}' height='#{@options[:height]}' type='image/svg+xml' width='#{@options[:width]}'></object>
107
+ </div>")
108
+ else
109
+ builder.html("<img src='#{@url}' alt='#{@options[:alt]}' />")
110
+ end
111
+ end
112
+ def create_file(directory)
113
+ raise "Must be implemented"
114
+ end
115
+ def report_building_html(builder)
116
+ create_file(builder.directory)
117
+ generate_tag_html(builder)
118
+ end
119
+ # return filename
120
+ def generate_raster_from_svg(dir)
121
+
122
+ out_file="#{dir}/#{@id}.png"
123
+ `rsvg '#{filename}' #{out_file}`
124
+ out_file
125
+ end
126
+ def report_building_rtf(builder)
127
+ require 'tmpdir'
128
+ directory=Dir::mktmpdir
129
+ create_file(directory)
130
+ raise "Not implemented on RTF::Document. Use gem install clbustos-rtf for support" unless builder.rtf.respond_to? :image
131
+ if @type=='svg'
132
+ builder.rtf.image(generate_raster_from_svg(directory))
133
+ else
134
+ builder.rtf.image(filename)
69
135
  end
70
136
  end
71
- out+= border
72
- builder.preformatted(out)
73
137
  end
74
- def report_building_rtf(builder)
75
- raise "Not implemented on RTF::Document. Use gem install thecrisoshow-ruby-rtf for support" unless builder.rtf.respond_to? :image
76
- builder.rtf.image(@filename)
138
+
139
+ class ImageBlob < Image
140
+ attr_accessor :blob
141
+ def initialize(blob, options=Hash.new)
142
+ super(options)
143
+ @blob=blob
144
+ if !@type
145
+ if blob[0,40]=~/<svg/
146
+ @type='svg'
147
+ else
148
+ @type='jpg'
149
+ end
150
+ end
151
+ end
152
+ def image_magick
153
+ Magick::Image.from_blob(@blob)
154
+ end
155
+ def create_file(directory)
156
+ FileUtils.mkdir_p directory+"/images"
157
+ @filename=directory+"/images/"+@id+"."+@type
158
+ @url="images/"+@id+"."+@type
159
+ File.open(@filename,"w") do |fp|
160
+ fp.write @blob
161
+ end
162
+ @filename
163
+ end
164
+
77
165
  end
78
- def report_building_html(builder)
79
- basedir=builder.directory+"/images"
80
- out=basedir+"/"+File.basename(@filename)
81
- if(File.exists? @filename)
82
- if !File.exists? out
166
+
167
+ class ImageFilename < Image
168
+ def initialize(filename, options=Hash.new)
169
+ super(options)
170
+ @filename=filename
171
+ File.basename(@filename)=~/\.(.+)$/
172
+ @type=File.basename($1)
173
+ end
174
+ def image_magick
175
+ Magick::Image.read(@filename).first
176
+ end
177
+ def create_file(directory)
178
+ basedir=directory+"/images"
179
+ out=basedir+"/"+File.basename(@filename)
180
+ @url="images/#{File.basename(@filename)}"
181
+ if(File.exists? @filename)
83
182
  FileUtils.mkdir_p basedir
84
- FileUtils.cp @filename, out
183
+ if (!File.exists? out or (File.mtime(out) < File.mtime(@filename)))
184
+ FileUtils.cp @filename, out
185
+ end
85
186
  end
86
187
  end
87
- builder.html("<img src='images/#{File.basename(@filename)}' alt='#{@options[:alt]}' />")
88
188
  end
89
189
  end