caxlsx 2.0.2 → 3.0.4

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 (210) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +125 -30
  3. data/README.md +65 -151
  4. data/Rakefile +9 -11
  5. data/examples/{image1.jpeg → assets/image1.jpeg} +0 -0
  6. data/examples/generate.rb +15 -0
  7. data/lib/axlsx.rb +35 -17
  8. data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
  9. data/lib/axlsx/content_type/content_type.rb +1 -1
  10. data/lib/axlsx/doc_props/app.rb +1 -1
  11. data/lib/axlsx/doc_props/core.rb +5 -5
  12. data/lib/axlsx/drawing/area_chart.rb +99 -0
  13. data/lib/axlsx/drawing/area_series.rb +110 -0
  14. data/lib/axlsx/drawing/axes.rb +1 -1
  15. data/lib/axlsx/drawing/axis.rb +12 -9
  16. data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
  17. data/lib/axlsx/drawing/bar_chart.rb +143 -0
  18. data/lib/axlsx/drawing/bar_series.rb +12 -14
  19. data/lib/axlsx/drawing/bubble_chart.rb +59 -0
  20. data/lib/axlsx/drawing/bubble_series.rb +63 -0
  21. data/lib/axlsx/drawing/cat_axis.rb +5 -5
  22. data/lib/axlsx/drawing/chart.rb +52 -8
  23. data/lib/axlsx/drawing/d_lbls.rb +4 -4
  24. data/lib/axlsx/drawing/drawing.rb +6 -1
  25. data/lib/axlsx/drawing/graphic_frame.rb +3 -3
  26. data/lib/axlsx/drawing/hyperlink.rb +1 -3
  27. data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
  28. data/lib/axlsx/drawing/line_chart.rb +10 -10
  29. data/lib/axlsx/drawing/line_series.rb +32 -3
  30. data/lib/axlsx/drawing/marker.rb +1 -1
  31. data/lib/axlsx/drawing/num_data.rb +4 -4
  32. data/lib/axlsx/drawing/num_data_source.rb +6 -6
  33. data/lib/axlsx/drawing/num_val.rb +3 -1
  34. data/lib/axlsx/drawing/one_cell_anchor.rb +3 -2
  35. data/lib/axlsx/drawing/pic.rb +25 -19
  36. data/lib/axlsx/drawing/picture_locking.rb +1 -3
  37. data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
  38. data/lib/axlsx/drawing/pie_series.rb +6 -6
  39. data/lib/axlsx/drawing/scaling.rb +6 -6
  40. data/lib/axlsx/drawing/scatter_chart.rb +10 -10
  41. data/lib/axlsx/drawing/scatter_series.rb +40 -7
  42. data/lib/axlsx/drawing/ser_axis.rb +2 -2
  43. data/lib/axlsx/drawing/series.rb +3 -3
  44. data/lib/axlsx/drawing/series_title.rb +4 -2
  45. data/lib/axlsx/drawing/str_data.rb +3 -3
  46. data/lib/axlsx/drawing/str_val.rb +3 -1
  47. data/lib/axlsx/drawing/title.rb +23 -4
  48. data/lib/axlsx/drawing/two_cell_anchor.rb +6 -1
  49. data/lib/axlsx/drawing/val_axis.rb +1 -1
  50. data/lib/axlsx/drawing/view_3D.rb +2 -2
  51. data/lib/axlsx/drawing/vml_drawing.rb +1 -1
  52. data/lib/axlsx/package.rb +58 -47
  53. data/lib/axlsx/rels/relationship.rb +27 -26
  54. data/lib/axlsx/rels/relationships.rb +7 -4
  55. data/lib/axlsx/stylesheet/border_pr.rb +2 -2
  56. data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
  57. data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
  58. data/lib/axlsx/stylesheet/cell_style.rb +1 -3
  59. data/lib/axlsx/stylesheet/color.rb +1 -3
  60. data/lib/axlsx/stylesheet/font.rb +11 -3
  61. data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
  62. data/lib/axlsx/stylesheet/num_fmt.rb +10 -3
  63. data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
  64. data/lib/axlsx/stylesheet/styles.rb +7 -7
  65. data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
  66. data/lib/axlsx/util/accessors.rb +6 -6
  67. data/lib/axlsx/util/constants.rb +108 -99
  68. data/lib/axlsx/util/mime_type_utils.rb +11 -0
  69. data/lib/axlsx/util/options_parser.rb +2 -1
  70. data/lib/axlsx/util/serialized_attributes.rb +16 -6
  71. data/lib/axlsx/util/simple_typed_list.rb +28 -52
  72. data/lib/axlsx/util/storage.rb +4 -4
  73. data/lib/axlsx/util/validators.rb +31 -19
  74. data/lib/axlsx/util/zip_command.rb +73 -0
  75. data/lib/axlsx/version.rb +1 -1
  76. data/lib/axlsx/workbook/defined_name.rb +11 -12
  77. data/lib/axlsx/workbook/defined_names.rb +2 -2
  78. data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
  79. data/lib/axlsx/workbook/workbook.rb +36 -20
  80. data/lib/axlsx/workbook/workbook_view.rb +80 -0
  81. data/lib/axlsx/workbook/workbook_views.rb +22 -0
  82. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
  83. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
  84. data/lib/axlsx/workbook/worksheet/break.rb +1 -3
  85. data/lib/axlsx/workbook/worksheet/cell.rb +164 -75
  86. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +63 -43
  87. data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
  88. data/lib/axlsx/workbook/worksheet/cfvos.rb +4 -1
  89. data/lib/axlsx/workbook/worksheet/col.rb +14 -13
  90. data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
  91. data/lib/axlsx/workbook/worksheet/cols.rb +5 -2
  92. data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
  93. data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
  94. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
  95. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
  96. data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
  97. data/lib/axlsx/workbook/worksheet/data_validation.rb +8 -6
  98. data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
  99. data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
  100. data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
  101. data/lib/axlsx/workbook/worksheet/merged_cells.rb +4 -2
  102. data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -0
  103. data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
  104. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
  105. data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
  106. data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
  107. data/lib/axlsx/workbook/worksheet/pivot_table.rb +44 -28
  108. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
  109. data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
  110. data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
  111. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -2
  112. data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -0
  113. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -0
  114. data/lib/axlsx/workbook/worksheet/row.rb +42 -52
  115. data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
  116. data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
  117. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  118. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +21 -3
  119. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
  120. data/lib/axlsx/workbook/worksheet/table.rb +6 -6
  121. data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
  122. data/lib/axlsx/workbook/worksheet/tables.rb +4 -1
  123. data/lib/axlsx/workbook/worksheet/worksheet.rb +76 -81
  124. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +10 -10
  125. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
  126. data/lib/caxlsx.rb +2 -0
  127. data/test/drawing/tc_area_chart.rb +39 -0
  128. data/test/drawing/tc_area_series.rb +71 -0
  129. data/test/drawing/tc_axis.rb +27 -0
  130. data/test/drawing/tc_bar_chart.rb +71 -0
  131. data/test/drawing/tc_bubble_chart.rb +44 -0
  132. data/test/drawing/tc_bubble_series.rb +21 -0
  133. data/test/drawing/tc_chart.rb +23 -10
  134. data/test/drawing/tc_data_source.rb +6 -0
  135. data/test/drawing/tc_drawing.rb +4 -4
  136. data/test/drawing/tc_hyperlink.rb +1 -1
  137. data/test/drawing/tc_line_chart.rb +5 -5
  138. data/test/drawing/tc_line_series.rb +47 -6
  139. data/test/drawing/tc_one_cell_anchor.rb +1 -1
  140. data/test/drawing/tc_pic.rb +11 -15
  141. data/test/drawing/tc_pie_series.rb +2 -1
  142. data/test/drawing/tc_scatter_series.rb +36 -1
  143. data/test/drawing/tc_series_title.rb +21 -0
  144. data/test/drawing/tc_str_val.rb +9 -0
  145. data/test/drawing/tc_title.rb +21 -0
  146. data/test/fixtures/image1.gif +0 -0
  147. data/test/fixtures/image1.jpeg +0 -0
  148. data/test/fixtures/image1.jpg +0 -0
  149. data/test/fixtures/image1.png +0 -0
  150. data/test/fixtures/image1_fake.jpg +0 -0
  151. data/test/rels/tc_relationship.rb +8 -0
  152. data/test/stylesheet/tc_font.rb +14 -2
  153. data/test/stylesheet/tc_styles.rb +29 -3
  154. data/test/tc_axlsx.rb +37 -0
  155. data/test/tc_helper.rb +2 -0
  156. data/test/tc_package.rb +50 -13
  157. data/test/util/tc_mime_type_utils.rb +13 -0
  158. data/test/util/tc_simple_typed_list.rb +2 -3
  159. data/test/util/tc_validators.rb +35 -11
  160. data/test/workbook/tc_defined_name.rb +12 -4
  161. data/test/workbook/tc_shared_strings_table.rb +16 -1
  162. data/test/workbook/tc_workbook.rb +38 -3
  163. data/test/workbook/tc_workbook_view.rb +50 -0
  164. data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
  165. data/test/workbook/worksheet/tc_break.rb +1 -1
  166. data/test/workbook/worksheet/tc_cell.rb +143 -9
  167. data/test/workbook/worksheet/tc_col.rb +18 -3
  168. data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
  169. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  170. data/test/workbook/worksheet/tc_data_validation.rb +11 -11
  171. data/test/workbook/worksheet/tc_header_footer.rb +2 -2
  172. data/test/workbook/worksheet/tc_icon_set.rb +1 -1
  173. data/test/workbook/worksheet/tc_outline_pr.rb +19 -0
  174. data/test/workbook/worksheet/tc_page_setup.rb +3 -3
  175. data/test/workbook/worksheet/tc_pivot_table.rb +21 -6
  176. data/test/workbook/worksheet/tc_print_options.rb +1 -1
  177. data/test/workbook/worksheet/tc_rich_text.rb +44 -0
  178. data/test/workbook/worksheet/tc_rich_text_run.rb +173 -0
  179. data/test/workbook/worksheet/tc_row.rb +24 -2
  180. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
  181. data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
  182. data/test/workbook/worksheet/tc_sheet_pr.rb +26 -4
  183. data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
  184. data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
  185. data/test/workbook/worksheet/tc_table.rb +2 -3
  186. data/test/workbook/worksheet/tc_worksheet.rb +123 -60
  187. metadata +180 -128
  188. data/examples/2010_comments.rb +0 -17
  189. data/examples/anchor_swapping.rb +0 -28
  190. data/examples/auto_filter.rb +0 -16
  191. data/examples/basic_charts.rb +0 -58
  192. data/examples/chart_colors.rb +0 -88
  193. data/examples/colored_links.rb +0 -59
  194. data/examples/conditional_formatting/example_conditional_formatting.rb +0 -74
  195. data/examples/conditional_formatting/getting_barred.rb +0 -37
  196. data/examples/conditional_formatting/hitting_the_high_notes.rb +0 -37
  197. data/examples/conditional_formatting/scaled_colors.rb +0 -39
  198. data/examples/conditional_formatting/stop_and_go.rb +0 -37
  199. data/examples/data_validation.rb +0 -50
  200. data/examples/example.rb +0 -777
  201. data/examples/extractive.rb +0 -45
  202. data/examples/ios_preview.rb +0 -14
  203. data/examples/page_setup.rb +0 -11
  204. data/examples/pivot_table.rb +0 -39
  205. data/examples/sheet_protection.rb +0 -10
  206. data/examples/skydrive/real_example.rb +0 -63
  207. data/examples/styles.rb +0 -66
  208. data/examples/underline.rb +0 -13
  209. data/examples/wrap_text.rb +0 -21
  210. data/lib/axlsx/util/parser.rb +0 -44
