axlsx 1.0.12 → 1.0.13
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +7 -3
- data/lib/axlsx.rb +57 -0
- data/lib/axlsx/content_type/content_type.rb +23 -0
- data/lib/axlsx/content_type/default.rb +37 -0
- data/lib/axlsx/content_type/override.rb +37 -0
- data/lib/axlsx/doc_props/app.rb +178 -0
- data/lib/axlsx/doc_props/core.rb +34 -0
- data/lib/axlsx/drawing/axis.rb +90 -0
- data/lib/axlsx/drawing/bar_3D_chart.rb +128 -0
- data/lib/axlsx/drawing/bar_series.rb +64 -0
- data/lib/axlsx/drawing/cat_axis.rb +63 -0
- data/lib/axlsx/drawing/cat_axis_data.rb +35 -0
- data/lib/axlsx/drawing/chart.rb +179 -0
- data/lib/axlsx/drawing/drawing.rb +137 -0
- data/lib/axlsx/drawing/graphic_frame.rb +52 -0
- data/lib/axlsx/drawing/line_3D_chart.rb +106 -0
- data/lib/axlsx/drawing/line_series.rb +46 -0
- data/lib/axlsx/drawing/marker.rb +61 -0
- data/lib/axlsx/drawing/one_cell_anchor.rb +89 -0
- data/lib/axlsx/drawing/pic.rb +153 -0
- data/lib/axlsx/drawing/picture_locking.rb +72 -0
- data/lib/axlsx/drawing/picture_locking.rb~ +36 -0
- data/lib/axlsx/drawing/pie_3D_chart.rb +41 -0
- data/lib/axlsx/drawing/pie_series.rb +56 -0
- data/lib/axlsx/drawing/scaling.rb +59 -0
- data/lib/axlsx/drawing/ser_axis.rb +45 -0
- data/lib/axlsx/drawing/series.rb +71 -0
- data/lib/axlsx/drawing/series_title.rb +22 -0
- data/lib/axlsx/drawing/title.rb +61 -0
- data/lib/axlsx/drawing/two_cell_anchor.rb +76 -0
- data/lib/axlsx/drawing/val_axis.rb +34 -0
- data/lib/axlsx/drawing/val_axis_data.rb +28 -0
- data/lib/axlsx/drawing/view_3D.rb +85 -0
- data/lib/axlsx/package.rb +215 -0
- data/lib/axlsx/rels/relationship.rb +44 -0
- data/lib/axlsx/rels/relationships.rb +25 -0
- data/lib/axlsx/stylesheet/border.rb +57 -0
- data/lib/axlsx/stylesheet/border_pr.rb +68 -0
- data/lib/axlsx/stylesheet/cell_alignment.rb +105 -0
- data/lib/axlsx/stylesheet/cell_protection.rb +36 -0
- data/lib/axlsx/stylesheet/cell_style.rb +65 -0
- data/lib/axlsx/stylesheet/color.rb +69 -0
- data/lib/axlsx/stylesheet/fill.rb +32 -0
- data/lib/axlsx/stylesheet/font.rb +139 -0
- data/lib/axlsx/stylesheet/gradient_fill.rb +76 -0
- data/lib/axlsx/stylesheet/gradient_stop.rb +33 -0
- data/lib/axlsx/stylesheet/num_fmt.rb +63 -0
- data/lib/axlsx/stylesheet/pattern_fill.rb +66 -0
- data/lib/axlsx/stylesheet/styles.rb +298 -0
- data/lib/axlsx/stylesheet/table_style.rb +47 -0
- data/lib/axlsx/stylesheet/table_style_element.rb +71 -0
- data/lib/axlsx/stylesheet/table_styles.rb +39 -0
- data/lib/axlsx/stylesheet/xf.rb +138 -0
- data/lib/axlsx/util/constants.rb +220 -0
- data/lib/axlsx/util/parser.rb +43 -0
- data/lib/axlsx/util/parser.rb~ +6 -0
- data/lib/axlsx/util/simple_typed_list.rb +160 -0
- data/lib/axlsx/util/validators.rb +132 -0
- data/lib/axlsx/version.rb +4 -0
- data/lib/axlsx/workbook/#workbook.rb# +165 -0
- data/lib/axlsx/workbook/workbook.rb +160 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +337 -0
- data/lib/axlsx/workbook/worksheet/row.rb +107 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +279 -0
- metadata +93 -141
- data/examples/follow_20111202.xlsx +0 -0
- data/test/content_type/tc_content_type.rb +0 -81
- data/test/content_type/tc_default.rb +0 -40
- data/test/content_type/tc_override.rb +0 -40
- data/test/doc_props/tc_app.rb +0 -19
- data/test/doc_props/tc_core.rb +0 -34
- data/test/drawing/tc_axis.rb +0 -40
- data/test/drawing/tc_bar_3D_chart.rb +0 -66
- data/test/drawing/tc_bar_series.rb +0 -34
- data/test/drawing/tc_cat_axis.rb +0 -32
- data/test/drawing/tc_cat_axis_data.rb +0 -18
- data/test/drawing/tc_chart.rb +0 -73
- data/test/drawing/tc_drawing.rb +0 -80
- data/test/drawing/tc_graphic_frame.rb +0 -26
- data/test/drawing/tc_line_3d_chart.rb +0 -48
- data/test/drawing/tc_line_series.rb +0 -27
- data/test/drawing/tc_marker.rb +0 -45
- data/test/drawing/tc_one_cell_anchor.rb +0 -67
- data/test/drawing/tc_pic.rb +0 -71
- data/test/drawing/tc_picture_locking.rb +0 -73
- data/test/drawing/tc_pie_3D_chart.rb +0 -33
- data/test/drawing/tc_pie_series.rb +0 -35
- data/test/drawing/tc_scaling.rb +0 -37
- data/test/drawing/tc_ser_axis.rb +0 -31
- data/test/drawing/tc_series.rb +0 -24
- data/test/drawing/tc_series_title.rb +0 -34
- data/test/drawing/tc_title.rb +0 -34
- data/test/drawing/tc_two_cell_anchor.rb +0 -38
- data/test/drawing/tc_val_axis.rb +0 -25
- data/test/drawing/tc_val_axis_data.rb +0 -18
- data/test/drawing/tc_view_3D.rb +0 -55
- data/test/rels/tc_relationship.rb +0 -16
- data/test/rels/tc_relationships.rb +0 -27
- data/test/stylesheet/tc_border.rb +0 -38
- data/test/stylesheet/tc_border_pr.rb +0 -33
- data/test/stylesheet/tc_cell_alignment.rb +0 -77
- data/test/stylesheet/tc_cell_protection.rb +0 -30
- data/test/stylesheet/tc_cell_style.rb +0 -58
- data/test/stylesheet/tc_color.rb +0 -38
- data/test/stylesheet/tc_fill.rb +0 -19
- data/test/stylesheet/tc_font.rb +0 -114
- data/test/stylesheet/tc_gradient_fill.rb +0 -65
- data/test/stylesheet/tc_gradient_stop.rb +0 -32
- data/test/stylesheet/tc_num_fmt.rb +0 -31
- data/test/stylesheet/tc_pattern_fill.rb +0 -38
- data/test/stylesheet/tc_styles.rb +0 -52
- data/test/stylesheet/tc_table_style.rb +0 -37
- data/test/stylesheet/tc_table_style_element.rb +0 -37
- data/test/stylesheet/tc_table_styles.rb +0 -30
- data/test/stylesheet/tc_xf.rb +0 -121
- data/test/tc_package.rb +0 -68
- data/test/util/tc_simple_typed_list.rb +0 -66
- data/test/util/tc_validators.rb +0 -76
- data/test/workbook/tc_workbook.rb +0 -60
- data/test/workbook/worksheet/tc_cell.rb +0 -179
- data/test/workbook/worksheet/tc_row.rb +0 -36
- data/test/workbook/worksheet/tc_worksheet.rb +0 -138
@@ -0,0 +1,128 @@
|
|
1
|
+
module Axlsx
|
2
|
+
|
3
|
+
# The Bar3DChart is a three dimentional barchart (who would have guessed?) that you can add to your worksheet.
|
4
|
+
# @see Worksheet#add_chart
|
5
|
+
# @see Chart#add_series
|
6
|
+
# @see Package#serialize
|
7
|
+
# @see README for an example
|
8
|
+
class Bar3DChart < Chart
|
9
|
+
|
10
|
+
# the category axis
|
11
|
+
# @return [CatAxis]
|
12
|
+
attr_reader :catAxis
|
13
|
+
|
14
|
+
# the valueaxis
|
15
|
+
# @return [ValAxis]
|
16
|
+
attr_reader :valAxis
|
17
|
+
|
18
|
+
# The direction of the bars in the chart
|
19
|
+
# must be one of [:bar, :col]
|
20
|
+
# @return [Symbol]
|
21
|
+
attr_reader :barDir
|
22
|
+
|
23
|
+
# space between bar or column clusters, as a percentage of the bar or column width.
|
24
|
+
# @return [String]
|
25
|
+
attr_reader :gapDepth
|
26
|
+
|
27
|
+
# space between bar or column clusters, as a percentage of the bar or column width.
|
28
|
+
# @return [String]
|
29
|
+
attr_reader :gapWidth
|
30
|
+
|
31
|
+
#grouping for a column, line, or area chart.
|
32
|
+
# must be one of [:percentStacked, :clustered, :standard, :stacked]
|
33
|
+
# @return [Symbol]
|
34
|
+
attr_reader :grouping
|
35
|
+
|
36
|
+
# The shabe of the bars or columns
|
37
|
+
# must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
|
38
|
+
# @return [Symbol]
|
39
|
+
attr_reader :shape
|
40
|
+
|
41
|
+
# validation regex for gap amount percent
|
42
|
+
GAP_AMOUNT_PERCENT = /0*(([0-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%/
|
43
|
+
|
44
|
+
# Creates a new bar chart object
|
45
|
+
# @param [GraphicFrame] frame The workbook that owns this chart.
|
46
|
+
# @option options [Cell, String] title
|
47
|
+
# @option options [Boolean] show_legend
|
48
|
+
# @option options [Symbol] barDir
|
49
|
+
# @option options [Symbol] grouping
|
50
|
+
# @option options [String] gapWidth
|
51
|
+
# @option options [String] gapDepth
|
52
|
+
# @option options [Symbol] shape
|
53
|
+
# @option options [Integer] rotX
|
54
|
+
# @option options [String] hPercent
|
55
|
+
# @option options [Integer] rotY
|
56
|
+
# @option options [String] depthPercent
|
57
|
+
# @option options [Boolean] rAngAx
|
58
|
+
# @option options [Integer] perspective
|
59
|
+
# @see Chart
|
60
|
+
# @see View3D
|
61
|
+
def initialize(frame, options={})
|
62
|
+
@barDir = :bar
|
63
|
+
@grouping = :clustered
|
64
|
+
@gapWidth, @gapDepth, @shape = nil, nil, nil
|
65
|
+
@catAxId = rand(8 ** 8)
|
66
|
+
@valAxId = rand(8 ** 8)
|
67
|
+
@catAxis = CatAxis.new(@catAxId, @valAxId)
|
68
|
+
@valAxis = ValAxis.new(@valAxId, @catAxId)
|
69
|
+
super(frame, options)
|
70
|
+
@series_type = BarSeries
|
71
|
+
@view3D = View3D.new({:rAngAx=>1}.merge(options))
|
72
|
+
end
|
73
|
+
|
74
|
+
# The direction of the bars in the chart
|
75
|
+
# must be one of [:bar, :col]
|
76
|
+
def barDir=(v)
|
77
|
+
RestrictionValidator.validate "Bar3DChart.barDir", [:bar, :col], v
|
78
|
+
@barDir = v
|
79
|
+
end
|
80
|
+
|
81
|
+
#grouping for a column, line, or area chart.
|
82
|
+
# must be one of [:percentStacked, :clustered, :standard, :stacked]
|
83
|
+
def grouping=(v)
|
84
|
+
RestrictionValidator.validate "Bar3DChart.grouping", [:percentStacked, :clustered, :standard, :stacked], v
|
85
|
+
@grouping = v
|
86
|
+
end
|
87
|
+
|
88
|
+
# space between bar or column clusters, as a percentage of the bar or column width.
|
89
|
+
def gapWidth=(v)
|
90
|
+
RegexValidator.validate "Bar3DChart.gapWidth", GAP_AMOUNT_PERCENT, v
|
91
|
+
@gapWidth=(v)
|
92
|
+
end
|
93
|
+
|
94
|
+
# space between bar or column clusters, as a percentage of the bar or column width.
|
95
|
+
def gapDepth=(v)
|
96
|
+
RegexValidator.validate "Bar3DChart.gapWidth", GAP_AMOUNT_PERCENT, v
|
97
|
+
@gapDepth=(v)
|
98
|
+
end
|
99
|
+
|
100
|
+
# The shabe of the bars or columns
|
101
|
+
# must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
|
102
|
+
def shape=(v)
|
103
|
+
RestrictionValidator.validate "Bar3DChart.shape", [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax], v
|
104
|
+
@shape = v
|
105
|
+
end
|
106
|
+
|
107
|
+
# Serializes the bar chart
|
108
|
+
# @return [String]
|
109
|
+
def to_xml
|
110
|
+
super() do |xml|
|
111
|
+
xml.send('c:bar3DChart') {
|
112
|
+
xml.send('c:barDir', :val => barDir)
|
113
|
+
xml.send('c:grouping', :val=>grouping)
|
114
|
+
xml.send('c:varyColors', :val=>1)
|
115
|
+
@series.each { |ser| ser.to_xml(xml) }
|
116
|
+
xml.send('c:gapWidth', :val=>@gapWidth) unless @gapWidth.nil?
|
117
|
+
xml.send('c:gapDepth', :val=>@gapDepth) unless @gapDepth.nil?
|
118
|
+
xml.send('c:shape', :val=>@shape) unless @shape.nil?
|
119
|
+
xml.send('c:axId', :val=>@catAxId)
|
120
|
+
xml.send('c:axId', :val=>@valAxId)
|
121
|
+
xml.send('c:axId', :val=>0)
|
122
|
+
}
|
123
|
+
@catAxis.to_xml(xml)
|
124
|
+
@valAxis.to_xml(xml)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# A BarSeries defines the title, data and labels for bar charts
|
3
|
+
# @note The recommended way to manage series is to use Chart#add_series
|
4
|
+
# @see Worksheet#add_chart
|
5
|
+
# @see Chart#add_series
|
6
|
+
class BarSeries < Series
|
7
|
+
|
8
|
+
|
9
|
+
# The data for this series.
|
10
|
+
# @return [Array, SimpleTypedList]
|
11
|
+
attr_reader :data
|
12
|
+
|
13
|
+
# The labels for this series.
|
14
|
+
# @return [Array, SimpleTypedList]
|
15
|
+
attr_reader :labels
|
16
|
+
|
17
|
+
# The shabe of the bars or columns
|
18
|
+
# must be one of [:percentStacked, :clustered, :standard, :stacked]
|
19
|
+
# @return [Symbol]
|
20
|
+
attr_reader :shape
|
21
|
+
|
22
|
+
# Creates a new series
|
23
|
+
# @option options [Array, SimpleTypedList] data
|
24
|
+
# @option options [Array, SimpleTypedList] labels
|
25
|
+
# @option options [String] title
|
26
|
+
# @option options [String] shape
|
27
|
+
# @param [Chart] chart
|
28
|
+
def initialize(chart, options={})
|
29
|
+
@shape = :box
|
30
|
+
super(chart, options)
|
31
|
+
self.labels = CatAxisData.new(options[:labels]) unless options[:labels].nil?
|
32
|
+
self.data = ValAxisData.new(options[:data]) unless options[:data].nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
# The shabe of the bars or columns
|
36
|
+
# must be one of [:percentStacked, :clustered, :standard, :stacked]
|
37
|
+
def shape=(v)
|
38
|
+
RestrictionValidator.validate "BarSeries.shape", [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax], v
|
39
|
+
@shape = v
|
40
|
+
end
|
41
|
+
|
42
|
+
# Serializes the series
|
43
|
+
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
44
|
+
# @return [String]
|
45
|
+
def to_xml(xml)
|
46
|
+
super(xml) do |xml_inner|
|
47
|
+
@labels.to_xml(xml_inner) unless @labels.nil?
|
48
|
+
@data.to_xml(xml_inner) unless @data.nil?
|
49
|
+
xml_inner.send('c:shape', :val=>@shape)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# assigns the data for this series
|
57
|
+
def data=(v) DataTypeValidator.validate "Series.data", [SimpleTypedList], v; @data = v; end
|
58
|
+
|
59
|
+
# assigns the labels for this series
|
60
|
+
def labels=(v) DataTypeValidator.validate "Series.labels", [SimpleTypedList], v; @labels = v; end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Axlsx
|
2
|
+
#A CatAxis object defines a chart category axis
|
3
|
+
class CatAxis < Axis
|
4
|
+
|
5
|
+
# 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.
|
6
|
+
# @return [Boolean]
|
7
|
+
attr_reader :auto
|
8
|
+
|
9
|
+
# specifies how the perpendicular axis is crossed
|
10
|
+
# must be one of [:ctr, :l, :r]
|
11
|
+
# @return [Symbol]
|
12
|
+
attr_reader :lblAlgn
|
13
|
+
|
14
|
+
# The offset of the labels
|
15
|
+
# must be between a string between 0 and 1000
|
16
|
+
# @return [Integer]
|
17
|
+
attr_reader :lblOffset
|
18
|
+
|
19
|
+
# regex for validating label offset
|
20
|
+
LBL_OFFSET_REGEX = /0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)%/
|
21
|
+
|
22
|
+
# Creates a new CatAxis object
|
23
|
+
# @param [Integer] axId the id of this axis. Inherited
|
24
|
+
# @param [Integer] crossAx the id of the perpendicular axis. Inherited
|
25
|
+
# @option options [Symbol] axPos. Inherited
|
26
|
+
# @option options [Symbol] tickLblPos. Inherited
|
27
|
+
# @option options [Symbol] crosses. Inherited
|
28
|
+
# @option options [Boolean] auto
|
29
|
+
# @option options [Symbol] lblAlgn
|
30
|
+
# @option options [Integer] lblOffset
|
31
|
+
def initialize(axId, crossAx, options={})
|
32
|
+
self.auto = true
|
33
|
+
self.lblAlgn = :ctr
|
34
|
+
self.lblOffset = "100%"
|
35
|
+
super(axId, crossAx, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
# 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.
|
39
|
+
def auto=(v) Axlsx::validate_boolean(v); @auto = v; end
|
40
|
+
|
41
|
+
# specifies how the perpendicular axis is crossed
|
42
|
+
# must be one of [:ctr, :l, :r]
|
43
|
+
def lblAlgn=(v) RestrictionValidator.validate "#{self.class}.lblAlgn", [:ctr, :l, :r], v; @lblAlgn = v; end
|
44
|
+
|
45
|
+
# The offset of the labels
|
46
|
+
# must be between a string between 0 and 1000
|
47
|
+
def lblOffset=(v) RegexValidator.validate "#{self.class}.lblOffset", LBL_OFFSET_REGEX, v; @lblOffset = v; end
|
48
|
+
|
49
|
+
# Serializes the category axis
|
50
|
+
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
51
|
+
# @return [String]
|
52
|
+
def to_xml(xml)
|
53
|
+
xml.send('c:catAx') {
|
54
|
+
super(xml)
|
55
|
+
xml.send('c:auto', :val=>@auto)
|
56
|
+
xml.send('c:lblAlgn', :val=>@lblAlgn)
|
57
|
+
xml.send('c:lblOffset', :val=>@lblOffset)
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# The CatAxisData class serializes the category axis data for a chart
|
3
|
+
class CatAxisData < SimpleTypedList
|
4
|
+
|
5
|
+
# Create a new CatAxisData object
|
6
|
+
# @param [Array, SimpleTypedList] data the data for this category axis. This can be a simple array or a simple typed list of cells.
|
7
|
+
def initialize(data=[])
|
8
|
+
super Object
|
9
|
+
@list.concat data if data.is_a?(Array)
|
10
|
+
data.each { |i| @list << i } if data.is_a?(SimpleTypedList)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Serializes the category axis data
|
14
|
+
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
15
|
+
# @return [String]
|
16
|
+
def to_xml(xml)
|
17
|
+
xml.send('c:cat') {
|
18
|
+
xml.send('c:strRef') {
|
19
|
+
xml.send('c:f', Axlsx::cell_range(@list))
|
20
|
+
xml.send('c:strCache') {
|
21
|
+
xml.send('c:ptCount', :val=>size)
|
22
|
+
each_with_index do |item, index|
|
23
|
+
v = item.is_a?(Cell) ? item.value : item
|
24
|
+
xml.send('c:pt', :idx=>index) {
|
25
|
+
xml.send('c:v', v)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Axlsx
|
3
|
+
# A Chart is the superclass for specific charts
|
4
|
+
# @note Worksheet#add_chart is the recommended way to create charts for your worksheets.
|
5
|
+
# @see README for examples
|
6
|
+
class Chart
|
7
|
+
|
8
|
+
|
9
|
+
# The 3D view properties for the chart
|
10
|
+
attr_reader :view3D
|
11
|
+
|
12
|
+
# A reference to the graphic frame that owns this chart
|
13
|
+
# @return [GraphicFrame]
|
14
|
+
attr_reader :graphic_frame
|
15
|
+
|
16
|
+
# A collection of series objects that are applied to the chart
|
17
|
+
# @return [SimpleTypedList]
|
18
|
+
attr_reader :series
|
19
|
+
|
20
|
+
# The type of series to use for this chart.
|
21
|
+
# @return [Series]
|
22
|
+
attr_reader :series_type
|
23
|
+
|
24
|
+
#TODO data labels!
|
25
|
+
#attr_reader :dLabls
|
26
|
+
|
27
|
+
# The title object for the chart.
|
28
|
+
# @return [Title]
|
29
|
+
attr_reader :title
|
30
|
+
|
31
|
+
# The style for the chart.
|
32
|
+
# see ECMA Part 1 §21.2.2.196
|
33
|
+
# @return [Integer]
|
34
|
+
attr_reader :style
|
35
|
+
|
36
|
+
# Show the legend in the chart
|
37
|
+
# @return [Boolean]
|
38
|
+
attr_reader :show_legend
|
39
|
+
|
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
|
+
def initialize(frame, options={})
|
45
|
+
@style = 2
|
46
|
+
@graphic_frame=frame
|
47
|
+
@graphic_frame.anchor.drawing.worksheet.workbook.charts << self
|
48
|
+
@series = SimpleTypedList.new Series
|
49
|
+
@show_legend = true
|
50
|
+
@series_type = Series
|
51
|
+
options.each do |o|
|
52
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
53
|
+
end
|
54
|
+
start_at *options[:start_at] if options[:start_at]
|
55
|
+
end_at *options[:end_at] if options[:start_at]
|
56
|
+
yield self if block_given?
|
57
|
+
end
|
58
|
+
|
59
|
+
# The index of this chart in the workbooks charts collection
|
60
|
+
# @return [Integer]
|
61
|
+
def index
|
62
|
+
@graphic_frame.anchor.drawing.worksheet.workbook.charts.index(self)
|
63
|
+
end
|
64
|
+
|
65
|
+
# The part name for this chart
|
66
|
+
# @return [String]
|
67
|
+
def pn
|
68
|
+
"#{CHART_PN % (index+1)}"
|
69
|
+
end
|
70
|
+
|
71
|
+
# The title object for the chart.
|
72
|
+
# @param [String, Cell] v
|
73
|
+
# @return [Title]
|
74
|
+
def title=(v)
|
75
|
+
v = Title.new(v) if v.is_a?(String) || v.is_a?(Cell)
|
76
|
+
DataTypeValidator.validate "#{self.class}.title", Title, v
|
77
|
+
@title = v
|
78
|
+
end
|
79
|
+
|
80
|
+
# Show the legend in the chart
|
81
|
+
# @param [Boolean] v
|
82
|
+
# @return [Boolean]
|
83
|
+
def show_legend=(v) Axlsx::validate_boolean(v); @show_legend = v; end
|
84
|
+
|
85
|
+
|
86
|
+
# The style for the chart.
|
87
|
+
# see ECMA Part 1 §21.2.2.196
|
88
|
+
# @param [Integer] v must be between 1 and 48
|
89
|
+
def style=(v) DataTypeValidator.validate "Chart.style", Integer, v, lambda { |arg| arg >= 1 && arg <= 48 }; @style = v; end
|
90
|
+
|
91
|
+
# backwards compatibility to allow chart.to and chart.from access to anchor markers
|
92
|
+
# @note This will be disconinued in version 2.0.0. Please use the end_at method
|
93
|
+
def to
|
94
|
+
@graphic_frame.anchor.to
|
95
|
+
end
|
96
|
+
|
97
|
+
# backwards compatibility to allow chart.to and chart.from access to anchor markers
|
98
|
+
# @note This will be disconinued in version 2.0.0. please use the start_at method
|
99
|
+
def from
|
100
|
+
@graphic_frame.anchor.from
|
101
|
+
end
|
102
|
+
|
103
|
+
# Adds a new series to the chart's series collection.
|
104
|
+
# @return [Series]
|
105
|
+
# @see Series
|
106
|
+
def add_series(options={})
|
107
|
+
@series_type.new(self, options)
|
108
|
+
@series.last
|
109
|
+
end
|
110
|
+
|
111
|
+
# Chart Serialization
|
112
|
+
# serializes the chart
|
113
|
+
def to_xml
|
114
|
+
builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
|
115
|
+
xml.send('c:chartSpace',:'xmlns:c' => XML_NS_C, :'xmlns:a' => XML_NS_A) {
|
116
|
+
xml.send('c:date1904', :val=>Axlsx::Workbook.date1904)
|
117
|
+
xml.send('c:style', :val=>style)
|
118
|
+
xml.send('c:chart') {
|
119
|
+
@title.to_xml(xml) unless @title.nil?
|
120
|
+
@view3D.to_xml(xml) unless @view3D.nil?
|
121
|
+
xml.send('c:plotArea') {
|
122
|
+
xml.send('c:layout')
|
123
|
+
yield xml if block_given?
|
124
|
+
}
|
125
|
+
if @show_legend
|
126
|
+
xml.send('c:legend') {
|
127
|
+
xml.send('c:legendPos', :val => "r")
|
128
|
+
xml.send('c:layout')
|
129
|
+
}
|
130
|
+
end
|
131
|
+
}
|
132
|
+
}
|
133
|
+
end
|
134
|
+
builder.to_xml
|
135
|
+
end
|
136
|
+
|
137
|
+
# This is a short cut method to set the start anchor position
|
138
|
+
# If you need finer granularity in positioning use
|
139
|
+
# graphic_frame.anchor.from.colOff / rowOff
|
140
|
+
# @param [Integer] x The column
|
141
|
+
# @param [Integer] y The row
|
142
|
+
# @return [Marker]
|
143
|
+
def start_at(x, y=0)
|
144
|
+
x, y = *parse_coord_args(x, y)
|
145
|
+
@graphic_frame.anchor.from.col = x
|
146
|
+
@graphic_frame.anchor.from.row = y
|
147
|
+
end
|
148
|
+
|
149
|
+
# This is a short cut method to set the end anchor position
|
150
|
+
# If you need finer granularity in positioning use
|
151
|
+
# graphic_frame.anchor.to.colOff / rowOff
|
152
|
+
# @param [Integer] x The column
|
153
|
+
# @param [Integer] y The row
|
154
|
+
# @return [Marker]
|
155
|
+
def end_at(x, y=0)
|
156
|
+
x, y = *parse_coord_args(x, y)
|
157
|
+
@graphic_frame.anchor.to.col = x
|
158
|
+
@graphic_frame.anchor.to.row = y
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def parse_coord_args(x, y=0)
|
164
|
+
if x.is_a?(String)
|
165
|
+
x, y = *Axlsx::name_to_indices(x)
|
166
|
+
end
|
167
|
+
if x.is_a?(Cell)
|
168
|
+
x, y = *x.pos
|
169
|
+
end
|
170
|
+
if x.is_a?(Array)
|
171
|
+
x, y = *x
|
172
|
+
end
|
173
|
+
[x, y]
|
174
|
+
end
|
175
|
+
|
176
|
+
def view3D=(v) DataTypeValidator.validate "#{self.class}.view3D", View3D, v; @view3D = v; end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|