write_xlsx 0.62.0 → 0.64.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 (107) hide show
  1. data/README.rdoc +14 -1
  2. data/examples/chart_data_tools.rb +215 -0
  3. data/examples/chart_pie.rb +36 -5
  4. data/examples/sparklines2.rb +1 -1
  5. data/examples/tab_colors.rb +3 -3
  6. data/lib/write_xlsx/chart.rb +559 -516
  7. data/lib/write_xlsx/chart/area.rb +4 -1
  8. data/lib/write_xlsx/chart/axis.rb +132 -0
  9. data/lib/write_xlsx/chart/bar.rb +17 -9
  10. data/lib/write_xlsx/chart/column.rb +9 -1
  11. data/lib/write_xlsx/chart/line.rb +24 -0
  12. data/lib/write_xlsx/chart/radar.rb +2 -2
  13. data/lib/write_xlsx/chart/scatter.rb +19 -0
  14. data/lib/write_xlsx/chart/stock.rb +10 -3
  15. data/lib/write_xlsx/drawing.rb +43 -44
  16. data/lib/write_xlsx/package/vml.rb +21 -14
  17. data/lib/write_xlsx/shape.rb +173 -22
  18. data/lib/write_xlsx/sparkline.rb +524 -0
  19. data/lib/write_xlsx/version.rb +1 -1
  20. data/lib/write_xlsx/workbook.rb +183 -115
  21. data/lib/write_xlsx/worksheet.rb +821 -1073
  22. data/lib/write_xlsx/worksheet/cell_data.rb +132 -0
  23. data/lib/write_xlsx/worksheet/print_style.rb +51 -0
  24. data/test/chart/test_add_series.rb +31 -6
  25. data/test/chart/test_write_d_lbls.rb +18 -18
  26. data/test/chart/test_write_number_format.rb +20 -24
  27. data/test/drawing/test_drawing_shape_01.rb +1 -1
  28. data/test/drawing/test_drawing_shape_02.rb +2 -2
  29. data/test/drawing/test_drawing_shape_03.rb +5 -5
  30. data/test/drawing/test_drawing_shape_04.rb +3 -3
  31. data/test/drawing/test_drawing_shape_05.rb +4 -4
  32. data/test/drawing/test_drawing_shape_07.rb +2 -2
  33. data/test/perl_output/chart_data_tools.xlsx +0 -0
  34. data/test/perl_output/chart_pie.xlsx +0 -0
  35. data/test/regression/disabled_test_vml04.rb +2 -2
  36. data/test/regression/test_chart_drop_lines01.rb +46 -0
  37. data/test/regression/test_chart_drop_lines02.rb +51 -0
  38. data/test/regression/test_chart_drop_lines03.rb +46 -0
  39. data/test/regression/test_chart_drop_lines04.rb +64 -0
  40. data/test/regression/test_chart_errorbars01.rb +47 -0
  41. data/test/regression/test_chart_errorbars02.rb +57 -0
  42. data/test/regression/test_chart_errorbars03.rb +53 -0
  43. data/test/regression/test_chart_errorbars04.rb +48 -0
  44. data/test/regression/test_chart_errorbars05.rb +47 -0
  45. data/test/regression/test_chart_errorbars06.rb +47 -0
  46. data/test/regression/test_chart_errorbars07.rb +66 -0
  47. data/test/regression/test_chart_font02.rb +1 -1
  48. data/test/regression/test_chart_font06.rb +1 -1
  49. data/test/regression/test_chart_gridlines04.rb +2 -1
  50. data/test/regression/test_chart_gridlines08.rb +2 -1
  51. data/test/regression/test_chart_points01.rb +37 -0
  52. data/test/regression/test_chart_points02.rb +40 -0
  53. data/test/regression/test_chart_points03.rb +42 -0
  54. data/test/regression/test_chart_points04.rb +52 -0
  55. data/test/regression/test_chart_points05.rb +49 -0
  56. data/test/regression/test_chart_points06.rb +49 -0
  57. data/test/regression/test_chartsheet05.rb +1 -1
  58. data/test/regression/test_chartsheet06.rb +1 -1
  59. data/test/regression/test_comment01.rb +1 -1
  60. data/test/regression/test_comment02.rb +1 -1
  61. data/test/regression/test_comment03.rb +1 -1
  62. data/test/regression/test_comment04.rb +2 -2
  63. data/test/regression/test_comment06.rb +1 -1
  64. data/test/regression/test_comment07.rb +1 -1
  65. data/test/regression/test_comment08.rb +1 -1
  66. data/test/regression/test_comment09.rb +1 -1
  67. data/test/regression/test_comment10.rb +1 -1
  68. data/test/regression/test_default_row04.rb +1 -1
  69. data/test/regression/test_escapes02.rb +1 -1
  70. data/test/regression/test_hyperlink15.rb +2 -2
  71. data/test/regression/test_shape_connect01.rb +6 -6
  72. data/test/regression/test_shape_connect02.rb +6 -6
  73. data/test/regression/test_shape_connect03.rb +11 -11
  74. data/test/regression/test_shape_connect04.rb +10 -10
  75. data/test/regression/test_shape_scale01.rb +2 -2
  76. data/test/regression/test_shape_stencil01.rb +3 -3
  77. data/test/regression/test_tab_color01.rb +1 -1
  78. data/test/regression/test_table04.rb +1 -1
  79. data/test/regression/test_table05.rb +1 -1
  80. data/test/regression/test_table06.rb +1 -1
  81. data/test/regression/test_vml01.rb +1 -1
  82. data/test/regression/test_vml02.rb +1 -1
  83. data/test/regression/test_vml03.rb +2 -2
  84. data/test/regression/xlsx_files/chart_drop_lines01.xlsx +0 -0
  85. data/test/regression/xlsx_files/chart_drop_lines02.xlsx +0 -0
  86. data/test/regression/xlsx_files/chart_drop_lines03.xlsx +0 -0
  87. data/test/regression/xlsx_files/chart_drop_lines04.xlsx +0 -0
  88. data/test/regression/xlsx_files/chart_errorbars01.xlsx +0 -0
  89. data/test/regression/xlsx_files/chart_errorbars02.xlsx +0 -0
  90. data/test/regression/xlsx_files/chart_errorbars03.xlsx +0 -0
  91. data/test/regression/xlsx_files/chart_errorbars04.xlsx +0 -0
  92. data/test/regression/xlsx_files/chart_errorbars05.xlsx +0 -0
  93. data/test/regression/xlsx_files/chart_errorbars06.xlsx +0 -0
  94. data/test/regression/xlsx_files/chart_errorbars07.xlsx +0 -0
  95. data/test/regression/xlsx_files/chart_points01.xlsx +0 -0
  96. data/test/regression/xlsx_files/chart_points02.xlsx +0 -0
  97. data/test/regression/xlsx_files/chart_points03.xlsx +0 -0
  98. data/test/regression/xlsx_files/chart_points04.xlsx +0 -0
  99. data/test/regression/xlsx_files/chart_points05.xlsx +0 -0
  100. data/test/regression/xlsx_files/chart_points06.xlsx +0 -0
  101. data/test/regression/xlsx_files/chart_stock02.xlsx +0 -0
  102. data/test/test_example_match.rb +278 -57
  103. data/test/worksheet/test_convert_date_time_02.rb +427 -433
  104. data/test/worksheet/test_convert_date_time_03.rb +1 -1
  105. data/test/worksheet/test_write_sheet_pr.rb +2 -2
  106. data/test/worksheet/test_write_sheet_view1.rb +2 -2
  107. metadata +80 -10
