write_xlsx 0.70.0 → 0.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.rdoc +7 -1
  4. data/lib/write_xlsx/chart.rb +133 -1713
  5. data/lib/write_xlsx/chart/axis.rb +6 -8
  6. data/lib/write_xlsx/chart/caption.rb +19 -0
  7. data/lib/write_xlsx/chart/scatter.rb +15 -15
  8. data/lib/write_xlsx/chart/series.rb +307 -0
  9. data/lib/write_xlsx/chart/stock.rb +5 -5
  10. data/lib/write_xlsx/version.rb +1 -1
  11. data/lib/write_xlsx/workbook.rb +1 -1
  12. data/lib/write_xlsx/worksheet.rb +2 -2
  13. data/test/chart/test_add_series.rb +113 -115
  14. data/test/chart/test_write_d_lbls.rb +19 -18
  15. data/test/chart/test_write_number_format.rb +4 -4
  16. data/test/helper.rb +13 -0
  17. data/test/perl_output/comments2.xlsx +0 -0
  18. data/test/perl_output/demo.xlsx +0 -0
  19. data/test/regression/images/issue32.jpg +0 -0
  20. data/test/regression/images/issue32.png +0 -0
  21. data/test/regression/images/logo.png +0 -0
  22. data/test/regression/images/mylogo.png +0 -0
  23. data/test/regression/test_chart_area04.rb +44 -0
  24. data/test/regression/test_chart_bar24.rb +1 -2
  25. data/test/regression/test_chart_column04.rb +1 -1
  26. data/test/regression/test_chart_line02.rb +1 -1
  27. data/test/regression/test_chart_scatter07.rb +1 -1
  28. data/test/regression/test_chart_stock02.rb +1 -1
  29. data/test/regression/test_image10.rb +24 -0
  30. data/test/regression/test_image11.rb +24 -0
  31. data/test/regression/test_image12.rb +27 -0
  32. data/test/regression/test_image13.rb +27 -0
  33. data/test/regression/test_image14.rb +29 -0
  34. data/test/regression/test_image15.rb +29 -0
  35. data/test/regression/test_image16.rb +24 -0
  36. data/test/regression/test_image17.rb +27 -0
  37. data/test/regression/test_image18.rb +27 -0
  38. data/test/regression/xlsx_files/image10.xlsx +0 -0
  39. data/test/regression/xlsx_files/image11.xlsx +0 -0
  40. data/test/regression/xlsx_files/image12.xlsx +0 -0
  41. data/test/regression/xlsx_files/image13.xlsx +0 -0
  42. data/test/regression/xlsx_files/image14.xlsx +0 -0
  43. data/test/regression/xlsx_files/image15.xlsx +0 -0
  44. data/test/regression/xlsx_files/image16.xlsx +0 -0
  45. data/test/regression/xlsx_files/image17.xlsx +0 -0
  46. data/test/regression/xlsx_files/image18.xlsx +0 -0
  47. data/test/republic.png +0 -0
  48. data/test/test_example_match.rb +2 -4
  49. data/test/workbook/test_workbook_01.rb +1 -1
  50. data/test/workbook/test_workbook_02.rb +1 -1
  51. data/test/workbook/test_workbook_03.rb +1 -1
  52. data/write_xlsx.gemspec +1 -1
  53. metadata +53 -30
  54. data/html/en/doc_en.html +0 -7765
  55. data/html/index.html +0 -16
  56. data/html/style.css +0 -433
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3bc15768bd6ed7228ff33b5a332b90c0f996b8e0
4
- data.tar.gz: 3e3a148d8c17d061b6fb8f11c82a0a09e87645a8
3
+ metadata.gz: 104355ee8489de1e6777be4649f8ac0c6003e094
4
+ data.tar.gz: 3f96a27434ef9282fcd9701a47fedfcfafe05318
5
5
  SHA512:
6
- metadata.gz: bdaf8c7ef0d30401256fd972b5b27ebc85e6a07bc5e06279ace3a0e5befb65dfc3fe7e9c54e4a53e0c615a16123ff596081a2619bfd99b20872d7aa59d35ba20
7
- data.tar.gz: 4c76548dbb4d508f6c5801eb772a717a9f1a18d803f650d310428f705b6d16d6343f5c1b31d6265b570eace0d603ceb9119c39a0c09b5590dcfd4d1f6753d36b
6
+ metadata.gz: 5f416e1dd40635ea678d10a8561bde047615ddb1ad2610bd63693b1f92362edefac594d055ff063568a97b1f1df592e94c007e9faae7af231bcb91b814ebc80c
7
+ data.tar.gz: 92e174651ff4dd4c54e3501f583b7b206e9ab2a2b20ca6366137dd8ba65ef6bc48b8f001f6fda89f476875a9161f18c3c202f5cae70b84adb35e30c5df017e67
data/.gitignore CHANGED
@@ -4,6 +4,7 @@
4
4
  .yardoc
5
5
  Gemfile.lock
6
6
  InstalledFiles
7
+ _site
7
8
  _yardoc
8
9
  coverage
9
10
  doc/
data/README.rdoc CHANGED
@@ -1,9 +1,11 @@
1
1
  = write_xlsx
2
2
 
3
- gem to create a new file in the Excel 2007+ XLSX format, and you can use the same interface as writeexcel gem. write_xlsx is converted from Perl's module Excel::Writer::XLSX-0.65, https://github.com/jmcnamara/excel-writer-xlsx .
3
+ gem to create a new file in the Excel 2007+ XLSX format, and you can use the same interface as writeexcel gem. write_xlsx is converted from Perl's module Excel::Writer::XLSX-0.70, https://github.com/jmcnamara/excel-writer-xlsx .
4
4
 
5
5
  == Description
6
6
 
7
+ Reference doc : http://cxn03651.github.io/write_xlsx/
8
+
7
9
  The WriteXLSX supports the following features:
8
10
  * Multiple worksheets
9
11
  * Strings and numbers
@@ -75,6 +77,10 @@ the first worksheet in an Excel XML spreadsheet called ruby.xlsx:
75
77
  workbook.close
76
78
 
77
79
  == Recent change
80
+ 2013-09-02 v0.71.0
81
+ Fixed issue in image handling.
82
+ Added fix to ensure formula calculation on load regardless of Excel version.
83
+
78
84
  2013-07-13 v0.70.0
79
85
  Fix for rendering images that are the same size as cell boundaries.
80
86
  Fix for inaccurate column width calculation.
@@ -2,6 +2,8 @@
2
2
  require 'write_xlsx/package/xml_writer_simple'
3
3
  require 'write_xlsx/utility'
4
4
  require 'write_xlsx/chart/axis'
5
+ require 'write_xlsx/chart/caption'
6
+ require 'write_xlsx/chart/series'
5
7
 
6
8
  module Writexlsx
7
9
  class Table
@@ -33,467 +35,6 @@ def attributes
33
35
  end
34
36
  end
35
37
 
