axlsx 1.1.4 → 1.3.1

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 (242) hide show
  1. data/.yardopts +6 -2
  2. data/CHANGELOG.md +72 -0
  3. data/README.md +114 -31
  4. data/Rakefile +11 -3
  5. data/examples/auto_filter.rb +16 -0
  6. data/examples/auto_filter.xlsx +0 -0
  7. data/examples/basic_charts.rb +58 -0
  8. data/examples/chart_colors.rb +17 -2
  9. data/examples/data_validation.rb +50 -0
  10. data/examples/example.rb +171 -60
  11. data/examples/example.xlsx +0 -0
  12. data/examples/example_streamed.xlsx +0 -0
  13. data/examples/extractive.pdf +0 -0
  14. data/examples/extractive.rb +3 -0
  15. data/examples/extractive.xlsx +0 -0
  16. data/examples/hyperlinks.rb +23 -0
  17. data/examples/hyperlinks.xlsx +0 -0
  18. data/examples/no-use_autowidth.xlsx +0 -0
  19. data/examples/page_setup.rb +11 -0
  20. data/examples/page_setup.xlsx +0 -0
  21. data/examples/scraping_html.rb +91 -0
  22. data/examples/shared_strings_example.xlsx +0 -0
  23. data/examples/sheet_protection.rb +10 -0
  24. data/examples/sheet_view.rb +34 -0
  25. data/examples/skydrive/axlsx.csv +1 -0
  26. data/examples/skydrive/axlsx.xlsx +0 -0
  27. data/examples/skydrive/real_example.rb +8 -8
  28. data/examples/sprk2012/Screen Shot 2012-09-11 at 10.42.06 PM.png +0 -0
  29. data/examples/sprk2012/Screen Shot 2012-09-11 at 11.07.48 PM.png +0 -0
  30. data/examples/sprk2012/Screen Shot 2012-09-11 at 8.31.50 PM.png +0 -0
  31. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.23.27 PM.png +0 -0
  32. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.32.06 PM.png +0 -0
  33. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.33.35 PM.png +0 -0
  34. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.46.44 PM.png +0 -0
  35. data/examples/sprk2012/Screen Shot 2012-09-12 at 5.07.23 PM.png +0 -0
  36. data/examples/sprk2012/basics.rb +11 -0
  37. data/examples/sprk2012/basics.xlsx +0 -0
  38. data/examples/sprk2012/gravatar.jpeg +0 -0
  39. data/examples/sprk2012/hair_club.jpg +0 -0
  40. data/examples/sprk2012/images.rb +9 -0
  41. data/examples/sprk2012/images.xlsx +0 -0
  42. data/examples/sprk2012/line_chart.rb +56 -0
  43. data/examples/sprk2012/line_chart.xlsx +0 -0
  44. data/examples/sprk2012/sprk2012.key +0 -0
  45. data/examples/sprk2012/styles.rb +20 -0
  46. data/examples/sprk2012/styles.xlsx +0 -0
  47. data/examples/styles.rb +62 -0
  48. data/examples/styles.xlsx +0 -0
  49. data/examples/two_cell_anchor_image.rb +11 -0
  50. data/lib/axlsx/content_type/content_type.rb +2 -0
  51. data/lib/axlsx/content_type/default.rb +30 -15
  52. data/lib/axlsx/content_type/override.rb +29 -14
  53. data/lib/axlsx/doc_props/app.rb +161 -104
  54. data/lib/axlsx/doc_props/core.rb +9 -5
  55. data/lib/axlsx/drawing/ax_data_source.rb +7 -6
  56. data/lib/axlsx/drawing/axis.rb +82 -36
  57. data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
  58. data/lib/axlsx/drawing/bar_series.rb +2 -1
  59. data/lib/axlsx/drawing/cat_axis.rb +43 -39
  60. data/lib/axlsx/drawing/chart.rb +65 -54
  61. data/lib/axlsx/drawing/d_lbls.rb +100 -0
  62. data/lib/axlsx/drawing/drawing.rb +20 -8
  63. data/lib/axlsx/drawing/graphic_frame.rb +2 -1
  64. data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
  65. data/lib/axlsx/drawing/num_data.rb +2 -2
  66. data/lib/axlsx/drawing/num_data_source.rb +4 -1
  67. data/lib/axlsx/drawing/pic.rb +44 -4
  68. data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
  69. data/lib/axlsx/drawing/scatter_chart.rb +2 -8
  70. data/lib/axlsx/drawing/title.rb +21 -9
  71. data/lib/axlsx/drawing/two_cell_anchor.rb +46 -9
  72. data/lib/axlsx/drawing/view_3D.rb +42 -32
  73. data/lib/axlsx/drawing/vml_drawing.rb +42 -0
  74. data/lib/axlsx/drawing/vml_shape.rb +125 -0
  75. data/lib/axlsx/package.rb +43 -16
  76. data/lib/axlsx/rels/relationship.rb +3 -3
  77. data/lib/axlsx/rels/relationships.rb +1 -11
  78. data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
  79. data/lib/axlsx/stylesheet/styles.rb +11 -2
  80. data/lib/axlsx/stylesheet/table_style.rb +3 -3
  81. data/lib/axlsx/util/constants.rb +131 -2
  82. data/lib/axlsx/util/simple_typed_list.rb +18 -22
  83. data/lib/axlsx/util/validators.rb +100 -9
  84. data/lib/axlsx/version.rb +2 -7
  85. data/lib/axlsx/workbook/defined_name.rb +174 -0
  86. data/lib/axlsx/workbook/defined_names.rb +21 -0
  87. data/lib/axlsx/workbook/workbook.rb +70 -13
  88. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +77 -0
  89. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +102 -0
  90. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +253 -0
  91. data/lib/axlsx/workbook/worksheet/cell.rb +41 -8
  92. data/lib/axlsx/workbook/worksheet/col.rb +15 -0
  93. data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
  94. data/lib/axlsx/workbook/worksheet/comment.rb +101 -0
  95. data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
  96. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
  97. data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
  98. data/lib/axlsx/workbook/worksheet/data_validation.rb +245 -0
  99. data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
  100. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +1 -1
  101. data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
  102. data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
  103. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +47 -0
  104. data/lib/axlsx/workbook/worksheet/page_setup.rb +241 -0
  105. data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
  106. data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
  107. data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
  108. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
  109. data/lib/axlsx/workbook/worksheet/row.rb +36 -20
  110. data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
  111. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +49 -0
  112. data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
  113. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +107 -0
  114. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +224 -0
  115. data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
  116. data/lib/axlsx/workbook/worksheet/table.rb +10 -3
  117. data/lib/axlsx/workbook/worksheet/table_style_info.rb +68 -0
  118. data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
  119. data/lib/axlsx/workbook/worksheet/worksheet.rb +414 -254
  120. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
  121. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
  122. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +101 -0
  123. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +38 -0
  124. data/lib/axlsx.rb +38 -16
  125. data/test/content_type/tc_content_type.rb +1 -6
  126. data/test/doc_props/tc_app.rb +31 -1
  127. data/test/doc_props/tc_core.rb +3 -1
  128. data/test/drawing/tc_axis.rb +38 -3
  129. data/test/drawing/tc_bar_3D_chart.rb +12 -12
  130. data/test/drawing/tc_bar_series.rb +1 -2
  131. data/test/drawing/tc_cat_axis.rb +3 -3
  132. data/test/drawing/tc_chart.rb +29 -9
  133. data/test/drawing/tc_d_lbls.rb +47 -0
  134. data/test/drawing/tc_drawing.rb +11 -5
  135. data/test/drawing/tc_hyperlink.rb +4 -5
  136. data/test/drawing/tc_line_series.rb +7 -3
  137. data/test/drawing/tc_num_data.rb +5 -1
  138. data/test/drawing/tc_pic.rb +22 -2
  139. data/test/drawing/tc_pie_3D_chart.rb +4 -8
  140. data/test/drawing/tc_pie_series.rb +7 -2
  141. data/test/drawing/tc_scatter_chart.rb +6 -1
  142. data/test/drawing/tc_scatter_series.rb +1 -1
  143. data/test/drawing/tc_series.rb +1 -1
  144. data/test/drawing/tc_title.rb +16 -0
  145. data/test/drawing/tc_two_cell_anchor.rb +1 -2
  146. data/test/drawing/tc_view_3D.rb +18 -18
  147. data/test/drawing/tc_vml_drawing.rb +25 -0
  148. data/test/drawing/tc_vml_shape.rb +100 -0
  149. data/test/rels/tc_relationship.rb +1 -0
  150. data/test/stylesheet/tc_gradient_fill.rb +8 -0
  151. data/test/stylesheet/tc_pattern_fill.rb +7 -1
  152. data/test/stylesheet/tc_styles.rb +16 -4
  153. data/test/stylesheet/tc_table_style.rb +8 -0
  154. data/test/stylesheet/tc_table_style_element.rb +10 -1
  155. data/test/tc_helper.rb +1 -0
  156. data/test/tc_package.rb +94 -17
  157. data/test/util/tc_simple_typed_list.rb +13 -0
  158. data/test/util/tc_validators.rb +101 -8
  159. data/test/workbook/tc_defined_name.rb +41 -0
  160. data/test/workbook/tc_workbook.rb +5 -3
  161. data/test/workbook/worksheet/auto_filter/tc_auto_filter.rb +38 -0
  162. data/test/workbook/worksheet/auto_filter/tc_filter_column.rb +76 -0
  163. data/test/workbook/worksheet/auto_filter/tc_filters.rb +50 -0
  164. data/test/workbook/worksheet/tc_cell.rb +53 -7
  165. data/test/workbook/worksheet/tc_col.rb +9 -0
  166. data/test/workbook/worksheet/tc_comment.rb +57 -0
  167. data/test/workbook/worksheet/tc_comments.rb +57 -0
  168. data/test/workbook/worksheet/tc_conditional_formatting.rb +44 -0
  169. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  170. data/test/workbook/worksheet/tc_data_validation.rb +265 -0
  171. data/test/workbook/worksheet/tc_page_set_up_pr.rb +15 -0
  172. data/test/workbook/worksheet/tc_page_setup.rb +143 -0
  173. data/test/workbook/worksheet/tc_pane.rb +94 -0
  174. data/test/workbook/worksheet/tc_print_options.rb +72 -0
  175. data/test/workbook/worksheet/tc_protected_range.rb +17 -0
  176. data/test/workbook/worksheet/tc_row.rb +32 -14
  177. data/test/workbook/worksheet/tc_selection.rb +94 -0
  178. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +18 -0
  179. data/test/workbook/worksheet/tc_sheet_pr.rb +27 -0
  180. data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
  181. data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
  182. data/test/workbook/worksheet/{table/tc_table.rb → tc_table.rb} +9 -12
  183. data/test/workbook/worksheet/tc_table_style_info.rb +53 -0
  184. data/test/workbook/worksheet/tc_worksheet.rb +155 -51
  185. data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +64 -0
  186. metadata +194 -81
  187. data/examples/#extractive.csv# +0 -0
  188. data/examples/#extractive.rb# +0 -45
  189. data/examples/chart_colors.rb~ +0 -0
  190. data/examples/chart_colors.xlsx +0 -0
  191. data/examples/colored_series_data.xlsx +0 -0
  192. data/examples/conditional_formatting/getting_barred.xlsx +0 -0
  193. data/examples/example.csv +0 -1000
  194. data/examples/extractive.csv +0 -1
  195. data/examples/extractive.csv~ +0 -1
  196. data/examples/extractive.rb~ +0 -3
  197. data/examples/stack.rb +0 -21
  198. data/examples/stack.rb~ +0 -27
  199. data/examples/stack.xlsx +0 -0
  200. data/examples/~$chart_colors.xlsx +0 -0
  201. data/examples/~$extractive.xlsx +0 -0
  202. data/lib/axlsx/drawing/ax_data_source.rb~ +0 -55
  203. data/lib/axlsx/drawing/data_source.rb~ +0 -51
  204. data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
  205. data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
  206. data/lib/axlsx/drawing/num_data.rb~ +0 -51
  207. data/lib/axlsx/drawing/num_data_source.rb~ +0 -54
  208. data/lib/axlsx/drawing/num_val.rb~ +0 -40
  209. data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
  210. data/lib/axlsx/drawing/ref.rb~ +0 -41
  211. data/lib/axlsx/drawing/str_data.rb~ +0 -58
  212. data/lib/axlsx/drawing/str_val.rb~ +0 -35
  213. data/lib/axlsx/util/cbf.rb +0 -333
  214. data/lib/axlsx/util/cfb.rb~ +0 -201
  215. data/lib/axlsx/util/font_tables.rb~ +0 -0
  216. data/lib/axlsx/util/ms_off_crypto.rb +0 -189
  217. data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
  218. data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
  219. data/lib/axlsx/util/parser.rb~ +0 -6
  220. data/lib/axlsx/util/storage.rb~ +0 -0
  221. data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
  222. data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
  223. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  224. data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
  225. data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
  226. data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
  227. data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
  228. data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
  229. data/lib/schema/dc.xsd~ +0 -118
  230. data/lib/schema/dcterms.xsd~ +0 -331
  231. data/lib/schema/opc-coreProperties.xsd~ +0 -50
  232. data/test/drawing/tc_data_source.rb~ +0 -30
  233. data/test/drawing/tc_num_data.rb~ +0 -35
  234. data/test/drawing/tc_num_val.rb~ +0 -29
  235. data/test/drawing/tc_str_data.rb~ +0 -30
  236. data/test/drawing/tc_str_val.rb~ +0 -26
  237. data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
  238. data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
  239. data/test/workbook/worksheet/tc_col.rb~ +0 -10
  240. data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
  241. data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
  242. data/test/workbook/worksheet/tc_icon_set.rb~ +0 -0