@@ -28,7 +28,7 @@ def initialize(subtype)
28
28
 
29
29
  # Override and reset the default axis values.
30
30
  if @subtype == 'percent_stacked'
31
- @y_axis[:_defaults][:num_format] = '0%'
31
+ @y_axis.defaults[:num_format] = '0%'
32
32
  end
33
33
 
34
34
  set_y_axis
@@ -60,6 +60,9 @@ def write_area_chart(params)
60
60
  # Write the series elements.
61
61
  series.each {|s| write_series(s)}
62
62
 
63
+ # Write the c:dropLines element.
64
+ write_drop_lines
65
+
63
66
  # Write the c:marker element.
64
67
  write_marker_value
65
68
 
@@ -0,0 +1,132 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'write_xlsx/package/xml_writer_simple'
3
+ require 'write_xlsx/utility'
4
+
5
+ module Writexlsx
6
+ class Chart
7
+ class Axis
8
+ include Writexlsx::Utility
9
+
10
+ attr_accessor :defaults, :name, :formula, :data_id, :reverse
11
+ attr_accessor :min, :max
12
+ attr_accessor :minor_unit, :major_unit, :minor_unit_type, :major_unit_type
13
+ attr_accessor :log_base, :crossing, :position, :label_position, :visible
14
+ attr_accessor :num_format, :num_format_linked, :num_font, :name_font
15
+ attr_accessor :major_gridlines, :minor_gridlines, :major_tick_mark
16
+
17
+ #
18
+ # Convert user defined axis values into axis instance.
19
+ #
20
+ def merge_with_hash(chart, params) # :nodoc:
21
+ @chart = chart
22
+ args = (defaults || {}).merge(params)
23
+
24
+ @name, @formula = @chart.process_names(args[:name], args[:name_formula])
25
+ @data_id = @chart.get_data_id(@formula, args[:data])
26
+ @reverse = args[:reverse]
27
+ @min = args[:min]
28
+ @max = args[:max]
29
+ @minor_unit = args[:minor_unit]
30
+ @major_unit = args[:major_unit]
31
+ @minor_unit_type = args[:minor_unit_type]
32
+ @major_unit_type = args[:major_unit_type]
33
+ @log_base = args[:log_base]
34
+ @crossing = args[:crossing]
35
+ @label_position = args[:label_position]
36
+ @num_format = args[:num_format]
37
+ @num_format_linked = args[:num_format_linked]
38
+ @visible = args[:visible] || 1
39
+
40
+ # Map major/minor_gridlines properties.
41
+ [:major_gridlines, :minor_gridlines].each do |lines|
42
+ if args[lines] && ptrue?(args[lines][:visible])
43
+ instance_variable_set("@#{lines}", gridline_properties(args[lines]))
44
+ else
45
+ instance_variable_set("@#{lines}", nil)
46
+ end
47
+ end
48
+ @major_tick_mark = args[:major_tick_mark]
49
+
50
+ # Only use the first letter of bottom, top, left or right.
51
+ @position = args[:position]
52
+ @position = @position.downcase[0, 1] if @position
53
+
54
+ # Set the font properties if present.
55
+ @num_font = @chart.convert_font_args(args[:num_font])
56
+ @name_font = @chart.convert_font_args(args[:name_font])
57
+ end
58
+
59
+ #
60
+ # Write the <c:numberFormat> element. Note: It is assumed that if a user
61
+ # defined number format is supplied (i.e., non-default) then the sourceLinked
62
+ # attribute is 0. The user can override this if required.
63
+ #
64
+
65
+ def write_number_format(writer) # :nodoc:
66
+ source_linked = 1
67
+
68
+ # Check if a user defined number format has been set.
69
+ if @defaults && @num_format != @defaults[:num_format]
70
+ source_linked = 0
71
+ end
72
+
73
+ # User override of sourceLinked.
74
+ if ptrue?(@num_format_linked)
75
+ source_linked = 1
76
+ end
77
+
78
+ attributes = [
79
+ 'formatCode', @num_format,
80
+ 'sourceLinked', source_linked
81
+ ]
82
+
83
+ writer.empty_tag('c:numFmt', attributes)
84
+ end
85
+
86
+ #
87
+ # Write the <c:numFmt> element. Special case handler for category axes which
88
+ # don't always have a number format.
89
+ #
90
+ def write_cat_number_format(writer, cat_has_num_fmt)
91
+ source_linked = 1
92
+ default_format = true
93
+
94
+ # Check if a user defined number format has been set.
95
+ if @defaults && @num_format != @defaults[:num_format]
96
+ source_linked = 0
97
+ default_format = false
98
+ end
99
+
100
+ # User override of linkedSource.
101
+ if @num_format_linked
102
+ source_linked = 1
103
+ end
104
+
105
+ # Skip if cat doesn't have a num format (unless it is non-default).
106
+ if !cat_has_num_fmt && default_format
107
+ return ''
108
+ end
109
+
110
+ attributes = [
111
+ 'formatCode', @num_format,
112
+ 'sourceLinked', source_linked,
113
+ ]
114
+
115
+ writer.empty_tag('c:numFmt', attributes)
116
+ end
117
+
118
+ #
119
+ # Convert user defined gridline properties to the structure required internally.
120
+ #
121
+ def gridline_properties(args)
122
+ # Set the visible property for the gridline.
123
+ gridline = { :_visible => args[:visible] }
124
+
125
+ # Set the line properties for the gridline.
126
+ gridline[:_line] = @chart.line_properties(args[:line])
127
+
128
+ gridline
129
+ end
130
+ end
131
+ end
132
+ end
@@ -29,19 +29,19 @@ def initialize(subtype)
29
29
  @show_crosses = false
