write_xlsx 0.0.4 → 0.51.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 (688) hide show
  1. data/Gemfile +4 -2
  2. data/README.rdoc +14 -12
  3. data/Rakefile +8 -8
  4. data/VERSION +1 -1
  5. data/examples/chart_secondary_axis.rb +55 -0
  6. data/examples/date_time.rb +84 -0
  7. data/examples/panes.rb +108 -0
  8. data/examples/regions.rb +49 -0
  9. data/examples/shape1.rb +36 -0
  10. data/examples/shape2.rb +53 -0
  11. data/examples/shape3.rb +32 -0
  12. data/examples/shape4.rb +55 -0
  13. data/examples/shape5.rb +48 -0
  14. data/examples/shape6.rb +48 -0
  15. data/examples/shape7.rb +74 -0
  16. data/examples/shape8.rb +73 -0
  17. data/examples/shape_all.rb +241 -0
  18. data/examples/stats.rb +69 -0
  19. data/examples/stats_ext.rb +77 -0
  20. data/examples/stocks.rb +73 -0
  21. data/examples/tables.rb +360 -0
  22. data/lib/write_xlsx.rb +25 -1
  23. data/lib/write_xlsx/chart.rb +656 -260
  24. data/lib/write_xlsx/chart/area.rb +41 -7
  25. data/lib/write_xlsx/chart/bar.rb +16 -17
  26. data/lib/write_xlsx/chart/column.rb +5 -15
  27. data/lib/write_xlsx/chart/line.rb +15 -6
  28. data/lib/write_xlsx/chart/pie.rb +7 -21
  29. data/lib/write_xlsx/chart/scatter.rb +90 -20
  30. data/lib/write_xlsx/chart/stock.rb +24 -43
  31. data/lib/write_xlsx/chartsheet.rb +29 -11
  32. data/lib/write_xlsx/drawing.rb +354 -35
  33. data/lib/write_xlsx/format.rb +72 -21
  34. data/lib/write_xlsx/package/app.rb +2 -5
  35. data/lib/write_xlsx/package/comments.rb +5 -1
  36. data/lib/write_xlsx/package/content_types.rb +10 -0
  37. data/lib/write_xlsx/package/packager.rb +41 -7
  38. data/lib/write_xlsx/package/relationships.rb +1 -1
  39. data/lib/write_xlsx/package/shared_strings.rb +36 -8
  40. data/lib/write_xlsx/package/styles.rb +12 -9
  41. data/lib/write_xlsx/package/table.rb +194 -0
  42. data/lib/write_xlsx/package/vml.rb +26 -27
  43. data/lib/write_xlsx/package/xml_writer_simple.rb +25 -4
  44. data/lib/write_xlsx/shape.rb +172 -0
  45. data/lib/write_xlsx/utility.rb +20 -0
  46. data/lib/write_xlsx/workbook.rb +499 -141
  47. data/lib/write_xlsx/worksheet.rb +1162 -153
  48. data/test/chart/test_add_series.rb +43 -4
  49. data/test/chart/test_write_d_lbls.rb +274 -0
  50. data/test/chart/test_write_major_gridlines.rb +1 -1
  51. data/test/chartsheet/test_chartsheet01.rb +31 -0
  52. data/test/drawing/test_drawing_shape_01.rb +68 -0
  53. data/test/drawing/test_drawing_shape_02.rb +73 -0
  54. data/test/drawing/test_drawing_shape_03.rb +38 -0
  55. data/test/drawing/test_drawing_shape_04.rb +121 -0
  56. data/test/drawing/test_drawing_shape_05.rb +45 -0
  57. data/test/drawing/test_drawing_shape_06.rb +42 -0
  58. data/test/drawing/test_drawing_shape_07.rb +47 -0
  59. data/test/drawing/test_write_a_graphic_frame_locks.rb +18 -0
  60. data/test/drawing/test_write_c_chart.rb +18 -0
  61. data/test/drawing/test_write_c_nv_graphic_frame_pr.rb +28 -0
  62. data/test/drawing/test_write_c_nv_pr.rb +18 -0
  63. data/test/drawing/test_write_col.rb +18 -0
  64. data/test/drawing/test_write_col_off.rb +18 -0
  65. data/test/drawing/test_write_ext.rb +18 -0
  66. data/test/drawing/test_write_pos.rb +18 -0
  67. data/test/drawing/test_write_row.rb +18 -0
  68. data/test/drawing/test_write_row_off.rb +18 -0
  69. data/test/drawing/test_write_xfrm_extension.rb +18 -0
  70. data/test/drawing/test_write_xfrm_offset.rb +18 -0
  71. data/test/helper.rb +93 -50
  72. data/test/package/shared_strings/test_write_si.rb +10 -1
  73. data/test/package/table/test_table01.rb +42 -0
  74. data/test/package/table/test_table02.rb +44 -0
  75. data/test/package/table/test_table03.rb +48 -0
  76. data/test/package/table/test_table04.rb +46 -0
  77. data/test/package/table/test_table05.rb +46 -0
  78. data/test/package/table/test_table06.rb +52 -0
  79. data/test/package/table/test_table07.rb +47 -0
  80. data/test/package/table/test_table08.rb +53 -0
  81. data/test/package/table/test_table09.rb +65 -0
  82. data/test/package/table/test_table10.rb +45 -0
  83. data/test/package/table/test_table11.rb +60 -0
  84. data/test/package/table/test_table12.rb +60 -0
  85. data/test/package/table/test_write_auto_filter.rb +16 -0
  86. data/test/package/table/test_write_table_column.rb +15 -0
  87. data/test/package/table/test_write_table_style_info.rb +25 -0
  88. data/test/package/table/test_write_xml_declaration.rb +15 -0
  89. data/test/perl_output/a_simple.xlsx +0 -0
  90. data/test/perl_output/array_formula.xlsx +0 -0
  91. data/test/perl_output/chart_secondary_axis.xlsx +0 -0
  92. data/test/perl_output/data_validate.xlsx +0 -0
  93. data/test/perl_output/date_time.xlsx +0 -0
  94. data/test/perl_output/demo.xlsx +0 -0
  95. data/test/perl_output/formats.xlsx +0 -0
  96. data/test/perl_output/headers.xlsx +0 -0
  97. data/test/perl_output/outline_collapsed.xlsx +0 -0
  98. data/test/perl_output/panes.xlsx +0 -0
  99. data/test/perl_output/regions.xlsx +0 -0
  100. data/test/perl_output/shape1.xlsx +0 -0
  101. data/test/perl_output/shape2.xlsx +0 -0
  102. data/test/perl_output/shape3.xlsx +0 -0
  103. data/test/perl_output/shape4.xlsx +0 -0
  104. data/test/perl_output/shape5.xlsx +0 -0
  105. data/test/perl_output/shape6.xlsx +0 -0
  106. data/test/perl_output/shape7.xlsx +0 -0
  107. data/test/perl_output/shape8.xlsx +0 -0
  108. data/test/perl_output/shape_all.xlsx +0 -0
  109. data/test/perl_output/stats.xlsx +0 -0
  110. data/test/perl_output/stats_ext.xlsx +0 -0
  111. data/test/perl_output/stocks.xlsx +0 -0
  112. data/test/perl_output/tables.xlsx +0 -0
  113. data/test/regression/images/blue.jpg +0 -0
  114. data/test/regression/images/blue.png +0 -0
  115. data/test/regression/images/grey.jpg +0 -0
  116. data/test/regression/images/grey.png +0 -0
  117. data/test/regression/images/red.bmp +0 -0
  118. data/test/regression/images/red.jpg +0 -0
  119. data/test/regression/images/red.png +0 -0
  120. data/test/regression/images/yellow.jpg +0 -0
  121. data/test/regression/images/yellow.png +0 -0
  122. data/test/regression/test_array_formula01.rb +31 -0
  123. data/test/regression/test_array_formula02.rb +32 -0
  124. data/test/regression/test_autofilter00.rb +84 -0
  125. data/test/regression/test_autofilter01.rb +86 -0
  126. data/test/regression/test_autofilter02.rb +104 -0
  127. data/test/regression/test_autofilter03.rb +104 -0
  128. data/test/regression/test_autofilter04.rb +107 -0
  129. data/test/regression/test_autofilter05.rb +108 -0
  130. data/test/regression/test_autofilter06.rb +108 -0
  131. data/test/regression/test_autofilter07.rb +107 -0
  132. data/test/regression/test_chart_area01.rb +45 -0
  133. data/test/regression/test_chart_area02.rb +45 -0
  134. data/test/regression/test_chart_area03.rb +45 -0
  135. data/test/regression/test_chart_axis01.rb +46 -0
  136. data/test/regression/test_chart_axis02.rb +46 -0
  137. data/test/regression/test_chart_axis03.rb +68 -0
  138. data/test/regression/test_chart_axis04.rb +53 -0
  139. data/test/regression/test_chart_axis05.rb +48 -0
  140. data/test/regression/test_chart_axis06.rb +50 -0
  141. data/test/regression/test_chart_axis07.rb +54 -0
  142. data/test/regression/test_chart_axis08.rb +53 -0
  143. data/test/regression/test_chart_axis09.rb +47 -0
  144. data/test/regression/test_chart_axis10.rb +53 -0
  145. data/test/regression/test_chart_axis11.rb +47 -0
  146. data/test/regression/test_chart_axis12.rb +47 -0
  147. data/test/regression/test_chart_axis13.rb +53 -0
  148. data/test/regression/test_chart_axis14.rb +67 -0
  149. data/test/regression/test_chart_axis15.rb +48 -0
  150. data/test/regression/test_chart_axis16.rb +70 -0
  151. data/test/regression/test_chart_axis17.rb +46 -0
  152. data/test/regression/test_chart_axis18.rb +44 -0
  153. data/test/regression/test_chart_axis19.rb +46 -0
  154. data/test/regression/test_chart_axis20.rb +46 -0
  155. data/test/regression/test_chart_axis21.rb +50 -0
  156. data/test/regression/test_chart_bar01.rb +44 -0
  157. data/test/regression/test_chart_bar02.rb +55 -0
  158. data/test/regression/test_chart_bar03.rb +67 -0
  159. data/test/regression/test_chart_bar04.rb +70 -0
  160. data/test/regression/test_chart_bar05.rb +43 -0
  161. data/test/regression/test_chart_bar06.rb +50 -0
  162. data/test/regression/test_chart_bar07.rb +54 -0
  163. data/test/regression/test_chart_bar08.rb +44 -0
  164. data/test/regression/test_chart_bar09.rb +43 -0
  165. data/test/regression/test_chart_bar10.rb +47 -0
  166. data/test/regression/test_chart_bar11.rb +71 -0
  167. data/test/regression/test_chart_bar12.rb +43 -0
  168. data/test/regression/test_chart_bar13.rb +53 -0
  169. data/test/regression/test_chart_bar14.rb +63 -0
  170. data/test/regression/test_chart_bar15.rb +53 -0
  171. data/test/regression/test_chart_bar16.rb +51 -0
  172. data/test/regression/test_chart_bar17.rb +47 -0
  173. data/test/regression/test_chart_bar18.rb +58 -0
  174. data/test/regression/test_chart_bar19.rb +50 -0
  175. data/test/regression/test_chart_bar20.rb +47 -0
  176. data/test/regression/test_chart_bar21.rb +53 -0
  177. data/test/regression/test_chart_bar22.rb +68 -0
  178. data/test/regression/test_chart_bar23.rb +62 -0
  179. data/test/regression/test_chart_bar24.rb +46 -0
  180. data/test/regression/test_chart_blank01.rb +41 -0
  181. data/test/regression/test_chart_blank02.rb +41 -0
  182. data/test/regression/test_chart_blank03.rb +41 -0
  183. data/test/regression/test_chart_blank04.rb +41 -0
  184. data/test/regression/test_chart_blank05.rb +46 -0
  185. data/test/regression/test_chart_blank06.rb +41 -0
  186. data/test/regression/test_chart_column01.rb +43 -0
  187. data/test/regression/test_chart_column02.rb +45 -0
  188. data/test/regression/test_chart_column03.rb +45 -0
  189. data/test/regression/test_chart_column04.rb +45 -0
  190. data/test/regression/test_chart_column05.rb +39 -0
  191. data/test/regression/test_chart_column06.rb +46 -0
  192. data/test/regression/test_chart_crossing01.rb +50 -0
  193. data/test/regression/test_chart_crossing02.rb +48 -0
  194. data/test/regression/test_chart_crossing03.rb +53 -0
  195. data/test/regression/test_chart_crossing04.rb +53 -0
  196. data/test/regression/test_chart_format01.rb +44 -0
  197. data/test/regression/test_chart_format02.rb +45 -0
  198. data/test/regression/test_chart_format03.rb +46 -0
  199. data/test/regression/test_chart_format04.rb +45 -0
  200. data/test/regression/test_chart_format05.rb +45 -0
  201. data/test/regression/test_chart_format06.rb +52 -0
  202. data/test/regression/test_chart_format07.rb +57 -0
  203. data/test/regression/test_chart_format08.rb +52 -0
  204. data/test/regression/test_chart_format09.rb +56 -0
  205. data/test/regression/test_chart_format10.rb +59 -0
  206. data/test/regression/test_chart_format11.rb +63 -0
  207. data/test/regression/test_chart_format12.rb +60 -0
  208. data/test/regression/test_chart_format13.rb +52 -0
  209. data/test/regression/test_chart_format14.rb +56 -0
  210. data/test/regression/test_chart_format15.rb +54 -0
  211. data/test/regression/test_chart_format16.rb +57 -0
  212. data/test/regression/test_chart_format17.rb +40 -0
  213. data/test/regression/test_chart_format18.rb +44 -0
  214. data/test/regression/test_chart_line01.rb +39 -0
  215. data/test/regression/test_chart_line02.rb +45 -0
  216. data/test/regression/test_chart_name01.rb +46 -0
  217. data/test/regression/test_chart_name02.rb +58 -0
  218. data/test/regression/test_chart_name03.rb +58 -0
  219. data/test/regression/test_chart_pie01.rb +36 -0
  220. data/test/regression/test_chart_scatter01.rb +45 -0
  221. data/test/regression/test_chart_scatter02.rb +49 -0
  222. data/test/regression/test_chart_scatter03.rb +49 -0
  223. data/test/regression/test_chart_scatter04.rb +49 -0
  224. data/test/regression/test_chart_scatter05.rb +49 -0
  225. data/test/regression/test_chart_scatter06.rb +51 -0
  226. data/test/regression/test_chart_scatter07.rb +60 -0
  227. data/test/regression/test_chart_sparse01.rb +54 -0
  228. data/test/regression/test_chart_stock01.rb +72 -0
  229. data/test/regression/test_chart_stock02.rb +73 -0
  230. data/test/regression/test_chart_str01.rb +48 -0
  231. data/test/regression/test_chart_str02.rb +52 -0
  232. data/test/regression/test_chartsheet01.rb +46 -0
  233. data/test/regression/test_chartsheet02.rb +50 -0
  234. data/test/regression/test_chartsheet03.rb +48 -0
  235. data/test/regression/test_chartsheet04.rb +48 -0
  236. data/test/regression/test_chartsheet05.rb +48 -0
  237. data/test/regression/test_chartsheet06.rb +48 -0
  238. data/test/regression/test_chartsheet07.rb +57 -0
  239. data/test/regression/test_chartsheet08.rb +61 -0
  240. data/test/regression/test_chartsheet09.rb +52 -0
  241. data/test/regression/test_comment01.rb +27 -0
  242. data/test/regression/test_comment02.rb +28 -0
  243. data/test/regression/test_comment03.rb +32 -0
  244. data/test/regression/test_comment04.rb +37 -0
  245. data/test/regression/test_comment06.rb +34 -0
  246. data/test/regression/test_comment07.rb +36 -0
  247. data/test/regression/test_comment08.rb +36 -0
  248. data/test/regression/test_comment09.rb +32 -0
  249. data/test/regression/test_comment10.rb +31 -0
  250. data/test/regression/test_cond_format01.rb +46 -0
  251. data/test/regression/test_cond_format02.rb +41 -0
  252. data/test/regression/test_cond_format03.rb +52 -0
  253. data/test/regression/test_cond_format04.rb +51 -0
  254. data/test/regression/test_cond_format05.rb +41 -0
  255. data/test/regression/test_cond_format06.rb +45 -0
  256. data/test/regression/test_cond_format07.rb +62 -0
  257. data/test/regression/test_cond_format08.rb +46 -0
  258. data/test/regression/test_cond_format10.rb +43 -0
  259. data/test/regression/test_cond_format11.rb +47 -0
  260. data/test/regression/test_cond_format12.rb +47 -0
  261. data/test/regression/test_custom_colors01.rb +33 -0
  262. data/test/regression/test_date_1904_01.rb +36 -0
  263. data/test/regression/test_date_1904_02.rb +39 -0
  264. data/test/regression/test_defined_name01.rb +47 -0
  265. data/test/regression/test_escapes01.rb +37 -0
  266. data/test/regression/test_escapes02.rb +33 -0
  267. data/test/regression/test_escapes03.rb +34 -0
  268. data/test/regression/test_fit_to_pages01.rb +37 -0
  269. data/test/regression/test_fit_to_pages02.rb +37 -0
  270. data/test/regression/test_fit_to_pages03.rb +37 -0
  271. data/test/regression/test_fit_to_pages04.rb +37 -0
  272. data/test/regression/test_fit_to_pages05.rb +37 -0
  273. data/test/regression/test_format01.rb +35 -0
  274. data/test/regression/test_format02.rb +47 -0
  275. data/test/regression/test_format03.rb +31 -0
  276. data/test/regression/test_format04.rb +41 -0
  277. data/test/regression/test_gridlines01.rb +36 -0
  278. data/test/regression/test_hyperlink01.rb +23 -0
  279. data/test/regression/test_hyperlink02.rb +27 -0
  280. data/test/regression/test_hyperlink03.rb +32 -0
  281. data/test/regression/test_hyperlink04.rb +31 -0
  282. data/test/regression/test_hyperlink05.rb +26 -0
  283. data/test/regression/test_hyperlink06.rb +25 -0
  284. data/test/regression/test_hyperlink07.rb +24 -0
  285. data/test/regression/test_hyperlink08.rb +24 -0
  286. data/test/regression/test_hyperlink09.rb +25 -0
  287. data/test/regression/test_hyperlink10.rb +24 -0
  288. data/test/regression/test_hyperlink11.rb +24 -0
  289. data/test/regression/test_hyperlink12.rb +25 -0
  290. data/test/regression/test_hyperlink13.rb +24 -0
  291. data/test/regression/test_hyperlink14.rb +24 -0
  292. data/test/regression/test_hyperlink15.rb +26 -0
  293. data/test/regression/test_hyperlink16.rb +26 -0
  294. data/test/regression/test_hyperlink17.rb +27 -0
  295. data/test/regression/test_hyperlink18.rb +27 -0
  296. data/test/regression/test_image01.rb +23 -0
  297. data/test/regression/test_image02.rb +23 -0
  298. data/test/regression/test_image03.rb +23 -0
  299. data/test/regression/test_image04.rb +23 -0
  300. data/test/regression/test_image05.rb +26 -0
  301. data/test/regression/test_image06.rb +36 -0
  302. data/test/regression/test_image07.rb +25 -0
  303. data/test/regression/test_outline01.rb +86 -0
  304. data/test/regression/test_outline02.rb +89 -0
  305. data/test/regression/test_outline03.rb +59 -0
  306. data/test/regression/test_outline04.rb +55 -0
  307. data/test/regression/test_outline05.rb +90 -0
  308. data/test/regression/test_outline06.rb +89 -0
  309. data/test/regression/test_page_breaks01.rb +36 -0
  310. data/test/regression/test_page_breaks02.rb +36 -0
  311. data/test/regression/test_page_breaks03.rb +36 -0
  312. data/test/regression/test_page_breaks04.rb +36 -0
  313. data/test/regression/test_page_breaks05.rb +36 -0
  314. data/test/regression/test_page_breaks06.rb +37 -0
  315. data/test/regression/test_page_view01.rb +36 -0
  316. data/test/regression/test_panes01.rb +66 -0
  317. data/test/regression/test_print_across01.rb +37 -0
  318. data/test/regression/test_print_area01.rb +36 -0
  319. data/test/regression/test_print_area02.rb +36 -0
  320. data/test/regression/test_print_area03.rb +36 -0
  321. data/test/regression/test_print_area04.rb +36 -0
  322. data/test/regression/test_print_area05.rb +36 -0
  323. data/test/regression/test_print_area06.rb +36 -0
  324. data/test/regression/test_print_area07.rb +37 -0
  325. data/test/regression/test_print_options01.rb +36 -0
  326. data/test/regression/test_print_options02.rb +36 -0
  327. data/test/regression/test_print_options03.rb +36 -0
  328. data/test/regression/test_print_options04.rb +36 -0
  329. data/test/regression/test_print_options05.rb +39 -0
  330. data/test/regression/test_print_options06.rb +37 -0
  331. data/test/regression/test_print_scale01.rb +37 -0
  332. data/test/regression/test_print_scale02.rb +37 -0
  333. data/test/regression/test_properties01.rb +40 -0
  334. data/test/regression/test_repeat01.rb +36 -0
  335. data/test/regression/test_repeat02.rb +36 -0
  336. data/test/regression/test_repeat03.rb +37 -0
  337. data/test/regression/test_repeat04.rb +36 -0
  338. data/test/regression/test_repeat05.rb +43 -0
  339. data/test/regression/test_rich_string01.rb +28 -0
  340. data/test/regression/test_rich_string02.rb +28 -0
  341. data/test/regression/test_rich_string03.rb +28 -0
  342. data/test/regression/test_rich_string04.rb +28 -0
  343. data/test/regression/test_rich_string05.rb +30 -0
  344. data/test/regression/test_rich_string06.rb +27 -0
  345. data/test/regression/test_rich_string07.rb +33 -0
  346. data/test/regression/test_rich_string08.rb +29 -0
  347. data/test/regression/test_rich_string09.rb +31 -0
  348. data/test/regression/test_rich_string10.rb +30 -0
  349. data/test/regression/test_rich_string11.rb +29 -0
  350. data/test/regression/test_row_col_format01.rb +24 -0
  351. data/test/regression/test_row_col_format02.rb +25 -0
  352. data/test/regression/test_row_col_format03.rb +24 -0
  353. data/test/regression/test_row_col_format04.rb +25 -0
  354. data/test/regression/test_row_col_format05.rb +26 -0
  355. data/test/regression/test_row_col_format06.rb +29 -0
  356. data/test/regression/test_row_col_format07.rb +24 -0
  357. data/test/regression/test_row_col_format08.rb +34 -0
  358. data/test/regression/test_row_col_format09.rb +33 -0
  359. data/test/regression/test_row_col_format10.rb +24 -0
  360. data/test/regression/test_row_col_format11.rb +23 -0
  361. data/test/regression/test_row_col_format12.rb +23 -0
  362. data/test/regression/test_row_col_format13.rb +28 -0
  363. data/test/regression/test_row_col_format14.rb +28 -0
  364. data/test/regression/test_shape_connect01.rb +46 -0
  365. data/test/regression/test_shape_connect02.rb +42 -0
  366. data/test/regression/test_shape_connect03.rb +78 -0
  367. data/test/regression/test_shape_connect04.rb +75 -0
  368. data/test/regression/test_shape_scale01.rb +47 -0
  369. data/test/regression/test_shape_stencil01.rb +44 -0
  370. data/test/regression/test_shared_strings01.rb +34 -0
  371. data/test/regression/test_shared_strings02.rb +47 -0
  372. data/test/regression/test_simple01.rb +24 -0
  373. data/test/regression/test_simple02.rb +32 -0
  374. data/test/regression/test_tab_color01.rb +29 -0
  375. data/test/regression/test_table01.rb +27 -0
  376. data/test/regression/test_table02.rb +37 -0
  377. data/test/regression/test_table03.rb +30 -0
  378. data/test/regression/test_table04.rb +34 -0
  379. data/test/regression/test_table05.rb +38 -0
  380. data/test/regression/test_table06.rb +41 -0
  381. data/test/regression/test_table07.rb +29 -0
  382. data/test/regression/test_table08.rb +48 -0
  383. data/test/regression/test_table09.rb +65 -0
  384. data/test/regression/test_table10.rb +68 -0
  385. data/test/regression/test_table11.rb +37 -0
  386. data/test/regression/test_table12.rb +36 -0
  387. data/test/regression/test_table13.rb +51 -0
  388. data/test/regression/test_table14.rb +51 -0
  389. data/test/regression/xlsx_files/array_formula01.xlsx +0 -0
  390. data/test/regression/xlsx_files/array_formula02.xlsx +0 -0
  391. data/test/regression/xlsx_files/autofilter00.xlsx +0 -0
  392. data/test/regression/xlsx_files/autofilter01.xlsx +0 -0
  393. data/test/regression/xlsx_files/autofilter02.xlsx +0 -0
  394. data/test/regression/xlsx_files/autofilter03.xlsx +0 -0
  395. data/test/regression/xlsx_files/autofilter04.xlsx +0 -0
  396. data/test/regression/xlsx_files/autofilter05.xlsx +0 -0
  397. data/test/regression/xlsx_files/autofilter06.xlsx +0 -0
  398. data/test/regression/xlsx_files/autofilter07.xlsx +0 -0
  399. data/test/regression/xlsx_files/chart_area01.xlsx +0 -0
  400. data/test/regression/xlsx_files/chart_area02.xlsx +0 -0
  401. data/test/regression/xlsx_files/chart_area03.xlsx +0 -0
  402. data/test/regression/xlsx_files/chart_area04.xlsx +0 -0
  403. data/test/regression/xlsx_files/chart_axis01.xlsx +0 -0
  404. data/test/regression/xlsx_files/chart_axis02.xlsx +0 -0
  405. data/test/regression/xlsx_files/chart_axis03.xlsx +0 -0
  406. data/test/regression/xlsx_files/chart_axis04.xlsx +0 -0
  407. data/test/regression/xlsx_files/chart_axis05.xlsx +0 -0
  408. data/test/regression/xlsx_files/chart_axis06.xlsx +0 -0
  409. data/test/regression/xlsx_files/chart_axis07.xlsx +0 -0
  410. data/test/regression/xlsx_files/chart_axis08.xlsx +0 -0
  411. data/test/regression/xlsx_files/chart_axis09.xlsx +0 -0
  412. data/test/regression/xlsx_files/chart_axis10.xlsx +0 -0
  413. data/test/regression/xlsx_files/chart_axis11.xlsx +0 -0
  414. data/test/regression/xlsx_files/chart_axis12.xlsx +0 -0
  415. data/test/regression/xlsx_files/chart_axis13.xlsx +0 -0
  416. data/test/regression/xlsx_files/chart_axis14.xlsx +0 -0
  417. data/test/regression/xlsx_files/chart_axis15.xlsx +0 -0
  418. data/test/regression/xlsx_files/chart_axis16.xlsx +0 -0
  419. data/test/regression/xlsx_files/chart_axis17.xlsx +0 -0
  420. data/test/regression/xlsx_files/chart_axis18.xlsx +0 -0
  421. data/test/regression/xlsx_files/chart_axis19.xlsx +0 -0
  422. data/test/regression/xlsx_files/chart_axis20.xlsx +0 -0
  423. data/test/regression/xlsx_files/chart_axis21.xlsx +0 -0
  424. data/test/regression/xlsx_files/chart_bar01.xlsx +0 -0
  425. data/test/regression/xlsx_files/chart_bar02.xlsx +0 -0
  426. data/test/regression/xlsx_files/chart_bar03.xlsx +0 -0
  427. data/test/regression/xlsx_files/chart_bar04.xlsx +0 -0
  428. data/test/regression/xlsx_files/chart_bar05.xlsx +0 -0
  429. data/test/regression/xlsx_files/chart_bar06.xlsx +0 -0
  430. data/test/regression/xlsx_files/chart_bar07.xlsx +0 -0
  431. data/test/regression/xlsx_files/chart_bar08.xlsx +0 -0
  432. data/test/regression/xlsx_files/chart_bar09.xlsx +0 -0
  433. data/test/regression/xlsx_files/chart_bar10.xlsx +0 -0
  434. data/test/regression/xlsx_files/chart_bar11.xlsx +0 -0
  435. data/test/regression/xlsx_files/chart_bar12.xlsx +0 -0
  436. data/test/regression/xlsx_files/chart_bar13.xlsx +0 -0
  437. data/test/regression/xlsx_files/chart_bar14.xlsx +0 -0
  438. data/test/regression/xlsx_files/chart_bar15.xlsx +0 -0
  439. data/test/regression/xlsx_files/chart_bar16.xlsx +0 -0
  440. data/test/regression/xlsx_files/chart_bar17.xlsx +0 -0
  441. data/test/regression/xlsx_files/chart_bar18.xlsx +0 -0
  442. data/test/regression/xlsx_files/chart_bar19.xlsx +0 -0
  443. data/test/regression/xlsx_files/chart_bar20.xlsx +0 -0
  444. data/test/regression/xlsx_files/chart_bar21.xlsx +0 -0
  445. data/test/regression/xlsx_files/chart_bar22.xlsx +0 -0
  446. data/test/regression/xlsx_files/chart_bar23.xlsx +0 -0
  447. data/test/regression/xlsx_files/chart_bar24.xlsx +0 -0
  448. data/test/regression/xlsx_files/chart_blank01.xlsx +0 -0
  449. data/test/regression/xlsx_files/chart_blank02.xlsx +0 -0
  450. data/test/regression/xlsx_files/chart_blank03.xlsx +0 -0
  451. data/test/regression/xlsx_files/chart_blank04.xlsx +0 -0
  452. data/test/regression/xlsx_files/chart_blank05.xlsx +0 -0
  453. data/test/regression/xlsx_files/chart_blank06.xlsx +0 -0
  454. data/test/regression/xlsx_files/chart_column01.xlsx +0 -0
  455. data/test/regression/xlsx_files/chart_column02.xlsx +0 -0
  456. data/test/regression/xlsx_files/chart_column03.xlsx +0 -0
  457. data/test/regression/xlsx_files/chart_column04.xlsx +0 -0
  458. data/test/regression/xlsx_files/chart_column05.xlsx +0 -0
  459. data/test/regression/xlsx_files/chart_column06.xlsx +0 -0
  460. data/test/regression/xlsx_files/chart_crossing01.xlsx +0 -0
  461. data/test/regression/xlsx_files/chart_crossing02.xlsx +0 -0
  462. data/test/regression/xlsx_files/chart_crossing03.xlsx +0 -0
  463. data/test/regression/xlsx_files/chart_crossing04.xlsx +0 -0
  464. data/test/regression/xlsx_files/chart_format01.xlsx +0 -0
  465. data/test/regression/xlsx_files/chart_format02.xlsx +0 -0
  466. data/test/regression/xlsx_files/chart_format03.xlsx +0 -0
  467. data/test/regression/xlsx_files/chart_format04.xlsx +0 -0
  468. data/test/regression/xlsx_files/chart_format05.xlsx +0 -0
  469. data/test/regression/xlsx_files/chart_format06.xlsx +0 -0
  470. data/test/regression/xlsx_files/chart_format07.xlsx +0 -0
  471. data/test/regression/xlsx_files/chart_format08.xlsx +0 -0
  472. data/test/regression/xlsx_files/chart_format09.xlsx +0 -0
  473. data/test/regression/xlsx_files/chart_format10.xlsx +0 -0
  474. data/test/regression/xlsx_files/chart_format11.xlsx +0 -0
  475. data/test/regression/xlsx_files/chart_format12.xlsx +0 -0
  476. data/test/regression/xlsx_files/chart_format13.xlsx +0 -0
  477. data/test/regression/xlsx_files/chart_format14.xlsx +0 -0
  478. data/test/regression/xlsx_files/chart_format15.xlsx +0 -0
  479. data/test/regression/xlsx_files/chart_format16.xlsx +0 -0
  480. data/test/regression/xlsx_files/chart_format17.xlsx +0 -0
  481. data/test/regression/xlsx_files/chart_format18.xlsx +0 -0
  482. data/test/regression/xlsx_files/chart_line01.xlsx +0 -0
  483. data/test/regression/xlsx_files/chart_line02.xlsx +0 -0
  484. data/test/regression/xlsx_files/chart_name01.xlsx +0 -0
  485. data/test/regression/xlsx_files/chart_name02.xlsx +0 -0
  486. data/test/regression/xlsx_files/chart_name03.xlsx +0 -0
  487. data/test/regression/xlsx_files/chart_pie01.xlsx +0 -0
  488. data/test/regression/xlsx_files/chart_scatter01.xlsx +0 -0
  489. data/test/regression/xlsx_files/chart_scatter02.xlsx +0 -0
  490. data/test/regression/xlsx_files/chart_scatter03.xlsx +0 -0
  491. data/test/regression/xlsx_files/chart_scatter04.xlsx +0 -0
  492. data/test/regression/xlsx_files/chart_scatter05.xlsx +0 -0
  493. data/test/regression/xlsx_files/chart_scatter06.xlsx +0 -0
  494. data/test/regression/xlsx_files/chart_scatter07.xlsx +0 -0
  495. data/test/regression/xlsx_files/chart_sparse01.xlsx +0 -0
  496. data/test/regression/xlsx_files/chart_stock01.xlsx +0 -0
  497. data/test/regression/xlsx_files/chart_stock02.xlsx +0 -0
  498. data/test/regression/xlsx_files/chart_str01.xlsx +0 -0
  499. data/test/regression/xlsx_files/chart_str02.xlsx +0 -0
  500. data/test/regression/xlsx_files/chartsheet01.xlsx +0 -0
  501. data/test/regression/xlsx_files/chartsheet02.xlsx +0 -0
  502. data/test/regression/xlsx_files/chartsheet03.xlsx +0 -0
  503. data/test/regression/xlsx_files/chartsheet04.xlsx +0 -0
  504. data/test/regression/xlsx_files/chartsheet05.xlsx +0 -0
  505. data/test/regression/xlsx_files/chartsheet06.xlsx +0 -0
  506. data/test/regression/xlsx_files/chartsheet07.xlsx +0 -0
  507. data/test/regression/xlsx_files/chartsheet08.xlsx +0 -0
  508. data/test/regression/xlsx_files/chartsheet09.xlsx +0 -0
  509. data/test/regression/xlsx_files/comment01.xlsx +0 -0
  510. data/test/regression/xlsx_files/comment02.xlsx +0 -0
  511. data/test/regression/xlsx_files/comment03.xlsx +0 -0
  512. data/test/regression/xlsx_files/comment04.xlsx +0 -0
  513. data/test/regression/xlsx_files/comment05.xlsx +0 -0
  514. data/test/regression/xlsx_files/comment06.xlsx +0 -0
  515. data/test/regression/xlsx_files/comment07.xlsx +0 -0
  516. data/test/regression/xlsx_files/comment08.xlsx +0 -0
  517. data/test/regression/xlsx_files/comment09.xlsx +0 -0
  518. data/test/regression/xlsx_files/comment10.xlsx +0 -0
  519. data/test/regression/xlsx_files/cond_format01.xlsx +0 -0
  520. data/test/regression/xlsx_files/cond_format02.xlsx +0 -0
  521. data/test/regression/xlsx_files/cond_format03.xlsx +0 -0
  522. data/test/regression/xlsx_files/cond_format04.xlsx +0 -0
  523. data/test/regression/xlsx_files/cond_format05.xlsx +0 -0
  524. data/test/regression/xlsx_files/cond_format06.xlsx +0 -0
  525. data/test/regression/xlsx_files/cond_format07.xlsx +0 -0
  526. data/test/regression/xlsx_files/cond_format08.xlsx +0 -0
  527. data/test/regression/xlsx_files/cond_format10.xlsx +0 -0
  528. data/test/regression/xlsx_files/cond_format11.xlsx +0 -0
  529. data/test/regression/xlsx_files/cond_format12.xlsx +0 -0
  530. data/test/regression/xlsx_files/custom_colors01.xlsx +0 -0
  531. data/test/regression/xlsx_files/date_1904_01.xlsx +0 -0
  532. data/test/regression/xlsx_files/date_1904_02.xlsx +0 -0
  533. data/test/regression/xlsx_files/defined_name01.xlsx +0 -0
  534. data/test/regression/xlsx_files/escapes01.xlsx +0 -0
  535. data/test/regression/xlsx_files/escapes02.xlsx +0 -0
  536. data/test/regression/xlsx_files/escapes03.xlsx +0 -0
  537. data/test/regression/xlsx_files/filehandle01.xlsx +0 -0
  538. data/test/regression/xlsx_files/fit_to_pages01.xlsx +0 -0
  539. data/test/regression/xlsx_files/fit_to_pages02.xlsx +0 -0
  540. data/test/regression/xlsx_files/fit_to_pages03.xlsx +0 -0
  541. data/test/regression/xlsx_files/fit_to_pages04.xlsx +0 -0
  542. data/test/regression/xlsx_files/fit_to_pages05.xlsx +0 -0
  543. data/test/regression/xlsx_files/format01.xlsx +0 -0
  544. data/test/regression/xlsx_files/format02.xlsx +0 -0
  545. data/test/regression/xlsx_files/format03.xlsx +0 -0
  546. data/test/regression/xlsx_files/format04.xlsx +0 -0
  547. data/test/regression/xlsx_files/gridlines01.xlsx +0 -0
  548. data/test/regression/xlsx_files/hyperlink01.xlsx +0 -0
  549. data/test/regression/xlsx_files/hyperlink02.xlsx +0 -0
  550. data/test/regression/xlsx_files/hyperlink03.xlsx +0 -0
  551. data/test/regression/xlsx_files/hyperlink04.xlsx +0 -0
  552. data/test/regression/xlsx_files/hyperlink05.xlsx +0 -0
  553. data/test/regression/xlsx_files/hyperlink06.xlsx +0 -0
  554. data/test/regression/xlsx_files/hyperlink07.xlsx +0 -0
  555. data/test/regression/xlsx_files/hyperlink08.xlsx +0 -0
  556. data/test/regression/xlsx_files/hyperlink09.xlsx +0 -0
  557. data/test/regression/xlsx_files/hyperlink10.xlsx +0 -0
  558. data/test/regression/xlsx_files/hyperlink11.xlsx +0 -0
  559. data/test/regression/xlsx_files/hyperlink12.xlsx +0 -0
  560. data/test/regression/xlsx_files/hyperlink13.xlsx +0 -0
  561. data/test/regression/xlsx_files/hyperlink14.xlsx +0 -0
  562. data/test/regression/xlsx_files/hyperlink15.xlsx +0 -0
  563. data/test/regression/xlsx_files/hyperlink16.xlsx +0 -0
  564. data/test/regression/xlsx_files/hyperlink17.xlsx +0 -0
  565. data/test/regression/xlsx_files/hyperlink18.xlsx +0 -0
  566. data/test/regression/xlsx_files/image01.xlsx +0 -0
  567. data/test/regression/xlsx_files/image02.xlsx +0 -0
  568. data/test/regression/xlsx_files/image03.xlsx +0 -0
  569. data/test/regression/xlsx_files/image04.xlsx +0 -0
  570. data/test/regression/xlsx_files/image05.xlsx +0 -0
  571. data/test/regression/xlsx_files/image06.xlsx +0 -0
  572. data/test/regression/xlsx_files/image07.xlsx +0 -0
  573. data/test/regression/xlsx_files/outline01.xlsx +0 -0
  574. data/test/regression/xlsx_files/outline02.xlsx +0 -0
  575. data/test/regression/xlsx_files/outline03.xlsx +0 -0
  576. data/test/regression/xlsx_files/outline04.xlsx +0 -0
  577. data/test/regression/xlsx_files/outline05.xlsx +0 -0
  578. data/test/regression/xlsx_files/outline06.xlsx +0 -0
  579. data/test/regression/xlsx_files/page_breaks01.xlsx +0 -0
  580. data/test/regression/xlsx_files/page_breaks02.xlsx +0 -0
  581. data/test/regression/xlsx_files/page_breaks03.xlsx +0 -0
  582. data/test/regression/xlsx_files/page_breaks04.xlsx +0 -0
  583. data/test/regression/xlsx_files/page_breaks05.xlsx +0 -0
  584. data/test/regression/xlsx_files/page_breaks06.xlsx +0 -0
  585. data/test/regression/xlsx_files/page_view01.xlsx +0 -0
  586. data/test/regression/xlsx_files/panes01.xlsx +0 -0
  587. data/test/regression/xlsx_files/print_across01.xlsx +0 -0
  588. data/test/regression/xlsx_files/print_area01.xlsx +0 -0
  589. data/test/regression/xlsx_files/print_area02.xlsx +0 -0
  590. data/test/regression/xlsx_files/print_area03.xlsx +0 -0
  591. data/test/regression/xlsx_files/print_area04.xlsx +0 -0
  592. data/test/regression/xlsx_files/print_area05.xlsx +0 -0
  593. data/test/regression/xlsx_files/print_area06.xlsx +0 -0
  594. data/test/regression/xlsx_files/print_area07.xlsx +0 -0
  595. data/test/regression/xlsx_files/print_options01.xlsx +0 -0
  596. data/test/regression/xlsx_files/print_options02.xlsx +0 -0
  597. data/test/regression/xlsx_files/print_options03.xlsx +0 -0
  598. data/test/regression/xlsx_files/print_options04.xlsx +0 -0
  599. data/test/regression/xlsx_files/print_options05.xlsx +0 -0
  600. data/test/regression/xlsx_files/print_options06.xlsx +0 -0
  601. data/test/regression/xlsx_files/print_scale01.xlsx +0 -0
  602. data/test/regression/xlsx_files/print_scale02.xlsx +0 -0
  603. data/test/regression/xlsx_files/properties01.xlsx +0 -0
  604. data/test/regression/xlsx_files/repeat01.xlsx +0 -0
  605. data/test/regression/xlsx_files/repeat02.xlsx +0 -0
  606. data/test/regression/xlsx_files/repeat03.xlsx +0 -0
  607. data/test/regression/xlsx_files/repeat04.xlsx +0 -0
  608. data/test/regression/xlsx_files/repeat05.xlsx +0 -0
  609. data/test/regression/xlsx_files/rich_string01.xlsx +0 -0
  610. data/test/regression/xlsx_files/rich_string02.xlsx +0 -0
  611. data/test/regression/xlsx_files/rich_string03.xlsx +0 -0
  612. data/test/regression/xlsx_files/rich_string04.xlsx +0 -0
  613. data/test/regression/xlsx_files/rich_string05.xlsx +0 -0
  614. data/test/regression/xlsx_files/rich_string06.xlsx +0 -0
  615. data/test/regression/xlsx_files/rich_string07.xlsx +0 -0
  616. data/test/regression/xlsx_files/rich_string08.xlsx +0 -0
  617. data/test/regression/xlsx_files/rich_string09.xlsx +0 -0
  618. data/test/regression/xlsx_files/rich_string10.xlsx +0 -0
  619. data/test/regression/xlsx_files/rich_string11.xlsx +0 -0
  620. data/test/regression/xlsx_files/row_col_format01.xlsx +0 -0
  621. data/test/regression/xlsx_files/row_col_format02.xlsx +0 -0
  622. data/test/regression/xlsx_files/row_col_format03.xlsx +0 -0
  623. data/test/regression/xlsx_files/row_col_format04.xlsx +0 -0
  624. data/test/regression/xlsx_files/row_col_format05.xlsx +0 -0
  625. data/test/regression/xlsx_files/row_col_format06.xlsx +0 -0
  626. data/test/regression/xlsx_files/row_col_format07.xlsx +0 -0
  627. data/test/regression/xlsx_files/row_col_format08.xlsx +0 -0
  628. data/test/regression/xlsx_files/row_col_format09.xlsx +0 -0
  629. data/test/regression/xlsx_files/row_col_format10.xlsx +0 -0
  630. data/test/regression/xlsx_files/row_col_format11.xlsx +0 -0
  631. data/test/regression/xlsx_files/row_col_format12.xlsx +0 -0
  632. data/test/regression/xlsx_files/row_col_format13.xlsx +0 -0
  633. data/test/regression/xlsx_files/row_col_format14.xlsx +0 -0
  634. data/test/regression/xlsx_files/shape_connect01.xlsx +0 -0
  635. data/test/regression/xlsx_files/shape_connect02.xlsx +0 -0
  636. data/test/regression/xlsx_files/shape_connect03.xlsx +0 -0
  637. data/test/regression/xlsx_files/shape_connect04.xlsx +0 -0
  638. data/test/regression/xlsx_files/shape_scale01.xlsx +0 -0
  639. data/test/regression/xlsx_files/shape_stencil01.xlsx +0 -0
  640. data/test/regression/xlsx_files/shared_strings01.xlsx +0 -0
  641. data/test/regression/xlsx_files/shared_strings02.xlsx +0 -0
  642. data/test/regression/xlsx_files/simple01.xlsx +0 -0
  643. data/test/regression/xlsx_files/simple02.xlsx +0 -0
  644. data/test/regression/xlsx_files/tab_color01.xlsx +0 -0
  645. data/test/regression/xlsx_files/table01.xlsx +0 -0
  646. data/test/regression/xlsx_files/table02.xlsx +0 -0
  647. data/test/regression/xlsx_files/table03.xlsx +0 -0
  648. data/test/regression/xlsx_files/table04.xlsx +0 -0
  649. data/test/regression/xlsx_files/table05.xlsx +0 -0
  650. data/test/regression/xlsx_files/table06.xlsx +0 -0
  651. data/test/regression/xlsx_files/table07.xlsx +0 -0
  652. data/test/regression/xlsx_files/table08.xlsx +0 -0
  653. data/test/regression/xlsx_files/table09.xlsx +0 -0
  654. data/test/regression/xlsx_files/table10.xlsx +0 -0
  655. data/test/regression/xlsx_files/table11.xlsx +0 -0
  656. data/test/regression/xlsx_files/table12.xlsx +0 -0
  657. data/test/regression/xlsx_files/table13.xlsx +0 -0
  658. data/test/regression/xlsx_files/table14.xlsx +0 -0
  659. data/test/test_example_match.rb +2386 -889
  660. data/test/workbook/test_write_defined_names.rb +1 -1
  661. data/test/worksheet/test_cond_format_01.rb +82 -0
  662. data/test/worksheet/test_cond_format_02.rb +87 -0
  663. data/test/worksheet/test_cond_format_03.rb +97 -0
  664. data/test/worksheet/test_cond_format_04.rb +85 -0
  665. data/test/worksheet/test_cond_format_05.rb +96 -0
  666. data/test/worksheet/test_cond_format_06.rb +106 -0
  667. data/test/worksheet/test_cond_format_07.rb +116 -0
  668. data/test/worksheet/test_cond_format_08.rb +115 -0
  669. data/test/worksheet/test_cond_format_09.rb +108 -0
  670. data/test/worksheet/test_cond_format_10.rb +83 -0
  671. data/test/worksheet/test_cond_format_11.rb +85 -0
  672. data/test/worksheet/test_cond_format_12.rb +133 -0
  673. data/test/worksheet/test_cond_format_13.rb +135 -0
  674. data/test/worksheet/test_cond_format_14.rb +132 -0
  675. data/test/worksheet/test_cond_format_15.rb +93 -0
  676. data/test/worksheet/test_cond_format_16.rb +138 -0
  677. data/test/worksheet/test_cond_format_17.rb +141 -0
  678. data/test/worksheet/test_cond_format_18.rb +135 -0
  679. data/test/worksheet/test_cond_format_19.rb +139 -0
  680. data/test/worksheet/test_write_array_formula_01.rb +3 -4
  681. data/test/worksheet/test_write_data_validation_01.rb +1 -1
  682. data/test/worksheet/test_write_data_validation_02.rb +2 -2
  683. data/test/worksheet/test_write_methods.rb +6 -1
  684. data/test/worksheet/test_write_page_setup.rb +1 -1
  685. data/test/worksheet/test_write_sheet_view.rb +1 -1
  686. data/write_xlsx.gemspec +644 -9
  687. metadata +649 -22
  688. data/test/chart/test_write_chart_space.rb +0 -15