36
- # ==SYNOPSIS
37
- #
38
- # To create a simple Excel file with a chart using WriteXLSX:
39
- #
40
- # require 'rubygems'
41
- # require 'write_xlsx'
42
- #
43
- # workbook = WriteXLSX.new('chart.xlsx')
44
- # worksheet = workbook.add_worksheet
45
- #
46
- # # Add the worksheet data the chart refers to.
47
- # data = [
48
- # [ 'Category', 2, 3, 4, 5, 6, 7 ],
49
- # [ 'Value', 1, 4, 5, 2, 1, 5 ]
50
- # ]
51
- #
52
- # worksheet.write( 'A1', data )
53
- #
54
- # # Add a worksheet chart.
55
- # chart = workbook.add_chart( type => 'column' )
56
- #
57
- # # Configure the chart.
58
- # chart.add_series(
59
- # :categories => '=Sheet1!$A$2:$A$7',
60
- # :values => '=Sheet1!$B$2:$B$7'
61
- # )
62
- #
63
- # workbook.close
64
- #
65
- # ==DESCRIPTION
66
- #
67
- # The Chart is an abstract base class for modules that implement
68
- # charts in WriteXLSX. The information below is applicable to all of
69
- # the available subclasses.
70
- #
71
- # The Chart isn't used directly. A chart object is created via
72
- # the {WriteXLXS#add_chart()}
73
- # method where the chart type is specified:
74
- #
75
- # chart = workbook.add_chart( :type => 'column' )
76
- #
77
- # Currently the supported chart types are:
78
- #
79
- # ===area
80
- # Creates an Area (filled line) style chart. See Writexlsx::Chart::Area.
81
- #
82
- # ===bar
83
- # Creates a Bar style (transposed histogram) chart. See Writexlsx::Chart::Bar.
84
- #
85
- # ===column
86
- # Creates a Column style (histogram) chart. See Writexlsx::Chart::Column.
87
- #
88
- # ===line
89
- # Creates a Line style chart. See Writexlsx::Chart::Line.
90
- #
91
- # ===pie
92
- # Creates a Pie style chart. See Writexlsx::Chart::Pie.
93
- #
94
- # ===scatter
95
- # Creates a Scatter style chart. See Writexlsx::Chart::Scatter.
96
- #
97
- # ===stock
98
- # Creates a Stock style chart. See Writexlsx::Chart::Stock.
99
- #
100
- # ===radar
101
- # Creates a Radar style chart. See Writexlsx::Chart::Radar.
102
- #
103
- # Chart subtypes are also supported in some cases:
104
- #
105
- # workbook.add_chart(:type => 'bar', :subtype => 'stacked')
106
- #
107
- # The currently available subtypes are:
108
- #
109
- # area
110
- # stacked
111
- # percent_stacked
112
- #
113
- # bar
114
- # stacked
115
- # percent_stacked
116
- #
117
- # column
118
- # stacked
119
- # percent_stacked
120
- #
121
- # scatter
122
- # straight_with_markers
123
- # straight
124
- # smooth_with_markers
125
- # smooth
126
- #
127
- # radar
128
- # with_markers
129
- # filled
130
- #
131
- # ==CHART FORMATTING
132
- #
133
- # The following chart formatting properties can be set for any chart object
134
- # that they apply to (and that are supported by WriteXLSX) such
135
- # as chart lines, column fill areas, plot area borders, markers and other
136
- # chart elements documented above.
137
- #
138
- # line
139
- # border
140
- # fill
141
- # marker
142
- # trendline
143
- # data_labels
144
- #
145
- # Chart formatting properties are generally set using hash refs.
146
- #
147
- # chart.add_series(
148
- # :values => '=Sheet1!$B$1:$B$5',
149
- # :line => { color => 'blue' }
150
- # )
151
- #
152
- # In some cases the format properties can be nested. For example a marker
153
- # may contain border and fill sub-properties.
154
- #
155
- # chart.add_series(
156
- # :values => '=Sheet1!$B$1:$B$5',
157
- # :line => { color => 'blue' },
158
- # :marker => {
159
- # :type => 'square',
160
- # :size => 5,
161
- # :border => { color => 'red' },
162
- # :fill => { color => 'yellow' }
163
- # }
164
- # )
165
- #
166
- # ===Line
167
- #
168
- # The line format is used to specify properties of line objects that appear
169
- # in a chart such as a plotted line on a chart or a border.
170
- #
171
- # The following properties can be set for line formats in a chart.
172
- #
173
- # none
174
- # color
175
- # width
176
- # dash_type
177
- # The none property is uses to turn the line off (it is always on by default
178
- # except in Scatter charts). This is useful if you wish to plot a series
179
- # with markers but without a line.
180
- #
181
- # chart.add_series(
182
- # :values => '=Sheet1!$B$1:$B$5',
183
- # :line => { none => 1 }
184
- # )
185
- # The color property sets the color of the line.
186
- #
187
- # chart.add_series(
188
- # :values => '=Sheet1!$B$1:$B$5',
189
- # :line => { color => 'red' }
190
- # )
191
- # The available colors are shown in the main WriteXLSX documentation.
192
- # It is also possible to set the color of a line with a HTML style RGB color:
193
- #
194
- # chart.add_series(
195
- # :line => { color => '#FF0000' }
196
- # )
197
- # The width property sets the width of the line. It should be specified
198
- # in increments of 0.25 of a point as in Excel.
199
- #
200
- # chart.add_series(
201
- # :values => '=Sheet1!$B$1:$B$5',
202
- # :line => { width => 3.25 }
203
- # )
204
- # The dash_type property sets the dash style of the line.
205
- #
206
- # chart->add_series(
207
- # :values => '=Sheet1!$B$1:$B$5',
208
- # :line => { dash_type => 'dash_dot' }
209
- # )
210
- # The following dash_type values are available. They are shown in the
211
- # order that they appear in the Excel dialog.
212
- #
213
- # solid
214
- # round_dot
215
- # square_dot
216
- # dash
217
- # dash_dot
218
- # long_dash
219
- # long_dash_dot
220
- # long_dash_dot_dot
221
- # The default line style is solid.
222
- #
223
- # More than one line property can be specified at time:
224
- #
225
- # chart.add_series(
226
- # :values => '=Sheet1!$B$1:$B$5',
227
- # :line => {
228
- # :color => 'red',
229
- # :width => 1.25,
230
- # :dash_type => 'square_dot'
231
- # }
232
- # )
233
- # ===Border
234
- #
235
- # The border property is a synonym for line.
236
- #
237
- # It can be used as a descriptive substitute for line in chart types such
238
- # as Bar and Column that have a border and fill style rather than a line
239
- # style. In general chart objects with a border property will also have a
240
- # fill property.
241
- #
242
- # ===Fill
243
- #
244
- # The fill format is used to specify filled areas of chart objects such
245
- # as the interior of a column or the background of the chart itself.
246
- #
247
- # The following properties can be set for fill formats in a chart.
248
- #
249
- # none
250
- # color
251
- # The none property is uses to turn the fill property off (it is
252
- # generally on by default).
253
- #
254
- # chart.add_series(
255
- # :values => '=Sheet1!$B$1:$B$5',
256
- # :fill => { none => 1 }
257
- # )
258
- # The color property sets the color of the fill area.
259
- #
260
- # chart.add_series(
261
- # :values => '=Sheet1!$B$1:$B$5',
262
- # :fill => { color => 'red' }
263
- # )
264
- # The available colors are shown in the main WriteXLSX documentation.
265
- # It is also possible to set the color of a fill with a HTML style RGB color:
266
- #
267
- # chart.add_series(
268
- # :fill => { color => '#FF0000' }
269
- # )
270
- # The fill format is generally used in conjunction with a border format
271
- # which has the same properties as a line format.
272
- #
273
- # chart.add_series(
274
- # :values => '=Sheet1!$B$1:$B$5',
275
- # :border => { color => 'red' },
276
- # :fill => { color => 'yellow' }
277
- # )
278
- # ===Marker
279
- #
280
- # The marker format specifies the properties of the markers used to
281
- # distinguish series on a chart. In general only Line and Scatter
282
- # chart types and trendlines use markers.
283
- #
284
- # The following properties can be set for marker formats in a chart.
285
- #
286
- # type
287
- # size
288
- # border
289
- # fill
290
- # The type property sets the type of marker that is used with a series.
291
- #
292
- # chart.add_series(
293
- # :values => '=Sheet1!$B$1:$B$5',
294
- # :marker => { type => 'diamond' }
295
- # )
296
- # The following type properties can be set for marker formats in a chart.
297
- # These are shown in the same order as in the Excel format dialog.
298
- #
299
- # automatic
300
- # none
301
- # square
302
- # diamond
303
- # triangle
304
- # x
305
- # star
306
- # short_dash
307
- # long_dash
308
- # circle
309
- # plus
310
- # The automatic type is a special case which turns on a marker using the
311
- # default marker style for the particular series number.
312
- #
313
- # chart.add_series(
314
- # :values => '=Sheet1!$B$1:$B$5',
315
- # :marker => { type => 'automatic' }
316
- # )
317
- # If automatic is on then other marker properties such as size,
318
- # border or fill cannot be set.
319
- #
320
- # The size property sets the size of the marker and is generally used in
321
- # conjunction with type.
322
- #
323
- # chart.add_series(
324
- # :values => '=Sheet1!$B$1:$B$5',
325
- # :marker => { type => 'diamond', size => 7 }
326
- # )
327
- # Nested border and fill properties can also be set for a marker.
328
- # These have the same sub-properties as shown above.
329
- #
330
- # chart.add_series(
331
- # :values => '=Sheet1!$B$1:$B$5',
332
- # :marker => {
333
- # :type => 'square',
334
- # :size => 5,
335
- # :border => { color => 'red' },
336
- # :fill => { color => 'yellow' }
337
- # }
338
- # )
339
- # ===Trendline
340
- #
341
- # A trendline can be added to a chart series to indicate trends in the data
342
- # such as a moving average or a polynomial fit.
343
- #
344
- # The following properties can be set for trendline formats in a chart.
345
- #
346
- # type
347
- # order (for polynomial trends)
348
- # period (for moving average)
349
- # forward (for all except moving average)
350
- # backward (for all except moving average)
351
- # name
352
- # line
353
- # The type property sets the type of trendline in the series.
354
- #
355
- # chart.add_series(
356
- # :values => '=Sheet1!$B$1:$B$5',
357
- # :trendline => { type => 'linear' }
358
- # )
359
- # The available trendline types are:
360
- #
361
- # exponential
362
- # linear
363
- # log
364
- # moving_average
365
- # polynomial
366
- # power
367
- # A polynomial trendline can also specify the order of the polynomial.
368
- # The default value is 2.
369
- #
370
- # chart.add_series(
371
- # :values => '=Sheet1!$B$1:$B$5',
372
- # :trendline => {
373
- # :type => 'polynomial',
374
- # :order => 3
375
- # }
376
- # )
377
- # A moving_average trendline can also the period of the moving average.
378
- # The default value is 2.
379
- #
380
- # chart.add_series(
381
- # :values => '=Sheet1!$B$1:$B$5',
382
- # :trendline => {
383
- # :type => 'moving_average',
384
- # :period => 3
385
- # }
386
- # )
387
- # The forward and backward properties set the forecast period of the
388
- # trendline.
389
- #
390
- # chart.add_series(
391
- # :values => '=Sheet1!$B$1:$B$5',
392
- # :trendline => {
393
- # :type => 'linear',
394
- # :forward => 0.5,
395
- # :backward => 0.5
396
- # }
397
- # )
398
- # The name property sets an optional name for the trendline that will
399
- # appear in the chart legend. If it isn't specified the Excel default
400
- # name will be displayed. This is usually a combination of the trendline
401
- # type and the series name.
402
- #
403
- # chart.add_series(
404
- # :values => '=Sheet1!$B$1:$B$5',
405
- # :trendline => {
406
- # :type => 'linear',
407
- # :name => 'Interpolated trend'
408
- # }
409
- # )
410
- # Several of these properties can be set in one go:
411
- #
412
- # chart.add_series(
413
- # :values => '=Sheet1!$B$1:$B$5',
414
- # :trendline => {
415
- # :type => 'linear',
416
- # :name => 'My trend name',
417
- # :forward => 0.5,
418
- # :backward => 0.5,
419
- # :line => {
420
- # :color => 'red',
421
- # :width => 1,
422
- # :dash_type => 'long_dash'
423
- # }
424
- # }
425
- # )
426
- # Trendlines cannot be added to series in a stacked chart or pie chart or
427
- # (when implemented) to 3-D, radar, surface, or doughnut charts.
428
- #
429
- # ==Data Labels
430
- #
431
- # Data labels can be added to a chart series to indicate the values of
432
- # the plotted data points.
433
- #
434
- # The following properties can be set for data_labels formats in a chart.
435
- #
436
- # :value
437
- # :category
438
- # :series_name
439
- # :position
440
- # :leader_lines
441
- # :percentage
442
- #
443
- # The value property turns on the Value data label for a series.
444
- #
445
- # chart.add_series(
446
- # :values => '=Sheet1!$B$1:$B$5',
447
- # :data_labels => { :value => 1 }
448
- # )
449
- # The category property turns on the Category Name data label for a series.
450
- #
451
- # chart.add_series(
452
- # :values => '=Sheet1!$B$1:$B$5',
453
- # :data_labels => { :category => 1 }
454
- # )
455
- # The series_name property turns on the Series Name data label for a series.
456
- #
457
- # chart.add_series(
458
- # :values => '=Sheet1!$B$1:$B$5',
459
- # :data_labels => { :series_name => 1 }
460
- # )
461
- # The C<position> property is used to position the data label for a series.
462
- #
463
- # chart.add_series(
464
- # :values => '=Sheet1!$B$1:$B$5',
465
- # :data_labels => { :value => 1, :position => 'center' }
466
- # )
467
- #
468
- # Valid positions are:
469
- #
470
- # :center
471
- # :right
472
- # :left
473
- # :top
474
- # :bottom
475
- # :above # Same as top
476
- # :below # Same as bottom
477
- # :inside_end # Pie chart mainly.
478
- # :outside_end # Pie chart mainly.
479
- # :best_fit # Pie chart mainly.
480
- #
481
- # The C<percentage> property is used to turn on the I<Percentage>
482
- # for the data label for a series. It is mainly used for pie charts.
483
- #
484
- # chart.add_series(
485
- # :values => '=Sheet1!$B$1:$B$5',
486
- # :data_labels => { :percentage => 1 }
487
- # )
488
- #
489
- # The C<leader_lines> property is used to turn on I<Leader Lines>
490
- # for the data label for a series. It is mainly used for pie charts.
491
- #
492
- # chart.add_series(
493
- # :values => '=Sheet1!$B$1:$B$5',
494
- # :data_labels => { :value => 1, :leader_lines => 1 }
495
- # )
496
- #
497
38
  class Chart
