axlsx 1.1.4 → 1.2.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.
- data/.yardopts +5 -2
- data/CHANGELOG.md +39 -0
- data/README.md +108 -31
- data/Rakefile +11 -3
- data/examples/basic_charts.rb +54 -0
- data/examples/chart_colors.rb +17 -2
- data/examples/data_validation.rb +50 -0
- data/examples/example.rb +130 -47
- data/examples/example.xlsx +0 -0
- data/examples/example_streamed.xlsx +0 -0
- data/examples/extractive.pdf +0 -0
- data/examples/extractive.rb +3 -0
- data/examples/no-use_autowidth.xlsx +0 -0
- data/examples/scraping_html.rb +91 -0
- data/examples/shared_strings_example.xlsx +0 -0
- data/examples/sheet_protection.rb +10 -0
- data/examples/sheet_view.rb +34 -0
- data/examples/two_cell_anchor_image.rb +11 -0
- data/lib/axlsx/content_type/content_type.rb +2 -0
- data/lib/axlsx/content_type/default.rb +30 -15
- data/lib/axlsx/content_type/override.rb +29 -14
- data/lib/axlsx/doc_props/app.rb +161 -104
- data/lib/axlsx/doc_props/core.rb +9 -5
- data/lib/axlsx/drawing/ax_data_source.rb +7 -6
- data/lib/axlsx/drawing/axis.rb +82 -36
- data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
- data/lib/axlsx/drawing/bar_series.rb +2 -1
- data/lib/axlsx/drawing/cat_axis.rb +43 -39
- data/lib/axlsx/drawing/chart.rb +65 -54
- data/lib/axlsx/drawing/d_lbls.rb +100 -0
- data/lib/axlsx/drawing/drawing.rb +20 -8
- data/lib/axlsx/drawing/graphic_frame.rb +2 -1
- data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
- data/lib/axlsx/drawing/num_data.rb +2 -2
- data/lib/axlsx/drawing/num_data_source.rb +4 -1
- data/lib/axlsx/drawing/pic.rb +44 -4
- data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
- data/lib/axlsx/drawing/scatter_chart.rb +2 -8
- data/lib/axlsx/drawing/title.rb +21 -9
- data/lib/axlsx/drawing/two_cell_anchor.rb +46 -9
- data/lib/axlsx/drawing/view_3D.rb +41 -31
- data/lib/axlsx/drawing/vml_drawing.rb +42 -0
- data/lib/axlsx/drawing/vml_shape.rb +125 -0
- data/lib/axlsx/package.rb +44 -16
- data/lib/axlsx/rels/relationship.rb +3 -3
- data/lib/axlsx/rels/relationships.rb +1 -11
- data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +1 -1
- data/lib/axlsx/stylesheet/table_style.rb +3 -3
- data/lib/axlsx/util/constants.rb +28 -0
- data/lib/axlsx/util/simple_typed_list.rb +15 -21
- data/lib/axlsx/util/validators.rb +80 -7
- data/lib/axlsx/version.rb +2 -7
- data/lib/axlsx/workbook/defined_name.rb +174 -0
- data/lib/axlsx/workbook/defined_names.rb +21 -0
- data/lib/axlsx/workbook/workbook.rb +65 -13
- data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +35 -7
- data/lib/axlsx/workbook/worksheet/col.rb +15 -0
- data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
- data/lib/axlsx/workbook/worksheet/comment.rb +101 -0
- data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
- data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
- data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
- data/lib/axlsx/workbook/worksheet/data_validation.rb +245 -0
- data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
- data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
- data/lib/axlsx/workbook/worksheet/page_setup.rb +113 -0
- data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
- data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
- data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
- data/lib/axlsx/workbook/worksheet/row.rb +36 -20
- data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +24 -0
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +224 -0
- data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
- data/lib/axlsx/workbook/worksheet/table.rb +2 -2
- data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +377 -255
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
- data/lib/axlsx.rb +30 -15
- data/test/content_type/tc_content_type.rb +1 -6
- data/test/doc_props/tc_app.rb +31 -1
- data/test/doc_props/tc_core.rb +3 -1
- data/test/drawing/tc_axis.rb +38 -3
- data/test/drawing/tc_bar_3D_chart.rb +12 -12
- data/test/drawing/tc_bar_series.rb +1 -2
- data/test/drawing/tc_cat_axis.rb +3 -3
- data/test/drawing/tc_chart.rb +29 -9
- data/test/drawing/tc_d_lbls.rb +47 -0
- data/test/drawing/tc_drawing.rb +11 -5
- data/test/drawing/tc_hyperlink.rb +4 -5
- data/test/drawing/tc_line_series.rb +7 -3
- data/test/drawing/tc_num_data.rb +5 -1
- data/test/drawing/tc_pic.rb +22 -2
- data/test/drawing/tc_pie_3D_chart.rb +4 -8
- data/test/drawing/tc_pie_series.rb +7 -2
- data/test/drawing/tc_scatter_chart.rb +6 -1
- data/test/drawing/tc_scatter_series.rb +1 -1
- data/test/drawing/tc_series.rb +1 -1
- data/test/drawing/tc_title.rb +16 -0
- data/test/drawing/tc_two_cell_anchor.rb +1 -2
- data/test/drawing/tc_view_3D.rb +18 -18
- data/test/drawing/tc_vml_drawing.rb +25 -0
- data/test/drawing/tc_vml_shape.rb +100 -0
- data/test/rels/tc_relationship.rb +1 -0
- data/test/stylesheet/tc_gradient_fill.rb +8 -0
- data/test/stylesheet/tc_pattern_fill.rb +7 -1
- data/test/stylesheet/tc_styles.rb +3 -4
- data/test/stylesheet/tc_table_style.rb +8 -0
- data/test/stylesheet/tc_table_style_element.rb +10 -1
- data/test/tc_helper.rb +1 -0
- data/test/tc_package.rb +93 -17
- data/test/util/tc_simple_typed_list.rb +13 -0
- data/test/util/tc_validators.rb +95 -9
- data/test/workbook/tc_defined_name.rb +41 -0
- data/test/workbook/tc_workbook.rb +5 -3
- data/test/workbook/worksheet/table/tc_table.rb +3 -11
- data/test/workbook/worksheet/tc_cell.rb +30 -6
- data/test/workbook/worksheet/tc_col.rb +9 -0
- data/test/workbook/worksheet/tc_comment.rb +57 -0
- data/test/workbook/worksheet/tc_comments.rb +57 -0
- data/test/workbook/worksheet/tc_conditional_formatting.rb +44 -0
- data/test/workbook/worksheet/tc_data_bar.rb +1 -1
- data/test/workbook/worksheet/tc_data_validation.rb +265 -0
- data/test/workbook/worksheet/tc_page_setup.rb +138 -0
- data/test/workbook/worksheet/tc_pane.rb +94 -0
- data/test/workbook/worksheet/tc_print_options.rb +72 -0
- data/test/workbook/worksheet/tc_protected_range.rb +17 -0
- data/test/workbook/worksheet/tc_row.rb +32 -14
- data/test/workbook/worksheet/tc_selection.rb +94 -0
- data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
- data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
- data/test/workbook/worksheet/tc_worksheet.rb +138 -48
- metadata +140 -80
- data/examples/#extractive.csv# +0 -0
- data/examples/#extractive.rb# +0 -45
- data/examples/chart_colors.rb~ +0 -0
- data/examples/chart_colors.xlsx +0 -0
- data/examples/colored_series_data.xlsx +0 -0
- data/examples/conditional_formatting/getting_barred.xlsx +0 -0
- data/examples/example.csv +0 -1000
- data/examples/extractive.csv +0 -1
- data/examples/extractive.csv~ +0 -1
- data/examples/extractive.rb~ +0 -3
- data/examples/extractive.xlsx +0 -0
- data/examples/stack.rb +0 -21
- data/examples/stack.rb~ +0 -27
- data/examples/stack.xlsx +0 -0
- data/examples/~$chart_colors.xlsx +0 -0
- data/examples/~$extractive.xlsx +0 -0
- data/lib/axlsx/drawing/ax_data_source.rb~ +0 -55
- data/lib/axlsx/drawing/data_source.rb~ +0 -51
- data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
- data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
- data/lib/axlsx/drawing/num_data.rb~ +0 -51
- data/lib/axlsx/drawing/num_data_source.rb~ +0 -54
- data/lib/axlsx/drawing/num_val.rb~ +0 -40
- data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
- data/lib/axlsx/drawing/ref.rb~ +0 -41
- data/lib/axlsx/drawing/str_data.rb~ +0 -58
- data/lib/axlsx/drawing/str_val.rb~ +0 -35
- data/lib/axlsx/util/cbf.rb +0 -333
- data/lib/axlsx/util/cfb.rb~ +0 -201
- data/lib/axlsx/util/font_tables.rb~ +0 -0
- data/lib/axlsx/util/ms_off_crypto.rb +0 -189
- data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
- data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
- data/lib/axlsx/util/parser.rb~ +0 -6
- data/lib/axlsx/util/storage.rb~ +0 -0
- data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
- data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
- data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
- data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
- data/lib/schema/dc.xsd~ +0 -118
- data/lib/schema/dcterms.xsd~ +0 -331
- data/lib/schema/opc-coreProperties.xsd~ +0 -50
- data/test/drawing/tc_data_source.rb~ +0 -30
- data/test/drawing/tc_num_data.rb~ +0 -35
- data/test/drawing/tc_num_val.rb~ +0 -29
- data/test/drawing/tc_str_data.rb~ +0 -30
- data/test/drawing/tc_str_val.rb~ +0 -26
- data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
- data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
- data/test/workbook/worksheet/tc_col.rb~ +0 -10
- data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
- data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
- data/test/workbook/worksheet/tc_icon_set.rb~ +0 -0
|
@@ -10,24 +10,29 @@ module Axlsx
|
|
|
10
10
|
|
|
11
11
|
# the category axis
|
|
12
12
|
# @return [CatAxis]
|
|
13
|
-
attr_reader :
|
|
13
|
+
attr_reader :cat_axis
|
|
14
|
+
alias :catAxis :cat_axis
|
|
14
15
|
|
|
15
|
-
# the
|
|
16
|
+
# the value axis
|
|
16
17
|
# @return [ValAxis]
|
|
17
|
-
attr_reader :
|
|
18
|
+
attr_reader :val_axis
|
|
19
|
+
alias :valAxis :val_axis
|
|
18
20
|
|
|
19
21
|
# The direction of the bars in the chart
|
|
20
22
|
# must be one of [:bar, :col]
|
|
21
23
|
# @return [Symbol]
|
|
22
|
-
attr_reader :
|
|
24
|
+
attr_reader :bar_dir
|
|
25
|
+
alias :barDir :bar_dir
|
|
23
26
|
|
|
24
27
|
# space between bar or column clusters, as a percentage of the bar or column width.
|
|
25
28
|
# @return [String]
|
|
26
|
-
attr_reader :
|
|
29
|
+
attr_reader :gap_depth
|
|
30
|
+
alias :gapDepth :gap_depth
|
|
27
31
|
|
|
28
32
|
# space between bar or column clusters, as a percentage of the bar or column width.
|
|
29
33
|
# @return [String]
|
|
30
|
-
attr_reader :
|
|
34
|
+
attr_reader :gap_width
|
|
35
|
+
alias :gapWidth :gap_width
|
|
31
36
|
|
|
32
37
|
#grouping for a column, line, or area chart.
|
|
33
38
|
# must be one of [:percentStacked, :clustered, :standard, :stacked]
|
|
@@ -46,38 +51,42 @@ module Axlsx
|
|
|
46
51
|
# @param [GraphicFrame] frame The workbook that owns this chart.
|
|
47
52
|
# @option options [Cell, String] title
|
|
48
53
|
# @option options [Boolean] show_legend
|
|
49
|
-
# @option options [Symbol]
|
|
54
|
+
# @option options [Symbol] bar_dir
|
|
50
55
|
# @option options [Symbol] grouping
|
|
51
|
-
# @option options [String]
|
|
52
|
-
# @option options [String]
|
|
56
|
+
# @option options [String] gap_width
|
|
57
|
+
# @option options [String] gap_depth
|
|
53
58
|
# @option options [Symbol] shape
|
|
54
|
-
# @option options [Integer]
|
|
55
|
-
# @option options [String]
|
|
56
|
-
# @option options [Integer]
|
|
57
|
-
# @option options [String]
|
|
58
|
-
# @option options [Boolean]
|
|
59
|
+
# @option options [Integer] rot_x
|
|
60
|
+
# @option options [String] h_percent
|
|
61
|
+
# @option options [Integer] rot_y
|
|
62
|
+
# @option options [String] depth_percent
|
|
63
|
+
# @option options [Boolean] r_ang_ax
|
|
59
64
|
# @option options [Integer] perspective
|
|
60
65
|
# @see Chart
|
|
61
66
|
# @see View3D
|
|
62
67
|
def initialize(frame, options={})
|
|
63
|
-
@
|
|
68
|
+
@bar_dir = :bar
|
|
64
69
|
@grouping = :clustered
|
|
65
|
-
@
|
|
66
|
-
@
|
|
67
|
-
@
|
|
68
|
-
@
|
|
69
|
-
@
|
|
70
|
+
@shape = :box
|
|
71
|
+
@gap_width = 150
|
|
72
|
+
@gap_width, @gap_depth, @shape = nil, nil, nil
|
|
73
|
+
@cat_ax_id = rand(8 ** 8)
|
|
74
|
+
@val_ax_id = rand(8 ** 8)
|
|
75
|
+
@cat_axis = CatAxis.new(@cat_ax_id, @val_ax_id)
|
|
76
|
+
@val_axis = ValAxis.new(@val_ax_id, @cat_ax_id, :tick_lbl_pos => :low, :ax_pos => :l)
|
|
70
77
|
super(frame, options)
|
|
71
78
|
@series_type = BarSeries
|
|
72
|
-
@
|
|
79
|
+
@view_3D = View3D.new({:r_ang_ax=>1}.merge(options))
|
|
80
|
+
@d_lbls = nil
|
|
73
81
|
end
|
|
74
82
|
|
|
75
83
|
# The direction of the bars in the chart
|
|
76
84
|
# must be one of [:bar, :col]
|
|
77
|
-
def
|
|
78
|
-
RestrictionValidator.validate "Bar3DChart.
|
|
79
|
-
@
|
|
85
|
+
def bar_dir=(v)
|
|
86
|
+
RestrictionValidator.validate "Bar3DChart.bar_dir", [:bar, :col], v
|
|
87
|
+
@bar_dir = v
|
|
80
88
|
end
|
|
89
|
+
alias :barDir= :bar_dir=
|
|
81
90
|
|
|
82
91
|
#grouping for a column, line, or area chart.
|
|
83
92
|
# must be one of [:percentStacked, :clustered, :standard, :stacked]
|
|
@@ -87,16 +96,18 @@ module Axlsx
|
|
|
87
96
|
end
|
|
88
97
|
|
|
89
98
|
# space between bar or column clusters, as a percentage of the bar or column width.
|
|
90
|
-
def
|
|
91
|
-
RegexValidator.validate "Bar3DChart.
|
|
92
|
-
@
|
|
99
|
+
def gap_width=(v)
|
|
100
|
+
RegexValidator.validate "Bar3DChart.gap_width", GAP_AMOUNT_PERCENT, v
|
|
101
|
+
@gap_width=(v)
|
|
93
102
|
end
|
|
103
|
+
alias :gapWidth= :gap_width=
|
|
94
104
|
|
|
95
105
|
# space between bar or column clusters, as a percentage of the bar or column width.
|
|
96
|
-
def
|
|
97
|
-
RegexValidator.validate "Bar3DChart.
|
|
98
|
-
@
|
|
106
|
+
def gap_depth=(v)
|
|
107
|
+
RegexValidator.validate "Bar3DChart.gap_didth", GAP_AMOUNT_PERCENT, v
|
|
108
|
+
@gap_depth=(v)
|
|
99
109
|
end
|
|
110
|
+
alias :gapDepth= :gap_depth=
|
|
100
111
|
|
|
101
112
|
# The shabe of the bars or columns
|
|
102
113
|
# must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
|
|
@@ -111,27 +122,20 @@ module Axlsx
|
|
|
111
122
|
def to_xml_string(str = '')
|
|
112
123
|
super(str) do |str_inner|
|
|
113
124
|
str_inner << '<c:bar3DChart>'
|
|
114
|
-
str_inner << '<c:barDir val="' <<
|
|
125
|
+
str_inner << '<c:barDir val="' << bar_dir.to_s << '"/>'
|
|
115
126
|
str_inner << '<c:grouping val="' << grouping.to_s << '"/>'
|
|
116
127
|
str_inner << '<c:varyColors val="1"/>'
|
|
117
128
|
@series.each { |ser| ser.to_xml_string(str_inner) }
|
|
118
|
-
|
|
119
|
-
str_inner << '<c:
|
|
120
|
-
str_inner << '<c:
|
|
121
|
-
str_inner << '<c:showCatName val="0"/>'
|
|
122
|
-
str_inner << '<c:showSerName val="0"/>'
|
|
123
|
-
str_inner << '<c:showPercent val="0"/>'
|
|
124
|
-
str_inner << '<c:showBubbleSize val="0"/>'
|
|
125
|
-
str_inner << '</c:dLbls>'
|
|
126
|
-
str_inner << '<c:gapWidth val="' << @gapWidth.to_s << '"/>' unless @gapWidth.nil?
|
|
127
|
-
str_inner << '<c:gapDepth val="' << @gapDepth.to_s << '"/>' unless @gapDepth.nil?
|
|
129
|
+
@d_lbls.to_xml_string(str) if @d_lbls
|
|
130
|
+
str_inner << '<c:gapWidth val="' << @gap_width.to_s << '"/>' unless @gap_width.nil?
|
|
131
|
+
str_inner << '<c:gapDepth val="' << @gap_depth.to_s << '"/>' unless @gap_depth.nil?
|
|
128
132
|
str_inner << '<c:shape val="' << @shape.to_s << '"/>' unless @shape.nil?
|
|
129
|
-
str_inner << '<c:axId val="' << @
|
|
130
|
-
str_inner << '<c:axId val="' << @
|
|
133
|
+
str_inner << '<c:axId val="' << @cat_ax_id.to_s << '"/>'
|
|
134
|
+
str_inner << '<c:axId val="' << @val_ax_id.to_s << '"/>'
|
|
131
135
|
str_inner << '<c:axId val="0"/>'
|
|
132
136
|
str_inner << '</c:bar3DChart>'
|
|
133
|
-
@
|
|
134
|
-
@
|
|
137
|
+
@cat_axis.to_xml_string str_inner
|
|
138
|
+
@val_axis.to_xml_string str_inner
|
|
135
139
|
end
|
|
136
140
|
end
|
|
137
141
|
end
|
|
@@ -42,7 +42,7 @@ module Axlsx
|
|
|
42
42
|
def colors=(v) DataTypeValidator.validate "BarSeries.colors", [Array], v; @colors = v end
|
|
43
43
|
|
|
44
44
|
# The shabe of the bars or columns
|
|
45
|
-
# must be one of [:
|
|
45
|
+
# must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
|
|
46
46
|
def shape=(v)
|
|
47
47
|
RestrictionValidator.validate "BarSeries.shape", [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax], v
|
|
48
48
|
@shape = v
|
|
@@ -64,6 +64,7 @@ module Axlsx
|
|
|
64
64
|
|
|
65
65
|
@labels.to_xml_string(str_inner) unless @labels.nil?
|
|
66
66
|
@data.to_xml_string(str_inner) unless @data.nil?
|
|
67
|
+
# this is actually only required for shapes other than box
|
|
67
68
|
str_inner << '<c:shape val="' << shape.to_s << '"></c:shape>'
|
|
68
69
|
end
|
|
69
70
|
end
|
|
@@ -3,6 +3,26 @@ module Axlsx
|
|
|
3
3
|
#A CatAxis object defines a chart category axis
|
|
4
4
|
class CatAxis < Axis
|
|
5
5
|
|
|
6
|
+
# Creates a new CatAxis object
|
|
7
|
+
# @param [Integer] ax_id the id of this axis. Inherited
|
|
8
|
+
# @param [Integer] cross_ax the id of the perpendicular axis. Inherited
|
|
9
|
+
# @option options [Symbol] ax_pos. Inherited
|
|
10
|
+
# @option options [Symbol] tick_lbl_pos. Inherited
|
|
11
|
+
# @option options [Symbol] crosses. Inherited
|
|
12
|
+
# @option options [Boolean] auto
|
|
13
|
+
# @option options [Symbol] lbl_algn
|
|
14
|
+
# @option options [Integer] lbl_offset
|
|
15
|
+
# @option options [Integer] tick_lbl_skip
|
|
16
|
+
# @option options [Integer] tick_mark_skip
|
|
17
|
+
def initialize(ax_id, cross_ax, options={})
|
|
18
|
+
@tick_lbl_skip = 1
|
|
19
|
+
@tick_mark_skip = 1
|
|
20
|
+
self.auto = 1
|
|
21
|
+
self.lbl_algn = :ctr
|
|
22
|
+
self.lbl_offset = "100"
|
|
23
|
+
super(ax_id, cross_ax, options)
|
|
24
|
+
end
|
|
25
|
+
|
|
6
26
|
# From the docs: This element specifies that this axis is a date or text axis based on the data that is used for the axis labels, not a specific choice.
|
|
7
27
|
# @return [Boolean]
|
|
8
28
|
attr_reader :auto
|
|
@@ -10,64 +30,48 @@ module Axlsx
|
|
|
10
30
|
# specifies how the perpendicular axis is crossed
|
|
11
31
|
# must be one of [:ctr, :l, :r]
|
|
12
32
|
# @return [Symbol]
|
|
13
|
-
attr_reader :
|
|
33
|
+
attr_reader :lbl_algn
|
|
34
|
+
alias :lblAlgn :lbl_algn
|
|
14
35
|
|
|
15
36
|
# The offset of the labels
|
|
16
37
|
# must be between a string between 0 and 1000
|
|
17
38
|
# @return [Integer]
|
|
18
|
-
attr_reader :
|
|
19
|
-
|
|
39
|
+
attr_reader :lbl_offset
|
|
40
|
+
alias :lblOffset :lbl_offset
|
|
20
41
|
|
|
21
42
|
# The number of tick lables to skip between labels
|
|
22
43
|
# @return [Integer]
|
|
23
|
-
attr_reader :
|
|
44
|
+
attr_reader :tick_lbl_skip
|
|
45
|
+
alias :tickLblSkip :tick_lbl_skip
|
|
24
46
|
|
|
25
47
|
# The number of tickmarks to be skipped before the next one is rendered.
|
|
26
48
|
# @return [Boolean]
|
|
27
|
-
attr_reader :
|
|
28
|
-
|
|
49
|
+
attr_reader :tick_mark_skip
|
|
50
|
+
alias :tickMarkSkip :tick_mark_skip
|
|
29
51
|
|
|
30
52
|
# regex for validating label offset
|
|
31
|
-
LBL_OFFSET_REGEX = /0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)
|
|
32
|
-
|
|
33
|
-
# Creates a new CatAxis object
|
|
34
|
-
# @param [Integer] axId the id of this axis. Inherited
|
|
35
|
-
# @param [Integer] crossAx the id of the perpendicular axis. Inherited
|
|
36
|
-
# @option options [Symbol] axPos. Inherited
|
|
37
|
-
# @option options [Symbol] tickLblPos. Inherited
|
|
38
|
-
# @option options [Symbol] crosses. Inherited
|
|
39
|
-
# @option options [Boolean] auto
|
|
40
|
-
# @option options [Symbol] lblAlgn
|
|
41
|
-
# @option options [Integer] lblOffset
|
|
42
|
-
# @option options [Integer] tickLblSkip
|
|
43
|
-
# @option options [Integer] tickMarkSkip
|
|
44
|
-
def initialize(axId, crossAx, options={})
|
|
45
|
-
@tickLblSkip = 1
|
|
46
|
-
@tickMarkSkip = 1
|
|
47
|
-
self.auto = 1
|
|
48
|
-
self.lblAlgn = :ctr
|
|
49
|
-
self.lblOffset = "100%"
|
|
50
|
-
super(axId, crossAx, options)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
# @see tickLblSkip
|
|
55
|
-
def tickLblSkip=(v) Axlsx::validate_unsigned_int(v); @tickLblSkip = v; end
|
|
53
|
+
LBL_OFFSET_REGEX = /0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)/
|
|
56
54
|
|
|
57
|
-
# @see
|
|
58
|
-
def
|
|
55
|
+
# @see tick_lbl_skip
|
|
56
|
+
def tick_lbl_skip=(v) Axlsx::validate_unsigned_int(v); @tick_lbl_skip = v; end
|
|
57
|
+
alias :tickLblSkip= :tick_lbl_skip=
|
|
59
58
|
|
|
59
|
+
# @see tick_mark_skip
|
|
60
|
+
def tick_mark_skip=(v) Axlsx::validate_unsigned_int(v); @tick_mark_skip = v; end
|
|
61
|
+
alias :tickMarkSkip= :tick_mark_skip=
|
|
60
62
|
|
|
61
63
|
# From the docs: This element specifies that this axis is a date or text axis based on the data that is used for the axis labels, not a specific choice.
|
|
62
64
|
def auto=(v) Axlsx::validate_boolean(v); @auto = v; end
|
|
63
65
|
|
|
64
66
|
# specifies how the perpendicular axis is crossed
|
|
65
67
|
# must be one of [:ctr, :l, :r]
|
|
66
|
-
def
|
|
68
|
+
def lbl_algn=(v) RestrictionValidator.validate "#{self.class}.lbl_algn", [:ctr, :l, :r], v; @lbl_algn = v; end
|
|
69
|
+
alias :lblAlgn= :lbl_algn=
|
|
67
70
|
|
|
68
71
|
# The offset of the labels
|
|
69
72
|
# must be between a string between 0 and 1000
|
|
70
|
-
def
|
|
73
|
+
def lbl_offset=(v) RegexValidator.validate "#{self.class}.lbl_offset", LBL_OFFSET_REGEX, v; @lbl_offset = v; end
|
|
74
|
+
alias :lblOffset= :lbl_offset=
|
|
71
75
|
|
|
72
76
|
# Serializes the object
|
|
73
77
|
# @param [String] str
|
|
@@ -76,10 +80,10 @@ module Axlsx
|
|
|
76
80
|
str << '<c:catAx>'
|
|
77
81
|
super(str)
|
|
78
82
|
str << '<c:auto val="' << @auto.to_s << '"/>'
|
|
79
|
-
str << '<c:lblAlgn val="' << @
|
|
80
|
-
str << '<c:lblOffset val="' << @
|
|
81
|
-
str << '<c:tickLblSkip val="' << @
|
|
82
|
-
str << '<c:tickMarkSkip val="' << @
|
|
83
|
+
str << '<c:lblAlgn val="' << @lbl_algn.to_s << '"/>'
|
|
84
|
+
str << '<c:lblOffset val="' << @lbl_offset.to_i.to_s << '"/>'
|
|
85
|
+
str << '<c:tickLblSkip val="' << @tick_lbl_skip.to_s << '"/>'
|
|
86
|
+
str << '<c:tickMarkSkip val="' << @tick_mark_skip.to_s << '"/>'
|
|
83
87
|
str << '</c:catAx>'
|
|
84
88
|
end
|
|
85
89
|
|
data/lib/axlsx/drawing/chart.rb
CHANGED
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
module Axlsx
|
|
3
|
+
|
|
3
4
|
# A Chart is the superclass for specific charts
|
|
4
5
|
# @note Worksheet#add_chart is the recommended way to create charts for your worksheets.
|
|
5
6
|
# @see README for examples
|
|
6
7
|
class Chart
|
|
7
8
|
|
|
9
|
+
# Creates a new chart object
|
|
10
|
+
# @param [GraphicalFrame] frame The frame that holds this chart.
|
|
11
|
+
# @option options [Cell, String] title
|
|
12
|
+
# @option options [Boolean] show_legend
|
|
13
|
+
# @option options [Array|String|Cell] start_at The X, Y coordinates defining the top left corner of the chart.
|
|
14
|
+
# @option options [Array|String|Cell] end_at The X, Y coordinates defining the bottom right corner of the chart.
|
|
15
|
+
def initialize(frame, options={})
|
|
16
|
+
@style = 18
|
|
17
|
+
@view_3D = nil
|
|
18
|
+
@graphic_frame=frame
|
|
19
|
+
@graphic_frame.anchor.drawing.worksheet.workbook.charts << self
|
|
20
|
+
@series = SimpleTypedList.new Series
|
|
21
|
+
@show_legend = true
|
|
22
|
+
@series_type = Series
|
|
23
|
+
@title = Title.new
|
|
24
|
+
options.each do |o|
|
|
25
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
26
|
+
end
|
|
27
|
+
start_at(*options[:start_at]) if options[:start_at]
|
|
28
|
+
end_at(*options[:end_at]) if options[:end_at]
|
|
29
|
+
yield self if block_given?
|
|
30
|
+
end
|
|
8
31
|
|
|
9
32
|
# The 3D view properties for the chart
|
|
10
|
-
attr_reader :
|
|
33
|
+
attr_reader :view_3D
|
|
34
|
+
alias :view3D :view_3D
|
|
11
35
|
|
|
12
36
|
# A reference to the graphic frame that owns this chart
|
|
13
37
|
# @return [GraphicFrame]
|
|
@@ -22,7 +46,10 @@ module Axlsx
|
|
|
22
46
|
attr_reader :series_type
|
|
23
47
|
|
|
24
48
|
#TODO data labels!
|
|
25
|
-
|
|
49
|
+
def d_lbls
|
|
50
|
+
@d_lbls ||= DLbls.new(self.class)
|
|
51
|
+
end
|
|
52
|
+
|
|
26
53
|
|
|
27
54
|
# The title object for the chart.
|
|
28
55
|
# @return [Title]
|
|
@@ -37,29 +64,6 @@ module Axlsx
|
|
|
37
64
|
# @return [Boolean]
|
|
38
65
|
attr_reader :show_legend
|
|
39
66
|
|
|
40
|
-
# Creates a new chart object
|
|
41
|
-
# @param [GraphicalFrame] frame The frame that holds this chart.
|
|
42
|
-
# @option options [Cell, String] title
|
|
43
|
-
# @option options [Boolean] show_legend
|
|
44
|
-
# @option options [Array|String|Cell] start_at The X, Y coordinates defining the top left corner of the chart.
|
|
45
|
-
# @option options [Array|String|Cell] end_at The X, Y coordinates defining the bottom right corner of the chart.
|
|
46
|
-
def initialize(frame, options={})
|
|
47
|
-
@style = 2
|
|
48
|
-
@view3D = nil
|
|
49
|
-
@graphic_frame=frame
|
|
50
|
-
@graphic_frame.anchor.drawing.worksheet.workbook.charts << self
|
|
51
|
-
@series = SimpleTypedList.new Series
|
|
52
|
-
@show_legend = true
|
|
53
|
-
@series_type = Series
|
|
54
|
-
@title = Title.new
|
|
55
|
-
options.each do |o|
|
|
56
|
-
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
57
|
-
end
|
|
58
|
-
start_at(*options[:start_at]) if options[:start_at]
|
|
59
|
-
end_at(*options[:end_at]) if options[:end_at]
|
|
60
|
-
yield self if block_given?
|
|
61
|
-
end
|
|
62
|
-
|
|
63
67
|
# The index of this chart in the workbooks charts collection
|
|
64
68
|
# @return [Integer]
|
|
65
69
|
def index
|
|
@@ -89,7 +93,6 @@ module Axlsx
|
|
|
89
93
|
# @return [Boolean]
|
|
90
94
|
def show_legend=(v) Axlsx::validate_boolean(v); @show_legend = v; end
|
|
91
95
|
|
|
92
|
-
|
|
93
96
|
# The style for the chart.
|
|
94
97
|
# see ECMA Part 1 §21.2.2.196
|
|
95
98
|
# @param [Integer] v must be between 1 and 48
|
|
@@ -120,14 +123,14 @@ module Axlsx
|
|
|
120
123
|
# @return [String]
|
|
121
124
|
def to_xml_string(str = '')
|
|
122
125
|
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
|
123
|
-
str << '<c:chartSpace xmlns:c="' << XML_NS_C << '" xmlns:a="' << XML_NS_A << '">'
|
|
126
|
+
str << '<c:chartSpace xmlns:c="' << XML_NS_C << '" xmlns:a="' << XML_NS_A << '" xmlns:r="' << XML_NS_R << '">'
|
|
124
127
|
str << '<c:date1904 val="' << Axlsx::Workbook.date1904.to_s << '"/>'
|
|
125
128
|
str << '<c:style val="' << style.to_s << '"/>'
|
|
126
129
|
str << '<c:chart>'
|
|
127
130
|
@title.to_xml_string str
|
|
128
131
|
# do these need the c: namespace as well???
|
|
129
|
-
str << '<c:autoTitleDeleted val="
|
|
130
|
-
@
|
|
132
|
+
str << '<c:autoTitleDeleted val="' << (@title == nil).to_s << '"/>'
|
|
133
|
+
@view_3D.to_xml_string(str) if @view_3D
|
|
131
134
|
str << '<c:floor><c:thickness val="0"/></c:floor>'
|
|
132
135
|
str << '<c:sideWall><c:thickness val="0"/></c:sideWall>'
|
|
133
136
|
str << '<c:backWall><c:thickness val="0"/></c:backWall>'
|
|
@@ -146,19 +149,40 @@ module Axlsx
|
|
|
146
149
|
str << '<c:dispBlanksAs val="zero"/>'
|
|
147
150
|
str << '<c:showDLblsOverMax val="1"/>'
|
|
148
151
|
str << '</c:chart>'
|
|
152
|
+
str << '<c:printSettings>'
|
|
153
|
+
str << '<c:headerFooter/>'
|
|
154
|
+
str << '<c:pageMargins b="1.0" l="0.75" r="0.75" t="1.0" header="0.5" footer="0.5"/>'
|
|
155
|
+
str << '<c:pageSetup/>'
|
|
156
|
+
str << '</c:printSettings>'
|
|
149
157
|
str << '</c:chartSpace>'
|
|
150
158
|
end
|
|
151
159
|
|
|
152
|
-
# This is a short cut method to set the start
|
|
160
|
+
# This is a short cut method to set the anchor start marker position
|
|
153
161
|
# If you need finer granularity in positioning use
|
|
154
|
-
#
|
|
155
|
-
#
|
|
162
|
+
#
|
|
163
|
+
# This helper method acceps a fairly wide range of inputs exampled
|
|
164
|
+
# below
|
|
165
|
+
#
|
|
166
|
+
# @example
|
|
167
|
+
#
|
|
168
|
+
# start_at 0, 5 # The anchor start marker is set to 6th row of
|
|
169
|
+
# the first column
|
|
170
|
+
#
|
|
171
|
+
# start_at [0, 5] # The anchor start marker is set to start on the 6th row
|
|
172
|
+
# of the first column
|
|
173
|
+
#
|
|
174
|
+
# start_at "C1" # The anchor start marker is set to start on the first row
|
|
175
|
+
# of the third column
|
|
176
|
+
#
|
|
177
|
+
# start_at sheet.rows.first.cells.last # The anchor start
|
|
178
|
+
# marker is set to the location of a specific cell.
|
|
179
|
+
#
|
|
180
|
+
# @param [Array|String|Cell] x the column, coordinates, string
|
|
181
|
+
# reference or cell to use in setting the start marker position.
|
|
156
182
|
# @param [Integer] y The row
|
|
157
183
|
# @return [Marker]
|
|
158
184
|
def start_at(x=0, y=0)
|
|
159
|
-
|
|
160
|
-
@graphic_frame.anchor.from.col = x
|
|
161
|
-
@graphic_frame.anchor.from.row = y
|
|
185
|
+
@graphic_frame.anchor.start_at(x, y)
|
|
162
186
|
end
|
|
163
187
|
|
|
164
188
|
# This is a short cut method to set the end anchor position
|
|
@@ -167,28 +191,15 @@ module Axlsx
|
|
|
167
191
|
# @param [Integer] x The column - default 10
|
|
168
192
|
# @param [Integer] y The row - default 10
|
|
169
193
|
# @return [Marker]
|
|
194
|
+
# @see start_at
|
|
170
195
|
def end_at(x=10, y=10)
|
|
171
|
-
|
|
172
|
-
@graphic_frame.anchor.to.col = x
|
|
173
|
-
@graphic_frame.anchor.to.row = y
|
|
196
|
+
@graphic_frame.anchor.end_at(x, y)
|
|
174
197
|
end
|
|
175
198
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if x.is_a?(String)
|
|
180
|
-
x, y = *Axlsx::name_to_indices(x)
|
|
181
|
-
end
|
|
182
|
-
if x.is_a?(Cell)
|
|
183
|
-
x, y = *x.pos
|
|
184
|
-
end
|
|
185
|
-
if x.is_a?(Array)
|
|
186
|
-
x, y = *x
|
|
187
|
-
end
|
|
188
|
-
[x, y]
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def view3D=(v) DataTypeValidator.validate "#{self.class}.view3D", View3D, v; @view3D = v; end
|
|
199
|
+
# sets the view_3D object for the chart
|
|
200
|
+
def view_3D=(v) DataTypeValidator.validate "#{self.class}.view_3D", View3D, v; @view_3D = v; end
|
|
201
|
+
alias :view3D= :view_3D=
|
|
192
202
|
|
|
193
203
|
end
|
|
204
|
+
|
|
194
205
|
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
# There are more elements in the dLbls spec that allow for
|
|
3
|
+
# customizations and formatting. For now, I am just implementing the
|
|
4
|
+
# basics.
|
|
5
|
+
|
|
6
|
+
#The DLbls class manages serialization of data labels
|
|
7
|
+
# showLeaderLines and leaderLines are not currently implemented
|
|
8
|
+
class DLbls
|
|
9
|
+
|
|
10
|
+
# These attributes are all boolean so I'm doing a bit of a hand
|
|
11
|
+
# waving magic show to set up the attriubte accessors
|
|
12
|
+
# @note
|
|
13
|
+
# not all charts support all methods!
|
|
14
|
+
# Bar3DChart and Line3DChart and ScatterChart do not support d_lbl_pos or show_leader_lines
|
|
15
|
+
#
|
|
16
|
+
BOOLEAN_ATTRIBUTES = [:show_legend_key, :show_val, :show_cat_name, :show_ser_name, :show_percent, :show_bubble_size, :show_leader_lines]
|
|
17
|
+
|
|
18
|
+
# creates a new DLbls object
|
|
19
|
+
def initialize(chart_type, options={})
|
|
20
|
+
raise ArgumentError, 'chart_type must inherit from Chart' unless chart_type.superclass == Chart
|
|
21
|
+
@chart_type = chart_type
|
|
22
|
+
initialize_defaults
|
|
23
|
+
options.each do |o|
|
|
24
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Initialize all the values to false as Excel requires them to
|
|
29
|
+
# explicitly be disabled or all will show.
|
|
30
|
+
def initialize_defaults
|
|
31
|
+
BOOLEAN_ATTRIBUTES.each do |attr|
|
|
32
|
+
self.send("#{attr}=", false)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# The chart type that is using this data lables instance.
|
|
37
|
+
# This affects the xml output as not all chart types support the
|
|
38
|
+
# same data label attributes.
|
|
39
|
+
attr_reader :chart_type
|
|
40
|
+
|
|
41
|
+
# The position of the data labels in the chart
|
|
42
|
+
# @see d_lbl_pos= for a list of allowed values
|
|
43
|
+
# @return [Symbol]
|
|
44
|
+
def d_lbl_pos
|
|
45
|
+
return unless @chart_type == Pie3DChart
|
|
46
|
+
@d_lbl_pos ||= :bestFit
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @see DLbls#d_lbl_pos
|
|
50
|
+
# Assigns the label postion for this data labels on this chart.
|
|
51
|
+
# Allowed positions are :bestFilt, :b, :ctr, :inBase, :inEnd, :l,
|
|
52
|
+
# :outEnd, :r and :t
|
|
53
|
+
# The default is :bestFit
|
|
54
|
+
# @param [Symbol] label_position the postion you want to use.
|
|
55
|
+
def d_lbl_pos=(label_position)
|
|
56
|
+
return unless @chart_type == Pie3DChart
|
|
57
|
+
Axlsx::RestrictionValidator.validate 'DLbls#d_lbl_pos', [:bestFit, :b, :ctr, :inBase, :inEnd, :l, :outEnd, :r, :t], label_position
|
|
58
|
+
@d_lbl_pos = label_position
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Dynamically create accessors for boolean attriubtes
|
|
62
|
+
BOOLEAN_ATTRIBUTES.each do |attr|
|
|
63
|
+
class_eval %{
|
|
64
|
+
# The #{attr} attribute reader
|
|
65
|
+
# @return [Boolean]
|
|
66
|
+
attr_reader :#{attr}
|
|
67
|
+
|
|
68
|
+
# The #{attr} writer
|
|
69
|
+
# @param [Boolean] value The value to assign to #{attr}
|
|
70
|
+
# @return [Boolean]
|
|
71
|
+
def #{attr}=(value)
|
|
72
|
+
Axlsx::validate_boolean(value)
|
|
73
|
+
@#{attr} = value
|
|
74
|
+
end
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# serializes the data labels
|
|
80
|
+
# @return [String]
|
|
81
|
+
def to_xml_string(str = '')
|
|
82
|
+
validate_attributes_for_chart_type
|
|
83
|
+
str << '<c:dLbls>'
|
|
84
|
+
%w(d_lbl_pos show_legend_key show_val show_cat_name show_ser_name show_percent show_bubble_size show_leader_lines).each do |key|
|
|
85
|
+
next unless instance_values.keys.include?(key) && instance_values[key] != nil
|
|
86
|
+
str << "<c:#{Axlsx::camel(key, false)} val='#{instance_values[key]}' />"
|
|
87
|
+
end
|
|
88
|
+
str << '</c:dLbls>'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# nills out d_lbl_pos and show_leader_lines as these attributes, while valid in the spec actually chrash excel for any chart type other than pie charts.
|
|
92
|
+
def validate_attributes_for_chart_type
|
|
93
|
+
return if @chart_type == Pie3DChart
|
|
94
|
+
@d_lbl_pos = nil
|
|
95
|
+
@show_leader_lines = nil
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
module Axlsx
|
|
3
|
+
require 'axlsx/drawing/d_lbls.rb'
|
|
3
4
|
require 'axlsx/drawing/title.rb'
|
|
4
5
|
require 'axlsx/drawing/series_title.rb'
|
|
5
6
|
require 'axlsx/drawing/series.rb'
|
|
@@ -39,12 +40,16 @@ module Axlsx
|
|
|
39
40
|
require 'axlsx/drawing/pic.rb'
|
|
40
41
|
require 'axlsx/drawing/hyperlink.rb'
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
require 'axlsx/drawing/vml_drawing.rb'
|
|
44
|
+
require 'axlsx/drawing/vml_shape.rb'
|
|
45
|
+
|
|
46
|
+
# A Drawing is a canvas for charts and images. Each worksheet has a single drawing that manages anchors.
|
|
47
|
+
# The anchors reference the charts or images via graphical frames. This is not a trivial relationship so please do follow the advice in the note.
|
|
48
|
+
# @note The recommended way to manage drawings is to use the Worksheet.add_chart and Worksheet.add_image methods.
|
|
45
49
|
# @see Worksheet#add_chart
|
|
50
|
+
# @see Worksheet#add_image
|
|
46
51
|
# @see Chart
|
|
47
|
-
# see
|
|
52
|
+
# see examples/example.rb for an example of how to create a chart.
|
|
48
53
|
class Drawing
|
|
49
54
|
|
|
50
55
|
# The worksheet that owns the drawing
|
|
@@ -65,11 +70,17 @@ module Axlsx
|
|
|
65
70
|
@anchors = SimpleTypedList.new [TwoCellAnchor, OneCellAnchor]
|
|
66
71
|
end
|
|
67
72
|
|
|
68
|
-
|
|
73
|
+
|
|
74
|
+
# Adds an image to the chart If th end_at option is specified we create a two cell anchor. By default we use a one cell anchor.
|
|
69
75
|
# @note The recommended way to manage images is to use Worksheet.add_image. Please refer to that method for documentation.
|
|
70
76
|
# @see Worksheet#add_image
|
|
77
|
+
# @return [Pic]
|
|
71
78
|
def add_image(options={})
|
|
72
|
-
|
|
79
|
+
if options[:end_at]
|
|
80
|
+
TwoCellAnchor.new(self, options).add_pic(options)
|
|
81
|
+
else
|
|
82
|
+
OneCellAnchor.new(self, options)
|
|
83
|
+
end
|
|
73
84
|
@anchors.last.object
|
|
74
85
|
end
|
|
75
86
|
|
|
@@ -146,8 +157,9 @@ module Axlsx
|
|
|
146
157
|
# @param [String] str
|
|
147
158
|
# @return [String]
|
|
148
159
|
def to_xml_string(str = '')
|
|
149
|
-
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
|
150
|
-
str << '<xdr:wsDr xmlns:xdr="' << XML_NS_XDR << '" xmlns:a="' << XML_NS_A << '"
|
|
160
|
+
str << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
|
|
161
|
+
str << '<xdr:wsDr xmlns:xdr="' << XML_NS_XDR << '" xmlns:a="' << XML_NS_A << '">'
|
|
162
|
+
|
|
151
163
|
anchors.each { |anchor| anchor.to_xml_string(str) }
|
|
152
164
|
str << '</xdr:wsDr>'
|
|
153
165
|
end
|
|
@@ -32,9 +32,10 @@ module Axlsx
|
|
|
32
32
|
# @param [String] str
|
|
33
33
|
# @return [String]
|
|
34
34
|
def to_xml_string(str = '')
|
|
35
|
+
# macro attribute should be optional!
|
|
35
36
|
str << '<xdr:graphicFrame>'
|
|
36
37
|
str << '<xdr:nvGraphicFramePr>'
|
|
37
|
-
str << '<xdr:cNvPr id="
|
|
38
|
+
str << '<xdr:cNvPr id="' << @anchor.drawing.index.to_s << '" name="' << 'item_' << @anchor.drawing.index.to_s << '"/>'
|
|
38
39
|
str << '<xdr:cNvGraphicFramePr/>'
|
|
39
40
|
str << '</xdr:nvGraphicFramePr>'
|
|
40
41
|
str << '<xdr:xfrm>'
|