30
30
 
31
31
  # Override and reset the default axis values.
32
- if @x_axis[:_defaults]
33
- @x_axis[:_defaults][:major_gridlines] = { :visible => 1 }
32
+ if @x_axis.defaults
33
+ @x_axis.defaults[:major_gridlines] = { :visible => 1 }
34
34
  else
35
- @x_axis[:_defaults] = { :major_gridlines => { :visible => 1 } }
35
+ @x_axis.defaults = { :major_gridlines => { :visible => 1 } }
36
36
  end
37
- if @y_axis[:_defaults]
38
- @y_axis[:_defaults][:major_gridlines] = { :visible => 0 }
37
+ if @y_axis.defaults
38
+ @y_axis.defaults[:major_gridlines] = { :visible => 0 }
39
39
  else
40
- @y_axis[:_defaults] = { :major_gridlines => { :visible => 0 } }
40
+ @y_axis.defaults = { :major_gridlines => { :visible => 0 } }
41
41
  end
42
42
 
43
43
  if @subtype == 'percent_stacked'
44
- @x_axis[:_defaults][:num_format] = '0%'
44
+ @x_axis.defaults[:num_format] = '0%'
45
45
  end
46
46
 
47
47
  set_x_axis
@@ -55,8 +55,8 @@ def write_chart_type(params)
55
55
  if params[:primary_axes] != 0