data/Rakefile CHANGED
@@ -9,19 +9,17 @@ task :benchmark do
9
9
  end
10
10
 
11
11
  task :gendoc do
12
- #puts 'yard doc generation disabled until JRuby build native extensions for redcarpet or yard removes the dependency.'
13
- system "yardoc"
14
- system "yard stats --list-undoc"
12
+ system "yardoc"
13
+ system "yard stats --list-undoc"
15
14
  end
16
15
 
17
- task :test do
18
- require 'rake/testtask'
19
- Rake::TestTask.new do |t|
20
- t.libs << 'test'
21
- t.test_files = FileList['test/**/tc_*.rb']
22
- t.verbose = false
23
- t.warning = true
24
- end
16
+
17
+ require 'rake/testtask'
18
+ Rake::TestTask.new do |t|
19
+ t.libs << 'test'
20
+ t.test_files = FileList['test/**/tc_*.rb']
21
+ t.verbose = false
22
+ t.warning = true
25
23
  end
26
24
 
27
25
  task :release => :build do
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ files = if !ARGV.empty?
4
+ ARGV.select { |file| File.exist?(file) }
5
+ else
6
+ Dir['*_example.md']
7
+ end
8
+
9
+ files.each do |file|
10
+ puts "Executing #{file.split('.')[0].tr('_', ' ')}"
11
+ code = File.read(file).match(/```ruby(?<code>.+)```/m)[:code]
12
+ unless code.nil?
13
+ eval(['$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"', code].join("\n"))
14
+ end
15
+ end
@@ -1,6 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  require 'htmlentities'
3
3
  require 'axlsx/version.rb'