@@ -3,7 +3,7 @@
3
3
  require 'write_xlsx/workbook'
4
4
 
5
5
  #
6
- # write_xlsx is gem to create a new file in the Excel 2007+ XLSX format,
6
+ # write is gem to create a new file in the Excel 2007+ XLSX format,
7
7
  # and you can use the same interface as writeexcel gem.
8
8
  # write_xlsx is converted from Perl’s module github.com/jmcnamara/excel-writer-xlsx .
9
9
  #
@@ -20,6 +20,8 @@
20
20
  # Charts
21
21
  # Autofilters
22
22
  # Data validation
23
+ # Conditional formatting
24
+ # Tables
23
25
  # Hyperlinks
24
26
  # Defined names
25
27
  # Grouping/Outlines
@@ -55,8 +57,30 @@
55
57
  # # Write a number and a formula using A1 notation
56
58
  # worksheet.write('A3', 1.2345)
57
59
  # worksheet.write('A4', '=SIN(PI()/4)')
60
+ #
58
61
  # workbook.close
59
62
  #
63
+ # == Description
64
+ #
65
+ # The WriteXLSX gem can be used to create an Excel file in the 2007+ XLSX
66
+ # format.
67
+ #
68
+ # The XLSX format is the Office Open XML(OOXML) format used by Excel 2007
69
+ # and later.
70
+ #
71
+ # Multiple worksheets can be added to a workbook and formatting can be applied
72
+ # to cells. Text, numbers and formulas can be written to the cells.
73
+ #
74
+ # This module cannot, as yet, be used to write to an exsisting Excel XLSX file.
75
+ #
76
+ # == WriteXLSX and WriteExcel
77
+ #
78
+ # WriteXLSX uses the same interface as the WriteExcel gem which produces an
79
+ # Excel file in binary XLS format.
80
+ #
81
+ # WriteXLSX supports all the features of WriteExcel and in some cases has more
82
+ # functionally.
83
+ #
60
84
  # == Other Methods