56
56
  # Reverse X and Y axes for Bar charts.
57
57
  @y_axis, @x_axis = @x_axis, @y_axis
58
- if @y2_axis[:_position] == 'r'
59
- @y2_axis[:_position] = 't'
58
+ if @y2_axis.position == 'r'
59
+ @y2_axis.position = 't'
60
60
  end
61
61
  end
62
62
 
@@ -74,6 +74,14 @@ def write_bar_dir
74
74
 
75
75
  @writer.empty_tag('c:barDir', attributes)
76
76
  end
77
+
78
+ #
79
+ # Write the <c:errDir> element. Overridden from Chart class since it is not
80
+ # used in Bar charts.
81
+ #
82
+ def write_err_dir(direction)
83
+ # do nothing
84
+ end
77
85
  end
78
86
  end
79
87
  end
@@ -35,7 +35,7 @@ def initialize(subtype)
35
35
 
36
36
  # Override and reset the default axis values.
37
37
  if @subtype == 'percent_stacked'
38
- @y_axis[:_defaults][:num_format] = '0%'
38
+ @y_axis.defaults[:num_format] = '0%'
39
39
  end
40
40
 
41
41
  set_y_axis
@@ -59,6 +59,14 @@ def write_bar_dir
59
59
 
60
60
  @writer.empty_tag('c:barDir', attributes)
61
61
  end
62
+
63
+ #
64
+ # Write the <c:errDir> element. Overridden from Chart class since it is not
65
+ # used in Bar charts.
66
+ #
67
+ def write_err_dir(direction)
68
+ # do nothing
69
+ end
62
70
  end
63
71
  end
64
72
  end
@@ -45,6 +45,15 @@ def write_line_chart(params)
45
45
  # Write the series elements.