4
+ require 'mimemagic'
4
5
 
5
6
  require 'axlsx/util/simple_typed_list.rb'
6
7
  require 'axlsx/util/constants.rb'
@@ -8,8 +9,8 @@ require 'axlsx/util/validators.rb'
8
9
  require 'axlsx/util/accessors.rb'
9
10
  require 'axlsx/util/serialized_attributes'
10
11
  require 'axlsx/util/options_parser'
11
- # to be included with parsable intitites.
12
- #require 'axlsx/util/parser.rb'
12
+ require 'axlsx/util/mime_type_utils'
13
+ require 'axlsx/util/zip_command'
13
14
 
14
15
  require 'axlsx/stylesheet/styles.rb'
15
16
 
@@ -53,7 +54,7 @@ module Axlsx
53
54
  cells = sort_cells(cells)
54
55
  reference = "#{cells.first.reference(absolute)}:#{cells.last.reference(absolute)}"
55
56
  if absolute
56
- escaped_name = cells.first.row.worksheet.name.gsub "&apos;", "''"
57
+ escaped_name = cells.first.row.worksheet.name.gsub '&apos;', "''"
57
58
  "'#{escaped_name}'!#{reference}"
58
59
  else
59
60
  reference
@@ -65,7 +66,7 @@ module Axlsx
65
66
  # @param [Array] cells