498
39
  include Writexlsx::Utility
499
40
 
@@ -560,10 +101,11 @@ def initialize(subtype) # :nodoc:
560
101
  @protection = 0
561
102
  @chartarea = {}
562
103
  @plotarea = {}
563
- @x_axis = Axis.new
564
- @y_axis = Axis.new
565
- @x2_axis = Axis.new
566
- @y2_axis = Axis.new
104
+ @title = Caption.new(self)
105
+ @x_axis = Axis.new(self)
106
+ @y_axis = Axis.new(self)
107
+ @x2_axis = Axis.new(self)
108
+ @y2_axis = Axis.new(self)
567
109
  @name = ''
568
110
  @show_blanks = 'gap'
569
111
  @show_hidden_data = false
@@ -620,468 +162,6 @@ def assemble_xml_file # :nodoc:
620
162
  #
621
163
  # Add a series and it's properties to a chart.
622
164
  #
623
- # In an Excel chart a "series" is a collection of information such as
624
- # values, x-axis labels and the formatting that define which data is
625
- # plotted.
626
- #
627
- # With a WriteXLSX chart object the add_series() method is used to
628
- # set the properties for a series:
629
- #
630
- # chart.add_series(
631
- # :categories => '=Sheet1!$A$2:$A$10', # Optional.
632
- # :values => '=Sheet1!$B$2:$B$10', # Required.
633
- # :line => { :color => 'blue' }
634
- # )
635
- #
636
- # The properties that can be set are:
637
- #
638
- # ===:values
639
- # This is the most important property of a series and must be set
640
- # for every chart object. It links the chart with the worksheet data
641
- # that it displays. A formula or array ref can be used for the
642
- # data range, see below.
643
- #
644
- # ===:categories
645
- # This sets the chart category labels. The category is more or less
646
- # the same as the X-axis. In most chart types the categories property
647
- # is optional and the chart will just assume a sequential series
648
- # from 1 .. n.
649
- #
650
- # ===:name
651
- # Set the name for the series. The name is displayed in the chart
652
- # legend and in the formula bar. The name property is optional and
653
- # if it isn't supplied it will default to Series 1 .. n.
654
- #
655
- # ===:line
656
- # Set the properties of the series line type such as colour and
657
- # width. See the "CHART FORMATTING" section below.
658
- #
659
- # ===:border
660
- # Set the border properties of the series such as colour and style.
661
- # See the "CHART FORMATTING" section below.
662
- #
663
- # ===:fill
664
- # Set the fill properties of the series such as colour. See the
665
- # "CHART FORMATTING"
666
- # section below.
667
- #
668
- # ==:marker
669
- # Set the properties of the series marker such as style and color.
670
- # See the "CHART FORMATTING" section below.
671
- #
672
- # ===:trendline
673
- # Set the properties of the series trendline such as linear,
674
- # polynomial and moving average types. See the "CHART FORMATTING"
675
- # section below.
676
- #
677
- # ===:data_labels
678
- # Set data labels for the series. See the "CHART FORMATTING"
679
- # section below.
680
- #
681
- # ===:invert_if_negative
682
- # Invert the fill colour for negative values. Usually only applicable
683
- # to column and bar charts.
684
- #
685
- # ===:overlap
686
- # Set the overlap between series in a Bar/Column chart. The range is
687
- # <tt>+/- 100</tt>. Default is 0.
688
- #
689
- # :overlap => 20
690
- #
691
- # Note, it is only necessary to apply this property to one series of the chart.
692
- #
693
- # ===:gap
694
- # Set the gap between series in a Bar/Column chart. The range is
695
- # <tt>0 to 500</tt>. Default is 150.
696
- #
697
- # :gap => 200,
698
- #
699
- # Note, it is only necessary to apply this property to one series of the
700
- # chart.
701
- #
702
- # The categories and values can take either a range formula such
703
- # as <tt>=Sheet1!$A$2:$A$7</tt> or, more usefully when generating the range
704
- # programmatically, an array ref with zero indexed row/column values:
705
- #
706
- # [ sheetname, row_start, row_end, col_start, col_end ]
707
- #
708
- # The following are equivalent:
709
- #
710
- # chart.add_series( categories => '=Sheet1!$A$2:$A$7' ) # Same as ...
711
- # chart.add_series( categories => [ 'Sheet1', 1, 6, 0, 0 ] ) # Zero-indexed.
712
- #
713
- # You can add more than one series to a chart. In fact, some chart
714
- # types such as stock require it. The series numbering and order in
715
- # the Excel chart will be the same as the order in which that are added
716
- # in WriteXLSX.
717
- #
718
- # # Add the first series.
719
- # chart.add_series(
720
- # :categories => '=Sheet1!$A$2:$A$7',
721
- # :values => '=Sheet1!$B$2:$B$7',
722
- # :name => 'Test data series 1'
723
- # )
724
- #
725
- # # Add another series. Same categories. Different range values.
726
- # chart.add_series(
727
- # :categories => '=Sheet1!$A$2:$A$7',
728
- # :values => '=Sheet1!$C$2:$C$7',
729
- # :name => 'Test data series 2'
730
- # )
731
- #
732
- # ==SERIES OPTIONS
733
- #
734
- # This section details the following properties of add_series() in more
735
- # detail:
736
- #
737
- # marker
738
- # trendline
739
- # y_error_bars
740
- # x_error_bars
741
- # data_labels
742
- # points
743
- #
744
- # ===Marker
745
- #
746
- # The marker format specifies the properties of the markers used to
747
- # distinguish series on a chart. In general only Line and Scatter chart
748
- # types and trendlines use markers.
749
- #
750
- # The following properties can be set for marker formats in a chart.
751
- #
752
- # type
753
- # size
754
- # border
755
- # fill
756
- #
757
- # The type property sets the type of marker that is used with a series.
758
- #
759
- # chart.add_series(
760
- # :values => '=Sheet1!$B$1:$B$5',
761
- # :marker => { :type => 'diamond' }
762
- # )
763
- #
764
- # The following type properties can be set for marker formats in a chart.
765
- # These are shown in the same order as in the Excel format dialog.
766
- #
767
- # automatic
768
- # none
769
- # square
770
- # diamond
771
- # triangle
772
- # x
773
- # star
774
- # short_dash
775
- # long_dash
776
- # circle
777
- # plus
778
- #
779
- # The automatic type is a special case which turns on a marker using the
780
- # default marker style for the particular series number.
781
- #
782
- # chart.add_series(
783
- # :values => '=Sheet1!$B$1:$B$5',
784
- # :marker => { :type => 'automatic' }
785
- # )
786
- #
787
- # If automatic is on then other marker properties such as size, border or
788
- # fill cannot be set.
789
- #
790
- # The size property sets the size of the marker and is generally used in
791
- # conjunction with type.
792
- #
793
- # chart.add_series(
794
- # :values => '=Sheet1!$B$1:$B$5',
795
- # :marker => { :type => 'diamond', :size => 7 }
796
- # )
797
- #
798
- # Nested border and fill properties can also be set for a marker. See the
799
- # "CHART FORMATTING"
800
- # section below.
801
- #
802
- # chart.add_series(
803
- # :values => '=Sheet1!$B$1:$B$5',
804
- # :marker => {
805
- # :type => 'square',
806
- # :size => 5,
807
- # :border => { :color => 'red' },
808
- # :fill => { :color => 'yellow' }
809
- # }
810
- # )
811
- #
812
- # ===Trendline
813
- #
814
- # A trendline can be added to a chart series to indicate trends in the data
815
- # such as a moving average or a polynomial fit.
816
- #
817
- # The following properties can be set for trendlines in a chart series.
818
- #
819
- # type
820
- # order (for polynomial trends)
821
- # period (for moving average)
822
- # forward (for all except moving average)
823
- # backward (for all except moving average)
824
- # name
825
- # line
826
- #
827
- # The type property sets the type of trendline in the series.
828
- #
829
- # chart.add_series(
830
- # :values => '=Sheet1!$B$1:$B$5',
831
- # :trendline => { :type => 'linear' }
832
- # )
833
- #
834
- # The available trendline types are:
835
- #
836
- # exponential
837
- # linear
838
- # log
839
- # moving_average
840
- # polynomial
841
- # power
842
- #
843
- # A polynomial trendline can also specify the order of the polynomial.
844
- # The default value is 2.
845
- #
846
- # chart.add_series(
847
- # :values => '=Sheet1!$B$1:$B$5',
848
- # :trendline => {
849
- # :type => 'polynomial',
850
- # :order => 3
851
- # }
852
- # )
853
- #
854
- # A moving_average trendline can also specify the period of the moving
855
- # average. The default value is 2.
856
- #
857
- # chart.add_series(
858
- # :values => '=Sheet1!$B$1:$B$5',
859
- # :trendline => {
860
- # :type => 'moving_average',
861
- # :period => 3,
862
- # }
863
- # )
864
- #
865
- # The forward and backward properties set the forecast period of the
866
- # trendline.
867
- #
868
- # chart.add_series(
869
- # :values => '=Sheet1!$B$1:$B$5',
870
- # :trendline => {
871
- # :type => 'linear',
872
- # :forward => 0.5,
873
- # :backward => 0.5
874
- # }
875
- # )
876
- #
877
- # The name property sets an optional name for the trendline that will
878
- # appear in the chart legend. If it isn't specified the Excel default
879
- # name will be displayed. This is usually a combination of the
880
- # trendline type and the series name.
881
- #
882
- # chart.add_series(
883
- # :values => '=Sheet1!$B$1:$B$5',
884
- # :trendline => {
885
- # :type => 'linear',
886
- # :name => 'Interpolated trend'
887
- # }
888
- # )
889
- #
890
- # Several of these properties can be set in one go:
891
- #
892
- # chart.add_series(
893
- # :values => '=Sheet1!$B$1:$B$5',
894
- # :trendline => {
895
- # :type => 'linear',
896
- # :name => 'My trend name',
897
- # :forward => 0.5,
898
- # :backward => 0.5,
899
- # :line => {
900
- # :color => 'red',
901
- # :width => 1,
902
- # :dash_type => 'long_dash'
903
- # }
904
- # }
905
- # )
906
- #
907
- # Trendlines cannot be added to series in a stacked chart or pie chart,
908
- # radar chart or (when implemented) to 3D, surface, or doughnut charts.
909
- #
910
- # ===Error Bars
911
- #
912
- # Error bars can be added to a chart series to indicate error bounds in the
913
- # data. The error bars can be vertical y_error_bars (the most common type)
914
- # or horizontal x_error_bars (for Bar and Scatter charts only).
915
- #
916
- # The following properties can be set for error bars in a chart series.
917
- #
918
- # type
919
- # value (for all types except standard error)
920
- # direction
921
- # end_style
922
- # line
923
- #
924
- # The type property sets the type of error bars in the series.
925
- #
926
- # chart.add_series(
927
- # :values => '=Sheet1!$B$1:$B$5',
928
- # :y_error_bars => { :type => 'standard_error' }
929
- # )
930
- #
931
- # The available error bars types are available:
932
- #
933
- # fixed
934
- # percentage
935
- # standard_deviation
936
- # standard_error
937
- #
938
- # Note, the "custom" error bars type is not supported.
939
- #
940
- # All error bar types, except for standard_error must also have a value
941
- # associated with it for the error bounds:
942
- #
943
- # chart.add_series(
944
- # :values => '=Sheet1!$B$1:$B$5',
945
- # :y_error_bars => {
946
- # :type => 'percentage',
947
- # :value => 5
948
- # }
949
- # )
950
- #
951
- # The direction property sets the direction of the error bars. It should
952
- # be one of the following:
953
- #
954
- # plus # Positive direction only.
955
- # minus # Negative direction only.
956
- # both # Plus and minus directions, The default.
957
- #
958
- # The end_style property sets the style of the error bar end cap. The
959
- # options are 1 (the default) or 0 (for no end cap):
960
- #
961
- # chart.add_series(
962
- # :values => '=Sheet1!$B$1:$B$5',
963
- # :y_error_bars => {
964
- # :type => 'fixed',
965
- # :value => 2,
966
- # :end_style => 0,
967
- # :direction => 'minus'
968
- # }
969
- # )
970
- #
971
- # ===Data Labels
972
- #
973
- # Data labels can be added to a chart series to indicate the values of the
974
- # plotted data points.
975
- #
976
- # The following properties can be set for data_labels formats in a chart.
977
- #
978
- # value
979
- # category
980
- # series_name
981
- # position
982
- # leader_lines
983
- # percentage
984
- #
985
- # The value property turns on the Value data label for a series.
986
- #
987
- # chart.add_series(
988
- # :values => '=Sheet1!$B$1:$B$5',
989
- # :data_labels => { :value => 1 }
990
- # )
991
- # The category property turns on the Category Name data label for a series.
992
- #
993
- # chart.add_series(
994
- # :values => '=Sheet1!$B$1:$B$5',
995
- # :data_labels => { :category => 1 }
996
- # )
997
- #
998
- # The series_name property turns on the Series Name data label for a series.
999
- #
1000
- # chart.add_series(
1001
- # :values => '=Sheet1!$B$1:$B$5',
1002
- # :data_labels => { :series_name => 1 }
1003
- # )
1004
- #
1005
- # The position property is used to position the data label for a series.
1006
- #
1007
- # chart.add_series(
1008
- # :values => '=Sheet1!$B$1:$B$5',
1009
- # :data_labels => { :value => 1, :position => 'center' },
1010
- # )
1011
- #
1012
- # Valid positions are:
1013
- #
1014
- # center
1015
- # right
1016
- # left
1017
- # top
1018
- # bottom
1019
- # above # Same as top
1020
- # below # Same as bottom
1021
- # inside_end # Pie chart mainly.
1022
- # outside_end # Pie chart mainly.
1023
- # best_fit # Pie chart mainly.
1024
- #
1025
- # The percentage property is used to turn on the display of data labels as
1026
- # a Percentage for a series. It is mainly used for pie charts.
1027
- #
1028
- # chart.add_series(
1029
- # :values => '=Sheet1!$B$1:$B$5',
1030
- # :data_labels => { :percentage => 1 }
1031
- # )
1032
- #
1033
- # The leader_lines property is used to turn on Leader Lines for the data
1034
- # label for a series. It is mainly used for pie charts.
1035
- #
1036
- # chart.add_series(
1037
- # :values => '=Sheet1!$B$1:$B$5',
1038
- # :data_labels => { :value => 1, :leader_lines => 1 }
1039
- # )
1040
- #
1041
- # Note: Even when leader lines are turned on they aren't automatically
1042
- # visible in Excel or Excel::Writer::XLSX. Due to an Excel limitation
1043
- # (or design) leader lines only appear if the data label is moved
1044
- # manually or if the data labels are very close and need to be adjusted
1045
- # automatically.
1046
- #
1047
- # ===Points
1048
- #
1049
- # In general formatting is applied to an entire series in a chart. However,
1050
- # it is occasionally required to format individual points in a series. In
1051
- # particular this is required for Pie charts where each segment is
1052
- # represented by a point.
1053
- #
1054
- # In these cases it is possible to use the points property of add_series():
1055
- #
1056
- # chart.add_series(
1057
- # :values => '=Sheet1!$A$1:$A$3',
1058
- # :points => [
1059
- # { :fill => { :color => '#FF0000' } },
1060
- # { :fill => { ?color => '#CC0000' } },
1061
- # { :fill => { :color => '#990000' } }
1062
- # ]
1063
- # )
1064
- #
1065
- # The points property takes an array ref of format options (see the
1066
- # "CHART FORMATTING"
1067
- # section below). To assign default properties to points in a series pass
1068
- # nil values in the array ref:
1069
- #
1070
- # # Format point 3 of 3 only.
1071
- # chart.add_series(
1072
- # :values => '=Sheet1!$A$1:$A$3',
1073
- # :points => [
1074
- # nil,
1075
- # nil,
1076
- # { :fill => { :color => '#990000' } }
1077
- # ]
1078
- # )
1079
- #
1080
- # # Format the first point only.
1081
- # chart.add_series(
1082
- # :values => '=Sheet1!$A$1:$A$3',
1083
- # :points => [ { :fill => { :color => '#FF0000' } } ]
1084
- # )
1085
165
  def add_series(params)
