write_xlsx 1.12.3 → 1.15.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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +22 -0
  3. data/Changes +23 -0
  4. data/README.md +1 -1
  5. data/lib/write_xlsx/chart/area.rb +2 -2
  6. data/lib/write_xlsx/chart/axis.rb +55 -32
  7. data/lib/write_xlsx/chart/axis_writer.rb +528 -0
  8. data/lib/write_xlsx/chart/bar.rb +2 -2
  9. data/lib/write_xlsx/chart/caption.rb +16 -9
  10. data/lib/write_xlsx/chart/chart_area.rb +121 -0
  11. data/lib/write_xlsx/chart/column.rb +2 -2
  12. data/lib/write_xlsx/chart/d_pt_point_writer.rb +14 -0
  13. data/lib/write_xlsx/chart/doughnut.rb +0 -3
  14. data/lib/write_xlsx/chart/formatting_writer.rb +652 -0
  15. data/lib/write_xlsx/chart/initialization.rb +100 -0
  16. data/lib/write_xlsx/chart/line.rb +4 -3
  17. data/lib/write_xlsx/chart/pie.rb +6 -2
  18. data/lib/write_xlsx/chart/radar.rb +2 -2
  19. data/lib/write_xlsx/chart/scatter.rb +4 -3
  20. data/lib/write_xlsx/chart/series.rb +35 -15
  21. data/lib/write_xlsx/chart/series_data.rb +132 -0
  22. data/lib/write_xlsx/chart/series_writer.rb +318 -0
  23. data/lib/write_xlsx/chart/settings.rb +226 -0
  24. data/lib/write_xlsx/chart/stock.rb +2 -2
  25. data/lib/write_xlsx/chart/table.rb +50 -0
  26. data/lib/write_xlsx/chart/xml_writer.rb +305 -0
  27. data/lib/write_xlsx/chart.rb +286 -2477
  28. data/lib/write_xlsx/chartsheet.rb +35 -83
  29. data/lib/write_xlsx/constants.rb +11 -0
  30. data/lib/write_xlsx/drawing.rb +5 -3
  31. data/lib/write_xlsx/format/alignment_state.rb +39 -0
  32. data/lib/write_xlsx/format/alignment_style.rb +92 -0
  33. data/lib/write_xlsx/format/border_state.rb +47 -0
  34. data/lib/write_xlsx/format/border_style.rb +116 -0
  35. data/lib/write_xlsx/format/fill_state.rb +26 -0
  36. data/lib/write_xlsx/format/fill_style.rb +52 -0
  37. data/lib/write_xlsx/format/font_state.rb +74 -0
  38. data/lib/write_xlsx/format/font_style.rb +172 -0
  39. data/lib/write_xlsx/format/format_state.rb +65 -0
  40. data/lib/write_xlsx/format/number_format_state.rb +20 -0
  41. data/lib/write_xlsx/format/number_format_style.rb +28 -0
  42. data/lib/write_xlsx/format/protection_state.rb +20 -0
  43. data/lib/write_xlsx/format/protection_style.rb +28 -0
  44. data/lib/write_xlsx/format.rb +1093 -426
  45. data/lib/write_xlsx/formats.rb +0 -2
  46. data/lib/write_xlsx/image_property.rb +4 -1
  47. data/lib/write_xlsx/inserted_chart.rb +1 -1
  48. data/lib/write_xlsx/object_positioning.rb +203 -0
  49. data/lib/write_xlsx/package/app.rb +3 -3
  50. data/lib/write_xlsx/package/button.rb +6 -2
  51. data/lib/write_xlsx/package/comments.rb +11 -3
  52. data/lib/write_xlsx/package/conditional_format.rb +7 -3
  53. data/lib/write_xlsx/package/content_types.rb +2 -2
  54. data/lib/write_xlsx/package/core.rb +2 -2
  55. data/lib/write_xlsx/package/custom.rb +3 -2
  56. data/lib/write_xlsx/package/metadata.rb +2 -2
  57. data/lib/write_xlsx/package/packager.rb +0 -3
  58. data/lib/write_xlsx/package/relationships.rb +2 -2
  59. data/lib/write_xlsx/package/rich_value.rb +4 -2
  60. data/lib/write_xlsx/package/rich_value_rel.rb +2 -2
  61. data/lib/write_xlsx/package/rich_value_structure.rb +2 -2
  62. data/lib/write_xlsx/package/rich_value_types.rb +3 -3
  63. data/lib/write_xlsx/package/shared_strings.rb +2 -2
  64. data/lib/write_xlsx/package/styles.rb +13 -9
  65. data/lib/write_xlsx/package/table.rb +8 -2
  66. data/lib/write_xlsx/package/theme.rb +0 -3
  67. data/lib/write_xlsx/package/vml.rb +2 -2
  68. data/lib/write_xlsx/page_setup.rb +192 -0
  69. data/lib/write_xlsx/shape.rb +97 -100
  70. data/lib/write_xlsx/sheets.rb +9 -4
  71. data/lib/write_xlsx/sparkline.rb +2 -2
  72. data/lib/write_xlsx/utility/cell_reference.rb +124 -0
  73. data/lib/write_xlsx/utility/chart_formatting.rb +262 -0
  74. data/lib/write_xlsx/utility/common.rb +44 -0
  75. data/lib/write_xlsx/utility/date_time.rb +113 -0
  76. data/lib/write_xlsx/utility/dimensions.rb +40 -0
  77. data/lib/write_xlsx/utility/drawing.rb +136 -0
  78. data/lib/write_xlsx/utility/rich_text.rb +184 -0
  79. data/lib/write_xlsx/utility/sheetname_quoting.rb +73 -0
  80. data/lib/write_xlsx/utility/string_width.rb +45 -0
  81. data/lib/write_xlsx/utility/url.rb +27 -0
  82. data/lib/write_xlsx/utility/xml_primitives.rb +32 -0
  83. data/lib/write_xlsx/version.rb +1 -1
  84. data/lib/write_xlsx/workbook/chart_data.rb +188 -0
  85. data/lib/write_xlsx/workbook/format_preparation.rb +199 -0
  86. data/lib/write_xlsx/workbook/initialization.rb +223 -0
  87. data/lib/write_xlsx/workbook/package_preparation.rb +231 -0
  88. data/lib/write_xlsx/workbook/workbook_writer.rb +164 -0
  89. data/lib/write_xlsx/workbook.rb +143 -981
  90. data/lib/write_xlsx/worksheet/asset_manager.rb +60 -0
  91. data/lib/write_xlsx/worksheet/autofilter.rb +390 -0
  92. data/lib/write_xlsx/worksheet/cell_data.rb +13 -6
  93. data/lib/write_xlsx/worksheet/cell_data_manager.rb +47 -0
  94. data/lib/write_xlsx/worksheet/cell_data_store.rb +61 -0
  95. data/lib/write_xlsx/worksheet/columns.rb +204 -0
  96. data/lib/write_xlsx/worksheet/comments_support.rb +61 -0
  97. data/lib/write_xlsx/worksheet/conditional_formats.rb +30 -0
  98. data/lib/write_xlsx/worksheet/data_validation.rb +9 -1
  99. data/lib/write_xlsx/worksheet/data_writing.rb +1017 -0
  100. data/lib/write_xlsx/worksheet/drawing_methods.rb +308 -0
  101. data/lib/write_xlsx/worksheet/drawing_preparation.rb +290 -0
  102. data/lib/write_xlsx/worksheet/drawing_relations.rb +76 -0
  103. data/lib/write_xlsx/worksheet/drawing_xml_writer.rb +50 -0
  104. data/lib/write_xlsx/worksheet/formatting.rb +418 -0
  105. data/lib/write_xlsx/worksheet/hyperlink.rb +9 -1
  106. data/lib/write_xlsx/worksheet/initialization.rb +146 -0
  107. data/lib/write_xlsx/worksheet/panes.rb +64 -0
  108. data/lib/write_xlsx/worksheet/print_options.rb +72 -0
  109. data/lib/write_xlsx/worksheet/protection.rb +65 -0
  110. data/lib/write_xlsx/worksheet/rich_text_helpers.rb +78 -0
  111. data/lib/write_xlsx/worksheet/row_col_sizing.rb +69 -0
  112. data/lib/write_xlsx/worksheet/rows.rb +84 -0
  113. data/lib/write_xlsx/worksheet/selection.rb +41 -0
  114. data/lib/write_xlsx/worksheet/xml_writer.rb +1246 -0
  115. data/lib/write_xlsx/worksheet.rb +376 -4530
  116. metadata +66 -4
  117. data/lib/write_xlsx/utility.rb +0 -986
  118. data/lib/write_xlsx/worksheet/page_setup.rb +0 -192