61
85
  #
62
86
  # see Writexlsx::Workbook, Writexlsx::Worksheet, Writexlsx::Chart etc.
@@ -368,65 +368,100 @@ module Writexlsx
368
368
  #
369
369
  # The following properties can be set for data_labels formats in a chart.
370
370
  #
371
- # value
372
- # category
373
- # series_name
371
+ # :value
372
+ # :category
373
+ # :series_name
374
+ # :position
375
+ # :leader_lines
376
+ # :percentage
377
+ #
374
378
  # The value property turns on the Value data label for a series.
375
379
  #
376
380
  # chart.add_series(
377
381
  # :values => '=Sheet1!$B$1:$B$5',
378
- # :data_labels => { value => 1 }
382
+ # :data_labels => { :value => 1 }
379
383
  # )
380
384
  # The category property turns on the Category Name data label for a series.
381
385
  #
382
386
  # chart.add_series(
383
387
  # :values => '=Sheet1!$B$1:$B$5',
384
- # :data_labels => { category => 1 }
388
+ # :data_labels => { :category => 1 }
385
389
  # )
386
390
  # The series_name property turns on the Series Name data label for a series.
387
391
  #
388
392
  # chart.add_series(
389
393
  # :values => '=Sheet1!$B$1:$B$5',
390
- # :data_labels => { series_name => 1 }
394
+ # :data_labels => { :series_name => 1 }
395
+ # )
396
+ # The C<position> property is used to position the data label for a series.
397
+ #
398
+ # chart.add_series(
399
+ # :values => '=Sheet1!$B$1:$B$5',
400
+ # :data_labels => { :value => 1, :position => 'center' }
391
401
  # )