1086
166
  # Check that the required input has been specified.
1087
167
  unless params.has_key?(:values)
@@ -1092,284 +172,18 @@ def add_series(params)
1092
172
  raise "Must specify ':categories' in add_series for this chart type"
1093
173
  end
1094
174
 
1095
- # Convert aref params into a formula string.
1096
- values = aref_to_formula(params[:values])
1097
- categories = aref_to_formula(params[:categories])
1098
-
1099
- # Switch name and name_formula parameters if required.
1100
- name, name_formula = process_names(params[:name], params[:name_formula])
1101
-
1102
- # Get an id for the data equivalent to the range formula.
1103
- cat_id = get_data_id(categories, params[:categories_data])
1104
- val_id = get_data_id(values, params[:values_data])
1105
- name_id = get_data_id(name_formula, params[:name_data])
1106
-
1107
- # Set the line properties for the series.
1108
- line = line_properties(params[:line])
1109
-
1110
- # Allow 'border' as a synonym for 'line' in bar/column style charts.
1111
- line = line_properties(params[:border]) if params[:border]
1112
-
1113
- # Set the fill properties for the series.
1114
- fill = fill_properties(params[:fill])
1115
-
1116
- # Set the marker properties for the series.
1117
- marker = marker_properties(params[:marker])
1118
-
1119
- # Set the trendline properties for the series.
1120
- trendline = trendline_properties(params[:trendline])
1121
-
1122
- # Set the line smooth property for the series.
1123
- smooth = params[:smooth]
175
+ @series << Series.new(self, params)
1124
176
 
1125
- # Set the error bars properties for the series.
1126
- y_error_bars = error_bars_properties(params[:y_error_bars])
1127
- x_error_bars = error_bars_properties(params[:x_error_bars])
1128
-
1129
- # Set the point properties for the series.
1130
- points = points_properties(params[:points])
1131
-
1132
- # Set the labels properties for the series.
1133
- labels = labels_properties(params[:data_labels])
1134
-
1135
- # Set the "invert if negative" fill property.
1136
- invert_if_neg = params[:invert_if_negative]
1137
-
1138
- # Set the gap for Bar/Column charts.
1139
- if params[:gap]
1140
- @series_gap = params[:gap]
1141
- end
1142
-
1143
- # Set the overlap for Bar/Column charts.
1144
- if params[:overlap]
1145
- @series_overlap = params[:overlap]
1146
- end
1147
-
1148
- # Set the secondary axis properties.
1149
- x2_axis = params[:x2_axis]
1150
- y2_axis = params[:y2_axis]
1151
-
1152
- # Add the user supplied data to the internal structures.
1153
- @series << {
1154
- :_values => values,
1155
- :_categories => categories,
1156
- :_name => name,
1157
- :_name_formula => name_formula,
1158
- :_name_id => name_id,
1159
- :_val_data_id => val_id,
1160
- :_cat_data_id => cat_id,
1161
- :_line => line,
1162
- :_fill => fill,
1163
- :_marker => marker,
1164
- :_trendline => trendline,
1165
- :_smooth => smooth,
1166
- :_labels => labels,
1167
- :_invert_if_neg => invert_if_neg,
1168
- :_x2_axis => x2_axis,
1169
- :_y2_axis => y2_axis,
1170
- :_points => points,
1171
- :_error_bars => {
1172
- :_x_error_bars => x_error_bars,
1173
- :_y_error_bars => y_error_bars
1174
- }
1175
- }
177
+ # Set the gap and overlap for Bar/Column charts.
178
+ @series_gap = params[:gap] if params[:gap]
179
+ @series_overlap = params[:overlap] if params[:overlap]
1176
180
  end
1177
181
 
1178
182
  #