@@ -0,0 +1,528 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ ###############################################################################
5
+ #
6
+ # axis_writer.rb - axis-specific XML output helpers
7
+ #
8
+ ###############################################################################
9
+
10
+ module Writexlsx
11
+ class Chart
12
+ module AxisWriter
13
+ private
14
+
15
+ #
16
+ # Write the <c:catAx> element. Usually the X axis.
17
+ #
18
+ def write_cat_axis(params) # :nodoc:
19
+ x_axis = params[:x_axis]
20
+ y_axis = params[:y_axis]
21
+ axis_ids = params[:axis_ids]
22
+
23
+ # if there are no axis_ids then we don't need to write this element
24
+ return unless axis_ids
25
+ return if axis_ids.empty?
26
+
27
+ position = @cat_axis_position
28
+ is_y_axis = @horiz_cat_axis
29
+
30
+ # Overwrite the default axis position with a user supplied value.
31
+ position = x_axis.position || position
32
+
33
+ @writer.tag_elements('c:catAx') do
34
+ write_axis_id(axis_ids[0])
35
+ # Write the c:scaling element.
36
+ write_scaling(x_axis.reverse)
37
+
38
+ write_delete(1) unless ptrue?(x_axis.visible)
39
+
40
+ # Write the c:axPos element.
41
+ write_axis_pos(position, y_axis.reverse)
42
+
43
+ # Write the c:majorGridlines element.
44
+ write_major_gridlines(x_axis.major_gridlines)
45
+
46
+ # Write the c:minorGridlines element.
47
+ write_minor_gridlines(x_axis.minor_gridlines)
48
+
49
+ # Write the axis title elements.
50
+ write_chart_title(x_axis.title, is_y_axis)
51
+
52
+ # Write the c:numFmt element.
53
+ write_cat_number_format(x_axis)
54
+
55
+ # Write the c:majorTickMark element.
56
+ write_major_tick_mark(x_axis.major_tick_mark)
57
+
58
+ # Write the c:minorTickMark element.
59
+ write_minor_tick_mark(x_axis.minor_tick_mark)
60
+
61
+ # Write the c:tickLblPos element.
62
+ write_tick_label_pos(x_axis.label_position)
63
+
64
+ # Write the c:spPr element for the axis line.
65
+ write_sp_pr(x_axis)
66
+
67
+ # Write the axis font elements.
68
+ write_axis_font(x_axis.num_font)
69
+
70
+ # Write the c:crossAx element.
71
+ write_cross_axis(axis_ids[1])
72
+
73
+ write_crossing(y_axis.crossing) if @show_crosses || ptrue?(x_axis.visible)
74
+ # Write the c:auto element.
75
+ write_auto(1) unless x_axis.text_axis
76
+ # Write the c:labelAlign element.
77
+ write_label_align(x_axis.label_align)
78
+ # Write the c:labelOffset element.
79
+ write_label_offset(100)
80
+ # Write the c:tickLblSkip element.
81
+ write_tick_lbl_skip(x_axis.interval_unit)
82
+ # Write the c:tickMarkSkip element.
83
+ write_tick_mark_skip(x_axis.interval_tick)
84
+ end
85
+ end
86
+
87
+ #
88
+ # Write the <c:valAx> element. Usually the Y axis.
89
+ #
90
+ def write_val_axis(x_axis, y_axis, axis_ids, position = nil)
91
+ return unless axis_ids && !axis_ids.empty?
92
+
93
+ write_val_axis_base(
94
+ x_axis, y_axis,
95
+ axis_ids[0],
96
+ axis_ids[1],
97
+ y_axis.position || position || @val_axis_position
98
+ )
99
+ end
100
+ public :write_val_axis
101
+
102
+ def write_val_axis_base(x_axis, y_axis, axis_ids_0, axis_ids_1, position) # :nodoc:
103
+ @writer.tag_elements('c:valAx') do
104
+ write_axis_id(axis_ids_1)
105
+
106
+ # Write the c:scaling element.
107
+ write_scaling_with_param(y_axis)
108
+
109
+ write_delete(1) unless ptrue?(y_axis.visible)
110
+
111
+ # Write the c:axPos element.
112
+ write_axis_pos(position, x_axis.reverse)
113
+
114
+ # Write the c:majorGridlines element.
115
+ write_major_gridlines(y_axis.major_gridlines)
116
+
117
+ # Write the c:minorGridlines element.
118
+ write_minor_gridlines(y_axis.minor_gridlines)
119
+
120
+ # Write the axis title elements.
121
+ write_chart_title(y_axis.title, @horiz_val_axis)
122
+
123
+ # Write the c:numberFormat element.
124
+ write_number_format(y_axis)
125
+
126
+ # Write the c:majorTickMark element.
127
+ write_major_tick_mark(y_axis.major_tick_mark)
128
+
129
+ # Write the c:minorTickMark element.
130
+ write_minor_tick_mark(y_axis.minor_tick_mark)
131
+
132
+ # Write the c:tickLblPos element.
133
+ write_tick_label_pos(y_axis.label_position)
134
+
135
+ # Write the c:spPr element for the axis line.
136
+ write_sp_pr(y_axis)
137
+
138
+ # Write the axis font elements.
139
+ write_axis_font(y_axis.num_font)
140
+
141
+ # Write the c:crossAx element.
142
+ write_cross_axis(axis_ids_0)
143
+
144
+ write_crossing(x_axis.crossing)
145
+
146
+ # Write the c:crossBetween element.
147
+ write_cross_between(x_axis.position_axis)
148
+
149
+ # Write the c:majorUnit element.
150
+ write_c_major_unit(y_axis.major_unit)
151
+
152
+ # Write the c:minorUnit element.
153
+ write_c_minor_unit(y_axis.minor_unit)
154
+
155
+ # Write the c:dispUnits element.
156
+ write_disp_units(y_axis.display_units, y_axis.display_units_visible)
157
+ end
158
+ end
159
+
160
+ #
161
+ # Write the <c:dateAx> element. Usually the X axis.
162
+ #
163
+ def write_date_axis(params) # :nodoc:
164
+ x_axis = params[:x_axis]
165
+ y_axis = params[:y_axis]
166
+ axis_ids = params[:axis_ids]
167
+
168
+ return unless axis_ids && !axis_ids.empty?
169
+
170
+ position = @cat_axis_position
171
+
172
+ # Overwrite the default axis position with a user supplied value.
173
+ position = x_axis.position || position
174
+
175
+ @writer.tag_elements('c:dateAx') do
176
+ write_axis_id(axis_ids[0])
177
+ # Write the c:scaling element.
178
+ write_scaling_with_param(x_axis)
179
+
180
+ write_delete(1) unless ptrue?(x_axis.visible)
181
+
182
+ # Write the c:axPos element.
183
+ write_axis_pos(position, y_axis.reverse)
184
+
185
+ # Write the c:majorGridlines element.
186
+ write_major_gridlines(x_axis.major_gridlines)
187
+
188
+ # Write the c:minorGridlines element.
189
+ write_minor_gridlines(x_axis.minor_gridlines)
190
+
191
+ # Write the axis title elements.
192
+ write_chart_title(x_axis.title)
193
+
194
+ # Write the c:numFmt element.
195
+ write_number_format(x_axis)
196
+ # Write the c:majorTickMark element.
197
+ write_major_tick_mark(x_axis.major_tick_mark)
198
+
199
+ # Write the c:tickLblPos element.
200
+ write_tick_label_pos(x_axis.label_position)
201
+ # Write the c:spPr element for the axis line.
202
+ write_sp_pr(x_axis)
203
+ # Write the font elements.
204
+ write_axis_font(x_axis.num_font)
205
+ # Write the c:crossAx element.
206
+ write_cross_axis(axis_ids[1])
207
+
208
+ write_crossing(y_axis.crossing) if @show_crosses || ptrue?(x_axis.visible)
209
+
210
+ # Write the c:auto element.
211
+ write_auto(1)
212
+ # Write the c:labelOffset element.
213
+ write_label_offset(100)
214
+ # Write the c:tickLblSkip element.
215
+ write_tick_lbl_skip(x_axis.interval_unit)
216
+ # Write the c:tickMarkSkip element.
217
+ write_tick_mark_skip(x_axis.interval_tick)
218
+ # Write the c:majorUnit element.
219
+ write_c_major_unit(x_axis.major_unit)
220
+ # Write the c:majorTimeUnit element.
221
+ write_c_major_time_unit(x_axis.major_unit_type) if x_axis.major_unit
222
+ # Write the c:minorUnit element.
223
+ write_c_minor_unit(x_axis.minor_unit)
224
+ # Write the c:minorTimeUnit element.
225
+ write_c_minor_time_unit(x_axis.minor_unit_type) if x_axis.minor_unit
226
+ end
227
+ end
228
+
229
+ def write_crossing(crossing)
230
+ # Note, the category crossing comes from the value axis.
231
+ if [nil, 'max', 'min'].include?(crossing)
232
+ # Write the c:crosses element.
233
+ write_crosses(crossing)
234
+ else
235
+ # Write the c:crossesAt element.
236
+ write_c_crosses_at(crossing)
237
+ end
238
+ end
239
+
240
+ def write_scaling_with_param(param)
241
+ write_scaling(
242
+ param.reverse,
243
+ param.min,
244
+ param.max,
245
+ param.log_base
246
+ )
247
+ end
248
+
249
+ #
250
+ # Write the <c:scaling> element.
251
+ #
252
+ def write_scaling(reverse, min = nil, max = nil, log_base = nil) # :nodoc:
253
+ @writer.tag_elements('c:scaling') do
254
+ # Write the c:logBase element.
255
+ write_c_log_base(log_base)
256
+ # Write the c:orientation element.
257
+ write_orientation(reverse)
258
+ # Write the c:max element.
259
+ write_c_max(max)
260
+ # Write the c:min element.
261
+ write_c_min(min)
262
+ end
263
+ end
264
+
265
+ #
266
+ # Write the <c:logBase> element.
267
+ #
268
+ def write_c_log_base(val) # :nodoc:
269
+ return unless ptrue?(val)
270
+
271
+ @writer.empty_tag('c:logBase', [['val', val]])
272
+ end
273
+
274
+ #
275
+ # Write the <c:orientation> element.
276
+ #
277
+ def write_orientation(reverse = nil) # :nodoc:
278
+ val = ptrue?(reverse) ? 'maxMin' : 'minMax'
279
+
280
+ @writer.empty_tag('c:orientation', [['val', val]])
281
+ end
282
+
283
+ #
284
+ # Write the <c:max> element.
285
+ #
286
+ def write_c_max(max = nil) # :nodoc:
287
+ @writer.empty_tag('c:max', [['val', max]]) if max
288
+ end
289
+
290
+ #
291
+ # Write the <c:min> element.
292
+ #
293
+ def write_c_min(min = nil) # :nodoc:
294
+ @writer.empty_tag('c:min', [['val', min]]) if min
295
+ end
296
+
297
+ #
298
+ # Write the <c:axPos> element.
299
+ #
300
+ def write_axis_pos(val, reverse = false) # :nodoc:
301
+ if reverse
302
+ val = 'r' if val == 'l'
303
+ val = 't' if val == 'b'
304
+ end
305
+
306
+ @writer.empty_tag('c:axPos', [['val', val]])
307
+ end
308
+
309
+ #
310
+ # Write the <c:numberFormat> element. Note: It is assumed that if a user
311
+ # defined number format is supplied (i.e., non-default) then the sourceLinked
312
+ # attribute is 0. The user can override this if required.
313
+ #
314
+
315
+ def write_number_format(axis) # :nodoc:
316
+ axis.write_number_format(@writer)
317
+ end
318
+
319
+ #
320
+ # Write the <c:numFmt> element. Special case handler for category axes which
321
+ # don't always have a number format.
322
+ #
323
+ def write_cat_number_format(axis)
324
+ axis.write_cat_number_format(@writer, @cat_has_num_fmt)
325
+ end
326
+
327
+ #
328
+ # Write the <c:majorTickMark> element.
329
+ #
330
+ def write_major_tick_mark(val)
331
+ return unless ptrue?(val)
332
+
333
+ @writer.empty_tag('c:majorTickMark', [['val', val]])
334
+ end
335
+
336
+ #
337
+ # Write the <c:minorTickMark> element.
338
+ #
339
+ def write_minor_tick_mark(val)
340
+ return unless ptrue?(val)
341
+
342
+ @writer.empty_tag('c:minorTickMark', [['val', val]])
343
+ end
344
+
345
+ #
346
+ # Write the <c:tickLblPos> element.
347
+ #
348
+ def write_tick_label_pos(val) # :nodoc:
349
+ val ||= 'nextTo'
350
+ val = 'nextTo' if val == 'next_to'
351
+
352
+ @writer.empty_tag('c:tickLblPos', [['val', val]])
353
+ end
354
+
355
+ #
356
+ # Write the <c:crossAx> element.
357
+ #
358
+ def write_cross_axis(val = 'autoZero') # :nodoc:
359
+ @writer.empty_tag('c:crossAx', [['val', val]])
360
+ end
361
+
362
+ #
363
+ # Write the <c:crosses> element.
364
+ #
365
+ def write_crosses(val) # :nodoc:
366
+ val ||= 'autoZero'
367
+
368
+ @writer.empty_tag('c:crosses', [['val', val]])
369
+ end
370
+
371
+ #
372
+ # Write the <c:crossesAt> element.
373
+ #
374
+ def write_c_crosses_at(val) # :nodoc:
375
+ @writer.empty_tag('c:crossesAt', [['val', val]])
376
+ end
377
+
378
+ #
379
+ # Write the <c:auto> element.
380
+ #
381
+ def write_auto(val) # :nodoc:
382
+ @writer.empty_tag('c:auto', [['val', val]])
383
+ end
384
+
385
+ #
386
+ # Write the <c:labelAlign> element.
387
+ #
388
+ def write_label_align(val) # :nodoc:
389
+ val ||= 'ctr'
390
+ if val == 'right'
391
+ val = 'r'
392
+ elsif val == 'left'
393
+ val = 'l'
394
+ end
395
+ @writer.empty_tag('c:lblAlgn', [['val', val]])
396
+ end
397
+
398
+ #
399
+ # Write the <c:labelOffset> element.
400
+ #
401
+ def write_label_offset(val) # :nodoc:
402
+ @writer.empty_tag('c:lblOffset', [['val', val]])
403
+ end
404
+
405
+ #
406
+ # Write the <c:tickLblSkip> element.
407
+ #
408
+ def write_tick_lbl_skip(val) # :nodoc:
409
+ return unless val
410
+
411
+ @writer.empty_tag('c:tickLblSkip', [['val', val]])
412
+ end
413
+
414
+ #
415
+ # Write the <c:tickMarkSkip> element.
416
+ #
417
+ def write_tick_mark_skip(val) # :nodoc:
418
+ return unless val
419
+
420
+ @writer.empty_tag('c:tickMarkSkip', [['val', val]])
421
+ end
422
+
423
+ #
424
+ # Write the <c:majorGridlines> element.
425
+ #
426
+ def write_major_gridlines(gridlines) # :nodoc:
427
+ write_gridlines_base('c:majorGridlines', gridlines)
428
+ end
429
+
430
+ #
431
+ # Write the <c:minorGridlines> element.
432
+ #
433
+ def write_minor_gridlines(gridlines) # :nodoc:
434
+ write_gridlines_base('c:minorGridlines', gridlines)
435
+ end
436
+
437
+ def write_gridlines_base(tag, gridlines) # :nodoc:
438
+ return unless gridlines
439
+ return if gridlines.respond_to?(:[]) && !ptrue?(gridlines[:_visible])
440
+
441
+ if gridlines.line_defined?
442
+ @writer.tag_elements(tag) { write_sp_pr(gridlines) }
443
+ else
444
+ @writer.empty_tag(tag)
445
+ end
446
+ end
447
+
448
+ #
449
+ # Write the <c:crossBetween> element.
450
+ #
451
+ def write_cross_between(val = nil) # :nodoc:
452
+ val ||= @cross_between
453
+
454
+ @writer.empty_tag('c:crossBetween', [['val', val]])
455
+ end
456
+
457
+ #
458
+ # Write the <c:majorUnit> element.
459
+ #
460
+ def write_c_major_unit(val = nil) # :nodoc:
461
+ return unless val
462
+
463
+ @writer.empty_tag('c:majorUnit', [['val', val]])
464
+ end
465
+
466
+ #
467
+ # Write the <c:minorUnit> element.
468
+ #
469
+ def write_c_minor_unit(val = nil) # :nodoc:
470
+ return unless val
471
+
472
+ @writer.empty_tag('c:minorUnit', [['val', val]])
473
+ end
474
+
475
+ #
476
+ # Write the <c:majorTimeUnit> element.
477
+ #
478
+ def write_c_major_time_unit(val) # :nodoc:
479
+ val ||= 'days'
480
+
481
+ @writer.empty_tag('c:majorTimeUnit', [['val', val]])
482
+ end
483
+
484
+ #
485
+ # Write the <c:minorTimeUnit> element.
486
+ #
487
+ def write_c_minor_time_unit(val) # :nodoc:
488
+ val ||= 'days'
489
+
490
+ @writer.empty_tag('c:minorTimeUnit', [['val', val]])
491
+ end
492
+
493
+ #
494
+ # Write the <c:dispUnits> element.
495
+ #
496
+ def write_disp_units(units, display)
497
+ return unless ptrue?(units)
498
+
499
+ attributes = [['val', units]]
500
+
501
+ @writer.tag_elements('c:dispUnits') do
502
+ @writer.empty_tag('c:builtInUnit', attributes)
503
+ if ptrue?(display)
504
+ @writer.tag_elements('c:dispUnitsLbl') do
505
+ @writer.empty_tag('c:layout')
506
+ end
507
+ end
508
+ end
509
+ end
510
+
511
+ #
512
+ # Write the axis font elements.
513
+ #
514
+ def write_axis_font(font) # :nodoc:
515
+ return unless font
516
+
517
+ @writer.tag_elements('c:txPr') do
518
+ write_a_body_pr(font[:_rotation])
519
+ write_a_lst_style
520
+ @writer.tag_elements('a:p') do
521
+ write_a_p_pr_rich(font)
522
+ write_a_end_para_rpr
523
+ end
524
+ end
525
+ end
526
+ end
527
+ end
528
+ end
@@ -14,12 +14,12 @@
14
14
  #