66
67
  # @return [Array]
67
68
  def self.sort_cells(cells)
68
- cells.sort { |x, y| [x.index, x.row.index] <=> [y.index, y.row.index] }
69
+ cells.sort { |x, y| [x.index, x.row.row_index] <=> [y.index, y.row.row_index] }
69
70
  end
70
71
 
71
72
  #global reference html entity encoding
@@ -88,20 +89,21 @@ module Axlsx
88
89
  # @note This follows the standard spreadsheet convention of naming columns A to Z, followed by AA to AZ etc.
89
90
  # @return [String]
90
91
  def self.col_ref(index)
91
- chars = []
92
+ chars = ''
92
93
  while index >= 26 do
93
- chars << ((index % 26) + 65).chr
94
- index = (index / 26).to_i - 1
94
+ index, char = index.divmod(26)
95
+ chars.prepend((char + 65).chr)
96
+ index -= 1
95
97
  end
96
- chars << (index + 65).chr
97
- chars.reverse.join
98
+ chars.prepend((index + 65).chr)
99
+ chars
98
100
  end
99
101
 
100
102
  # @return [String] The alpha(column)numeric(row) reference for this sell.
101
103
  # @example Relative Cell Reference
102
104
  # ws.rows.first.cells.first.r #=> "A1"
103
105
  def self.cell_r(c_index, r_index)
104
- Axlsx::col_ref(c_index).to_s << (r_index+1).to_s
106
+ col_ref(c_index) << (r_index+1).to_s
105
107
  end
106
108
 
107
109
  # Creates an array of individual cell references based on an excel reference range.
@@ -113,7 +115,7 @@ module Axlsx
113
115
  end_col, end_row = name_to_indices($2)