@@ -10,24 +10,29 @@ module Axlsx
10
10
 
11
11
  # the category axis
12
12
  # @return [CatAxis]
13
- attr_reader :catAxis
13
+ attr_reader :cat_axis
14
+ alias :catAxis :cat_axis
14
15
 
15
- # the valueaxis
16
+ # the value axis
16
17
  # @return [ValAxis]
17
- attr_reader :valAxis
18
+ attr_reader :val_axis
19
+ alias :valAxis :val_axis
18
20
 
19
21
  # The direction of the bars in the chart
20
22
  # must be one of [:bar, :col]
21
23
  # @return [Symbol]
22
- attr_reader :barDir
24
+ attr_reader :bar_dir
25
+ alias :barDir :bar_dir
23
26
 
24
27
  # space between bar or column clusters, as a percentage of the bar or column width.
25
28
  # @return [String]
26
- attr_reader :gapDepth
29
+ attr_reader :gap_depth
30
+ alias :gapDepth :gap_depth
27
31
 
28
32
  # space between bar or column clusters, as a percentage of the bar or column width.
29
33
  # @return [String]
30
- attr_reader :gapWidth
34
+ attr_reader :gap_width
35
+ alias :gapWidth :gap_width
31
36
 
32
37
  #grouping for a column, line, or area chart.