15
15
 
16
16
  require 'write_xlsx/package/xml_writer_simple'
17
- require 'write_xlsx/utility'
17
+ require 'write_xlsx/utility/xml_primitives'
18
18
 
19
19
  module Writexlsx
20
20
  class Chart
21
21
  class Bar < self
22
- include Writexlsx::Utility
22
+ include Writexlsx::Utility::XmlPrimitives
23
23
 
24
24
  def initialize(subtype)
25
25
  super
@@ -4,26 +4,33 @@
4
4
  module Writexlsx
5
5
  class Chart
6
6
  class Caption
7
- include Writexlsx::Utility
7
+ include Writexlsx::Utility::Common
8
+ include Writexlsx::Utility::RichText
8
9
 
9
- attr_accessor :name, :formula, :data_id, :name_font
10
+ attr_accessor :name, :formula, :data_id, :font
11
+ attr_accessor :line, :fill, :pattern, :gradient
10
12
  attr_reader :layout, :overlay, :none
11
13
 
12
14
  def initialize(chart)
13
15
  @chart = chart
14
16
  end
15
17
 
16
- def merge_with_hash(params) # :nodoc:
18
+ def apply_text_options(params) # :nodoc:
17
19
  @name, @formula = chart.process_names(params[:name], params[:name_formula])
