axlsx 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +95 -72
- data/examples/example.rb +83 -0
- data/examples/example.rb~ +79 -0
- data/examples/multi_chart.xlsx +0 -0
- data/lib/axlsx/drawing/bar_3D_chart.rb +2 -2
- data/lib/axlsx/drawing/bar_series.rb +1 -0
- data/lib/axlsx/drawing/chart.rb +11 -0
- data/lib/axlsx/drawing/drawing.rb +5 -1
- data/lib/axlsx/drawing/line_3D_chart.rb +93 -0
- data/lib/axlsx/drawing/line_3D_chart.rb~ +138 -0
- data/lib/axlsx/drawing/line_series.rb +76 -0
- data/lib/axlsx/drawing/line_series.rb~ +91 -0
- data/lib/axlsx/drawing/pie_3D_chart.rb +1 -1
- data/lib/axlsx/drawing/ser_axis.rb +42 -0
- data/lib/axlsx/drawing/ser_axis.rb~ +48 -0
- data/lib/axlsx/drawing/series.rb +9 -7
- data/lib/axlsx/drawing/series_title.rb +22 -0
- data/lib/axlsx/drawing/series_title.rb~ +18 -0
- data/lib/axlsx/drawing/title.rb +1 -2
- data/lib/axlsx/util/constants.rb +1 -1
- data/test/drawing/tc_bar_series.rb +1 -1
- data/test/drawing/tc_chart.rb +7 -5
- data/test/drawing/tc_line_3d_chart.rb +48 -0
- data/test/drawing/tc_line_3d_chart.rb~ +48 -0
- data/test/drawing/tc_line_series.tc +34 -0
- data/test/drawing/tc_line_series.tc~ +34 -0
- data/test/drawing/tc_pie_series.rb +1 -1
- data/test/drawing/tc_ser_axis.rb +23 -0
- data/test/drawing/tc_ser_axis.rb~ +20 -0
- data/test/drawing/tc_series.rb +1 -1
- data/test/drawing/tc_series_title.rb +34 -0
- data/test/drawing/tc_series_title.rb~ +34 -0
- data/test/tc_package.rb +15 -13
- metadata +24 -5
@@ -0,0 +1,48 @@
|
|
1
|
+
module Axlsx
|
2
|
+
#A CatAxis object defines a chart category axis
|
3
|
+
class SerAxis < Axis
|
4
|
+
|
5
|
+
# @return [Boolean]
|
6
|
+
attr_accessor :tickLblSkip
|
7
|
+
|
8
|
+
# @return [Boolean]
|
9
|
+
attr_accessor :tickMarkSkip
|
10
|
+
|
11
|
+
# Creates a new SerAxis object
|
12
|
+
# @param [Integer] axId the id of this axis
|
13
|
+
# @param [Integer] crossAx the id of the perpendicular axis
|
14
|
+
# @option options [Symbol] axPos
|
15
|
+
# @option options [Symbol] tickLblPos
|
16
|
+
# @option options [Symbol] crosses
|
17
|
+
# @option options [Boolean] auto
|
18
|
+
# @option options [Symbol] lblAlgn
|
19
|
+
# @option options [Integer] lblOffset
|
20
|
+
def initialize(axId, crossAx, options={})
|
21
|
+
super(axId, crossAx, options)
|
22
|
+
self.auto = true
|
23
|
+
self.lblAlgn = :ctr
|
24
|
+
self.lblOffset = "100%"
|
25
|
+
options.each do |o|
|
26
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def auto=(v) Axlsx::validate_boolean(v); @auto = v; end
|
31
|
+
def lblAlgn=(v) RestrictionValidator.validate "#{self.class}.lblAlgn", [:ctr, :l, :r], v; @lblAlgn = v; end
|
32
|
+
def lblOffset=(v) RegexValidator.validate "#{self.class}.lblOffset", LBL_OFFSET_REGEX, v; @lblOffset = v; end
|
33
|
+
|
34
|
+
# Serializes the category axis
|
35
|
+
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
36
|
+
# @return [String]
|
37
|
+
def to_xml(xml)
|
38
|
+
xml.send('c:catAx') {
|
39
|
+
super(xml)
|
40
|
+
xml.send('c:auto', :val=>@auto)
|
41
|
+
xml.send('c:lblAlgn', :val=>@lblAlgn)
|
42
|
+
xml.send('c:lblOffset', :val=>@lblOffset)
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
data/lib/axlsx/drawing/series.rb
CHANGED
@@ -18,7 +18,7 @@ module Axlsx
|
|
18
18
|
attr_accessor :order
|
19
19
|
|
20
20
|
# The title of the series
|
21
|
-
# @return [
|
21
|
+
# @return [SeriesTitle]
|
22
22
|
attr_accessor :title
|
23
23
|
|
24
24
|
# Creates a new series
|
@@ -44,8 +44,12 @@ module Axlsx
|
|
44
44
|
@order || index
|
45
45
|
end
|
46
46
|
|
47
|
-
def title=(v)
|
48
|
-
|
47
|
+
def title=(v)
|
48
|
+
v = SeriesTitle.new(v) if v.is_a?(String) || v.is_a?(Cell)
|
49
|
+
DataTypeValidator.validate "#{self.class}.title", SeriesTitle, v
|
50
|
+
@title = v
|
51
|
+
end
|
52
|
+
|
49
53
|
private
|
50
54
|
|
51
55
|
# assigns the chart for this series
|
@@ -57,10 +61,8 @@ module Axlsx
|
|
57
61
|
def to_xml(xml)
|
58
62
|
xml.send('c:ser') {
|
59
63
|
xml.send('c:idx', :val=>index)
|
60
|
-
xml.send('c:order', :val=>order || index)
|
61
|
-
|
62
|
-
xml.send('c:v', self.title)
|
63
|
-
}
|
64
|
+
xml.send('c:order', :val=>order || index)
|
65
|
+
title.to_xml(xml) unless title.nil?
|
64
66
|
yield xml if block_given?
|
65
67
|
}
|
66
68
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# A series title is a Title with a slightly different serialization
|
3
|
+
class SeriesTitle < Title
|
4
|
+
|
5
|
+
# Serializes the series title
|
6
|
+
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
7
|
+
# @return [String]
|
8
|
+
def to_xml(xml)
|
9
|
+
xml.send('c:tx') {
|
10
|
+
xml.send('c:strRef') {
|
11
|
+
xml.send('c:f', range)
|
12
|
+
xml.send('c:strCache') {
|
13
|
+
xml.send('c:ptCount', :val=>1)
|
14
|
+
xml.send('c:pt', :idx=>0) {
|
15
|
+
xml.send('c:v', @text)
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Axlsx
|
2
|
+
class SeriesTitle < Title
|
3
|
+
|
4
|
+
def to_xml(xml)
|
5
|
+
xml.send('c:tx') {
|
6
|
+
xml.send('c:strRef') {
|
7
|
+
xml.send('c:f', range)
|
8
|
+
xml.send('c:strCache') {
|
9
|
+
xml.send('c:ptCount', :val=>1)
|
10
|
+
xml.send('c:pt', :idx=>0) {
|
11
|
+
xml.send('c:v', @text)
|
12
|
+
}
|
13
|
+
}
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/axlsx/drawing/title.rb
CHANGED
@@ -32,7 +32,6 @@ module Axlsx
|
|
32
32
|
end
|
33
33
|
|
34
34
|
# Not implemented at this time.
|
35
|
-
#def tx=(v) DataTypeValidator.validate 'Title.tx', Tx, v; @tx=v; end
|
36
35
|
#def layout=(v) DataTypeValidator.validate 'Title.layout', Layout, v; @layout = v; end
|
37
36
|
#def overlay=(v) Axlsx::validate_boolean v; @overlay=v; end
|
38
37
|
#def spPr=(v) DataTypeValidator.validate 'Title.spPr', SpPr, v; @spPr = v; end
|
@@ -55,7 +54,7 @@ module Axlsx
|
|
55
54
|
}
|
56
55
|
}
|
57
56
|
end
|
58
|
-
|
57
|
+
|
59
58
|
private
|
60
59
|
|
61
60
|
# returns the excel style abslute reference for the title when title is a Cell object
|
data/lib/axlsx/util/constants.rb
CHANGED
@@ -11,7 +11,7 @@ class TestBarSeries < Test::Unit::TestCase
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_initialize
|
14
|
-
assert_equal(@series.title, "bob", "series title has been applied")
|
14
|
+
assert_equal(@series.title.text, "bob", "series title has been applied")
|
15
15
|
assert_equal(@series.data, [0,1,2], "data option applied")
|
16
16
|
assert_equal(@series.labels, ["zero", "one","two"], "labels option applied")
|
17
17
|
assert_equal(@series.shape, :box, "series shape has been applied")
|
data/test/drawing/tc_chart.rb
CHANGED
@@ -28,19 +28,21 @@ class TestChart < Test::Unit::TestCase
|
|
28
28
|
assert_equal(@chart.title.cell, @row.cells.first)
|
29
29
|
end
|
30
30
|
|
31
|
+
def test_style
|
32
|
+
assert_raise(ArgumentError) { @chart.style = 49 }
|
33
|
+
assert_nothing_raised { @chart.style = 2 }
|
34
|
+
assert_equal(@chart.style, 2)
|
35
|
+
end
|
36
|
+
|
31
37
|
|
32
38
|
def test_add_series
|
33
39
|
s = @chart.add_series :data=>[0,1,2,3], :labels => ["one", 1, "anything"], :title=>"bob"
|
34
40
|
assert_equal(@chart.series.last, s, "series has been added to chart series collection")
|
35
|
-
assert_equal(s.title, "bob", "series title has been applied")
|
41
|
+
assert_equal(s.title.text, "bob", "series title has been applied")
|
36
42
|
assert_equal(s.data, [0,1,2,3], "data option applied")
|
37
43
|
assert_equal(s.labels, ["one",1,"anything"], "labels option applied")
|
38
44
|
end
|
39
45
|
|
40
|
-
def test_create_range
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
46
|
def test_pn
|
45
47
|
assert_equal(@chart.pn, "charts/chart1.xml")
|
46
48
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'axlsx.rb'
|
3
|
+
|
4
|
+
class TestLine3DChart < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@p = Axlsx::Package.new
|
8
|
+
ws = @p.workbook.add_worksheet
|
9
|
+
@row = ws.add_row ["one", 1, Time.now]
|
10
|
+
@chart = ws.add_chart Axlsx::Line3DChart, :title => "fishery"
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_initialization
|
17
|
+
assert_equal(@chart.grouping, :standard, "grouping defualt incorrect")
|
18
|
+
assert_equal(@chart.series_type, Axlsx::LineSeries, "series type incorrect")
|
19
|
+
assert(@chart.catAxis.is_a?(Axlsx::CatAxis), "category axis not created")
|
20
|
+
assert(@chart.valAxis.is_a?(Axlsx::ValAxis), "value access not created")
|
21
|
+
assert(@chart.serAxis.is_a?(Axlsx::SerAxis), "value access not created")
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_grouping
|
25
|
+
assert_raise(ArgumentError, "require valid grouping") { @chart.grouping = :inverted }
|
26
|
+
assert_nothing_raised("allow valid grouping") { @chart.grouping = :stacked }
|
27
|
+
assert(@chart.grouping == :stacked)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_gapDepth
|
31
|
+
assert_raise(ArgumentError, "require valid gapDepth") { @chart.gapDepth = 200 }
|
32
|
+
assert_nothing_raised("allow valid gapDepth") { @chart.gapDepth = "200%" }
|
33
|
+
assert(@chart.gapDepth == "200%")
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def test_to_xml
|
38
|
+
schema = Nokogiri::XML::Schema(File.open(Axlsx::DRAWING_XSD))
|
39
|
+
doc = Nokogiri::XML(@chart.to_xml)
|
40
|
+
errors = []
|
41
|
+
schema.validate(doc).each do |error|
|
42
|
+
errors.push error
|
43
|
+
puts error.message
|
44
|
+
end
|
45
|
+
assert(errors.empty?, "error free validation")
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'axlsx.rb'
|
3
|
+
|
4
|
+
class TestBar3DChart < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@p = Axlsx::Package.new
|
8
|
+
ws = @p.workbook.add_worksheet
|
9
|
+
@row = ws.add_row ["one", 1, Time.now]
|
10
|
+
@chart = ws.add_chart Axlsx::Bar3DChart, :title => "fishery"
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_initialization
|
17
|
+
assert_equal(@chart.grouping, :clustered, "grouping defualt incorrect")
|
18
|
+
assert_equal(@chart.series_type, Axlsx::LineSeries, "series type incorrect")
|
19
|
+
assert(@chart.catAxis.is_a?(Axlsx::CatAxis), "category axis not created")
|
20
|
+
assert(@chart.valAxis.is_a?(Axlsx::ValAxis), "value access not created")
|
21
|
+
assert(@chart.serAxis.is_a?(Axlsx::ValAxis), "value access not created")
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_grouping
|
25
|
+
assert_raise(ArgumentError, "require valid grouping") { @chart.grouping = :inverted }
|
26
|
+
assert_nothing_raised("allow valid grouping") { @chart.grouping = :standard }
|
27
|
+
assert(@chart.grouping == :standard)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_gapDepth
|
31
|
+
assert_raise(ArgumentError, "require valid gapDepth") { @chart.gapDepth = 200 }
|
32
|
+
assert_nothing_raised("allow valid gapDepth") { @chart.gapDepth = "200%" }
|
33
|
+
assert(@chart.gapDepth == "200%")
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def test_to_xml
|
38
|
+
schema = Nokogiri::XML::Schema(File.open(Axlsx::DRAWING_XSD))
|
39
|
+
doc = Nokogiri::XML(@chart.to_xml)
|
40
|
+
errors = []
|
41
|
+
schema.validate(doc).each do |error|
|
42
|
+
errors.push error
|
43
|
+
puts error.message
|
44
|
+
end
|
45
|
+
assert(errors.empty?, "error free validation")
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'axlsx.rb'
|
3
|
+
|
4
|
+
class TestLineSeries < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
p = Axlsx::Package.new
|
8
|
+
@ws = p.workbook.add_worksheet :name=>"hmmm"
|
9
|
+
chart = @ws.drawing.add_chart Axlsx::Line3DChart, :title => "fishery"
|
10
|
+
@series = chart.add_series :data=>[0,1,2], :labels=>["zero", "one", "two"], :title=>"bob"
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_initialize
|
14
|
+
assert_equal(@series.title.text, "bob", "series title has been applied")
|
15
|
+
assert_equal(@series.data, [0,1,2], "data option applied")
|
16
|
+
assert_equal(@series.labels, ["zero", "one","two"], "labels option applied")
|
17
|
+
assert_equal(@series.shape, :box, "series shape has been applied")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_data
|
21
|
+
assert_equal(@series.data, [0,1,2])
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_labels
|
25
|
+
assert_equal(@series.labels, ["zero", "one", "two"])
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_shape
|
29
|
+
assert_raise(ArgumentError, "require valid shape") { @series.shape = :teardropt }
|
30
|
+
assert_nothing_raised("allow valid shape") { @series.shape = :cone }
|
31
|
+
assert(@series.shape == :cone)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'axlsx.rb'
|
3
|
+
|
4
|
+
class TestLineSeries < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
p = Axlsx::Package.new
|
8
|
+
@ws = p.workbook.add_worksheet :name=>"hmmm"
|
9
|
+
chart = @ws.drawing.add_chart Axlsx::Bar3DChart, :title => "fishery"
|
10
|
+
@series = chart.add_series :data=>[0,1,2], :labels=>["zero", "one", "two"], :title=>"bob"
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_initialize
|
14
|
+
assert_equal(@series.title, "bob", "series title has been applied")
|
15
|
+
assert_equal(@series.data, [0,1,2], "data option applied")
|
16
|
+
assert_equal(@series.labels, ["zero", "one","two"], "labels option applied")
|
17
|
+
assert_equal(@series.shape, :box, "series shape has been applied")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_data
|
21
|
+
assert_equal(@series.data, [0,1,2])
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_labels
|
25
|
+
assert_equal(@series.labels, ["zero", "one", "two"])
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_shape
|
29
|
+
assert_raise(ArgumentError, "require valid shape") { @series.shape = :teardropt }
|
30
|
+
assert_nothing_raised("allow valid shape") { @series.shape = :cone }
|
31
|
+
assert(@series.shape == :cone)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -11,7 +11,7 @@ class TestPieSeries < Test::Unit::TestCase
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_initialize
|
14
|
-
assert_equal(@series.title, "bob", "series title has been applied")
|
14
|
+
assert_equal(@series.title.text, "bob", "series title has been applied")
|
15
15
|
assert_equal(@series.data, [0,1,2], "data option applied")
|
16
16
|
assert_equal(@series.labels, ["zero", "one","two"], "labels option applied")
|
17
17
|
assert_equal(@series.explosion, nil, "series shape has been applied")
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'axlsx.rb'
|
3
|
+
|
4
|
+
class TestSerAxis < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@axis = Axlsx::SerAxis.new 12345, 54321
|
7
|
+
end
|
8
|
+
def teardown
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_tickLblSkip
|
12
|
+
assert_raise(ArgumentError, "requires valid tickLblSkip") { @axis.tickLblSkip = :my_eyes }
|
13
|
+
assert_nothing_raised("accepts valid tickLblSkip") { @axis.tickLblSkip = false }
|
14
|
+
assert_equal(@axis.tickLblSkip, false)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_tickMarkSkip
|
18
|
+
assert_raise(ArgumentError, "requires valid tickMarkSkip") { @axis.tickMarkSkip = :my_eyes }
|
19
|
+
assert_nothing_raised("accepts valid tickMarkSkip") { @axis.tickMarkSkip = false }
|
20
|
+
assert_equal(@axis.tickMarkSkip, false)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'axlsx.rb'
|
3
|
+
|
4
|
+
class TestSerAxis < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@axis = Axlsx::ValAxis.new 12345, 54321
|
7
|
+
end
|
8
|
+
def teardown
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_initialization
|
12
|
+
assert_equal(@axis.crossBetween, :between, "axis crossBetween default incorrect")
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_crossBetween
|
16
|
+
assert_raise(ArgumentError, "requires valid crossBetween") { @axis.crossBetween = :my_eyes }
|
17
|
+
assert_nothing_raised("accepts valid crossBetween") { @axis.crossBetween = :midCat }
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
data/test/drawing/tc_series.rb
CHANGED
@@ -11,7 +11,7 @@ class TestSeries < Test::Unit::TestCase
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_initialize
|
14
|
-
assert_equal(@series.title, "bob", "series title has been applied")
|
14
|
+
assert_equal(@series.title.text, "bob", "series title has been applied")
|
15
15
|
assert_equal(@series.order, @series.index, "order is index by default")
|
16
16
|
assert_equal(@series.index, @series.chart.series.index(@series), "index is applied")
|
17
17
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'axlsx.rb'
|
3
|
+
|
4
|
+
class TestSeriesTitle < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@p = Axlsx::Package.new
|
7
|
+
ws = @p.workbook.add_worksheet
|
8
|
+
@row = ws.add_row ["one", 1, Time.now]
|
9
|
+
@title = Axlsx::SeriesTitle.new
|
10
|
+
@chart = ws.add_chart Axlsx::Bar3DChart
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_initialization
|
17
|
+
assert(@title.text == "")
|
18
|
+
assert(@title.cell == nil)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_text
|
22
|
+
assert_raise(ArgumentError, "text must be a string") { @title.text = 123 }
|
23
|
+
@title.cell = @row.cells.first
|
24
|
+
@title.text = "bob"
|
25
|
+
assert(@title.cell == nil, "setting title with text clears the cell")
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_cell
|
29
|
+
assert_raise(ArgumentError, "cell must be a Cell") { @title.cell = "123" }
|
30
|
+
@title.cell = @row.cells.first
|
31
|
+
assert(@title.text == "one")
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|