114
116
  (start_row..end_row).to_a.map do |row_num|
115
117
  (start_col..end_col).to_a.map do |col_num|
116
- "#{col_ref(col_num)}#{row_num+1}"
118
+ cell_r(col_num, row_num)
117
119
  end
118
120
  end
119
121
  end
@@ -127,14 +129,30 @@ module Axlsx
127
129
  s.gsub(/_(.)/){ $1.upcase }
128
130
  end
129
131
 
130
- # returns the provided string with all invalid control charaters
131
- # removed.
132
- # @param [String] str The sting to process
133
- # @return [String]
134
- def self.sanitize(str)
135
- str.gsub(CONTROL_CHAR_REGEX, '')
132
+ # returns the provided string with all invalid control charaters
133
+ # removed.
134
+ # @param [String] str The string to process
135
+ # @return [String]
136
+ def self.sanitize(str)
137
+ if str.frozen?
138
+ str.delete(CONTROL_CHARS)
139
+ else
140
+ str.delete!(CONTROL_CHARS)
141
+ str
136
142
  end
143
+ end
137
144
 
145
+ # If value is boolean return 1 or 0
146
+ # else return the value
147
+ # @param [Object] value The value to process
148
+ # @return [Object]
149
+ def self.booleanize(value)
150
+ if value == true || value == false
151
+ value ? 1 : 0
152
+ else
153
+ value
154
+ end
155
+ end
138
156
 
139
157
  # Instructs the serializer to not try to escape cell value input.
140
158
  # This will give you a huge speed bonus, but if you content has <, > or other xml character data
@@ -24,7 +24,7 @@ module Axlsx
24
24
  # Serialize the contenty type to xml
25
25
  def to_xml_string(node_name = '', str = '')
26
26
  str << "<#{node_name} "
27
- str << instance_values.map { |key, value| '' << Axlsx::camel(key) << '="' << value.to_s << '"' }.join(' ')
27
+ str << instance_values.map { |key, value| Axlsx::camel(key) << '="' << value.to_s << '"' }.join(' ')
28
28
  str << '/>'
29
29
  end
30
30
 
@@ -16,7 +16,7 @@ module Axlsx
16
16
  # @return [String]
17
17
  def to_xml_string(str = '')
18
18
  str << '<?xml version="1.0" encoding="UTF-8"?>'
19
- str << '<Types xmlns="' << XML_NS_T << '">'
19
+ str << ('<Types xmlns="' << XML_NS_T << '">')
20
20
  each { |type| type.to_xml_string(str) }
21
21
  str << '</Types>'
22
22
  end
@@ -222,7 +222,7 @@ module Axlsx
222
222
  # @return [String]
223
223
  def to_xml_string(str = '')
224
224
  str << '<?xml version="1.0" encoding="UTF-8"?>'
225
- str << '<Properties xmlns="' << APP_NS << '" xmlns:vt="' << APP_NS_VT << '">'
225
+ str << ('<Properties xmlns="' << APP_NS << '" xmlns:vt="' << APP_NS_VT << '">')
226
226
  instance_values.each do |key, value|
227
227
  node_name = Axlsx.camel(key)
228
228
  str << "<#{node_name}>#{value}</#{node_name}>"
@@ -25,11 +25,11 @@ module Axlsx
25
25
  # @return [String]
26
26
  def to_xml_string(str = '')
27
27
  str << '<?xml version="1.0" encoding="UTF-8"?>'
28
- str << '<cp:coreProperties xmlns:cp="' << CORE_NS << '" xmlns:dc="' << CORE_NS_DC << '" '
29
- str << 'xmlns:dcmitype="' << CORE_NS_DCMIT << '" xmlns:dcterms="' << CORE_NS_DCT << '" '
30
- str << 'xmlns:xsi="' << CORE_NS_XSI << '">'
31
- str << '<dc:creator>' << self.creator << '</dc:creator>'
32
- str << '<dcterms:created xsi:type="dcterms:W3CDTF">' << (created || Time.now).strftime('%Y-%m-%dT%H:%M:%S') << 'Z</dcterms:created>'
28
+ str << ('<cp:coreProperties xmlns:cp="' << CORE_NS << '" xmlns:dc="' << CORE_NS_DC << '" ')
29
+ str << ('xmlns:dcmitype="' << CORE_NS_DCMIT << '" xmlns:dcterms="' << CORE_NS_DCT << '" ')
30
+ str << ('xmlns:xsi="' << CORE_NS_XSI << '">')
31
+ str << ('<dc:creator>' << self.creator << '</dc:creator>')
32
+ str << ('<dcterms:created xsi:type="dcterms:W3CDTF">' << (created || Time.now).strftime('%Y-%m-%dT%H:%M:%S') << 'Z</dcterms:created>')
33
33
  str << '<cp:revision>0</cp:revision>'