1179
- # Set the properties of the X-axis.
1180
- #
1181
- # The set_x_axis() method is used to set properties of the X axis.
1182
- #
1183
- # chart.set_x_axis( :name => 'Quarterly results' )
1184
- #
1185
- # The properties that can be set are:
1186
- #
1187
- # :name
1188
- # :min
1189
- # :max
1190
- # :minor_unit
1191
- # :major_unit
1192
- # :crossing
1193
- # :reverse
1194
- # :log_base
1195
- # :label_position
1196
- # :major_gridlines
1197
- # :minor_gridlines
1198
- # :visible
1199
- #
1200
- # These are explained below. Some properties are only applicable to value
1201
- # or category axes, as indicated. See "Value and Category Axes" for an
1202
- # explanation of Excel's distinction between the axis types.
1203
- #
1204
- # ====:name
1205
- # Set the name (title or caption) for the axis. The name is displayed
1206
- # below the X axis. The name property is optional. The default is to
1207
- # have no axis name. (Applicable to category and value axes).
1208
- #
1209
- # chart.set_x_axis( :name => 'Quarterly results' )
1210
- #
1211
- # The name can also be a formula such as =Sheet1!$A$1.
1212
- #
1213
- # ====:min
1214
- # Set the minimum value for the axis range.
1215
- # (Applicable to value axes only).
1216
- #
1217
- # chart.set_x_axis( :min => 20 )
1218
- # ====:max
1219
- # Set the maximum value for the axis range.
1220
- # (Applicable to value axes only).
1221
- #
1222
- # chart.set_x_axis( :max => 80 )
1223
- # ====:minor_unit
1224
- # Set the increment of the minor units in the axis range.
1225
- # (Applicable to value axes only).
1226
- #
1227
- # chart.set_x_axis( :minor_unit => 0.4 )
1228
- # ====:major_unit
1229
- # Set the increment of the major units in the axis range.
1230
- # (Applicable to value axes only).
1231
- #
1232
- # chart.set_x_axis( :major_unit => 2 )
1233
- # ====:crossing
1234
- # Set the position where the y axis will cross the x axis.
1235
- # (Applicable to category and value axes).
1236
- #
1237
- # The crossing value can either be the string 'max' to set the crossing
1238
- # at the maximum axis value or a numeric value.
1239
- #
1240
- # chart.set_x_axis( :crossing => 3 )
1241
- # # or
1242
- # chart.set_x_axis( :crossing => 'max' )
1243
- # For category axes the numeric value must be an integer to represent
1244
- # the category number that the axis crosses at. For value axes it can
1245
- # have any value associated with the axis.
1246
- #
1247
- # If crossing is omitted (the default) the crossing will be set
1248
- # automatically by Excel based on the chart data.
1249
- #
1250
- # ====:reverse
1251
- # Reverse the order of the axis categories or values.
1252
- # (Applicable to category and value axes).
1253
- #
1254
- # chart.set_x_axis( :reverse => 1 )
1255
- # ====:log_base
1256
- # Set the log base of the axis range.
1257
- # (Applicable to value axes only).
183
+ # Set the properties of the x-axis.
1258
184
  #
1259
- # chart.set_x_axis( :log_base => 10 )
1260
- # ====:label_position
1261
- # Set the "Axis labels" position for the axis.
1262
- # The following positions are available:
1263
- #
1264
- # next_to (the default)
1265
- # high
1266
- # low
1267
- # none
1268
- # More than one property can be set in a call to set_x_axis:
1269
- #
1270
- # chart.set_x_axis(
1271
- # :name => 'Quarterly results',
1272
- # :min => 10,
1273
- # :max => 80
1274
- # )
1275
- #
1276
- # ==CHART FONTS
1277
- #
1278
- # The following font properties can be set for any chart object that they
1279
- # apply to (and that are supported by WriteXLSX) such as chart titles,
1280
- # axis labels and axis numbering. They correspond to the equivalent
1281
- # Worksheet cell Format object properties. See "FORMAT_METHODS" for more
1282
- # information.
1283
- #
1284
- # name
1285
- # size
1286
- # bold
1287
- # italic
1288
- # underline
1289
- # rotation
1290
- # color
1291
- #
1292
- # The following explains the available font properties:
1293
- #
1294
- # ===name
1295
- # Set the font name:
1296
- #
1297
- # chart.set_x_axis( :num_font => { :name => 'Arial' } )
1298
- #
1299
- # ===size
1300
- # Set the font size:
1301
- #
1302
- # chart.set_x_axis( :num_font => { :name => 'Arial', :size => 10 } )
1303
- #
1304
- # ===bold
1305
- # Set the font bold property, should be 0 or 1:
1306
- #
1307
- # chart.set_x_axis( :num_font => { :bold => 1 } )
1308
- #
1309
- # ===italic
1310
- # Set the font italic property, should be 0 or 1:
1311
- #
1312
- # chart.set_x_axis( :num_font => { :italic => 1 } )
1313
- #
1314
- # ===underline
1315
- # Set the font underline property, should be 0 or 1:
1316
- #
1317
- # chart.set_x_axis( :num_font => { :underline => 1 } )
1318
- #
1319
- # ===rotation
1320
- # See the font rotation in the range -90 to 90:
1321
- #
1322
- # chart.set_x_axis(:num_font => { :rotation => 45 })
1323
- #
1324
- # This is useful for displaying large axis data such as dates in a more compact format.
1325
- #
1326
- # ===color
1327
- # Set the font color property. Can be a color index, a color name or HTML
1328
- # style RGB colour:
1329
- #
1330
- # chart.set_x_axis( :num_font => { :color => 'red' } )
1331
- # chart.set_y_axis( :num_font => { :color => '#92D050' } )
1332
- #
1333
- # Here is an example of Font formatting in a Chart program:
1334
- #
1335
- # # Format the chart title.
1336
- # chart.set_title(
1337
- # :name => 'Sales Results Chart',
1338
- # :name_font => {
1339
- # :name => 'Calibri',
1340
- # :color => 'yellow'
1341
- # }
1342
- # )
1343
- #
1344
- # # Format the X-axis.
1345
- # chart.set_x_axis(
1346
- # :name => 'Month',
1347
- # :name_font => {
1348
- # :name => 'Arial',
1349
- # :color => '#92D050'
1350
- # },
1351
- # :num_font => {
1352
- # :name => 'Courier New',
1353
- # :color => '#00B0F0'
1354
- # }
1355
- # )
1356
- #
1357
- # # Format the Y-axis.
1358
- # chart.set_y_axis(
1359
- # :name => 'Sales (1000 units)',
1360
- # :name_font => {
1361
- # :name => 'Century',
1362
- # :underline => 1,
1363
- # :color => 'red'
1364
- # },
1365
- # :num_font => {
1366
- # :bold => 1,
1367
- # :italic => 1,
1368
- # :color => '#7030A0'
1369
- # }
1370
- # )
1371
185
  def set_x_axis(params = {})
1372
- @x_axis.merge_with_hash(self, params)
186
+ @x_axis.merge_with_hash(params)
1373
187
  end
1374
188
 
1375
189
  #
@@ -1379,85 +193,33 @@ def set_x_axis(params = {})
1379
193
  # The properties that can be set are the same as for set_x_axis,
1380
194
  #
1381
195
  def set_y_axis(params = {})
1382
- @y_axis.merge_with_hash(self, params)
196
+ @y_axis.merge_with_hash(params)
1383
197
  end
1384
198
 
1385
199
  #
1386
200
  # Set the properties of the secondary X-axis.
1387
201
  #
1388
202
  def set_x2_axis(params = {})
1389
- @x2_axis.merge_with_hash(self, params)
203
+ @x2_axis.merge_with_hash(params)
1390
204
  end
1391
205
 
1392
206
  #
1393
207
  # Set the properties of the secondary Y-axis.
1394
208
  #
1395
209
  def set_y2_axis(params = {})
1396
- @y2_axis.merge_with_hash(self, params)
210
+ @y2_axis.merge_with_hash(params)
1397
211
  end
1398
212
 
1399
213
  #
1400
214
  # Set the properties of the chart title.
1401
215
  #
1402
- # The set_title() method is used to set properties of the chart title.
1403
- #
1404
- # chart.set_title( :name => 'Year End Results' )
1405
- #
1406
- # The properties that can be set are:
1407
- #
1408
- # ===:name
1409
- # Set the name (title) for the chart. The name is displayed above the
1410
- # chart. The name can also be a formula such as +=Sheet1!$A$1+. The name
1411
- # property is optional. The default is to have no chart title.
1412
- #
1413
- # ===:name_font
1414
- # Set the font properties for the chart title. See the "CHART FONTS" section.
1415
- #
1416
216
  def set_title(params)
1417
- name, name_formula = process_names(params[:name], params[:name_formula])
1418
- data_id = get_data_id(name_formula, params[:data])
1419
-
1420
- @title_name = name
1421
- @title_formula = name_formula
1422
- @title_data_id = data_id
1423
-
1424
- # Set the font properties if present.
1425
- @title_font = convert_font_args(params[:name_font])
217
+ @title.merge_with_hash(params)
1426
218
  end
1427
219
 
1428
220
  #
1429
221
  # Set the properties of the chart legend.
1430
222
  #
1431
- # The set_legend() method is used to set properties of the chart legend.
1432
- #
1433
- # chart.set_legend( :position => 'none' )
1434
- #
1435
- # The properties that can be set are:
1436
- #
1437
- # ===:position
1438
- # Set the position of the chart legend.
1439
- #
1440
- # chart.set_legend( :position => 'bottom' )
1441
- #
1442
- # The default legend position is right. The available positions are:
1443
- #
1444
- # none
1445
- # top
1446
- # bottom
1447
- # left
1448
- # right
1449
- # overlay_left
1450
- # overlay_right
1451
- #
1452
- # ===:delete_series
1453
- #
1454
- # This allows you to remove 1 or more series from the the legend
1455
- # (the series will still display on the chart). This property takes
1456
- # an array ref as an argument and the series are zero indexed:
1457
- #
1458
- # # Delete/hide series index 0 and 2 from the legend.
1459
- # chart.set_legend(:delete_series => [0, 2])
1460
- #
1461
223
  def set_legend(params)
1462
224
  @legend_position = params[:position] || 'right'
1463
225
  @legend_delete_series = params[:delete_series]
@@ -1466,13 +228,6 @@ def set_legend(params)
1466
228
  #
1467
229
  # Set the properties of the chart plotarea.
1468
230
  #
1469
- # The set_plotarea() method is used to set properties of the plot area
1470
- # of a chart.
1471
- #
1472
- # This method isn't implemented yet and is only available in
1473
- # writeexcel gem. However, it can be simulated using the
1474
- # set_style() method.
1475
- #
1476
231
  def set_plotarea(params)
1477
232
  # Convert the user defined properties to internal properties.
1478
233
  @plotarea = area_properties(params)
@@ -1481,22 +236,6 @@ def set_plotarea(params)
1481
236
  #
1482
237
  # Set the properties of the chart chartarea.
1483
238
  #
1484
- # The set_chartarea() method is used to set the properties of the chart
1485
- # area.
1486
- #
1487
- # chart.set_chartarea(
1488
- # :border => { :none => 1 },
1489
- # :fill => { :color => 'red' }
1490
- # )
1491
- #
1492
- # The properties that can be set are:
1493
- # ===:border
1494
- # Set the border properties of the chartarea such as colour and style.
1495
- # See the "CHART FORMATTING" section.
1496
- # ===:fill
1497
- # Set the fill properties of the plotarea such as colour. See the
1498
- # "CHART FORMATTING" section.
1499
- #
1500
239
  def set_chartarea(params)
1501
240
  # Convert the user defined properties to internal properties.
1502
241
  @chartarea = area_properties(params)
@@ -1505,13 +244,6 @@ def set_chartarea(params)
1505
244
  #