46
46
  series.each {|s| write_series(s)}
47
47
 
48
+ # Write the c:dropLines element.
49
+ write_drop_lines
50
+
51
+ # Write the c:hiLowLines element.
52
+ write_hi_low_lines
53
+
54
+ # Write the c:upDownBars element.
55
+ write_up_down_bars
56
+
48
57
  # Write the c:marker element.
49
58
  write_marker_value
50
59
 
@@ -52,6 +61,21 @@ def write_line_chart(params)
52
61
  write_axis_ids(params)
53
62
  end
54
63
  end
64
+
65
+ #
66
+ # Write an individual <c:dPt> element. Override the parent method to add
67
+ # markers.
68
+ #
69
+ def write_d_pt_point(index, point)
70
+ @writer.tag_elements('c:dPt') do
71
+ # Write the c:idx element.
72
+ write_idx(index)
73
+ @writer.tag_elements('c:marker') do
74
+ # Write the c:spPr element.
75
+ write_sp_pr(point)
76
+ end
77
+ end
78
+ end
55
79
  end
56
80
  end
57
81
  end
@@ -36,11 +36,11 @@ def initialize(subtype)
36
36
  end
37
37
 
38
38
  # Override and reset the default axis values.
39
- @x_axis[:_defaults][:major_gridlines] = { :visible => 1 }
39
+ @x_axis.defaults[:major_gridlines] = { :visible => 1 }
40
40
  set_x_axis
41
41
 
42
42
  # Hardcode major_tick_mark for now untill there is an accessor.
43
- @y_axis[:_major_tick_mark] = 'cross'
43
+ @y_axis.major_tick_mark = 'cross'
44
44
  end
45
45
 
46
46
  #
@@ -110,10 +110,14 @@ def write_ser(series)
110
110
  write_sp_pr(series)
111
111
  # Write the c:marker element.
112
112
  write_marker(series[:_marker])
113
+ # Write the c:dPt element.
114
+ write_d_pt(series[:_points])
113
115
  # Write the c:dLbls element.
114
116
  write_d_lbls(series[:_labels])
115
117
  # Write the c:trendline element.
116
118
  write_trendline(series[:_trendline])
119
+ # Write the c:errBars element.
120
+ write_error_bars(series[:_error_bars])
117
121
  # Write the c:xVal element.
118
122
  write_x_val(series)
119
123
  # Write the c:yVal element.
@@ -266,6 +270,21 @@ def modify_series_formatting
266
270
  end
267
271
  end
268
272
  end
273
+
274
+ #
275
+ # Write an individual <c:dPt> element. Override the parent method to add
276
+ # markers.
277
+ #
278
+ def write_d_pt_point(index, point)
279
+ @writer.tag_elements('c:dPt') do
280
+ # Write the c:idx element.
281
+ write_idx(index)
282
+ @writer.tag_elements('c:marker') do
283
+ # Write the c:spPr element.
284
+ write_sp_pr(point)
285
+ end
286
+ end
287
+ end
269
288
  end
270
289
  end
271
290
  end
@@ -27,10 +27,11 @@ class Stock < self
27
27
  def initialize(subtype)
28
28
  super(subtype)
29
29
  @show_crosses = false
30
+ @hi_low_lines = {}
30
31
 
31
32
  # Override and reset the default axis values.
32
- @x_axis[:_defaults][:num_format] = 'dd/mm/yyyy'
33
- @x2_axis[:_defaults][:num_format] = 'dd/mm/yyyy'
33
+ @x_axis.defaults[:num_format] = 'dd/mm/yyyy'
34
+ @x2_axis.defaults[:num_format] = 'dd/mm/yyyy'
34
35
  set_x_axis
35
36
  set_x2_axis
36
37
  end
@@ -62,8 +63,14 @@ def write_stock_chart(params)
62
63
  # Write the series elements.
63
64
  series.each {|s| write_series(s)}
64
65
 
66
+ # Write the c:dtopLines element.
67
+ write_drop_lines
68
+
65
69
  # Write the c:hiLowLines element.