34
34
  str << '</cp:coreProperties>'
35
35
  end
@@ -0,0 +1,99 @@
1
+ # encoding: UTF-8
2
+ module Axlsx
3
+
4
+ # The AreaChart is a two dimentional line chart (who would have guessed?) that you can add to your worksheet.
5
+ # @example Creating a chart
6
+ # # This example creates a line in a single sheet.
7
+ # require "rubygems" # if that is your preferred way to manage gems!
8
+ # require "axlsx"
9
+ #
10
+ # p = Axlsx::Package.new
11
+ # ws = p.workbook.add_worksheet
12
+ # ws.add_row ["This is a chart with no data in the sheet"]
13
+ #
14
+ # chart = ws.add_chart(Axlsx::AreaChart, :start_at=> [0,1], :end_at=>[0,6], :title=>"Most Popular Pets")
15
+ # chart.add_series :data => [1, 9, 10], :labels => ["Slimy Reptiles", "Fuzzy Bunnies", "Rottweiler"]
16
+ #
17
+ # @see Worksheet#add_chart
18
+ # @see Worksheet#add_row
19
+ # @see Chart#add_series
20
+ # @see Series
21
+ # @see Package#serialize
22
+ class AreaChart < Chart
23
+
24
+ # the category axis
25
+ # @return [CatAxis]
26
+ def cat_axis
27
+ axes[:cat_axis]
28
+ end
29
+ alias :catAxis :cat_axis
30
+
31
+ # the category axis
32
+ # @return [ValAxis]
33
+ def val_axis
34
+ axes[:val_axis]
35
+ end
36
+ alias :valAxis :val_axis
37
+
38
+ # must be one of [:percentStacked, :clustered, :standard, :stacked]
39
+ # @return [Symbol]
40
+ attr_reader :grouping
41
+
42
+ # Creates a new line chart object
43
+ # @param [GraphicFrame] frame The workbook that owns this chart.
44
+ # @option options [Cell, String] title
45
+ # @option options [Boolean] show_legend
46
+ # @option options [Symbol] grouping
47
+ # @see Chart
48
+ def initialize(frame, options={})
49
+ @vary_colors = false
50
+ @grouping = :standard
51
+ super(frame, options)
52
+ @series_type = AreaSeries
53
+ @d_lbls = nil
54
+ end
55
+
56
+ # @see grouping
57
+ def grouping=(v)
58
+ RestrictionValidator.validate "AreaChart.grouping", [:percentStacked, :standard, :stacked], v
59
+ @grouping = v
60
+ end
61
+
62
+ # The node name to use in serialization. As AreaChart is used as the
63
+ # base class for Liine3DChart we need to be sure to serialize the
64
+ # chart based on the actual class type and not a fixed node name.
65
+ # @return [String]
66
+ def node_name
67
+ path = self.class.to_s
68
+ if i = path.rindex('::')
69
+ path = path[(i+2)..-1]
70
+ end
71
+ path[0] = path[0].chr.downcase
72
+ path
73
+ end
74
+
75
+ # Serializes the object
76
+ # @param [String] str
77
+ # @return [String]
78
+ def to_xml_string(str = '')
79
+ super(str) do
80
+ str << ("<c:" << node_name << ">")
81
+ str << ('<c:grouping val="' << grouping.to_s << '"/>')
82
+ str << ('<c:varyColors val="' << vary_colors.to_s << '"/>')
83
+ @series.each { |ser| ser.to_xml_string(str) }
84
+ @d_lbls.to_xml_string(str) if @d_lbls
85
+ yield if block_given?
86
+ axes.to_xml_string(str, :ids => true)
87
+ str << ("</c:" << node_name << ">")
88
+ axes.to_xml_string(str)
89
+ end
90
+ end
91
+
92
+ # The axes for this chart. AreaCharts have a category and value
93
+ # axis.
94
+ # @return [Axes]
95
+ def axes
96
+ @axes ||= Axes.new(:cat_axis => CatAxis, :val_axis => ValAxis)
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,110 @@
1
+ # encoding: UTF-8
2
+ module Axlsx
3
+ # A AreaSeries defines the title, data and labels for line charts
4
+ # @note The recommended way to manage series is to use Chart#add_series
5
+ # @see Worksheet#add_chart
6
+ # @see Chart#add_series
7
+ class AreaSeries < Series
8
+
9
+ # The data for this series.
10
+ # @return [ValAxisData]
11
+ attr_reader :data
12
+
13
+ # The labels for this series.
14
+ # @return [CatAxisData]
15
+ attr_reader :labels
16
+
17
+ # The fill color for this series.
18
+ # Red, green, and blue is expressed as sequence of hex digits, RRGGBB. A perceptual gamma of 2.2 is used.
19
+ # @return [String]
20
+ attr_reader :color
21
+
22
+ # show markers on values
23
+ # @return [Boolean]
24
+ attr_reader :show_marker
25
+
26
+ # custom marker symbol
27
+ # @return [String]
28
+ attr_reader :marker_symbol
29
+
30
+ # line smoothing on values
31
+ # @return [Boolean]
32
+ attr_reader :smooth
33
+
34
+ # Creates a new series
35
+ # @option options [Array, SimpleTypedList] data
36
+ # @option options [Array, SimpleTypedList] labels
37
+ # @param [Chart] chart
38
+ def initialize(chart, options={})
39
+ @show_marker = false
40
+ @marker_symbol = options[:marker_symbol] ? options[:marker_symbol] : :default
41
+ @smooth = false
42
+ @labels, @data = nil, nil
43
+ super(chart, options)
44
+ @labels = AxDataSource.new(:data => options[:labels]) unless options[:labels].nil?
45
+ @data = NumDataSource.new(options) unless options[:data].nil?
46
+ end
47
+
48
+ # @see color
49
+ def color=(v)
50
+ @color = v
51
+ end
52
+
53
+ # @see show_marker
54
+ def show_marker=(v)
55
+ Axlsx::validate_boolean(v)
56
+ @show_marker = v
57
+ end
58
+
59
+ # @see marker_symbol
60
+ def marker_symbol=(v)
61
+ Axlsx::validate_marker_symbol(v)
62
+ @marker_symbol = v
63
+ end
64
+
65
+ # @see smooth
66
+ def smooth=(v)
67
+ Axlsx::validate_boolean(v)
68
+ @smooth = v
69
+ end
70
+
71
+ # Serializes the object
72
+ # @param [String] str
73
+ # @return [String]
74
+ def to_xml_string(str = '')
75
+ super(str) do
76
+ if color
77
+ str << '<c:spPr><a:solidFill>'
78
+ str << ('<a:srgbClr val="' << color << '"/>')
79
+ str << '</a:solidFill>'
80
+ str << '<a:ln w="28800">'
81
+ str << '<a:solidFill>'
82
+ str << ('<a:srgbClr val="' << color << '"/>')
83
+ str << '</a:solidFill>'
84
+ str << '</a:ln>'
85
+ str << '<a:round/>'
86
+ str << '</c:spPr>'
87
+ end
88
+
89
+ if !@show_marker
90
+ str << '<c:marker><c:symbol val="none"/></c:marker>'
91
+ elsif @marker_symbol != :default
92
+ str << '<c:marker><c:symbol val="' + @marker_symbol.to_s + '"/></c:marker>'
93
+ end
94
+
95
+ @labels.to_xml_string(str) unless @labels.nil?
96
+ @data.to_xml_string(str) unless @data.nil?
97
+ str << ('<c:smooth val="' << ((smooth) ? '1' : '0') << '"/>')
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ # assigns the data for this series
104
+ def data=(v) DataTypeValidator.validate "Series.data", [NumDataSource], v; @data = v; end
105
+
106
+ # assigns the labels for this series
107
+ def labels=(v) DataTypeValidator.validate "Series.labels", [AxDataSource], v; @labels = v; end
108
+
109
+ end
110
+ end
@@ -32,7 +32,7 @@ module Axlsx
32
32
  if options[:ids]