1506
245
  # Set on of the 42 built-in Excel chart styles. The default style is 2.
1507
246
  #
1508
- # The set_style() method is used to set the style of the chart to one
1509
- # of the 42 built-in styles available on the 'Design' tab in Excel:
1510
- #
1511
- # chart.set_style( 4 )
1512
- #
1513
- # The default style is 2.
1514
- #
1515
247
  def set_style(style_id = 2)
1516
248
  style_id = 2 if style_id < 0 || style_id > 42
1517
249
  @style_id = style_id
@@ -1520,16 +252,6 @@ def set_style(style_id = 2)
1520
252
  #
1521
253
  # Set the option for displaying blank data in a chart. The default is 'gap'.
1522
254
  #
1523
- # The show_blanks_as method controls how blank data is displayed in a chart.
1524
- #
1525
- # chart.show_blanks_as('span')
1526
- #
1527
- # The available options are:
1528
- #
1529
- # gap # Blank data is show as a gap. The default.
1530
- # zero # Blank data is displayed as zero.
1531
- # span # Blank data is connected with a line.
1532
- #
1533
255
  def show_blanks_as(option)
1534
256
  return unless option
1535
257
 
@@ -1550,35 +272,6 @@ def show_hidden_data
1550
272
  #
1551
273
  # Set dimensions for scale for the chart.
1552
274
  #
1553
- # The set_size() method is used to set the dimensions of the chart.
1554
- # The size properties that can be set are:
1555
- #
1556
- # width
1557
- # height
1558
- # x_scale
1559
- # y_scale
1560
- # x_offset
1561
- # y_offset
1562
- #
1563
- # The width and height are in pixels. The default chart width is 480
1564
- # pixels and the default height is 288 pixels. The size of the chart can
1565
- # be modified by setting the width and height or by setting the :x_scale
1566
- # and :y_scale:
1567
- #
1568
- # chart.set_size( :width => 720, :height => 576 )
1569
- #
1570
- # # Same as:
1571
- #
1572
- # chart.set_size( :x_scale => 1.5, :y_scale => 2 )
1573
- #
1574
- # The :x_offset and :y_offset position the top left corner of the chart
1575
- # in the cell that it is inserted into.
1576
- #
1577
- # Note: the :x_scale, :y_scale, :x_offset and :y_offset parameters can also
1578
- # be set via the insert_chart() method:
1579
- #
1580
- # worksheet.insert_chart( 'E2', chart, 2, 4, 1.5, 2 )
1581
- #
1582
275
  def set_size(params = {})
1583
276
  @width = params[:width] if params[:width]
1584
277
  @height = params[:height] if params[:height]
@@ -1595,17 +288,6 @@ def set_size(params = {})
1595
288
  # The set_table method adds a data table below the horizontal axis with the
1596
289
  # data used to plot the chart.
1597
290
  #
1598
- # chart.set_table
1599
- #
1600
- # The available options, with default values are:
1601
- #
1602
- # :vertical => true # Display vertical lines in the table.
1603
- # :horizontal => true # Display horizontal lines in the table.
1604
- # :outline => true # Display an outline in the table.
1605
- # :show_keys => false # Show the legend keys with the table data.
1606
- #
1607
- # The data table can only be shown with Bar, Column, Line, Area and Stock charts.
1608
- #
1609
291
  def set_table(params = {})
1610
292
  @table = Table.new(params)
1611
293
  end
@@ -1613,20 +295,6 @@ def set_table(params = {})
1613
295
  #
1614
296
  # Set properties for the chart up-down bars.
1615
297
  #
1616
- # The set_up_down_bars() method adds Up-Down bars to Line charts to
1617
- # indicate the difference between the first and last data series.
1618
- #
1619
- # chart.set_up_down_bars
1620
- # It is possible to format the up and down bars to add fill and border
1621
- # properties if required. See the "CHART FORMATTING" section below.
1622
- #
1623
- # chart.set_up_down_bars(
1624
- # :up => { :fill => { :color => 'green' } },
1625
- # :down => { :fill => { :color => 'red' } }
1626
- # )
1627
- # Up-down bars can only be applied to Line charts and to Stock charts
1628
- # (by default).
1629
- #
1630
298
  def set_up_down_bars(params = {})
1631
299
  # Map border to line.
1632
300
  [:up, :down].each do |up_down|
@@ -1653,18 +321,6 @@ def set_up_down_bars(params = {})
1653
321
  #
1654
322
  # Set properties for the chart drop lines.
1655
323
  #
1656
- # The set_drop_lines() method adds Drop Lines to charts to show the
1657
- # Category value of points in the data.
1658
- #
1659
- # chart.set_drop_lines
1660
- #
1661
- # It is possible to format the Drop Line line properties if required.
1662
- # See the "CHART FORMATTING" section below.
1663
- #
1664
- # chart.set_drop_lines(:line => { :color => 'red', :dash_type => 'square_dot' } )
1665
- #
1666
- # Drop Lines are only available in Line, Area and Stock charts.
1667
- #
1668
324
  def set_drop_lines(params = {})
1669
325
  # Set the drop line properties.
1670
326
  line = line_properties(params[:line])
@@ -1675,18 +331,6 @@ def set_drop_lines(params = {})
1675
331
  #
1676
332
  # Set properties for the chart high-low lines.
1677
333
  #
1678
- # The set_high_low_lines() method adds High-Low lines to charts to show
1679
- # the maximum and minimum values of points in a Category.
1680
- #
1681
- # chart.set_high_low_lines
1682
- #
1683
- # It is possible to format the High-Low Line line properties if required.
1684
- # See the "CHART FORMATTING" section below.
1685
- #
1686
- # chart.set_high_low_lines( :line => { :color => 'red' } )
1687
- #
1688
- # High-Low Lines are only available in Line and Stock charts.
1689
- #
1690
334
  def set_high_low_lines(params = {})
1691
335
  # Set the drop line properties.
1692
336
  line = line_properties(params[:line])
@@ -1742,53 +386,6 @@ def write_bar_chart(params) # :nodoc:
1742
386
  end
1743
387
  end
1744
388
 
1745
- #
1746
- # Switch name and name_formula parameters if required.
1747
- #
1748
- def process_names(name = nil, name_formula = nil) # :nodoc:
1749
- # Name looks like a formula, use it to set name_formula.
1750
- if name && name =~ /^=[^!]+!\$/
1751
- name_formula = name
1752
- name = ''
1753
- end
1754
-
1755
- [name, name_formula]
1756
- end
1757
-
1758
- #
1759
- # Assign an id to a each unique series formula or title/axis formula. Repeated
1760
- # formulas such as for categories get the same id. If the series or title
1761
- # has user specified data associated with it then that is also stored. This
1762
- # data is used to populate cached Excel data when creating a chart.
1763
- # If there is no user defined data then it will be populated by the parent
1764
- # workbook in Workbook::_add_chart_data
1765
- #
1766
- def get_data_id(formula, data) # :nodoc:
1767
- # Ignore series without a range formula.
1768
- return unless formula
1769
-
1770
- # Strip the leading '=' from the formula.
1771
- formula = formula.sub(/^=/, '')
1772
-
1773
- # Store the data id in a hash keyed by the formula and store the data
1774
- # in a separate array with the same id.
1775
- if !@formula_ids.has_key?(formula)
1776
- # Haven't seen this formula before.
1777
- id = @formula_data.size
1778
-
1779
- @formula_data << data
1780
- @formula_ids[formula] = id
1781
- else
1782
- # Formula already seen. Return existing id.
1783
- id = @formula_ids[formula]
1784
-
1785
- # Store user defined data if it isn't already there.
1786
- @formula_data[id] = data unless @formula_data[id]
1787
- end
1788
-
1789
- id
1790
- end
1791
-
1792
389
  #
1793
390
  # Convert user defined font values into private hash values.
1794
391
  #
@@ -1850,6 +447,53 @@ def line_properties(line) # :nodoc:
1850
447
  line
1851
448
  end
1852
449
 
450
+ #
451
+ # Switch name and name_formula parameters if required.
452
+ #
453
+ def process_names(name = nil, name_formula = nil) # :nodoc:
454
+ # Name looks like a formula, use it to set name_formula.
455
+ if name && name =~ /^=[^!]+!\$/
456
+ name_formula = name
457
+ name = ''
458
+ end
459
+
460
+ [name, name_formula]
461
+ end
462
+
463
+ #
464
+ # Assign an id to a each unique series formula or title/axis formula. Repeated
465
+ # formulas such as for categories get the same id. If the series or title
466
+ # has user specified data associated with it then that is also stored. This
467
+ # data is used to populate cached Excel data when creating a chart.
468
+ # If there is no user defined data then it will be populated by the parent
469
+ # workbook in Workbook::_add_chart_data
470
+ #
471
+ def get_data_id(formula, data) # :nodoc:
472
+ # Ignore series without a range formula.
473
+ return unless formula
474
+
475
+ # Strip the leading '=' from the formula.
476
+ formula = formula.sub(/^=/, '')
477
+
478
+ # Store the data id in a hash keyed by the formula and store the data
479
+ # in a separate array with the same id.
480
+ if !@formula_ids.has_key?(formula)
481
+ # Haven't seen this formula before.
482
+ id = @formula_data.size
483
+
484
+ @formula_data << data
485
+ @formula_ids[formula] = id
486
+ else
487
+ # Formula already seen. Return existing id.
488
+ id = @formula_ids[formula]
489
+
490
+ # Store user defined data if it isn't already there.
491
+ @formula_data[id] = data unless @formula_data[id]
492
+ end
493
+
494
+ id
495
+ end
496
+
1853
497
  private
1854
498
 
1855
499
  #
@@ -1863,15 +507,6 @@ def axes_series(params)
1863
507
  end
1864
508
  end
1865
509
 
1866
- #
1867
- # Convert and aref of row col values to a range formula.
1868
- #
1869
- def aref_to_formula(data) # :nodoc:
1870
- # If it isn't an array ref it is probably a formula already.
1871
- return data unless data.kind_of?(Array)
1872
- xl_range_formula(*data)
1873
- end
1874
-
1875
510
  #
1876
511
  # Find the overall type of the data associated with a series.
1877
512
  #
@@ -1993,175 +628,6 @@ def fill_properties(fill) # :nodoc:
1993
628
  fill
1994
629
  end
1995
630
 