392
- # Other formatting options
393
402
  #
394
- # Other formatting options will be added in time. If there is a feature that
395
- # you would like to see included drop me a line.
403
+ # Valid positions are:
404
+ #
405
+ # :center
406
+ # :right
407
+ # :left
408
+ # :top
409
+ # :bottom
410
+ # :above # Same as top
411
+ # :below # Same as bottom
412
+ # :inside_end # Pie chart mainly.
413
+ # :outside_end # Pie chart mainly.
414
+ # :best_fit # Pie chart mainly.
415
+ #
416
+ # The C<percentage> property is used to turn on the I<Percentage>
417
+ # for the data label for a series. It is mainly used for pie charts.
418
+ #
419
+ # chart.add_series(
420
+ # :values => '=Sheet1!$B$1:$B$5',
421
+ # :data_labels => { :percentage => 1 }
422
+ # )
423
+ #
424
+ # The C<leader_lines> property is used to turn on I<Leader Lines>
425
+ # for the data label for a series. It is mainly used for pie charts.
426
+ #
427
+ # chart.add_series(
428
+ # :values => '=Sheet1!$B$1:$B$5',
429
+ # :data_labels => { :value => 1, :leader_lines => 1 }
430
+ # )
396
431
  #
397
432
  class Chart
398
433
  include Writexlsx::Utility
399
434
 
400
- attr_accessor :id # :nodoc:
401
- attr_writer :index, :palette # :nodoc:
435
+ attr_accessor :id, :name # :nodoc:
436
+ attr_writer :index, :palette, :protection # :nodoc:
402
437
  attr_reader :embedded, :formula_ids, :formula_data # :nodoc:
403
438
 
404
439
  #
405
440
  # Factory method for returning chart objects based on their class type.
406
441
  #
407
- def self.factory(chart_subclass) # :nodoc:
408
- case chart_subclass.downcase.capitalize
442
+ def self.factory(current_subclass, subtype = nil) # :nodoc:
443
+ case current_subclass.downcase.capitalize
409
444
  when 'Area'
410
445
  require 'write_xlsx/chart/area'
411
- Chart::Area.new
446
+ Chart::Area.new(subtype)
412
447
  when 'Bar'
413
448
  require 'write_xlsx/chart/bar'
414
- Chart::Bar.new
449
+ Chart::Bar.new(subtype)
415
450
  when 'Column'