33
33
  # CatAxis must come first in the XML (for Microsoft Excel at least)
34
34
  sorted = axes.sort_by { |name, axis| axis.kind_of?(CatAxis) ? 0 : 1 }
35
- sorted.inject(str) { |string, axis| string << '<c:axId val="' << axis[1].id.to_s << '"/>' }
35
+ sorted.each { |axis| str << ('<c:axId val="' << axis[1].id.to_s << '"/>') }
36
36
  else
37
37
  axes.each { |axis| axis[1].to_xml_string(str) }
38
38
  end
@@ -150,10 +150,10 @@ module Axlsx
150
150
  # @param [String] str
151
151
  # @return [String]
152
152
  def to_xml_string(str = '')
153
- str << '<c:axId val="' << @id.to_s << '"/>'
153
+ str << ('<c:axId val="' << @id.to_s << '"/>')
154
154
  @scaling.to_xml_string str
155
- str << '<c:delete val="'<< @delete.to_s << '"/>'
156
- str << '<c:axPos val="' << @ax_pos.to_s << '"/>'
155
+ str << ('<c:delete val="' << @delete.to_s << '"/>')
156
+ str << ('<c:axPos val="' << @ax_pos.to_s << '"/>')
157
157
  str << '<c:majorGridlines>'
158
158
  # TODO shape properties need to be extracted into a class