66
- write_hi_low_lines if params[:primary_axes] == 1
70
+ write_hi_low_lines if ptrue?(params[:primary_axes])
71
+
72
+ # Write the c:upDownBars element.
73
+ write_up_down_bars
67
74
 
68
75
  # Write the c:marker element.
69
76
  write_marker_value
@@ -89,7 +89,7 @@ def write_two_cell_anchor(*args)
89
89
  attributes << :editAs << 'oneCell' if type == 2
90
90
 
91
91
  # Add attribute for shapes.
92
- attributes << :editAs << shape[:edit_as] if shape && !shape[:edit_as].nil?
92
+ attributes << :editAs << shape.edit_as if shape && !shape.edit_as.nil?
93
93
 
94
94
  @writer.tag_elements('xdr:twoCellAnchor', attributes) do
95
95
  # Write the xdr:from element.
@@ -400,7 +400,7 @@ def write_client_data
400
400
  # Write the <xdr:sp> element.
401
401
  #
402
402
  def write_sp(index, col_absolute, row_absolute, width, height, shape)
403
- if shape[:connect] != 0
403
+ if shape.connect != 0
404
404
  attributes = [:macro, '']
405
405
  @writer.tag_elements('xdr:cxnSp', attributes) do
406
406
 
@@ -422,7 +422,7 @@ def write_sp(index, col_absolute, row_absolute, width, height, shape)
422
422
  write_xdr_sp_pr(index, col_absolute, row_absolute, width, height, shape)
423
423
 
424
424
  # Write the xdr:txBody element.
425
- if shape[:text] != 0
425
+ if shape.text != 0
426
426
  write_txBody(col_absolute, row_absolute, width, height, shape)
427
427
  end
428
428
  end
@@ -435,21 +435,21 @@ def write_sp(index, col_absolute, row_absolute, width, height, shape)
435
435
  def write_nv_cxn_sp_pr(index, shape)
436
436
  @writer.tag_elements('xdr:nvCxnSpPr') do
437
437
 
438
- shape[:name] = [shape[:type], index].join(' ') unless shape[:name]
439
- write_c_nv_pr(shape[:id], shape[:name])
438
+ shape.name = [shape.type, index].join(' ') unless shape.name
439
+ write_c_nv_pr(shape.id, shape.name)
440
440
 
441
441
  @writer.tag_elements('xdr:cNvCxnSpPr') do
442
442
 
443
443
  attributes = [:noChangeShapeType, '1']
444
444
  @writer.empty_tag('a:cxnSpLocks', attributes)
445
445
 
446
- if shape[:start]
447
- attributes = ['id', shape[:start], 'idx', shape[:start_index]]
446
+ if shape.start
447
+ attributes = ['id', shape.start, 'idx', shape.start_index]
448
448
  @writer.empty_tag('a:stCxn', attributes)
449
449
  end
450
450
 
451
- if shape[:end]
452
- attributes = ['id', shape[:end], 'idx', shape[:end_index]]
451
+ if shape.end
452
+ attributes = ['id', shape.end, 'idx', shape.end_index]
453
453
  @writer.empty_tag('a:endCxn', attributes)
454
454
  end
455
455
  end
@@ -461,14 +461,13 @@ def write_nv_cxn_sp_pr(index, shape)
461
461
  #
462
462
  def write_nv_sp_pr(index, shape)
463
463
  attributes = []
464
+ attributes << 'txBox' << 1 if shape.tx_box
464
465
 
465
466
  @writer.tag_elements('xdr:nvSpPr') do
466
- shape_name = "#{shape[:type]} #{index}"
467
- write_c_nv_pr(shape[:id], shape_name)
468
- attributes = ['txBox', 1] if shape[:tx_box] != 0
467
+ write_c_nv_pr(shape.id, "#{shape.type} #{index}")
468
+
469
469
  @writer.tag_elements('xdr:cNvSpPr', attributes) do
470
- attributes = [:noChangeArrowheads, '1']
471
- @writer.empty_tag('a:spLocks', attributes)
470
+ @writer.empty_tag('a:spLocks', [:noChangeArrowheads, '1'])
472
471
  end
473
472
  end
474
473
  end
@@ -485,7 +484,7 @@ def write_pic(index, col_absolute, row_absolute, width, height, description)
485
484
 