416
451
  require 'write_xlsx/chart/column'
417
- Chart::Column.new
452
+ Chart::Column.new(subtype)
418
453
  when 'Line'
419
454
  require 'write_xlsx/chart/line'
420
- Chart::Line.new
455
+ Chart::Line.new(subtype)
421
456
  when 'Pie'
422
457
  require 'write_xlsx/chart/pie'
423
- Chart::Pie.new
458
+ Chart::Pie.new(subtype)
424
459
  when 'Scatter'
425
460
  require 'write_xlsx/chart/scatter'
426
- Chart::Scatter.new
461
+ Chart::Scatter.new(subtype)
427
462
  when 'Stock'
428
463
  require 'write_xlsx/chart/stock'
429
- Chart::Stock.new
464
+ Chart::Stock.new(subtype)
430
465
  end
431
466
  end
432
467
 
@@ -439,9 +474,11 @@ def initialize(subtype) # :nodoc:
439
474
  @series = []
440
475
  @embedded = 0
441
476
  @id = ''
477
+ @series_index = 0
442
478
  @style_id = 2
443
479
  @axis_ids = []
444
- @has_category = 0
480
+ @axis2_ids = []
481
+ @has_category = false
445
482
  @requires_category = 0
446
483
  @legend_position = 'right'
447
484
  @cat_axis_position = 'b'
@@ -453,6 +490,12 @@ def initialize(subtype) # :nodoc:
453
490
  @protection = 0
454
491
  @x_axis = {}
455
492
  @y_axis = {}
493
+ @x2_axis = {}
494
+ @y2_axis = {}
495
+ @name = ''
496
+ @show_blanks = 'gap'
497
+ @show_hidden_data = false
498
+ @show_crosses = true
456
499
 
457
500
  set_default_properties
458
501
  end
@@ -468,25 +511,23 @@ def assemble_xml_file # :nodoc:
468
511
  @writer.xml_decl
469
512
 
470
513
  # Write the c:chartSpace element.
471
- write_chart_space
472
-
473
- # Write the c:lang element.
474
- write_lang
514
+ write_chart_space do
475
515
 
476
- # Write the c:style element.
477
- write_style
516
+ # Write the c:lang element.
517
+ write_lang
478
518
 
479
- # Write the c:protection element.
480
- write_protection
519
+ # Write the c:style element.
520
+ write_style
481
521
 
482
- # Write the c:chart element.
483
- write_chart
522
+ # Write the c:protection element.
523
+ write_protection
484
524
 
485
- # Write the c:printSettings element.
486
- write_print_settings if @embedded
525
+ # Write the c:chart element.
526
+ write_chart
487
527
 
488
- # Close the worksheet tag.
489
- @writer.end_tag( 'c:chartSpace')
528
+ # Write the c:printSettings element.
529
+ write_print_settings if @embedded && @embedded != 0
530
+ end
490
531
 
491
532
  # Close the XML writer object and filehandle.
492
533
  @writer.crlf
@@ -629,6 +670,10 @@ def add_series(params)
629
670
  # Set the "invert if negative" fill property.
630
671
  invert_if_neg = params[:invert_if_negative]
631
672
 
673
+ # Set the secondary axis properties.
674
+ x2_axis = params[:x2_axis]
675
+ y2_axis = params[:y2_axis]
676
+
632
677
  # Add the user supplied data to the internal structures.
633
678
  @series << {
634
679
  :_values => values,
@@ -643,7 +688,9 @@ def add_series(params)
643
688
  :_marker => marker,
644
689
  :_trendline => trendline,
645
690
  :_labels => labels,
646
- :_invert_if_neg => invert_if_neg
691
+ :_invert_if_neg => invert_if_neg,
692
+ :_x2_axis => x2_axis,
693
+ :_y2_axis => y2_axis
647
694
  }
648
695
  end
649
696
 
@@ -742,7 +789,7 @@ def add_series(params)
742
789
  # :max => 80
743
790
  # )
744
791
  #
745
- def set_x_axis(params)
792
+ def set_x_axis(params = {})
746
793
  @x_axis = convert_axis_args(params)
747
794
  end
748
795
 
@@ -752,10 +799,43 @@ def set_x_axis(params)
752
799
  # The set_y_axis() method is used to set properties of the Y axis.
753
800
  # The properties that can be set are the same as for set_x_axis,
754
801
  #
755
- def set_y_axis(params)
756
- @y_axis = convert_axis_args(params)
802
+ def set_y_axis(params = {})
803
+ @y_axis =
804
+ convert_axis_args(
805
+ {:major_gridlines => {:visible => 1}}.
806
+ merge(params)
807
+ )
808
+ end
809
+
810
+ #
811
+ # Set the properties of the secondary X-axis.
812
+ #
813
+ def set_x2_axis(params = {})
814
+ @x2_axis =
815
+ convert_axis_args(
816
+ {
817
+ :label_position => 'none',
818
+ :crossing => 'max',
819
+ :visible => 0
820
+ }.
821
+ merge(params)
822
+ )
757
823
  end
758
824
 
825
+ #
826
+ # Set the properties of the secondary Y-axis.
827
+ #
828
+ def set_y2_axis(params = {})
829
+ @y2_axis =
830
+ convert_axis_args(
831
+ {
832
+ :major_gridlines => {:visible => 0},
833
+ :position => 'r',
834
+ :visible => 1
835
+ }.
836
+ merge(params)
837
+ )
838
+ end
759
839
  #
760
840
  # Set the properties of the chart title.
761
841
  #
@@ -955,6 +1035,36 @@ def set_style(style_id = 2)
955
1035
  @style_id = style_id
956
1036
  end
957
1037
 
1038
+ #
1039
+ # Set the option for displaying blank data in a chart. The default is 'gap'.
1040
+ #
1041
+ # The show_blanks_as method controls how blank data is displayed in a chart.
1042
+ #
1043
+ # chart.show_blanks_as('span')
1044
+ #
1045
+ # The available options are:
1046
+ #
1047
+ # gap # Blank data is show as a gap. The default.
1048
+ # zero # Blank data is displayed as zero.
1049
+ # span # Blank data is connected with a line.
1050
+ #
1051
+ def show_blanks_as(option)
1052
+ return unless option
1053
+
1054
+ unless [:gap, :zero, :span].include?(option.to_sym)
1055
+ raise "Unknown show_blanks_as() option '#{option}'\n"
1056
+ end
1057
+
1058
+ @show_blanks = option
1059
+ end
1060
+
1061
+ #
1062
+ # Display data in hidden rows or columns on the chart.
1063
+ #
1064
+ def show_hidden_data
1065
+ @show_hidden_data = true
1066
+ end
1067
+
958
1068
  #
959
1069
  # Setup the default configuration data for an embedded chart.
960
1070
  #
@@ -963,42 +1073,55 @@ def set_embedded_config_data
963
1073
 
964
1074
  # TODO. We may be able to remove this after refactoring.
965
1075
 
966
- @chartarea = {
967
- :_visible => 1,
968
- :_fg_color_index => 0x4E,
969
- :_fg_color_rgb => 0xFFFFFF,
970
- :_bg_color_index => 0x4D,
971
- :_bg_color_rgb => 0x000000,
972
- :_area_pattern => 0x0001,
973
- :_area_options => 0x0001,
974
- :_line_pattern => 0x0000,
975
- :_line_weight => 0x0000,
976
- :_line_color_index => 0x4D,
977
- :_line_color_rgb => 0x000000,
978
- :_line_options => 0x0009
979
- }
980
-
1076
+ @chartarea = default_chartarea_property_for_embedded
981
1077
  end
982
1078
 
983
- #
984
- # Write the <c:barChart> element.
985
- #
986
- def write_bar_chart # :nodoc:
987
- subtype = @subtype
988
- subtype = 'percentStacked' if subtype == 'percent_stacked'
1079
+ #
1080
+ # Write the <c:barChart> element.
1081
+ #
1082
+ def write_bar_chart(params) # :nodoc:
1083
+ if ptrue?(params[:primary_axes])
1084
+ series = get_primary_axes_series
1085
+ else
1086
+ series = get_secondary_axes_series
1087
+ end
1088
+ return if series.empty?
989
1089
 
990
- @writer.tag_elements('c:barChart') do
991
- # Write the c:barDir element.
992
- write_bar_dir
993
- # Write the c:grouping element.
994
- write_grouping(subtype)
995
- # Write the series elements.
996
- write_series
997
- end
1090
+ subtype = @subtype
1091
+ subtype = 'percentStacked' if subtype == 'percent_stacked'
1092
+
1093
+ @writer.tag_elements('c:barChart') do
1094
+ # Write the c:barDir element.
1095
+ write_bar_dir
1096
+ # Write the c:grouping element.
1097
+ write_grouping(subtype)
1098
+ # Write the c:ser elements.
1099
+ series.each {|s| write_ser(s)}
1100
+
1101
+ # write the c:marker element.
1102
+ write_marker_value
1103
+
1104
+ # write the c:overlap element.
1105
+ write_overlap if @subtype =~ /stacked/
1106
+
1107
+ # Write the c:axId elements
1108
+ write_axis_ids(params)
998
1109
  end
1110
+ end
999
1111
 
1000
1112
  private
1001
1113
 
1114
+ #
1115
+ # retun primary/secondary series by :primary_axes flag
1116
+ #
1117
+ def axes_series(params)
1118
+ if params[:primary_axes] != 0
1119
+ primary_axes_series
1120
+ else
1121
+ secondary_axes_series
1122
+ end
1123
+ end
1124
+
1002
1125
  #
1003
1126
  # Convert user defined axis values into private hash values.
1004
1127
  #
@@ -1021,7 +1144,9 @@ def convert_axis_args(params) # :nodoc:
1021
1144
  :_log_base => params[:log_base],
1022
1145
  :_crossing => params[:crossing],
1023
1146
  :_position => params[:position],
1024
- :_label_position => params[:label_position]
1147
+ :_label_position => params[:label_position],
1148
+ :_major_gridlines => params[:major_gridlines] || {:visible => 1},
1149
+ :_visible => params[:visible] ? params[:visible] : 1
1025
1150
  }
1026
1151
 
1027
1152
  # Only use the first letter of bottom, top, left or right.
@@ -1114,7 +1239,7 @@ def get_color(color) # :nodoc:
1114
1239
  # Convert a HTML style #RRGGBB color.
1115
1240
  if color and color =~ /^#[0-9a-fA-F]{6}$/
1116
1241
  color = color.sub(/^#/, '')
1117
- return color.upperca
1242
+ return color.upcase
1118
1243
  end
1119
1244
 
1120
1245
  index = Format.get_color(color)
@@ -1235,11 +1360,7 @@ def get_line_properties(line) # :nodoc:
1235
1360
  dash_type = line[:dash_type]
1236
1361
 
1237
1362
  if dash_type
1238
- if dash_types[dash_type]
1239
- line[dash_type] = dash_types[dash_type]
1240
- else
1241
- raise "Unknown dash type '#{dash_type}'\n"
1242
- end
1363
+ line[:dash_type] = value_or_raise(dash_types, dash_type, 'dash type')
1243
1364
  end
1244
1365
 
1245
1366
  line[:_defined] = 1
@@ -1282,26 +1403,21 @@ def get_marker_properties(marker) # :nodoc:
1282
1403
  }
1283
1404
 
1284
1405
  # Check for valid types.
1285
- marker_type = marker[type]
1406
+ marker_type = marker[:type]
1286
1407
 
1287
1408
  if marker_type
1288
- marker[automatic] = 1 if marker_type == 'automatic'
1289
-
1290
- if types[marker_type]
1291
- marker[type] = types[marker_type]
1292
- else
1293
- raise "Unknown marker type '#{marker_type}'\n"
1294
- end
1409
+ marker[:automatic] = 1 if marker_type == 'automatic'
1410
+ marker[:type] = value_or_raise(types, marker_type, 'maker type')
1295
1411
  end
1296
1412
 
1297
1413
  # Set the line properties for the marker..
1298
- line = get_line_properties(marker[line])
1414
+ line = get_line_properties(marker[:line])
1299
1415
 
1300
1416
  # Allow 'border' as a synonym for 'line'.
1301
- line = get_line_properties(marker[border]) if marker[border]
1417
+ line = get_line_properties(marker[:border]) if marker[:border]
1302
1418
 
1303
1419
  # Set the fill properties for the marker.
1304
- fill = get_fill_properties(marker[fill])
1420
+ fill = get_fill_properties(marker[:fill])
1305
1421
 
1306
1422
  marker[:_line] = line
1307
1423
  marker[:_fill] = fill
@@ -1325,22 +1441,18 @@ def get_trendline_properties(trendline) # :nodoc:
1325
1441
  }
1326
1442
 
1327
1443
  # Check the trendline type.
1328
- trend_type = trendline[type]
1444
+ trend_type = trendline[:type]
1329
1445
 
1330
- if types[trend_type]
1331
- trendline[type] = types[trend_type]
1332
- else
1333
- raise "Unknown trendline type '#{trend_type}'\n"
1334
- end
1446
+ trendline[:type] = value_or_raise(types, trend_type, 'trendline type')
1335
1447
 
1336
1448
  # Set the line properties for the trendline..
1337
- line = get_line_properties(trendline[line])
1449
+ line = get_line_properties(trendline[:line])
1338
1450
 
1339
1451
  # Allow 'border' as a synonym for 'line'.
1340
- line = get_line_properties(trendline[border]) if trendline[border]
1452
+ line = get_line_properties(trendline[:border]) if trendline[:border]
1341
1453
 
1342
1454
  # Set the fill properties for the trendline.