159
159
  if gridlines == false
@@ -165,21 +165,24 @@ module Axlsx
165
165
  end
166
166
  str << '</c:majorGridlines>'
167
167
  @title.to_xml_string(str) unless @title == nil
168
- str << '<c:numFmt formatCode="' << @format_code << '" sourceLinked="1"/>'
168
+ # Need to set sourceLinked to 0 if we're setting a format code on this row
169
+ # otherwise it will never take, as it will always prefer the 'General' formatting
170
+ # of the cells themselves
171
+ str << ('<c:numFmt formatCode="' << @format_code << '" sourceLinked="' << (@format_code.eql?('General') ? '1' : '0') << '"/>')
169
172
  str << '<c:majorTickMark val="none"/>'
170
173
  str << '<c:minorTickMark val="none"/>'
171
- str << '<c:tickLblPos val="' << @tick_lbl_pos.to_s << '"/>'
174
+ str << ('<c:tickLblPos val="' << @tick_lbl_pos.to_s << '"/>')
172
175
  # TODO - this is also being used for series colors
173
176
  # time to extract this into a class spPr - Shape Properties
174
177
  if @color
175
178
  str << '<c:spPr><a:ln><a:solidFill>'
176
- str << '<a:srgbClr val="' << @color << '"/>'
179
+ str << ('<a:srgbClr val="' << @color << '"/>')
177
180
  str << '</a:solidFill></a:ln></c:spPr>'
178
181
  end
179
182
  # some potential value in implementing this in full. Very detailed!
180
- str << '<c:txPr><a:bodyPr rot="' << @label_rotation.to_s << '"/><a:lstStyle/><a:p><a:pPr><a:defRPr/></a:pPr><a:endParaRPr/></a:p></c:txPr>'
181
- str << '<c:crossAx val="' << @cross_axis.id.to_s << '"/>'
182
- str << '<c:crosses val="' << @crosses.to_s << '"/>'
183
+ str << ('<c:txPr><a:bodyPr rot="' << @label_rotation.to_s << '"/><a:lstStyle/><a:p><a:pPr><a:defRPr/></a:pPr><a:endParaRPr/></a:p></c:txPr>')
184
+ str << ('<c:crossAx val="' << @cross_axis.id.to_s << '"/>')
185
+ str << ('<c:crosses val="' << @crosses.to_s << '"/>')
183
186
  end
184
187
 
185
188
  end