33
38
  # must be one of [:percentStacked, :clustered, :standard, :stacked]
@@ -46,38 +51,42 @@ module Axlsx
46
51
  # @param [GraphicFrame] frame The workbook that owns this chart.
47
52
  # @option options [Cell, String] title
48
53
  # @option options [Boolean] show_legend
49
- # @option options [Symbol] barDir
54
+ # @option options [Symbol] bar_dir
50
55
  # @option options [Symbol] grouping
51
- # @option options [String] gapWidth
52
- # @option options [String] gapDepth
56
+ # @option options [String] gap_width
57
+ # @option options [String] gap_depth
53
58
  # @option options [Symbol] shape
54
- # @option options [Integer] rotX
55
- # @option options [String] hPercent
56
- # @option options [Integer] rotY
57
- # @option options [String] depthPercent
58
- # @option options [Boolean] rAngAx
59
+ # @option options [Integer] rot_x
60
+ # @option options [String] h_percent
61
+ # @option options [Integer] rot_y
62
+ # @option options [String] depth_percent
63
+ # @option options [Boolean] r_ang_ax
59
64
  # @option options [Integer] perspective
60
65
  # @see Chart
61
66
  # @see View3D
62
67
  def initialize(frame, options={})
63
- @barDir = :bar
68
+ @bar_dir = :bar
64
69
  @grouping = :clustered
65
- @gapWidth, @gapDepth, @shape = nil, nil, nil
66
- @catAxId = rand(8 ** 8)
67
- @valAxId = rand(8 ** 8)
68
- @catAxis = CatAxis.new(@catAxId, @valAxId)
69
- @valAxis = ValAxis.new(@valAxId, @catAxId, :tickLblPos => :low)
70
+ @shape = :box
71
+ @gap_width = 150
72
+ @gap_width, @gap_depth, @shape = nil, nil, nil
73
+ @cat_ax_id = rand(8 ** 8)
74
+ @val_ax_id = rand(8 ** 8)
75
+ @cat_axis = CatAxis.new(@cat_ax_id, @val_ax_id)
76
+ @val_axis = ValAxis.new(@val_ax_id, @cat_ax_id, :tick_lbl_pos => :low, :ax_pos => :l)
70
77
  super(frame, options)