1343
- fill = get_fill_properties(trendline[fill])
1455
+ fill = get_fill_properties(trendline[:fill])
1344
1456
 
1345
1457
  trendline[:_line] = line
1346
1458
  trendline[:_fill] = fill
@@ -1354,28 +1466,83 @@ def get_trendline_properties(trendline) # :nodoc:
1354
1466
  def get_labels_properties(labels) # :nodoc:
1355
1467
  return nil unless labels
1356
1468
 
1357
- return labels
1469
+ position = labels[:position]
1470
+ if position.nil? || position.empty?
1471
+ labels.delete(:position)
1472
+ else
1473
+ # Map user defined label positions to Excel positions.
1474
+ positions = {
1475
+ :center => 'ctr',
1476
+ :right => 'r',
1477
+ :left => 'l',
1478
+ :top => 't',
1479
+ :above => 't',
1480
+ :bottom => 'b',
1481
+ :below => 'b',
1482
+ :inside_end => 'inEnd',
1483
+ :outside_end => 'outEnd',
1484
+ :best_fit => 'bestFit'
1485
+ }
1486
+
1487
+ labels[:position] = value_or_raise(positions, position, 'label position')
1488
+ end
1489
+
1490
+ labels
1491
+ end
1492
+
1493
+ def value_or_raise(hash, key, msg)
1494
+ raise "Unknown #{msg} '#{key}'" unless hash[key.to_sym]
1495
+ hash[key.to_sym]
1358
1496
  end
1359
1497
 
1360
1498
  #
1361
- # Add a unique id for an axis.
1499
+ # Returns series which use the primary axes.
1362
1500
  #
1363
- def add_axis_id # :nodoc:
1364
- chart_id = 1 + @id
1365
- axis_count = 1 + @axis_ids.size
1501
+ def get_primary_axes_series
1502
+ @series.reject {|s| s[:_y2_axis]}
1503
+ end
1504
+ alias :primary_axes_series :get_primary_axes_series
1366
1505
 
1367
- axis_id = sprintf('5%03d%04d', chart_id, axis_count)
1506
+ #
1507
+ # Returns series which use the secondary axes.
1508
+ #
1509
+ def get_secondary_axes_series
1510
+ @series.select {|s| s[:_y2_axis]}
1511
+ end
1512
+ alias :secondary_axes_series :get_secondary_axes_series
1368
1513
 
1369
- @axis_ids << axis_id
1514
+ #
1515
+ # Add a unique ids for primary or secondary axis.
1516
+ #
1517
+ def add_axis_ids(params) # :nodoc:
1518
+ chart_id = 1 + @id
1519
+ axis_count = 1 + @axis2_ids.size + @axis_ids.size
1370
1520
 
1371
- axis_id
1521
+ id1 = sprintf('5%03d%04d', chart_id, axis_count)
1522
+ id2 = sprintf('5%03d%04d', chart_id, axis_count + 1)
1523
+
1524
+ if ptrue?(params[:primary_axes])
1525
+ @axis_ids << id1 << id2
1526
+ else
1527
+ @axis2_ids << id1 << id2
1528
+ end
1372
1529
  end
1373
1530
 
1374
1531
  #
1375
1532
  # Setup the default properties for a chart.
1376
1533
  #
1377
1534
  def set_default_properties # :nodoc:
