caxlsx 2.0.2 → 3.0.4

Sign up to get free protection for your applications and to get access to all the features.
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