71
78
  @series_type = BarSeries
72
- @view3D = View3D.new({:rAngAx=>1}.merge(options))
79
+ @view_3D = View3D.new({:r_ang_ax=>1}.merge(options))
80
+ @d_lbls = nil
73
81
  end
74
82
 
75
83
  # The direction of the bars in the chart
76
84
  # must be one of [:bar, :col]
77
- def barDir=(v)
78
- RestrictionValidator.validate "Bar3DChart.barDir", [:bar, :col], v
79
- @barDir = v
85
+ def bar_dir=(v)
86
+ RestrictionValidator.validate "Bar3DChart.bar_dir", [:bar, :col], v
87
+ @bar_dir = v
80
88
  end
89
+ alias :barDir= :bar_dir=
81
90
 
82
91
  #grouping for a column, line, or area chart.
83
92
  # must be one of [:percentStacked, :clustered, :standard, :stacked]
@@ -87,16 +96,18 @@ module Axlsx
87
96
  end
88
97
 
89
98
  # space between bar or column clusters, as a percentage of the bar or column width.
90
- def gapWidth=(v)
91
- RegexValidator.validate "Bar3DChart.gapWidth", GAP_AMOUNT_PERCENT, v
92
- @gapWidth=(v)
99
+ def gap_width=(v)
100
+ RegexValidator.validate "Bar3DChart.gap_width", GAP_AMOUNT_PERCENT, v
101
+ @gap_width=(v)
93
102
  end
103
+ alias :gapWidth= :gap_width=
94
104
 
95
105
  # space between bar or column clusters, as a percentage of the bar or column width.
96
- def gapDepth=(v)
97
- RegexValidator.validate "Bar3DChart.gapWidth", GAP_AMOUNT_PERCENT, v
98
- @gapDepth=(v)
106
+ def gap_depth=(v)
107
+ RegexValidator.validate "Bar3DChart.gap_didth", GAP_AMOUNT_PERCENT, v
108
+ @gap_depth=(v)
99
109
  end
110
+ alias :gapDepth= :gap_depth=
100
111
 
101
112
  # The shabe of the bars or columns
102
113
  # must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
@@ -111,27 +122,20 @@ module Axlsx
111
122
  def to_xml_string(str = '')
112
123
  super(str) do |str_inner|
113
124
  str_inner << '<c:bar3DChart>'
114
- str_inner << '<c:barDir val="' << barDir.to_s << '"/>'
125
+ str_inner << '<c:barDir val="' << bar_dir.to_s << '"/>'
115
126
  str_inner << '<c:grouping val="' << grouping.to_s << '"/>'
116
127
  str_inner << '<c:varyColors val="1"/>'
117
128
  @series.each { |ser| ser.to_xml_string(str_inner) }
118
- str_inner << '<c:dLbls>'
119
- str_inner << '<c:showLegendKey val="0"/>'
120
- str_inner << '<c:showVal val="0"/>'
121
- str_inner << '<c:showCatName val="0"/>'
122
- str_inner << '<c:showSerName val="0"/>'
123
- str_inner << '<c:showPercent val="0"/>'
124
- str_inner << '<c:showBubbleSize val="0"/>'
125
- str_inner << '</c:dLbls>'
126
- str_inner << '<c:gapWidth val="' << @gapWidth.to_s << '"/>' unless @gapWidth.nil?
127
- str_inner << '<c:gapDepth val="' << @gapDepth.to_s << '"/>' unless @gapDepth.nil?
129
+ @d_lbls.to_xml_string(str) if @d_lbls
130
+ str_inner << '<c:gapWidth val="' << @gap_width.to_s << '"/>' unless @gap_width.nil?
131
+ str_inner << '<c:gapDepth val="' << @gap_depth.to_s << '"/>' unless @gap_depth.nil?
128
132
  str_inner << '<c:shape val="' << @shape.to_s << '"/>' unless @shape.nil?
129
- str_inner << '<c:axId val="' << @catAxId.to_s << '"/>'
130
- str_inner << '<c:axId val="' << @valAxId.to_s << '"/>'
133
+ str_inner << '<c:axId val="' << @cat_ax_id.to_s << '"/>'
134
+ str_inner << '<c:axId val="' << @val_ax_id.to_s << '"/>'
131
135
  str_inner << '<c:axId val="0"/>'
132
136
  str_inner << '</c:bar3DChart>'
133
- @catAxis.to_xml_string str_inner
134
- @valAxis.to_xml_string str_inner
137
+ @cat_axis.to_xml_string str_inner
138
+ @val_axis.to_xml_string str_inner
135
139
  end
136
140
  end
137
141
  end
@@ -42,7 +42,7 @@ module Axlsx
42
42
  def colors=(v) DataTypeValidator.validate "BarSeries.colors", [Array], v; @colors = v end
43
43
 
44
44
  # The shabe of the bars or columns
45
- # must be one of [:percentStacked, :clustered, :standard, :stacked]
45
+ # must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
46
46
  def shape=(v)
47
47
  RestrictionValidator.validate "BarSeries.shape", [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax], v
48
48
  @shape = v
@@ -64,6 +64,7 @@ module Axlsx
64
64
 
65
65
  @labels.to_xml_string(str_inner) unless @labels.nil?
66
66
  @data.to_xml_string(str_inner) unless @data.nil?
67
+ # this is actually only required for shapes other than box
67
68
  str_inner << '<c:shape val="' << shape.to_s << '"></c:shape>'
68
69
  end
69
70
  end
@@ -3,6 +3,26 @@ module Axlsx
3
3
  #A CatAxis object defines a chart category axis
4
4
  class CatAxis < Axis
5
5
 