1378
- @chartarea = {
1535
+ @chartarea = default_chartarea_property
1536
+ @plotarea = default_plotarea_property
1537
+ set_x_axis
1538
+ set_y_axis
1539
+
1540
+ set_x2_axis
1541
+ set_y2_axis
1542
+ end
1543
+
1544
+ def default_chartarea_property
1545
+ {
1379
1546
  :_visible => 0,
1380
1547
  :_fg_color_index => 0x4E,
1381
1548
  :_fg_color_rgb => 0xFFFFFF,
@@ -1389,8 +1556,22 @@ def set_default_properties # :nodoc:
1389
1556
  :_line_color_rgb => 0x000000,
1390
1557
  :_line_options => 0x0008
1391
1558
  }
1559
+ end
1560
+
1561
+ def default_chartarea_property_for_embedded
1562
+ default_chartarea_property.
1563
+ merge(
1564
+ :_visible => 1,
1565
+ :_area_pattern => 0x0001,
1566
+ :_area_options => 0x0001,
1567
+ :_line_pattern => 0x0000,
1568
+ :_line_weight => 0x0000,
1569
+ :_line_options => 0x0009
1570
+ )
1571
+ end
1392
1572
 
1393
- @plotarea = {
1573
+ def default_plotarea_property
1574
+ {
1394
1575
  :_visible => 1,
1395
1576
  :_fg_color_index => 0x16,
1396
1577
  :_fg_color_rgb => 0xC0C0C0,
@@ -1410,18 +1591,19 @@ def set_default_properties # :nodoc:
1410
1591
  # Write the <c:chartSpace> element.
1411
1592
  #
1412
1593
  def write_chart_space # :nodoc:
1413
- schema = 'http://schemas.openxmlformats.org/'
1414
- xmlns_c = schema + 'drawingml/2006/chart'
1415
- xmlns_a = schema + 'drawingml/2006/main'
1416
- xmlns_r = schema + 'officeDocument/2006/relationships'
1417
-
1418
- attributes = [
1419
- 'xmlns:c', xmlns_c,
1420
- 'xmlns:a', xmlns_a,
1421
- 'xmlns:r', xmlns_r
1422
- ]
1594
+ @writer.tag_elements('c:chartSpace', chart_space_attributes) do
1595
+ yield
1596
+ end
1597
+ end
1423
1598
 
1424
- @writer.start_tag('c:chartSpace', attributes)
1599
+ # for <c:chartSpace> element.
1600
+ def chart_space_attributes # :nodoc:
1601
+ schema = 'http://schemas.openxmlformats.org/'
1602
+ [
1603
+ 'xmlns:c', "#{schema}drawingml/2006/chart",
1604
+ 'xmlns:a', "#{schema}drawingml/2006/main",
1605
+ 'xmlns:r', "#{schema}officeDocument/2006/relationships"
1606
+ ]
1425
1607
  end
1426
1608
 
1427
1609
  #
@@ -1467,22 +1649,66 @@ def write_chart # :nodoc:
1467
1649
  write_legend
1468
1650
  # Write the c:plotVisOnly element.
1469
1651
  write_plot_vis_only
1652
+
1653
+ # Write the c:dispBlanksAs element.
1654
+ write_disp_blanks_as
1470
1655
  end
1471
1656
  end
1472
1657
 
1658
+ #
1659
+ # Write the <c:dispBlanksAs> element.
1660
+ #
1661
+ def write_disp_blanks_as
1662
+ val = @show_blanks
1663
+
1664
+ # Ignore the default value.
1665
+ return if val == 'gap'
1666
+
1667
+ attributes = ['val', val]
1668
+
1669
+ @writer.empty_tag('c:dispBlanksAs', attributes)
1670
+ end
1671
+
1473
1672
  #
1474
1673
  # Write the <c:plotArea> element.
1475
1674
  #
1476
- def write_plot_area # :nodoc:
1675
+ def write_plot_area # :nodoc:
1676
+ write_plot_area_base
1677
+ end
1678
+
1679
+ def write_plot_area_base(type = nil) # :nodoc:
1477
1680
  @writer.tag_elements('c:plotArea') do
1478
1681
  # Write the c:layout element.
1479
1682
  write_layout
1480
- # Write the subclass chart type element.
1481
- write_chart_type
1482
- # Write the c:catAx element.
1483
- write_cat_axis
1484
- # Write the c:catAx element.
1485
- write_val_axis
1683
+ # Write the subclass chart type elements for primary and secondary axes.
1684
+ write_chart_type(:primary_axes => 1)
1685
+ write_chart_type(:primary_axes => 0)
1686
+
1687
+ # Write the c:catAx elements for series using primary axes.
1688
+ params = {
1689
+ :x_axis => @x_axis,
1690
+ :y_axis => @y_axis,
1691
+ :axis_ids => @axis_ids
1692
+ }
1693
+ write_cat_or_date_axis(params, type)
1694
+ write_val_axis(params)
1695
+
1696
+ # Write c:valAx and c:catAx elements for series using secondary axes.
1697
+ params = {
1698
+ :x_axis => @x2_axis,
1699
+ :y_axis => @y2_axis,
1700
+ :axis_ids => @axis2_ids
1701
+ }
1702
+ write_val_axis(params)
1703
+ write_cat_or_date_axis(params, type)
1704
+ end
1705
+ end
1706
+
1707
+ def write_cat_or_date_axis(params, type)
1708
+ if type == :stock
1709
+ write_date_axis(params)
1710
+ else
1711
+ write_cat_axis(params)
1486
1712
  end
1487
1713
  end
1488
1714
 
@@ -1511,8 +1737,8 @@ def write_grouping(val) # :nodoc:
1511
1737
  #
1512
1738
  # Write the series elements.
1513
1739
  #
1514
- def write_series # :nodoc:
1515
- write_series_base { nil }
1740
+ def write_series(series) # :nodoc:
1741
+ write_ser(series)
1516
1742
  end
1517
1743
 
1518
1744
  def write_series_base
@@ -1542,7 +1768,10 @@ def write_series_base
1542
1768
  #
1543
1769
  # Write the <c:ser> element.
1544
1770
  #
1545
- def write_ser(index, series) # :nodoc:
1771
+ def write_ser(series) # :nodoc:
1772
+ index = @series_index
1773
+ @series_index += 1
1774
+
1546
1775
  @writer.tag_elements('c:ser') do
1547
1776
  # Write the c:idx element.
1548
1777
  write_idx(index)
@@ -1557,9 +1786,9 @@ def write_ser(index, series) # :nodoc:
1557
1786
  # Write the c:invertIfNegative element.
1558
1787
  write_c_invert_if_negative(series[:_invert_if_neg])
1559
1788
  # Write the c:dLbls element.
1560
- write_d_lbls(series[:labels])
1789
+ write_d_lbls(series[:_labels])
1561
1790
  # Write the c:trendline element.
1562
- write_trendline(series[:trendline])
1791
+ write_trendline(series[:_trendline])
1563
1792
  # Write the c:cat element.
1564
1793
  write_cat(series)
1565
1794
  # Write the c:val element.
@@ -1609,14 +1838,14 @@ def write_cat(series) # :nodoc:
1609
1838
  # Ignore <c:cat> elements for charts without category values.
1610
1839
  return unless formula
1611
1840
 
1612
- @has_category = 1
1841
+ @has_category = true
1613
1842
 
1614
1843
  @writer.tag_elements('c:cat') do
1615
1844
  # Check the type of cached data.
1616
1845
  type = get_data_type(data)
1617
1846
  if type == 'str'
1618
- @has_category = 0
1619
- # Write the c:numRef element.
1847
+ @has_category = false
1848
+ # Write the c:strRef element.
1620
1849
  write_str_ref(formula, data, type)
1621
1850
  else
1622
1851
  # Write the c:numRef element.
@@ -1636,23 +1865,18 @@ def write_val_base(formula, data_id, tag) # :nodoc:
1636
1865
  data = @formula_data[data_id]
1637
1866
 
1638
1867
  @writer.tag_elements(tag) do
1639
- # Check the type of cached data.
1640
- type = get_data_type(data)
1641
- if type == 'str'
1642
- # Write the c:numRef element.
1643
- write_str_ref(formula, data, type)
1644
- else
1645
- # Write the c:numRef element.
1646
- write_num_ref(formula, data, type)
1647
- end
1868
+ # Unlike Cat axes data should only be numeric.
1869
+
1870
+ # Write the c:numRef element.
1871
+ write_num_ref(formula, data, 'num')
1648
1872
  end
1649
1873
  end
1650
1874
 
1651
1875
  #
1652
- # Write the <c:numRef> element.
1876
+ # Write the <c:numRef> or <c:strRef> element.
1653
1877
  #
1654
- def write_num_ref(formula, data, type) # :nodoc:
1655
- @writer.tag_elements('c:numRef') do
1878
+ def write_num_or_str_ref(tag, formula, data, type) # :nodoc:
1879
+ @writer.tag_elements(tag) do
1656
1880
  # Write the c:f element.
1657
1881
  write_series_formula(formula)
1658
1882
  if type == 'num'
@@ -1665,21 +1889,18 @@ def write_num_ref(formula, data, type) # :nodoc:
1665
1889
  end
1666
1890
  end
1667
1891
 
1892
+ #
1893
+ # Write the <c:numRef> element.
1894
+ #
1895
+ def write_num_ref(formula, data, type) # :nodoc:
1896
+ write_num_or_str_ref('c:numRef', formula, data, type)
1897
+ end
1898
+
1668
1899
  #
1669
1900
  # Write the <c:strRef> element.
1670
1901
  #
1671
1902
  def write_str_ref(formula, data, type) # :nodoc:
1672
- @writer.tag_elements('c:strRef') do
1673
- # Write the c:f element.
1674
- write_series_formula(formula)
1675
- if type == 'num'
1676
- # Write the c:numCache element.
1677
- write_num_cache(data)
1678
- elsif type == 'str'
1679
- # Write the c:strCache element.
1680
- write_str_cache(data)
1681
- end
1682
- end
1903
+ write_num_or_str_ref('c:strRef', formula, data, type)
1683
1904
  end
1684
1905
 
1685
1906
  #
@@ -1692,6 +1913,24 @@ def write_series_formula(formula) # :nodoc:
1692
1913
  @writer.data_element('c:f', formula)
1693
1914
  end
1694
1915
 
1916
+ #
1917
+ # Write the <c:axId> elements for the primary or secondary axes.
1918
+ #
1919
+ def write_axis_ids(params)
1920
+ # Generate the axis ids.
1921
+ add_axis_ids(params)
1922
+
1923
+ if params[:primary_axes] != 0
1924
+ # Write the axis ids for the primary axes.
1925
+ write_axis_id(@axis_ids[0])
1926
+ write_axis_id(@axis_ids[1])
1927
+ else
1928
+ # Write the axis ids for the secondary axes.
1929
+ write_axis_id(@axis2_ids[0])
1930
+ write_axis_id(@axis2_ids[1])
1931
+ end
1932
+ end
1933
+
1695
1934
  #
1696
1935
  # Write the <c:axId> element.
1697
1936
  #
@@ -1704,25 +1943,34 @@ def write_axis_id(val) # :nodoc:
1704
1943
  #
1705
1944
  # Write the <c:catAx> element. Usually the X axis.
1706
1945
  #
1707
- def write_cat_axis(position = nil) # :nodoc:
1946
+ def write_cat_axis(params) # :nodoc:
1947
+ x_axis = params[:x_axis]
1948
+ y_axis = params[:y_axis]
1949
+ axis_ids = params[:axis_ids]
1950
+
1951
+ # if there are no axis_ids then we don't need to write this element
1952
+ return unless axis_ids
1953
+ return if axis_ids.empty?
1954
+
1708
1955
  position = @cat_axis_position
1709
1956
  horiz = @horiz_cat_axis
1710
- x_axis = @x_axis
1711
- y_axis = @y_axis
1712
1957
 
1713
1958
  # Overwrite the default axis position with a user supplied value.
1714
1959
  position = x_axis[:_position] || position
1715
1960
 
1716
1961
  @writer.tag_elements('c:catAx') do
1717
- write_axis_id(@axis_ids[0])
1962
+ write_axis_id(axis_ids[0])
1718
1963
  # Write the c:scaling element.
1719
1964
  write_scaling(x_axis[:_reverse])
1965
+
1966
+ write_delete(1) unless ptrue?(x_axis[:_visible])
1967
+
1720
1968
  # Write the c:axPos element.
1721
1969
  write_axis_pos(position, y_axis[:_reverse])
1722
1970
  # Write the axis title elements.
1723
- if title = @x_axis[:_formula]
1971
+ if title = x_axis[:_formula]
1724
1972
  write_title_formula(title, @x_axis[:_data_id], horiz)
1725
- elsif title = @x_axis[:_name]
1973
+ elsif title = x_axis[:_name]
1726
1974
  write_title_rich(title, horiz)
1727
1975
  end
1728
1976
  # Write the c:numFmt element.
@@ -1730,14 +1978,10 @@ def write_cat_axis(position = nil) # :nodoc:
1730
1978
  # Write the c:tickLblPos element.
1731
1979
  write_tick_label_pos(x_axis[:_label_position])
1732
1980
  # Write the c:crossAx element.
1733
- write_cross_axis(@axis_ids[1])
1734
- # Note, the category crossing comes from the value axis.
1735
- if nil_or_max?(y_axis[:_crossing])
1736
- # Write the c:crosses element.
1737
- write_crosses(y_axis[:_crossing])
1738
- else
1739
- # Write the c:crossesAt element.
1740
- write_c_crosses(y_axis[:_crossing])
1981
+ write_cross_axis(axis_ids[1])
1982
+
1983
+ if @show_crosses || ptrue?(x_axis[:_visible])
1984
+ write_crossing(y_axis[:_crossing])
1741
1985
  end
1742
1986
  # Write the c:auto element.
1743
1987
  write_auto(1)
@@ -1753,20 +1997,59 @@ def write_cat_axis(position = nil) # :nodoc:
1753
1997
  #
1754
1998
  # TODO. Maybe should have a _write_cat_val_axis method as well for scatter.
1755
1999
  #
1756
- def write_val_axis(position = nil, hide_major_gridlines = nil) # :nodoc:
1757
- params = {
1758
- :axis_position => @y_axis[:_position],
1759
- :axis_id => @axis_ids[1],
1760
- :scaling_axis => @y_axis,
1761
- :axis_position_element => @x_axis[:_reverse],
1762
- :title_axis => @y_axis,
1763
- :tick_label_pos => @y_axis[:_label_position],
1764
- :cross_axis => @axis_ids[0],
1765
- :category_crossing => @x_axis[:_crossing],
1766
- :major_unit => @y_axis[:_major_unit],
1767
- :minor_unit => @y_axis[:_minor_unit]
1768
- }
1769
- write_val_axis_common(position, hide_major_gridlines, params)
2000
+ def write_val_axis(params) # :nodoc:
2001
+ x_axis = params[:x_axis]
2002
+ y_axis = params[:y_axis]
2003
+ axis_ids = params[:axis_ids]
2004
+ position = params[:position] || @val_axis_position
2005
+ horiz = @horiz_val_axis
2006
+
2007
+ return unless axis_ids && !axis_ids.empty?
2008
+
2009
+ # OVerwrite the default axis position with a user supplied value.
2010
+ position = y_axis[:_position] || position
2011
+
2012
+ @writer.tag_elements('c:valAx') do
2013
+ write_axis_id(axis_ids[1])
2014
+
2015
+ # Write the c:scaling element.
2016
+ write_scaling_with_param(y_axis)
2017
+
2018
+ write_delete(1) unless ptrue?(y_axis[:_visible])
2019
+
2020
+ # Write the c:axPos element.
2021
+ write_axis_pos(position, x_axis[:_reverse])
2022
+
2023
+ # Write the c:majorGridlines element.
2024
+ write_major_gridlines(y_axis[:_major_gridlines])
2025
+
2026
+ # Write the axis title elements.
2027
+ if title = y_axis[:_formula]
2028
+ write_title_formula(title, y_axis[:_data_id], horiz)
2029
+ elsif title = y_axis[:_name]
2030
+ write_title_rich(title, horiz)
2031
+ end
2032
+
2033
+ # Write the c:numberFormat element.
2034
+ write_number_format
2035
+
2036
+ # Write the tickLblPos element.
2037
+ write_tick_label_pos(y_axis[:_label_position])
2038
+
2039
+ # Write the c:crossAx element.
2040
+ write_cross_axis(axis_ids[0])
2041
+
2042
+ write_crossing(x_axis[:_crossing])
2043
+
2044
+ # Write the c:crossBetween element.
2045
+ write_cross_between
2046
+
2047
+ # Write the c:majorUnit element.
2048
+ write_c_major_unit(y_axis[:_major_unit])
2049
+
2050
+ # Write the c:minorUnit element.
2051
+ write_c_minor_unit(y_axis[:_minor_unit])
2052
+ end
1770
2053
  end
1771
2054
 
1772
2055
  #
@@ -1774,20 +2057,56 @@ def write_val_axis(position = nil, hide_major_gridlines = nil) # :nodoc:
1774
2057
  #
1775
2058
  # Usually the X axis.
1776
2059
  #
1777
- def write_cat_val_axis(position, hide_major_gridlines) # :nodoc:
1778
- params = {
1779
- :axis_position => @x_axis[:_position],
1780
- :axis_id => @axis_ids[0],
1781
- :scaling_axis => @x_axis,
1782
- :axis_position_element => @y_axis[:_reverse],
1783
- :title_axis => @x_axis,
1784
- :tick_label_pos => @x_axis[:_label_position],
1785
- :cross_axis => @axis_ids[1],
1786
- :category_crossing => @y_axis[:_crossing],
1787
- :major_unit => @x_axis[:_major_unit],
1788
- :minor_unit => @x_axis[:_minor_unit]
1789
- }
1790
- write_val_axis_common(position, hide_major_gridlines, params)
2060
+ def write_cat_val_axis(params) # :nodoc:
2061
+ x_axis = params[:x_axis]
2062
+ y_axis = params[:y_axis]
2063
+ axis_ids = params[:axis_ids]
2064
+ position = params[:position] || @val_axis_position
2065
+ horiz = @horiz_val_axis
2066
+
2067
+ return unless axis_ids && !axis_ids.empty?
2068
+
2069
+ # Overwrite the default axis position with a user supplied value.
2070
+ position = x_axis[:_position] || position
2071
+
2072
+ @writer.tag_elements('c:valAx') do
2073
+ write_axis_id(axis_ids[0])
2074
+
2075
+ # Write the c:scaling element.
2076
+ write_scaling_with_param(x_axis)
2077
+
2078
+ write_delete(1) unless ptrue?(x_axis[:_visible])
2079
+
2080
+ # Write the c:axPos element.
2081
+ write_axis_pos(position, y_axis[:_reverse])
2082
+
2083
+ # Write the axis title elements.
2084
+ if title = x_axis[:_formula]
2085
+ write_title_formula(title, y_axis[:_data_id], horiz)
2086
+ elsif title = x_axis[:_name]
2087
+ write_title_rich(title, horiz)
2088
+ end
2089
+
2090
+ # Write the c:numberFormat element.
2091
+ write_number_format
2092
+
2093
+ # Write the c:tickLblPos element.
2094
+ write_tick_label_pos(x_axis[:_label_position])
2095
+
2096
+ # Write the c:crossAx element.
2097
+ write_cross_axis(axis_ids[1])
2098
+
2099
+ write_crossing(y_axis[:_crossing])
2100
+
2101
+ # Write the c:crossBetween element.
2102
+ write_cross_between
2103
+
2104
+ # Write the c:majorUnit element.
2105
+ write_c_major_unit(x_axis[:_major_unit])
2106
+
2107
+ # Write the c:minorunit element.
2108
+ write_c_minor_unit(x_axis[:_minor_unit])
2109
+ end
1791
2110
  end
1792
2111
 
1793
2112
  def write_val_axis_common(position, hide_major_gridlines, params) # :nodoc:
@@ -1800,9 +2119,8 @@ def write_val_axis_common(position, hide_major_gridlines, params) # :nodoc:
1800
2119
  @writer.tag_elements('c:valAx') do
1801
2120
  write_axis_id(params[:axis_id])
1802
2121
  # Write the c:scaling element.
1803
- write_scaling(
1804
- params[:scaling_axis][:_reverse], params[:scaling_axis][:_min],
1805
- params[:scaling_axis][:_max], params[:scaling_axis][:_log_base])
2122
+ write_scaling_with_param(params[:scaling_axis])
2123
+
1806
2124
  # Write the c:axPos element.
1807
2125
  write_axis_pos(position, params[:axis_position_element])
1808
2126
  # Write the c:majorGridlines element.
@@ -1819,14 +2137,9 @@ def write_val_axis_common(position, hide_major_gridlines, params) # :nodoc:
1819
2137
  write_tick_label_pos(params[:tick_label_pos])
1820
2138
  # Write the c:crossAx element.
1821
2139
  write_cross_axis(params[:cross_axis])
1822
- # Note, the category crossing comes from the value axis.
1823
- if nil_or_max?(params[:category_crossing])
1824
- # Write the c:crosses element.
1825
- write_crosses(params[:category_crossing])
1826
- else
1827
- # Write the c:crossesAt element.
1828
- write_c_crosses_at(params[:category_crossing])
1829
- end
2140
+
2141
+ write_crossing(params[:category_crossing])
2142
+
1830
2143
  # Write the c:crossBetween element.
1831
2144
  write_cross_between
1832
2145
  # Write the c:majorUnit element.
@@ -1839,15 +2152,25 @@ def write_val_axis_common(position, hide_major_gridlines, params) # :nodoc:
1839
2152
  #
1840
2153
  # Write the <c:dateAx> element. Usually the X axis.
1841
2154
  #
1842
- def write_date_axis(position = nil) # :nodoc:
2155
+ def write_date_axis(params) # :nodoc:
2156
+ x_axis = params[:x_axis]
2157
+ y_axis = params[:y_axis]
2158
+ axis_ids = params[:axis_ids]
2159
+
2160
+ return unless axis_ids && !axis_ids.empty?
2161
+
1843
2162
  position = @cat_axis_position
1844
- x_axis = @x_axis
1845
- y_axis = @y_axis
2163
+
2164
+ # Overwrite the default axis position with a user supplied value.
2165
+ position = x_axis[:_position] || position
1846
2166
 
1847
2167
  @writer.tag_elements('c:dateAx') do
1848
- write_axis_id(@axis_ids[0])
2168
+ write_axis_id(axis_ids[0])
1849
2169
  # Write the c:scaling element.
1850
- write_scaling(x_axis[:reverse], x_axis[:_min], x_axis[:_max], x_axis[:_log_base])
2170
+ write_scaling_with_param(x_axis)
2171
+
2172
+ write_delete(1) unless ptrue?(x_axis[:_visible])
2173
+
1851
2174
  # Write the c:axPos element.
1852
2175
  write_axis_pos(position, y_axis[:reverse])
1853
2176
  # Write the axis title elements.
@@ -1861,15 +2184,12 @@ def write_date_axis(position = nil) # :nodoc:
1861
2184
  # Write the c:tickLblPos element.
1862
2185
  write_tick_label_pos(x_axis[:_label_position])
1863
2186
  # Write the c:crossAx element.
1864
- write_cross_axis(@axis_ids[1])
1865
- # Note, the category crossing comes from the value axis.
1866
- if nil_or_max?(y_axis[:_crossing])
1867
- # Write the c:crossing element.
1868
- write_crosses(y_axis[:_crossing])
1869
- else
1870
- # Write the c:crossesAt element.
1871
- write_c_crosses_at(y_axis[:_crossing])
2187
+ write_cross_axis(axis_ids[1])
2188
+
2189
+ if @show_crosses || ptrue?(x_axis[:_visible])
2190
+ write_crossing(y_axis[:_crossing])
1872
2191
  end
2192
+
1873
2193
  # Write the c:auto element.
1874
2194
  write_auto(1)
1875
2195
  # Write the c:labelOffset element.
@@ -1889,6 +2209,25 @@ def write_date_axis(position = nil) # :nodoc:
1889
2209
  end
1890
2210
  end
1891
2211
 
2212
+ def write_crossing(crossing)
2213
+ # Note, the category crossing comes from the value axis.
2214
+ if nil_or_max?(crossing)
2215
+ # Write the c:crosses element.
2216
+ write_crosses(crossing)
2217
+ else
2218
+ # Write the c:crossesAt element.
2219
+ write_c_crosses_at(crossing)
2220
+ end
2221
+ end
2222
+
2223
+ def write_scaling_with_param(param)
2224
+ write_scaling(
2225
+ param[:_reverse],
2226
+ param[:_min],
2227
+ param[:_max],
2228
+ param[:_log_base]
2229
+ )
2230
+ end
1892
2231
  #
1893
2232
  # Write the <c:scaling> element.
1894
2233
  #
@@ -1905,22 +2244,11 @@ def write_scaling(reverse, min = nil, max = nil, log_base = nil) # :nodoc:
1905
2244
  end
1906
2245
  end
1907
2246
 
1908
- #
1909
- # Write the <c:orientation> element.
1910
- #
1911
- def write_orientation(reverse = nil) # :nodoc:
1912
- val = reverse ? 'maxMin' : 'minMax'
1913
-
1914
- attributes = ['val', val]
1915
-
1916
- @writer.empty_tag('c:orientation', attributes)
1917
- end
1918
-
1919
2247
  #
1920
2248
  # Write the <c:logBase> element.
1921
2249
  #
1922
2250
  def write_c_log_base(val) # :nodoc:
1923
- return if val == 0 || val.nil?
2251
+ return unless ptrue?(val)
1924
2252
 
1925
2253
  attributes = ['val', val]
1926
2254
 
@@ -1930,8 +2258,8 @@ def write_c_log_base(val) # :nodoc:
1930
2258
  #
1931
2259
  # Write the <c:orientation> element.
1932
2260
  #
1933
- def write_orientation(reverse = 'maxMin') # :nodoc:
1934
- val = 'minMax'
2261
+ def write_orientation(reverse = nil) # :nodoc:
2262
+ val = ptrue?(reverse) ? 'maxMin' : 'minMax'
1935
2263
 
1936
2264
  attributes = ['val', val]
1937
2265
 
@@ -2063,7 +2391,9 @@ def write_label_offset(val) # :nodoc:
2063
2391
  #
2064
2392
  # Write the <c:majorGridlines> element.
2065
2393
  #
2066
- def write_major_gridlines # :nodoc:
2394
+ def write_major_gridlines(options = {}) # :nodoc:
2395
+ return unless ptrue?(options[:visible])
2396
+
2067
2397
  @writer.empty_tag('c:majorGridlines')
2068
2398
  end
2069
2399
 
@@ -2120,7 +2450,8 @@ def write_c_minor_unit(val = nil) # :nodoc:
2120
2450
  #
2121
2451
  # Write the <c:majorTimeUnit> element.
2122
2452
  #
2123
- def write_c_major_time_unit(val = 'days') # :nodoc:
2453
+ def write_c_major_time_unit(val) # :nodoc:
2454
+ val ||= 'days'
2124
2455
  attributes = ['val', val]
2125
2456
 
2126
2457
  @writer.empty_tag('c:majorTimeUnit', attributes)
@@ -2129,7 +2460,8 @@ def write_c_major_time_unit(val = 'days') # :nodoc:
2129
2460
  #
2130
2461
  # Write the <c:minorTimeUnit> element.
2131
2462
  #
2132
- def write_c_minor_time_unit(val = 'days') # :nodoc:
2463
+ def write_c_minor_time_unit(val) # :nodoc:
2464
+ val ||= 'days'
2133
2465
  attributes = ['val', val]
2134
2466
 
2135
2467
  @writer.empty_tag('c:minorTimeUnit', attributes)
@@ -2216,6 +2548,9 @@ def write_overlay # :nodoc:
2216
2548
  def write_plot_vis_only # :nodoc:
2217
2549
  val = 1
2218
2550
 
2551
+ # Ignore this element if we are plitting hidden data.
2552
+ return if @show_hidden_data
2553
+
2219
2554
  attributes = ['val', val]
2220
2555
 
2221
2556
  @writer.empty_tag('c:plotVisOnly', attributes)
@@ -2287,7 +2622,7 @@ def write_title_rich(title, horiz = nil) # :nodoc:
2287
2622
  #
2288
2623
  # Write the <c:title> element for a rich string.
2289
2624
  #
2290
- def write_title_formula(title, data_id, horiz) # :nodoc:
2625
+ def write_title_formula(title, data_id, horiz = nil) # :nodoc:
2291
2626
  @writer.tag_elements('c:title') do
2292
2627
  # Write the c:tx element.
2293
2628
  write_tx_formula(title, data_id)
@@ -2347,7 +2682,7 @@ def write_a_body_pr(horiz) # :nodoc:
2347
2682
  'vert', vert
2348
2683
  ]
2349
2684
 
2350
- attributes = [] if !horiz || horiz == 0
2685
+ attributes = [] unless ptrue?(horiz)
2351
2686
 
2352
2687
  @writer.empty_tag('a:bodyPr', attributes)
2353
2688
  end
@@ -2374,7 +2709,7 @@ def write_a_p_rich(title) # :nodoc:
2374
2709
  #
2375
2710
  # Write the <a:p> element for formula titles.
2376
2711
  #
2377
- def write_a_p_formula(title) # :nodoc:
2712
+ def write_a_p_formula # :nodoc:
2378
2713
  @writer.tag_elements('a:p') do
2379
2714
  # Write the a:pPr element.
2380
2715
  write_a_p_pr_formula
@@ -2465,15 +2800,15 @@ def write_tx_pr(horiz) # :nodoc:
2465
2800
  def write_marker(marker = nil) # :nodoc:
2466
2801
  marker ||= @default_marker
2467
2802
 
2468
- return if marker.nil? || marker == 0
2469
- return if marker[:automatic] && marker[:automatic] != 0
2803
+ return unless ptrue?(marker)
2804
+ return if ptrue?(marker[:automatic])
2470
2805
 
2471
2806
  @writer.tag_elements('c:marker') do
2472
2807
  # Write the c:symbol element.
2473
2808
  write_symbol(marker[:type])
2474
2809
  # Write the c:size element.
2475
2810
  size = marker[:size]
2476
- write_marker_size(size) if !size.nil? && size != 0
2811
+ write_marker_size(size) if ptrue?(size)
2477
2812
  # Write the c:spPr element.
2478
2813
  write_sp_pr(marker)
2479
2814
  end
@@ -2514,14 +2849,22 @@ def write_symbol(val) # :nodoc:
2514
2849
  # Write the <c:spPr> element.
2515
2850
  #
2516
2851
  def write_sp_pr(series) # :nodoc:
2517
- return if (!series.has_key?(:_line) || series[:_line][:_defined].nil? || series[:_line][:_defined]== 0) &&
2518
- (!series.has_key?(:_fill) || series[:_fill][:_defined].nil? || series[:_fill][:_defined]== 0)
2852
+ return if (!series.has_key?(:_line) || !ptrue?(series[:_line][:_defined])) &&
2853
+ (!series.has_key?(:_fill) || !ptrue?(series[:_fill][:_defined]))
2519
2854
 
2520
2855
  @writer.tag_elements('c:spPr') do
2521
- # Write the a:solidFill element for solid charts such as pie and bar.
2522
- write_a_solid_fill(series[:_fill]) if series[:_fill] && series[:_fill][:_defined] != 0
2856
+ # Write the fill elements for solid charts such as pie and bar.
2857
+ if series[:_fill] && series[:_fill][:_defined] != 0
2858
+ if ptrue?(series[:_fill][:none])
2859
+ # Write the a:noFill element.
2860
+ write_a_no_fill
2861
+ else
2862
+ # Write the a:solidFill element.
2863
+ write_a_solid_fill(series[:_fill])
2864
+ end
2865
+ end
2523
2866
  # Write the a:ln element.
2524
- write_a_ln(series[:_line]) if series[:_line] && series[:_line][:_defined]
2867
+ write_a_ln(series[:_line]) if series[:_line] && series[:_line][:_defined] != 0
2525
2868
  end
2526
2869
  end
2527
2870
 
@@ -2544,7 +2887,7 @@ def write_a_ln(line) # :nodoc:
2544
2887
 
2545
2888
  @writer.tag_elements('a:ln', attributes) do
2546
2889
  # Write the line fill.
2547
- if !line[:none].nil? && line[:none] != 0
2890
+ if ptrue?(line[:none])
2548
2891
  # Write the a:noFill element.
2549
2892
  write_a_no_fill
2550
2893
  else
@@ -2606,19 +2949,19 @@ def write_trendline(trendline) # :nodoc:
2606
2949
 
2607
2950
  @writer.tag_elements('c:trendline') do
2608
2951
  # Write the c:name element.
2609
- write_name(trendline[name])
2952
+ write_name(trendline[:name])
2610
2953
  # Write the c:spPr element.
2611
2954
  write_sp_pr(trendline)
2612
2955
  # Write the c:trendlineType element.
2613
- write_trendline_type(trendline[type])
2956
+ write_trendline_type(trendline[:type])
2614
2957
  # Write the c:order element for polynomial trendlines.
2615
- write_trendline_order(trendline[order]) if trendline[type] == 'poly'
2958
+ write_trendline_order(trendline[:order]) if trendline[:type] == 'poly'
2616
2959
  # Write the c:period element for moving average trendlines.
2617
- write_period(trendline[period]) if trendline[type] == 'movingAvg'
2960
+ write_period(trendline[:period]) if trendline[:type] == 'movingAvg'
2618
2961
  # Write the c:forward element.
2619
- write_forward(trendline[forward])
2962
+ write_forward(trendline[:forward])
2620
2963
  # Write the c:backward element.
2621
- write_backward(trendline[backward])
2964
+ write_backward(trendline[:backward])
2622
2965
  end
2623
2966
  end
2624
2967
 
@@ -2703,9 +3046,25 @@ def write_overlap # :nodoc:
2703
3046
  #
2704
3047
  def write_num_cache(data) # :nodoc:
2705
3048
  @writer.tag_elements('c:numCache') do
3049
+
3050
+ # Write the c:formatCode element.
2706
3051
  write_format_code('General')
3052
+
3053
+ # Write the c:ptCount element.
2707
3054
  write_pt_count(data.size)
2708
- write_pts(data)
3055
+
3056
+ (0..data.size - 1).each do |i|
3057
+ token = data[i]
3058
+
3059
+ # Write non-numeric data as 0.
3060
+ if token &&
3061
+ !(token.to_s =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)
3062
+ token = 0
3063
+ end
3064
+
3065
+ # Write the c:pt element.
3066
+ write_pt(i, token)
3067
+ end
2709
3068
  end
2710
3069
  end
2711
3070
 
@@ -2773,12 +3132,18 @@ def write_d_lbls(labels) # :nodoc:
2773
3132
  return unless labels
2774
3133
 
2775
3134
  @writer.tag_elements('c:dLbls') do
3135
+ # Write the c:dLblPos element.
3136
+ write_d_lbl_pos(labels[:position]) if labels[:position]
2776
3137
  # Write the c:showVal element.
2777
- write_show_val if labels[value]
3138
+ write_show_val if labels[:value]
2778
3139
  # Write the c:showCatName element.
2779
- write_show_cat_name if labels[category]
3140
+ write_show_cat_name if labels[:category]
2780
3141
  # Write the c:showSerName element.
2781
- write_show_ser_name if labels[series_name]
3142
+ write_show_ser_name if labels[:series_name]
3143
+ # Write the c:showPercent element.
3144
+ write_show_percent if labels[:percentage]
3145
+ # Write the c:showLeaderLines element.
3146
+ write_show_leader_lines if labels[:leader_lines]
2782
3147
  end
2783
3148
  end
2784
3149
 
@@ -2815,6 +3180,37 @@ def write_show_ser_name # :nodoc:
2815
3180
  @writer.empty_tag('c:showSerName', attributes)
2816
3181
  end
2817
3182
 
3183
+ #
3184
+ # Write the <c:showPercent> element.
3185
+ #
3186
+ def write_show_percent
3187
+ val = 1
3188
+
3189
+ attributes = ['val', val]
3190
+
3191
+ @writer.empty_tag('c:showPercent', attributes)
3192
+ end
3193
+
3194
+ #
3195
+ # Write the <c:showLeaderLines> element.
3196
+ #
3197
+ def write_show_leader_lines
3198
+ val = 1
3199
+
3200
+ attributes = ['val', val]
3201
+
3202
+ @writer.empty_tag('c:showLeaderLines', attributes)
3203
+ end
3204
+
3205
+ #
3206
+ # Write the <c:dLblPos> element.
3207
+ #
3208
+ def write_d_lbl_pos(val)
3209
+ attributes = ['val', val]
3210
+
3211
+ @writer.empty_tag('c:dLblPos', attributes)
3212
+ end
3213
+
2818
3214
  #
2819
3215
  # Write the <c:delete> element.
2820
3216
  #
@@ -2830,7 +3226,7 @@ def write_delete(val) # :nodoc:
2830
3226
  def write_c_invert_if_negative(invert = nil) # :nodoc:
2831
3227
  val = 1
2832
3228
 
2833
- return unless invert
3229
+ return unless invert && invert != 0
2834
3230
 
2835
3231
  attributes = ['val', val]
2836
3232