1996
- #
1997
- # Convert user defined marker properties to the structure required internally.
1998
- #
1999
- def marker_properties(marker) # :nodoc:
2000
- return unless marker
2001
-
2002
- types = {
2003
- :automatic => 'automatic',
2004
- :none => 'none',
2005
- :square => 'square',
2006
- :diamond => 'diamond',
2007
- :triangle => 'triangle',
2008
- :x => 'x',
2009
- :star => 'start',
2010
- :dot => 'dot',
2011
- :short_dash => 'dot',
2012
- :dash => 'dash',
2013
- :long_dash => 'dash',
2014
- :circle => 'circle',
2015
- :plus => 'plus',
2016
- :picture => 'picture'
2017
- }
2018
-
2019
- # Check for valid types.
2020
- marker_type = marker[:type]
2021
-
2022
- if marker_type
2023
- marker[:automatic] = 1 if marker_type == 'automatic'
2024
- marker[:type] = value_or_raise(types, marker_type, 'maker type')
2025
- end
2026
-
2027
- # Set the line properties for the marker..
2028
- line = line_properties(marker[:line])
2029
-
2030
- # Allow 'border' as a synonym for 'line'.
2031
- line = line_properties(marker[:border]) if marker[:border]
2032
-
2033
- # Set the fill properties for the marker.
2034
- fill = fill_properties(marker[:fill])
2035
-
2036
- marker[:_line] = line
2037
- marker[:_fill] = fill
2038
-
2039
- marker
2040
- end
2041
-
2042
- #
2043
- # Convert user defined trendline properties to the structure required internally.
2044
- #
2045
- def trendline_properties(trendline) # :nodoc:
2046
- return unless trendline
2047
-
2048
- types = {
2049
- :exponential => 'exp',
2050
- :linear => 'linear',
2051
- :log => 'log',
2052
- :moving_average => 'movingAvg',
2053
- :polynomial => 'poly',
2054
- :power => 'power'
2055
- }
2056
-
2057
- # Check the trendline type.
2058
- trend_type = trendline[:type]
2059
-
2060
- trendline[:type] = value_or_raise(types, trend_type, 'trendline type')
2061
-
2062
- # Set the line properties for the trendline..
2063
- line = line_properties(trendline[:line])
2064
-
2065
- # Allow 'border' as a synonym for 'line'.
2066
- line = line_properties(trendline[:border]) if trendline[:border]
2067
-
2068
- # Set the fill properties for the trendline.
2069
- fill = fill_properties(trendline[:fill])
2070
-
2071
- trendline[:_line] = line
2072
- trendline[:_fill] = fill
2073
-
2074
- return trendline
2075
- end
2076
-
2077
- #
2078
- # Convert user defined error bars properties to structure required
2079
- # internally.
2080
- #
2081
- def error_bars_properties(params = {})
2082
- return if !ptrue?(params) || params.empty?
2083
-
2084
- # Default values.
2085
- error_bars = {
2086
- :_type => 'fixedVal',
2087
- :_value => 1,
2088
- :_endcap => 1,
2089
- :_direction => 'both'
2090
- }
2091
-
2092
- types = {
2093
- :fixed => 'fixedVal',
2094
- :percentage => 'percentage',
2095
- :standard_deviation => 'stdDev',
2096
- :standard_error => 'stdErr'
2097
- }
2098
-
2099
- # Check the error bars type.
2100
- error_type = params[:type].to_sym
2101
-
2102
- if types.key?(error_type)
2103
- error_bars[:_type] = types[error_type]
2104
- else
2105
- raise "Unknown error bars type '#{error_type}'\n"
2106
- end
2107
-
2108
- # Set the value for error types that require it.
2109
- if params.key?(:value)
2110
- error_bars[:_value] = params[:value]
2111
- end
2112
-
2113
- # Set the end-cap style.
2114
- if params.key?(:end_style)
2115
- error_bars[:_endcap] = params[:end_style]
2116
- end
2117
-
2118
- # Set the error bar direction.
2119
- if params.key?(:direction)
2120
- if params[:direction] == 'minus'
2121
- error_bars[:_direction] = 'minus'
2122
- elsif params[:direction] == 'plus'
2123
- error_bars[:_direction] = 'plus'
2124
- else
2125
- # Default to 'both'
2126
- end
2127
- end
2128
-
2129
- # Set the line properties for the error bars.
2130
- error_bars[:_line] = line_properties(params[:line])
2131
-
2132
- error_bars
2133
- end
2134
-
2135
- #
2136
- # Convert user defined labels properties to the structure required internally.
2137
- #
2138
- def labels_properties(labels) # :nodoc:
2139
- return nil unless labels
2140
-
2141
- position = labels[:position]
2142
- if position.nil? || position.empty?
2143
- labels.delete(:position)
2144
- else
2145
- # Map user defined label positions to Excel positions.
2146
- positions = {
2147
- :center => 'ctr',
2148
- :right => 'r',
2149
- :left => 'l',
2150
- :top => 't',
2151
- :above => 't',
2152
- :bottom => 'b',
2153
- :below => 'b',
2154
- :inside_end => 'inEnd',
2155
- :outside_end => 'outEnd',
2156
- :best_fit => 'bestFit'
2157
- }
2158
-
2159
- labels[:position] = value_or_raise(positions, position, 'label position')
2160
- end
2161
-
2162
- labels
2163
- end
2164
-
2165
631
  #
2166
632
  # Convert user defined area properties to the structure required internally.
2167
633
  #
@@ -2207,35 +673,6 @@ def area_properties(arg) # :nodoc:
2207
673
  return area
2208
674
  end
2209
675
 
2210
- #
2211
- # Convert user defined points properties to structure required internally.
2212
- #
2213
- def points_properties(user_points = nil)
2214
- return unless user_points
2215
-
2216
- points = []
2217
- user_points.each do |user_point|
2218
- if user_point
2219
- # Set the lline properties for the point.
2220
- line = line_properties(user_point[:line])
2221
-
2222
- # Allow 'border' as a synonym for 'line'.
2223
- if user_point[:border]
2224
- line = line_properties(user_point[:border])
2225
- end
2226
-
2227
- # Set the fill properties for the chartarea.
2228
- fill = fill_properties(user_point[:fill])
2229
-
2230
- point = {}
2231
- point[:_line] = line
2232
- point[:_fill] = fill
2233
- end
2234
- points << point
2235
- end
2236
- points
2237
- end
2238
-
2239
676
  def value_or_raise(hash, key, msg)
2240
677
  raise "Unknown #{msg} '#{key}'" unless hash[key.to_sym]
2241
678
  hash[key.to_sym]
@@ -2245,7 +682,7 @@ def value_or_raise(hash, key, msg)
2245
682
  # Returns series which use the primary axes.
2246
683
  #
2247
684
  def get_primary_axes_series
2248
- @series.reject {|s| s[:_y2_axis]}
685
+ @series.reject {|s| s.y2_axis}
2249
686
  end
2250
687
  alias :primary_axes_series :get_primary_axes_series
2251
688
 
@@ -2253,7 +690,7 @@ def get_primary_axes_series
2253
690
  # Returns series which use the secondary axes.
2254
691
  #
2255
692
  def get_secondary_axes_series
2256
- @series.select {|s| s[:_y2_axis]}
693
+ @series.select {|s| s.y2_axis}
2257
694
  end
2258
695
  alias :secondary_axes_series :get_secondary_axes_series
2259
696
 
@@ -2261,17 +698,21 @@ def get_secondary_axes_series
2261
698
  # Add a unique ids for primary or secondary axis.
2262
699
  #
2263
700
  def add_axis_ids(params) # :nodoc:
701
+ if ptrue?(params[:primary_axes])
702
+ @axis_ids += ids
703
+ else
704
+ @axis2_ids += ids
705
+ end
706
+ end
707
+
708
+ def ids
2264
709
  chart_id = 1 + @id
2265
710
  axis_count = 1 + @axis2_ids.size + @axis_ids.size
2266
711
 
2267
712
  id1 = sprintf('5%03d%04d', chart_id, axis_count)
2268
713
  id2 = sprintf('5%03d%04d', chart_id, axis_count + 1)
2269
714
 
2270
- if ptrue?(params[:primary_axes])
2271
- @axis_ids << id1 << id2
2272
- else
2273
- @axis2_ids << id1 << id2
2274
- end
715
+ [id1, id2]
2275
716
  end
2276
717
 
2277
718
  #
@@ -2426,10 +867,10 @@ def write_style # :nodoc:
2426
867
  def write_chart # :nodoc:
2427
868
  @writer.tag_elements('c:chart') do
2428
869
  # Write the chart title elements.
2429
- if title = @title_formula
2430
- write_title_formula(title, @title_data_id, nil, @title_font)
2431
- elsif title = @title_name
2432
- write_title_rich(title, nil, @title_font)
870
+ if @title.formula
871
+ write_title_formula(@title, nil)
872
+ elsif @title.name
873
+ write_title_rich(@title, nil)
2433
874
  end
2434
875
 
2435
876
  # Write the c:plotArea element.
@@ -2531,30 +972,6 @@ def write_series(series) # :nodoc:
2531
972
  write_ser(series)
2532
973
  end
2533
974
 
2534
- def write_series_base
2535
- # Write each series with subelements.
2536
- index = 0
2537
- @series.each do |series|
2538
- write_ser(index, series)
2539
- index += 1
2540
- end
2541
-
2542
- # Write the c:marker element.
2543
- write_marker_value
2544
-
2545
- # Write the c:overlap element
2546
- # block given by Bar and Column
2547
- yield
2548
-
2549
- # Generate the axis ids.
2550
- add_axis_id
2551
- add_axis_id
2552
-
2553
- # Write the c:axId element.
2554
- write_axis_id(@axis_ids[0])
2555
- write_axis_id(@axis_ids[1])
2556
- end
2557
-
2558
975
  #
2559
976
  # Write the <c:ser> element.
2560
977
  #
@@ -2572,23 +989,23 @@ def write_ser(series) # :nodoc:
2572
989
  # Write the c:spPr element.
2573
990
  write_sp_pr(series)
2574
991
  # Write the c:marker element.
2575
- write_marker(series[:_marker])
992
+ write_marker(series.marker)
2576
993
  # Write the c:invertIfNegative element.
2577
- write_c_invert_if_negative(series[:_invert_if_neg])
994
+ write_c_invert_if_negative(series.invert_if_neg)
2578
995
  # Write the c:dPt element.
2579
- write_d_pt(series[:_points])
996
+ write_d_pt(series.points)
2580
997
  # Write the c:dLbls element.
2581
- write_d_lbls(series[:_labels])
998
+ write_d_lbls(series.labels)
2582
999
  # Write the c:trendline element.
2583
- write_trendline(series[:_trendline])
1000
+ write_trendline(series.trendline)
2584
1001
  # Write the c:errBars element.
2585
- write_error_bars(series[:_error_bars])
1002
+ write_error_bars(series.error_bars)
2586
1003
  # Write the c:cat element.
2587
1004
  write_cat(series)
2588
1005
  # Write the c:val element.
2589
1006
  write_val(series)