6
+ # Creates a new CatAxis object
7
+ # @param [Integer] ax_id the id of this axis. Inherited
8
+ # @param [Integer] cross_ax the id of the perpendicular axis. Inherited
9
+ # @option options [Symbol] ax_pos. Inherited
10
+ # @option options [Symbol] tick_lbl_pos. Inherited
11
+ # @option options [Symbol] crosses. Inherited
12
+ # @option options [Boolean] auto
13
+ # @option options [Symbol] lbl_algn
14
+ # @option options [Integer] lbl_offset
15
+ # @option options [Integer] tick_lbl_skip
16
+ # @option options [Integer] tick_mark_skip
17
+ def initialize(ax_id, cross_ax, options={})
18
+ @tick_lbl_skip = 1
19
+ @tick_mark_skip = 1
20
+ self.auto = 1
21
+ self.lbl_algn = :ctr
22
+ self.lbl_offset = "100"
23
+ super(ax_id, cross_ax, options)
24
+ end
25
+
6
26
  # From the docs: This element specifies that this axis is a date or text axis based on the data that is used for the axis labels, not a specific choice.
7
27
  # @return [Boolean]
8
28
  attr_reader :auto
@@ -10,64 +30,48 @@ module Axlsx
10
30
  # specifies how the perpendicular axis is crossed
11
31
  # must be one of [:ctr, :l, :r]
12
32
  # @return [Symbol]
13
- attr_reader :lblAlgn
33
+ attr_reader :lbl_algn
34
+ alias :lblAlgn :lbl_algn
14
35
 
15
36
  # The offset of the labels
16
37
  # must be between a string between 0 and 1000
17
38
  # @return [Integer]
18
- attr_reader :lblOffset
19
-
39
+ attr_reader :lbl_offset
40
+ alias :lblOffset :lbl_offset
20
41
 
21
42
  # The number of tick lables to skip between labels
22
43
  # @return [Integer]
23
- attr_reader :tickLblSkip
44
+ attr_reader :tick_lbl_skip
45
+ alias :tickLblSkip :tick_lbl_skip
24
46
 
25
47
  # The number of tickmarks to be skipped before the next one is rendered.
26
48
  # @return [Boolean]
27
- attr_reader :tickMarkSkip
28
-
49
+ attr_reader :tick_mark_skip
50
+ alias :tickMarkSkip :tick_mark_skip
29
51
 
30
52
  # regex for validating label offset
31
- LBL_OFFSET_REGEX = /0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)%/
32
-
33
- # Creates a new CatAxis object
34
- # @param [Integer] axId the id of this axis. Inherited
35
- # @param [Integer] crossAx the id of the perpendicular axis. Inherited
36
- # @option options [Symbol] axPos. Inherited
37
- # @option options [Symbol] tickLblPos. Inherited
38
- # @option options [Symbol] crosses. Inherited
39
- # @option options [Boolean] auto
40
- # @option options [Symbol] lblAlgn
41
- # @option options [Integer] lblOffset
42
- # @option options [Integer] tickLblSkip
43
- # @option options [Integer] tickMarkSkip
44
- def initialize(axId, crossAx, options={})
45
- @tickLblSkip = 1
46
- @tickMarkSkip = 1
47
- self.auto = 1
48
- self.lblAlgn = :ctr
49
- self.lblOffset = "100%"
50
- super(axId, crossAx, options)
51
- end
52
-
53
-
54
- # @see tickLblSkip
55
- def tickLblSkip=(v) Axlsx::validate_unsigned_int(v); @tickLblSkip = v; end
53
+ LBL_OFFSET_REGEX = /0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)/
56
54
 
57
- # @see tickMarkSkip
58
- def tickMarkSkip=(v) Axlsx::validate_unsigned_int(v); @tickMarkSkip = v; end
55
+ # @see tick_lbl_skip
56
+ def tick_lbl_skip=(v) Axlsx::validate_unsigned_int(v); @tick_lbl_skip = v; end
57
+ alias :tickLblSkip= :tick_lbl_skip=
59
58
 
59
+ # @see tick_mark_skip
60
+ def tick_mark_skip=(v) Axlsx::validate_unsigned_int(v); @tick_mark_skip = v; end
61
+ alias :tickMarkSkip= :tick_mark_skip=
60
62
 
61
63
  # From the docs: This element specifies that this axis is a date or text axis based on the data that is used for the axis labels, not a specific choice.
62
64
  def auto=(v) Axlsx::validate_boolean(v); @auto = v; end
63
65
 
64
66
  # specifies how the perpendicular axis is crossed
65
67
  # must be one of [:ctr, :l, :r]
66
- def lblAlgn=(v) RestrictionValidator.validate "#{self.class}.lblAlgn", [:ctr, :l, :r], v; @lblAlgn = v; end
68
+ def lbl_algn=(v) RestrictionValidator.validate "#{self.class}.lbl_algn", [:ctr, :l, :r], v; @lbl_algn = v; end
69
+ alias :lblAlgn= :lbl_algn=
67
70
 
68
71
  # The offset of the labels
69
72
  # must be between a string between 0 and 1000
70
- def lblOffset=(v) RegexValidator.validate "#{self.class}.lblOffset", LBL_OFFSET_REGEX, v; @lblOffset = v; end
73
+ def lbl_offset=(v) RegexValidator.validate "#{self.class}.lbl_offset", LBL_OFFSET_REGEX, v; @lbl_offset = v; end
74
+ alias :lblOffset= :lbl_offset=
71
75
 
72
76
  # Serializes the object
73
77
  # @param [String] str
@@ -76,10 +80,10 @@ module Axlsx
76
80
  str << '<c:catAx>'
77
81
  super(str)
78
82
  str << '<c:auto val="' << @auto.to_s << '"/>'