486
485
  # Pictures are rectangle shapes by default.
487
486
  shape = Shape.new
488
- shape[:type] = 'rect'
487
+ shape.type = 'rect'
489
488
 
490
489
  # Write the xdr:spPr element.
491
490
  write_sp_pr(col_absolute, row_absolute, width, height, shape)
@@ -596,9 +595,9 @@ def write_xdr_sp_pr(index, col_absolute, row_absolute, width, height, shape)
596
595
  # Write the a:prstGeom element.
597
596
  write_a_prst_geom(shape)
598
597
 
599
- if shape[:fill].to_s.bytesize > 1
598
+ if shape.fill.to_s.bytesize > 1
600
599
  # Write the a:solidFill element.
601
- write_a_solid_fill(shape[:fill])
600
+ write_a_solid_fill(shape.fill)
602
601
  else
603
602
  @writer.empty_tag('a:noFill')
604
603
  end
@@ -611,15 +610,15 @@ def write_xdr_sp_pr(index, col_absolute, row_absolute, width, height, shape)
611
610
  #
612
611
  # Write the <a:xfrm> element.
613
612
  #
614
- def write_a_xfrm(col_absolute, row_absolute, width, height, shape = {})
613
+ def write_a_xfrm(col_absolute, row_absolute, width, height, shape = nil)
615
614
  attributes = []
616
615
 
617
- rotation = shape[:rotation] || 0
616
+ rotation = shape ? shape.rotation : 0
618
617
  rotation *= 60000
619
618
 
620
619
  attributes << 'rot' << rotation if rotation != 0
621
- attributes << 'flipH' << 1 if ptrue?(shape[:flip_h])
622
- attributes << 'flipV' << 1 if ptrue?(shape[:flip_v])
620
+ attributes << 'flipH' << 1 if shape && ptrue?(shape.flip_h)
621
+ attributes << 'flipV' << 1 if shape && ptrue?(shape.flip_v)
623
622
 
624
623
  @writer.tag_elements('a:xfrm', attributes) do
625
624
  # Write the a:off element.
@@ -659,7 +658,7 @@ def write_a_ext(cx, cy)
659
658
  #
660
659
  def write_a_prst_geom(shape = {})
661
660
  attributes = []
662
- attributes << 'prst' << shape[:type] if shape[:type]
661
+ attributes << 'prst' << shape.type if shape.type
663
662
 
664
663
  @writer.tag_elements('a:prstGeom', attributes) do
665
664
  # Write the a:avLst element.
@@ -671,11 +670,11 @@ def write_a_prst_geom(shape = {})
671
670
  # Write the <a:avLst> element.
672
671
  #
673
672
  def write_a_av_lst(shape = {})
674
- if shape[:adjustments].respond_to?(:empty?)
675
- adjustments = shape[:adjustments]
676
- elsif shape[:adjustments].respond_to?(:coerce)
677
- adjustments = [shape[:adjustments]]
678
- elsif !shape[:adjustments]
673
+ if shape.adjustments.respond_to?(:empty?)
674
+ adjustments = shape.adjustments
675
+ elsif shape.adjustments.respond_to?(:coerce)
676
+ adjustments = [shape.adjustments]
677
+ elsif !shape.adjustments
679
678
  adjustments = []
680
679
  end
681
680
 
@@ -685,7 +684,7 @@ def write_a_av_lst(shape = {})
685
684
  adjustments.each do |adj|
686
685
  i += 1
687
686
  # Only connectors have multiple adjustments.
688
- suffix = shape[:connect] != 0 ? i : ''
687
+ suffix = shape.connect != 0 ? i : ''
689
688
 
690
689
  # Scale Adjustments: 100,000 = 100%.
691
690
  adj_int = (adj * 1000).to_i
@@ -714,10 +713,10 @@ def write_a_solid_fill(rgb = '000000')
714
713
  # Write the <a:ln> elements.
715
714
  #
716
715
  def write_a_ln(shape = {})
717
- weight = shape[:line_weight] || 0
716
+ weight = shape.line_weight || 0
718
717
  attributes = ['w', weight * 9525]