2590
1007
  # Write the c:smooth element.
2591
- write_c_smooth(series[:_smooth]) if ptrue?(@smooth_allowed)
1008
+ write_c_smooth(series.smooth) if ptrue?(@smooth_allowed)
2592
1009
  end
2593
1010
  end
2594
1011
 
@@ -2610,10 +1027,10 @@ def write_order(val) # :nodoc:
2610
1027
  # Write the series name.
2611
1028
  #
2612
1029
  def write_series_name(series) # :nodoc:
2613
- if name = series[:_name_formula]
2614
- write_tx_formula(name, series[:_name_id])
2615
- elsif name = series[:_name]
2616
- write_tx_value(name)
1030
+ if series.name_formula
1031
+ write_tx_formula(series.name_formula, series.name_id)
1032
+ elsif series.name
1033
+ write_tx_value(series.name)
2617
1034
  end
2618
1035
  end
2619
1036
 
@@ -2622,8 +1039,8 @@ def write_series_name(series) # :nodoc:
2622
1039
  #
2623
1040
  def write_cat(series) # :nodoc:
2624
1041
 
2625
- formula = series[:_categories]
2626
- data_id = series[:_cat_data_id]
1042
+ formula = series.categories
1043
+ data_id = series.cat_data_id
2627
1044
 
2628
1045
  data = @formula_data[data_id] if data_id
2629
1046
 
@@ -2649,7 +1066,7 @@ def write_cat(series) # :nodoc:
2649
1066
  # Write the <c:val> element.
2650
1067
  #
2651
1068
  def write_val(series) # :nodoc:
2652
- write_val_base(series[:_values], series[:_val_data_id], 'c:val')
1069
+ write_val_base(series.values, series.val_data_id, 'c:val')
2653
1070
  end
2654
1071
 
2655
1072
  def write_val_base(formula, data_id, tag) # :nodoc:
@@ -2764,10 +1181,10 @@ def write_cat_axis(params) # :nodoc:
2764
1181
  write_minor_gridlines(x_axis.minor_gridlines)
2765
1182
 
2766
1183
  # Write the axis title elements.
2767
- if title = x_axis.formula
2768
- write_title_formula(title, @x_axis.data_id, horiz, @x_axis.name_font)
2769
- elsif title = x_axis.name
2770
- write_title_rich(title, horiz, x_axis.name_font)
1184
+ if x_axis.formula
1185
+ write_title_formula(x_axis, horiz, @x_axis)
1186
+ elsif x_axis.name
1187
+ write_title_rich(x_axis, horiz)
2771
1188
  end
2772
1189
 
2773
1190
  # Write the c:numFmt element.
@@ -2832,10 +1249,10 @@ def write_val_axis(params) # :nodoc:
2832
1249
  write_minor_gridlines(y_axis.minor_gridlines)
2833
1250
 
2834
1251
  # Write the axis title elements.
2835
- if title = y_axis.formula
2836
- write_title_formula(title, y_axis.data_id, horiz, y_axis.name_font)
2837
- elsif title = y_axis.name
2838
- write_title_rich(title, horiz, y_axis.name_font)
1252
+ if y_axis.formula
1253
+ write_title_formula(y_axis, horiz)
1254
+ elsif y_axis.name
1255
+ write_title_rich(y_axis, horiz)
2839
1256
  end
2840
1257
 
2841
1258
  # Write the c:numberFormat element.
@@ -2902,10 +1319,10 @@ def write_cat_val_axis(params) # :nodoc:
2902
1319
  write_minor_gridlines(x_axis.minor_gridlines)
2903
1320
 
2904
1321
  # Write the axis title elements.
2905
- if title = x_axis.formula
2906
- write_title_formula(title, y_axis.data_id, horiz, x_axis.name_font)
2907
- elsif title = x_axis.name
2908
- write_title_rich(title, horiz, x_axis.name_font)
1322
+ if x_axis.formula
1323
+ write_title_formula(x_axis, horiz)
1324
+ elsif x_axis.name
1325
+ write_title_rich(x_axis, horiz)
2909
1326
  end
2910
1327
 
2911
1328
  # Write the c:numberFormat element.
@@ -2968,10 +1385,10 @@ def write_date_axis(params) # :nodoc:
2968
1385
  write_minor_gridlines(x_axis.minor_gridlines)
2969
1386
 
2970
1387
  # Write the axis title elements.
2971
- if title = x_axis.formula
2972
- write_title_formula(title, x_axis.data_id, nil, x_axis.name_font)
2973
- elsif title = x_axis.name
2974
- write_title_rich(title, nil, x_axis.name_font)
1388
+ if x_axis.formula
1389
+ write_title_formula(x_axis, nil)
1390
+ elsif x_axis.name
1391
+ write_title_rich(x_axis, nil)
2975
1392
  end
2976
1393
  # Write the c:numFmt element.
2977
1394
  write_number_format(x_axis)
@@ -3371,10 +1788,10 @@ def write_page_setup # :nodoc:
3371
1788
  #
3372
1789
  # Write the <c:title> element for a rich string.
3373
1790
  #
3374
- def write_title_rich(title, horiz = nil, font = nil) # :nodoc:
1791
+ def write_title_rich(title, horiz = nil) # :nodoc:
3375
1792
  @writer.tag_elements('c:title') do
3376
1793
  # Write the c:tx element.
3377
- write_tx_rich(title, horiz, font)
1794
+ write_tx_rich(title, horiz)
3378
1795
  # Write the c:layout element.
3379
1796
  write_layout
3380
1797
  end
@@ -3383,22 +1800,22 @@ def write_title_rich(title, horiz = nil, font = nil) # :nodoc:
3383
1800
  #
3384
1801
  # Write the <c:title> element for a rich string.
3385
1802
  #
3386
- def write_title_formula(title, data_id, horiz = nil, font = nil) # :nodoc:
1803
+ def write_title_formula(title, horiz = nil, axis = nil) # :nodoc:
3387
1804
  @writer.tag_elements('c:title') do
3388
1805
  # Write the c:tx element.
3389
- write_tx_formula(title, data_id)
1806
+ write_tx_formula(title.formula, axis ? axis.data_id : title.data_id)
3390
1807
  # Write the c:layout element.
3391
1808
  write_layout
3392
1809
  # Write the c:txPr element.
3393
- write_tx_pr(horiz, font)
1810
+ write_tx_pr(horiz, axis ? axis.name_font : title.name_font)
3394
1811
  end
3395
1812
  end
3396
1813
 
3397
1814
  #
3398
1815
  # Write the <c:tx> element.
3399
1816
  #
3400
- def write_tx_rich(title, horiz, font = nil) # :nodoc:
3401
- @writer.tag_elements('c:tx') { write_rich(title, horiz, font) }
1817
+ def write_tx_rich(title, horiz) # :nodoc:
1818
+ @writer.tag_elements('c:tx') { write_rich(title, horiz) }
3402
1819
  end
3403
1820
 
3404
1821
  #
@@ -3420,14 +1837,14 @@ def write_tx_formula(title, data_id) # :nodoc:
3420
1837
  #
3421
1838
  # Write the <c:rich> element.
3422
1839
  #
3423
- def write_rich(title, horiz, font) # :nodoc:
1840
+ def write_rich(title, horiz) # :nodoc:
3424
1841
  @writer.tag_elements('c:rich') do
3425
1842
  # Write the a:bodyPr element.
3426
1843
  write_a_body_pr(horiz)
3427
1844
  # Write the a:lstStyle element.
3428
1845
  write_a_lst_style
3429
1846
  # Write the a:p element.
3430
- write_a_p_rich(title, font)
1847
+ write_a_p_rich(title)
3431
1848
  end
3432
1849
  end
3433
1850
 
@@ -3470,12 +1887,12 @@ def write_a_lst_style # :nodoc:
3470
1887
  #
3471
1888
  # Write the <a:p> element for rich string titles.
3472
1889
  #
3473
- def write_a_p_rich(title, font) # :nodoc:
1890
+ def write_a_p_rich(title) # :nodoc:
3474
1891
  @writer.tag_elements('a:p') do
3475
1892
  # Write the a:pPr element.
3476
- write_a_p_pr_rich(font)
1893
+ write_a_p_pr_rich(title.name_font)
3477
1894
  # Write the a:r element.
3478
- write_a_r(title, font)
1895
+ write_a_r(title)
3479
1896
  end
3480
1897
  end
3481
1898
 
@@ -3525,12 +1942,12 @@ def write_a_end_para_rpr # :nodoc:
3525
1942
  #
3526
1943
  # Write the <a:r> element.
3527
1944
  #
3528
- def write_a_r(title, font) # :nodoc:
1945
+ def write_a_r(title) # :nodoc:
3529
1946
  @writer.tag_elements('a:r') do
3530
1947
  # Write the a:rPr element.
3531
- write_a_r_pr(font)
1948
+ write_a_r_pr(title.name_font)
3532
1949
  # Write the a:t element.
3533
- write_a_t(title)
1950
+ write_a_t(title.name)
3534
1951
  end
3535
1952
  end
3536
1953
 
@@ -3631,22 +2048,25 @@ def write_symbol(val) # :nodoc:
3631
2048
  # Write the <c:spPr> element.
3632
2049
  #
3633
2050
  def write_sp_pr(series) # :nodoc:
3634
- return if (!series.has_key?(:_line) || !ptrue?(series[:_line][:_defined])) &&
3635
- (!series.has_key?(:_fill) || !ptrue?(series[:_fill][:_defined]))
2051
+ line = series.respond_to?(:line) ? series.line : series[:_line]
2052
+ fill = series.respond_to?(:fill) ? series.fill : series[:_fill]
2053
+
2054
+ return if (!line || !ptrue?(line[:_defined])) &&
2055
+ (!fill || !ptrue?(fill[:_defined]))
3636
2056
 
3637
2057
  @writer.tag_elements('c:spPr') do
3638
2058
  # Write the fill elements for solid charts such as pie and bar.
3639
- if series[:_fill] && series[:_fill][:_defined] != 0
3640
- if ptrue?(series[:_fill][:none])
2059
+ if fill && fill[:_defined] != 0
2060
+ if ptrue?(fill[:none])
3641
2061
  # Write the a:noFill element.
3642
2062
  write_a_no_fill
3643
2063
  else
3644
2064
  # Write the a:solidFill element.
3645
- write_a_solid_fill(series[:_fill])
2065
+ write_a_solid_fill(fill)
3646
2066
  end
3647
2067
  end
3648
2068
  # Write the a:ln element.
3649
- write_a_ln(series[:_line]) if series[:_line] && ptrue?(series[:_line][:_defined])
2069
+ write_a_ln(line) if line && ptrue?(line[:_defined])
3650
2070
  end
3651
2071
  end
3652
2072