79
- str << '<c:lblAlgn val="' << @lblAlgn.to_s << '"/>'
80
- str << '<c:lblOffset val="' << @lblOffset.to_s << '"/>'
81
- str << '<c:tickLblSkip val="' << @tickLblSkip.to_s << '"/>'
82
- str << '<c:tickMarkSkip val="' << @tickMarkSkip.to_s << '"/>'
83
+ str << '<c:lblAlgn val="' << @lbl_algn.to_s << '"/>'
84
+ str << '<c:lblOffset val="' << @lbl_offset.to_i.to_s << '"/>'
85
+ str << '<c:tickLblSkip val="' << @tick_lbl_skip.to_s << '"/>'
86
+ str << '<c:tickMarkSkip val="' << @tick_mark_skip.to_s << '"/>'
83
87
  str << '</c:catAx>'
84
88
  end
85
89
 
@@ -1,13 +1,37 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
+
3
4
  # A Chart is the superclass for specific charts
4
5
  # @note Worksheet#add_chart is the recommended way to create charts for your worksheets.
5
6
  # @see README for examples
6
7
  class Chart
7
8
 
9
+ # Creates a new chart object
10
+ # @param [GraphicalFrame] frame The frame that holds this chart.
11
+ # @option options [Cell, String] title
12
+ # @option options [Boolean] show_legend
13
+ # @option options [Array|String|Cell] start_at The X, Y coordinates defining the top left corner of the chart.
14
+ # @option options [Array|String|Cell] end_at The X, Y coordinates defining the bottom right corner of the chart.
15
+ def initialize(frame, options={})
16
+ @style = 18
17
+ @view_3D = nil
18
+ @graphic_frame=frame
19
+ @graphic_frame.anchor.drawing.worksheet.workbook.charts << self
20
+ @series = SimpleTypedList.new Series
21
+ @show_legend = true
22
+ @series_type = Series
23
+ @title = Title.new
24
+ options.each do |o|
25
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
26
+ end
27
+ start_at(*options[:start_at]) if options[:start_at]
28
+ end_at(*options[:end_at]) if options[:end_at]
29
+ yield self if block_given?
30
+ end
8
31
 
9
32
  # The 3D view properties for the chart
10
- attr_reader :view3D
33
+ attr_reader :view_3D
34
+ alias :view3D :view_3D
11
35
 
12
36
  # A reference to the graphic frame that owns this chart
13
37
  # @return [GraphicFrame]
@@ -22,7 +46,10 @@ module Axlsx
22
46
  attr_reader :series_type
23
47
 
24
48
  #TODO data labels!
25
- #attr_reader :dLabls
49
+ def d_lbls
50
+ @d_lbls ||= DLbls.new(self.class)
51
+ end
52
+
26
53
 
27
54
  # The title object for the chart.
28
55
  # @return [Title]
@@ -37,29 +64,6 @@ module Axlsx
37
64
  # @return [Boolean]
38
65
  attr_reader :show_legend
39
66
 
40
- # Creates a new chart object
41
- # @param [GraphicalFrame] frame The frame that holds this chart.
42
- # @option options [Cell, String] title
43
- # @option options [Boolean] show_legend
44
- # @option options [Array|String|Cell] start_at The X, Y coordinates defining the top left corner of the chart.
45
- # @option options [Array|String|Cell] end_at The X, Y coordinates defining the bottom right corner of the chart.
46
- def initialize(frame, options={})
47
- @style = 2
48
- @view3D = nil
49
- @graphic_frame=frame
50
- @graphic_frame.anchor.drawing.worksheet.workbook.charts << self
51
- @series = SimpleTypedList.new Series
52
- @show_legend = true
53
- @series_type = Series
54
- @title = Title.new
55
- options.each do |o|
56
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
57
- end
58
- start_at(*options[:start_at]) if options[:start_at]
59
- end_at(*options[:end_at]) if options[:end_at]
60
- yield self if block_given?
61
- end
62
-
63
67
  # The index of this chart in the workbooks charts collection
64
68
  # @return [Integer]
65
69
  def index
@@ -89,7 +93,6 @@ module Axlsx
89
93
  # @return [Boolean]
90
94
  def show_legend=(v) Axlsx::validate_boolean(v); @show_legend = v; end
91
95
 
92
-
93
96
  # The style for the chart.
94
97
  # see ECMA Part 1 §21.2.2.196
95
98
  # @param [Integer] v must be between 1 and 48
@@ -120,14 +123,14 @@ module Axlsx
120
123
  # @return [String]
121
124
  def to_xml_string(str = '')
122
125
  str << '<?xml version="1.0" encoding="UTF-8"?>'
123
- str << '<c:chartSpace xmlns:c="' << XML_NS_C << '" xmlns:a="' << XML_NS_A << '">'
126
+ str << '<c:chartSpace xmlns:c="' << XML_NS_C << '" xmlns:a="' << XML_NS_A << '" xmlns:r="' << XML_NS_R << '">'
124
127
  str << '<c:date1904 val="' << Axlsx::Workbook.date1904.to_s << '"/>'
125
128
  str << '<c:style val="' << style.to_s << '"/>'
126
129
  str << '<c:chart>'
127
130
  @title.to_xml_string str
128
131
  # do these need the c: namespace as well???
129
- str << '<c:autoTitleDeleted val="0"/>'
130
- @view3D.to_xml_string(str) if @view3D
132
+ str << '<c:autoTitleDeleted val="' << (@title == nil).to_s << '"/>'
133
+ @view_3D.to_xml_string(str) if @view_3D
131
134
  str << '<c:floor><c:thickness val="0"/></c:floor>'
132
135
  str << '<c:sideWall><c:thickness val="0"/></c:sideWall>'
133
136
  str << '<c:backWall><c:thickness val="0"/></c:backWall>'
@@ -146,19 +149,40 @@ module Axlsx
146
149
  str << '<c:dispBlanksAs val="zero"/>'