18
- @data_id = chart.data_id(@formula, params[:data])
19
- @name_font = convert_font_args(params[:name_font])
20
- @layout = chart.layout_properties(params[:layout], 1)
20
+ @name = nil if @name.respond_to?(:empty?) && @name.empty?
21
+ @data_id = chart.data_id(@formula, params[:data])
22
+ @font = convert_font_args(params[:font] || params[:name_font])
21
23
 
22
- # Set the title overlay option.
24
+ @layout = chart.layout_properties(params[:layout], 1)
23
25
  @overlay = params[:overlay]
26
+ @none = params[:none]
27
+ end
24
28
 
25
- # Set the no automatic title option.
26
- @none = params[:none]
29
+ def apply_format_options(params)
30
+ @line = chart.line_properties(params[:border] || params[:line])
31
+ @fill = chart.fill_properties(params[:fill])
32
+ @pattern = chart.pattern_properties(params[:pattern])
33
+ @gradient = chart.gradient_properties(params[:gradient])
27
34
  end
28
35
 
29
36
  private
@@ -0,0 +1,121 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ module Writexlsx
5
+ class Chart
6
+ class ChartArea
7
+ include Writexlsx::Utility::Common
8
+ include Writexlsx::Utility::ChartFormatting
9
+ include Writexlsx::Gradient
10
+
11
+ attr_reader :line, :fill, :pattern, :gradient, :layout
12
+
13
+ def initialize(params = {})
14
+ @layout = layout_properties(params[:layout])
15
+
16
+ # Allow 'border' as a synonym for 'line'.
17
+ border = params_to_border(params)
18
+
19
+ # Set the line properties for the chartarea.
20
+ @line = line_properties(border || params[:line])
21
+
22
+ # Set the pattern properties for the series.
23
+ @pattern = pattern_properties(params[:pattern])
24
+
25
+ # Set the gradient fill properties for the series.
26
+ @gradient = gradient_properties(params[:gradient])
27
+
28
+ # Map deprecated Spreadsheet::WriteExcel fill colour.
29
+ fill = params[:color] ? { color: params[:color] } : params[:fill]
30
+ @fill = fill_properties(fill)
31
+
32
+ # Pattern fill overrides solid fill.
33
+ @fill = nil if ptrue?(@pattern)
34
+
35
+ # Gradient fill overrides solid and pattern fills.
36
+ if ptrue?(@gradient)
37
+ @pattern = nil
38
+ @fill = nil
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def params_to_border(params)
45
+ line_weight = params[:line_weight]
46
+
47
+ # Map deprecated Spreadsheet::WriteExcel line_weight.
48
+ border = params[:border]
49
+ border = { width: swe_line_weight(line_weight) } if line_weight
50
+
51
+ # Map deprecated Spreadsheet::WriteExcel line_pattern.
52
+ if params[:line_pattern]
53
+ pattern = swe_line_pattern(params[:line_pattern])
54
+ if pattern == 'none'
55
+ border = { none: 1 }
56
+ else
57
+ border[:dash_type] = pattern
58
+ end
59
+ end
60
+
61
+ # Map deprecated Spreadsheet::WriteExcel line colour.
62
+ border[:color] = params[:line_color] if params[:line_color]
63
+ border
64
+ end
65
+
66
+ #
67
+ # Get the Spreadsheet::WriteExcel line pattern for backward compatibility.
68
+ #
69
+ def swe_line_pattern(val)
70
+ swe_line_pattern_hash[numeric_or_downcase(val)] || 'solid'
71
+ end
72
+
73
+ def swe_line_pattern_hash
74
+ {
75
+ 0 => 'solid',
76
+ 1 => 'dash',
77
+ 2 => 'dot',
78
+ 3 => 'dash_dot',
79
+ 4 => 'long_dash_dot_dot',
80
+ 5 => 'none',
81
+ 6 => 'solid',
82
+ 7 => 'solid',
83
+ 8 => 'solid',
84
+ 'solid' => 'solid',
85
+ 'dash' => 'dash',
86
+ 'dot' => 'dot',
87
+ 'dash-dot' => 'dash_dot',
88
+ 'dash-dot-dot' => 'long_dash_dot_dot',
89
+ 'none' => 'none',
90
+ 'dark-gray' => 'solid',
91
+ 'medium-gray' => 'solid',
92
+ 'light-gray' => 'solid'
93
+ }
94
+ end
95
+
96
+ #
97
+ # Get the Spreadsheet::WriteExcel line weight for backward compatibility.
98
+ #
99
+ def swe_line_weight(val)
100
+ swe_line_weight_hash[numeric_or_downcase(val)] || 1
101
+ end
102
+
103
+ def swe_line_weight_hash
104
+ {
105
+ 1 => 0.25,
106
+ 2 => 1,
107
+ 3 => 2,
108
+ 4 => 3,
109
+ 'hairline' => 0.25,
110
+ 'narrow' => 1,
111
+ 'medium' => 2,
112
+ 'wide' => 3
113
+ }
114
+ end
115
+
116
+ def numeric_or_downcase(val)
117
+ val.respond_to?(:coerce) ? val : val.downcase
118
+ end
119
+ end
120
+ end
121
+ end