719
718
  @writer.tag_elements('a:ln', attributes) do
720
- line = shape[:line] || 0
719
+ line = shape.line || 0
721
720
  if line.to_s.bytesize > 1
722
721
  # Write the a:solidFill element.
723
722
  write_a_solid_fill(line)
@@ -725,12 +724,12 @@ def write_a_ln(shape = {})
725
724
  @writer.empty_tag('a:noFill')
726
725
  end
727
726
 
728
- if shape[:line_type] != ''
729
- attributes = ['val', shape[:line_type]]
727
+ if shape.line_type != ''
728
+ attributes = ['val', shape.line_type]
730
729
  @writer.empty_tag('a:prstDash', attributes)
731
730
  end
732
731
 
733
- if shape[:connect] != 0
732
+ if shape.connect != 0
734
733
  @writer.empty_tag('a:round')
735
734
  else
736
735
  attributes = ['lim', 800000]
@@ -753,7 +752,7 @@ def write_txBody(col_absolute, row_absolute, width, height, shape)
753
752
  :tIns, "22860",
754
753
  :rIns, "27432",
755
754
  :bIns, "22860",
756
- :anchor, shape[:valign],
755
+ :anchor, shape.valign,
757
756
  :upright, "1"
758
757
  ]
759
758
  @writer.tag_elements('xdr:txBody') do
@@ -761,23 +760,23 @@ def write_txBody(col_absolute, row_absolute, width, height, shape)
761
760
  @writer.empty_tag('a:lstStyle')
762
761
 
763
762
  @writer.tag_elements('a:p') do
764
- rotation = shape[:format][:rotation] || 0
763
+ rotation = shape.format[:rotation] || 0
765
764
  rotation *= 60000
766
765
 
767
- attributes = [:algn, shape[:align], :rtl, rotation]
766
+ attributes = [:algn, shape.align, :rtl, rotation]
768
767
  @writer.tag_elements('a:pPr', attributes) do
769
768
  attributes = [:sz, "1000"]
770
769
  @writer.empty_tag('a:defRPr', attributes)
771
770
  end
772
771
 
773
772
  @writer.tag_elements('a:r') do
774
- size = shape[:format][:size] || 8
773
+ size = shape.format[:size] || 8
775
774
  size *= 100
776
775
 
777
- bold = shape[:format][:bold] || 0
778
- italic = shape[:format][:italic] || 0
779
- underline = ptrue?(shape[:format][:underline]) ? 'sng' : 'none'
780
- strike = ptrue?(shape[:format][:font_strikeout]) ? 'Strike' : 'noStrike'
776
+ bold = shape.format[:bold] || 0
777
+ italic = shape.format[:italic] || 0
778
+ underline = ptrue?(shape.format[:underline]) ? 'sng' : 'none'
779
+ strike = ptrue?(shape.format[:font_strikeout]) ? 'Strike' : 'noStrike'
781
780
 
782
781
  attributes = [
783
782
  :lang, "en-US",
@@ -789,7 +788,7 @@ def write_txBody(col_absolute, row_absolute, width, height, shape)
789
788
  :baseline, 0
790
789
  ]
791
790
  @writer.tag_elements('a:rPr', attributes) do
792
- color = shape[:format][:color]
791
+ color = shape.format[:color]
793
792
  if color
794
793
  color = shape.get_palette_color(color)
795
794
  color = color.sub(/^FF/, '') # Remove leading FF from rgb for shape color.
@@ -799,13 +798,13 @@ def write_txBody(col_absolute, row_absolute, width, height, shape)
799
798
 
800
799
  write_a_solid_fill(color)
801
800
 
802
- font = shape[:format][:font] || 'Calibri'
801
+ font = shape.format[:font] || 'Calibri'
803
802
  attributes = [:typeface, font]
804
803
  @writer.empty_tag('a:latin', attributes)
805
804
  @writer.empty_tag('a:cs', attributes)
806
805
  end
807
806
  @writer.tag_elements('a:t') do
808
- @writer.characters(shape[:text])
807
+ @writer.characters(shape.text)
809
808
  end
810
809
  end
811
810
  end