147
150
  str << '<c:showDLblsOverMax val="1"/>'
148
151
  str << '</c:chart>'
152
+ str << '<c:printSettings>'
153
+ str << '<c:headerFooter/>'
154
+ str << '<c:pageMargins b="1.0" l="0.75" r="0.75" t="1.0" header="0.5" footer="0.5"/>'
155
+ str << '<c:pageSetup/>'
156
+ str << '</c:printSettings>'
149
157
  str << '</c:chartSpace>'
150
158
  end
151
159
 
152
- # This is a short cut method to set the start anchor position
160
+ # This is a short cut method to set the anchor start marker position
153
161
  # If you need finer granularity in positioning use
154
- # graphic_frame.anchor.from.colOff / rowOff
155
- # @param [Integer] x The column
162
+ #
163
+ # This helper method acceps a fairly wide range of inputs exampled
164
+ # below
165
+ #
166
+ # @example
167
+ #
168
+ # start_at 0, 5 # The anchor start marker is set to 6th row of
169
+ # the first column
170
+ #
171
+ # start_at [0, 5] # The anchor start marker is set to start on the 6th row
172
+ # of the first column
173
+ #
174
+ # start_at "C1" # The anchor start marker is set to start on the first row
175
+ # of the third column
176
+ #
177
+ # start_at sheet.rows.first.cells.last # The anchor start
178
+ # marker is set to the location of a specific cell.
179
+ #
180
+ # @param [Array|String|Cell] x the column, coordinates, string
181
+ # reference or cell to use in setting the start marker position.
156
182
  # @param [Integer] y The row
157
183
  # @return [Marker]
158
184
  def start_at(x=0, y=0)
159
- x, y = *parse_coord_args(x, y)
160
- @graphic_frame.anchor.from.col = x
161
- @graphic_frame.anchor.from.row = y
185
+ @graphic_frame.anchor.start_at(x, y)
162
186
  end
163
187
 
164
188
  # This is a short cut method to set the end anchor position
@@ -167,28 +191,15 @@ module Axlsx
167
191
  # @param [Integer] x The column - default 10
168
192
  # @param [Integer] y The row - default 10
169
193
  # @return [Marker]
194
+ # @see start_at
170
195
  def end_at(x=10, y=10)
171
- x, y = *parse_coord_args(x, y)
172
- @graphic_frame.anchor.to.col = x
173
- @graphic_frame.anchor.to.row = y
196
+ @graphic_frame.anchor.end_at(x, y)
174
197
  end
175
198
 
176
- private
177
-
178
- def parse_coord_args(x, y=0)
179
- if x.is_a?(String)
180
- x, y = *Axlsx::name_to_indices(x)
181
- end
182
- if x.is_a?(Cell)
183
- x, y = *x.pos
184
- end
185
- if x.is_a?(Array)
186
- x, y = *x
187
- end
188
- [x, y]
189
- end
190
-
191
- def view3D=(v) DataTypeValidator.validate "#{self.class}.view3D", View3D, v; @view3D = v; end
199
+ # sets the view_3D object for the chart
200
+ def view_3D=(v) DataTypeValidator.validate "#{self.class}.view_3D", View3D, v; @view_3D = v; end
201
+ alias :view3D= :view_3D=
192
202
 
193
203
  end
204
+
194
205
  end
@@ -0,0 +1,100 @@
1
+ module Axlsx
2
+ # There are more elements in the dLbls spec that allow for
3
+ # customizations and formatting. For now, I am just implementing the
4
+ # basics.
5
+
6
+ #The DLbls class manages serialization of data labels
7
+ # showLeaderLines and leaderLines are not currently implemented
8
+ class DLbls
9
+
10
+ # These attributes are all boolean so I'm doing a bit of a hand
11
+ # waving magic show to set up the attriubte accessors
12
+ # @note
13
+ # not all charts support all methods!
14
+ # Bar3DChart and Line3DChart and ScatterChart do not support d_lbl_pos or show_leader_lines
15
+ #
16
+ BOOLEAN_ATTRIBUTES = [:show_legend_key, :show_val, :show_cat_name, :show_ser_name, :show_percent, :show_bubble_size, :show_leader_lines]
17
+
18
+ # creates a new DLbls object
19
+ def initialize(chart_type, options={})
20
+ raise ArgumentError, 'chart_type must inherit from Chart' unless chart_type.superclass == Chart
21
+ @chart_type = chart_type
22
+ initialize_defaults
23
+ options.each do |o|
24
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
25
+ end
26
+ end
27
+
28
+ # Initialize all the values to false as Excel requires them to
29
+ # explicitly be disabled or all will show.
30
+ def initialize_defaults
31
+ BOOLEAN_ATTRIBUTES.each do |attr|
32
+ self.send("#{attr}=", false)
33
+ end
34
+ end
35
+
36
+ # The chart type that is using this data lables instance.
37
+ # This affects the xml output as not all chart types support the
38
+ # same data label attributes.
39
+ attr_reader :chart_type
40
+
41
+ # The position of the data labels in the chart
42
+ # @see d_lbl_pos= for a list of allowed values
43
+ # @return [Symbol]
44
+ def d_lbl_pos
45
+ return unless @chart_type == Pie3DChart
46
+ @d_lbl_pos ||= :bestFit
47
+ end
48
+
49
+ # @see DLbls#d_lbl_pos
50
+ # Assigns the label postion for this data labels on this chart.
51
+ # Allowed positions are :bestFilt, :b, :ctr, :inBase, :inEnd, :l,
52
+ # :outEnd, :r and :t
53
+ # The default is :bestFit
54
+ # @param [Symbol] label_position the postion you want to use.
55
+ def d_lbl_pos=(label_position)
56
+ return unless @chart_type == Pie3DChart
57
+ Axlsx::RestrictionValidator.validate 'DLbls#d_lbl_pos', [:bestFit, :b, :ctr, :inBase, :inEnd, :l, :outEnd, :r, :t], label_position
58
+ @d_lbl_pos = label_position
59
+ end
60
+
61
+ # Dynamically create accessors for boolean attriubtes
62
+ BOOLEAN_ATTRIBUTES.each do |attr|
63
+ class_eval %{
64
+ # The #{attr} attribute reader
65
+ # @return [Boolean]
66
+ attr_reader :#{attr}
67
+
68
+ # The #{attr} writer
69
+ # @param [Boolean] value The value to assign to #{attr}
70
+ # @return [Boolean]
71
+ def #{attr}=(value)
72
+ Axlsx::validate_boolean(value)
73
+ @#{attr} = value
74
+ end
75
+ }
76
+ end
77
+
78
+
79
+ # serializes the data labels
80
+ # @return [String]
81
+ def to_xml_string(str = '')
82
+ validate_attributes_for_chart_type
83
+ str << '<c:dLbls>'
84
+ %w(d_lbl_pos show_legend_key show_val show_cat_name show_ser_name show_percent show_bubble_size show_leader_lines).each do |key|
85
+ next unless instance_values.keys.include?(key) && instance_values[key] != nil
86
+ str << "<c:#{Axlsx::camel(key, false)} val='#{instance_values[key]}' />"
87
+ end
88
+ str << '</c:dLbls>'
89
+ end
90
+
91
+ # nills out d_lbl_pos and show_leader_lines as these attributes, while valid in the spec actually chrash excel for any chart type other than pie charts.
92
+ def validate_attributes_for_chart_type
93
+ return if @chart_type == Pie3DChart
94
+ @d_lbl_pos = nil
95
+ @show_leader_lines = nil
96
+ end
97
+
98
+
99
+ end
100
+ end
@@ -1,5 +1,6 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
+ require 'axlsx/drawing/d_lbls.rb'
3
4
  require 'axlsx/drawing/title.rb'
4
5
  require 'axlsx/drawing/series_title.rb'
5
6
  require 'axlsx/drawing/series.rb'
@@ -39,12 +40,16 @@ module Axlsx
39
40
  require 'axlsx/drawing/pic.rb'
40
41
  require 'axlsx/drawing/hyperlink.rb'
41
42
 
42
- # A Drawing is a canvas for charts. Each worksheet has a single drawing that manages anchors.
43
- # The anchors reference the charts via graphical frames. This is not a trivial relationship so please do follow the advice in the note.
44
- # @note The recommended way to manage drawings is to use the Worksheet.add_chart method.
43
+ require 'axlsx/drawing/vml_drawing.rb'
44
+ require 'axlsx/drawing/vml_shape.rb'
45
+
46
+ # A Drawing is a canvas for charts and images. Each worksheet has a single drawing that manages anchors.
47
+ # The anchors reference the charts or images via graphical frames. This is not a trivial relationship so please do follow the advice in the note.
48
+ # @note The recommended way to manage drawings is to use the Worksheet.add_chart and Worksheet.add_image methods.
45
49
  # @see Worksheet#add_chart
50
+ # @see Worksheet#add_image
46
51
  # @see Chart
47
- # see README for an example of how to create a chart.
52
+ # see examples/example.rb for an example of how to create a chart.
48
53
  class Drawing
49
54
 
50
55
  # The worksheet that owns the drawing
@@ -65,11 +70,17 @@ module Axlsx
65
70
  @anchors = SimpleTypedList.new [TwoCellAnchor, OneCellAnchor]
66
71
  end
67
72
 
68
- # Adds an image to the chart
73
+
74
+ # Adds an image to the chart If th end_at option is specified we create a two cell anchor. By default we use a one cell anchor.
69
75
  # @note The recommended way to manage images is to use Worksheet.add_image. Please refer to that method for documentation.
70
76
  # @see Worksheet#add_image
77
+ # @return [Pic]
71
78
  def add_image(options={})
72
- OneCellAnchor.new(self, options)
79
+ if options[:end_at]
80
+ TwoCellAnchor.new(self, options).add_pic(options)
81
+ else
82
+ OneCellAnchor.new(self, options)
83
+ end
73
84
  @anchors.last.object
74
85
  end
75
86
 
@@ -146,8 +157,9 @@ module Axlsx
146
157
  # @param [String] str
147
158
  # @return [String]
148
159
  def to_xml_string(str = '')
149
- str << '<?xml version="1.0" encoding="UTF-8"?>'
150
- str << '<xdr:wsDr xmlns:xdr="' << XML_NS_XDR << '" xmlns:a="' << XML_NS_A << '" xmlns:c="' << XML_NS_C << '">'
160
+ str << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
161
+ str << '<xdr:wsDr xmlns:xdr="' << XML_NS_XDR << '" xmlns:a="' << XML_NS_A << '">'
162
+
151
163
  anchors.each { |anchor| anchor.to_xml_string(str) }
152
164
  str << '</xdr:wsDr>'
153
165
  end
@@ -32,9 +32,10 @@ module Axlsx
32
32
  # @param [String] str
33
33
  # @return [String]
34
34
  def to_xml_string(str = '')
35
+ # macro attribute should be optional!
35
36
  str << '<xdr:graphicFrame>'
36
37
  str << '<xdr:nvGraphicFramePr>'
37
- str << '<xdr:cNvPr id="2" name="' << chart.title.text << '"/>'
38
+ str << '<xdr:cNvPr id="' << @anchor.drawing.index.to_s << '" name="' << 'item_' << @anchor.drawing.index.to_s << '"/>'
38
39
  str << '<xdr:cNvGraphicFramePr/>'
39
40
  str << '</xdr:nvGraphicFramePr>'
40
41
  str << '<xdr:xfrm>'