diff --git a/examples/basic_charts.rb b/examples/basic_charts.rb
old mode 100644
new mode 100755
index 097af57e..5aa0acb0
--- a/examples/basic_charts.rb
+++ b/examples/basic_charts.rb
@@ -54,5 +54,36 @@
end
end
+# secondary axis in line chart
+ wb.add_worksheet(:name => "Secondary axis") do |sheet|
+ sheet.add_row %w(first second)
+ 10.times do
+ sheet.add_row [ rand(24)+1, rand(24)*100+1]
+ end
+ sheet.add_chart(Axlsx::LineChart, :title => "Simple Line Chart", :rotX => 30, :rotY => 20) do |chart|
+ chart.start_at 0, 5
+ chart.end_at 10, 25
+ chart.add_series :data => sheet["A2:A11"], :title => sheet["A1"], :color => "5B9BD5", :show_marker => true, :smooth => true
+ chart.add_series :data => sheet["B2:B11"], :title => sheet["B1"], :color => "ED7D31", :on_primary_axis => false
+
+ chart.catAxis.title = 'X Axis'
+ chart.valAxis.title = 'Primary Axis'
+ chart.secValAxis.title = "Secondary Axis"
+
+ # Set the text color of the title
+ chart.catAxis.title.text_color = "404040"
+ chart.valAxis.title.text_color = "5B9BD5"
+ chart.secValAxis.title.text_color = "ED7D31"
+
+ # Set the color of the axis values
+ chart.valAxis.text_color = "5B9BD5"
+ chart.secValAxis.text_color = "ED7D31"
+
+ # Set the luminance
+ chart.catAxis.gridlines_luminance = 0.25
+ chart.valAxis.gridlines_luminance = 0.25
+ end
+ end
+
p.serialize('basic_charts.xlsx')
diff --git a/lib/axlsx/drawing/axes.rb b/lib/axlsx/drawing/axes.rb
old mode 100644
new mode 100755
index dff87a9b..25edd5aa
--- a/lib/axlsx/drawing/axes.rb
+++ b/lib/axlsx/drawing/axes.rb
@@ -15,11 +15,12 @@ def initialize(options={})
end
end
- # [] provides assiciative access to a specic axis store in an axes
+ # [] provides associative access to a specic axis store in an axes
# instance.
# @return [Axis]
def [](name)
- axes.assoc(name)[1]
+ a = axes.assoc(name)
+ if a.nil? then nil else a[1] end
end
# Serializes the object
diff --git a/lib/axlsx/drawing/axis.rb b/lib/axlsx/drawing/axis.rb
old mode 100644
new mode 100755
index b2bb8fe7..67c3988b
--- a/lib/axlsx/drawing/axis.rb
+++ b/lib/axlsx/drawing/axis.rb
@@ -76,6 +76,10 @@ def initialize(options={})
# @return [Boolean]
attr_reader :gridlines
+ # specifies the gradient of the gridlines
+ # @return [Float]
+ attr_reader :gridlines_luminance
+
# specifies if gridlines should be shown in the chart
# @return [Boolean]
attr_reader :delete
@@ -83,6 +87,10 @@ def initialize(options={})
# the title for the axis. This can be a cell or a fixed string.
attr_reader :title
+ # Text color property
+ # @return [String]
+ attr_reader :text_color
+
# The color for this axis. This value is used when rendering the axis line in the chart.
# colors should be in 6 character rbg format
# @return [String] the rbg color assinged.
@@ -116,6 +124,14 @@ def format_code=(v) Axlsx::validate_string(v); @format_code = v; end
# default true
def gridlines=(v) Axlsx::validate_boolean(v); @gridlines = v; end
+ # Specify the gridlines luminance
+ # must be a float in (0..1)
+ # default nil
+ def gridlines_luminance=(v)
+ DataTypeValidator.validate 'Axis.gridlines_luminance', Float, v
+ @gridlines_luminance = v
+ end
+
# Specify if axis should be removed from the chart
# default false
def delete=(v) Axlsx::validate_boolean(v); @delete = v; end
@@ -146,6 +162,13 @@ def title=(v)
end
end
+ # Assigns a text color to the title
+ # colors should be in 6 character rbg format
+ def text_color=(v)
+ DataTypeValidator.validate 'Axis.text_color', String, v
+ @text_color = v
+ end
+
# Serializes the object
# @param [String] str
# @return [String]
@@ -157,11 +180,23 @@ def to_xml_string(str = '')
str << ''
# TODO shape properties need to be extracted into a class
if gridlines == false
+ # No gridlines
str << ''
str << ''
str << ''
str << ''
str << ''
+ elsif !@gridlines_luminance.nil? then
+ # light gridlines
+ str << ''
+ str << ''
+ str << ''
+ str << ''
+ str << ('')
+ str << ''
+ str << ''
+ str << ''
+ str << ''
end
str << ''
@title.to_xml_string(str) unless @title == nil
@@ -180,7 +215,13 @@ def to_xml_string(str = '')
str << ''
end
# some potential value in implementing this in full. Very detailed!
- str << ('')
+ str << ('')
+ if @text_color.nil? then
+ str << ''
+ else
+ str << ('')
+ end
+ str << ''
str << ('')
str << ('')
end
diff --git a/lib/axlsx/drawing/chart.rb b/lib/axlsx/drawing/chart.rb
old mode 100644
new mode 100755
index de87b91a..aaa688e7
--- a/lib/axlsx/drawing/chart.rb
+++ b/lib/axlsx/drawing/chart.rb
@@ -23,6 +23,7 @@ def initialize(frame, options={})
@show_legend = true
@legend_position = :r
@display_blanks_as = :gap
+ @rounded_corners = true
@series_type = Series
@title = Title.new
@bg_color = nil
@@ -98,6 +99,11 @@ def vary_colors=(v) Axlsx::validate_boolean(v); @vary_colors = v; end
# @return [String]
attr_reader :bg_color
+ # Use rounded corners for the chart?
+ # It defaults to true
+ # @return [Boolean]
+ attr_reader :rounded_corners
+
# The relationship object for this chart.
# @return [Relationship]
def relationship
@@ -178,6 +184,11 @@ def bg_color=(v)
@bg_color = v
end
+ # Should the chart have rounded corners?
+ # @param [Boolean] v
+ # @return [Boolean]
+ def rounded_corners=(v) Axlsx::validate_boolean(v); @rounded_corners = v; end
+
# Serializes the object
# @param [String] str
# @return [String]
@@ -185,6 +196,7 @@ def to_xml_string(str = '')
str << ''
str << ('')
str << ('')
+ str << '' if !@rounded_corners
str << ('')
str << ''
@title.to_xml_string str
diff --git a/lib/axlsx/drawing/line_chart.rb b/lib/axlsx/drawing/line_chart.rb
old mode 100644
new mode 100755
index a86355d5..1e60e1e3
--- a/lib/axlsx/drawing/line_chart.rb
+++ b/lib/axlsx/drawing/line_chart.rb
@@ -28,14 +28,28 @@ def cat_axis
end
alias :catAxis :cat_axis
- # the category axis
+ # the values axis
# @return [ValAxis]
def val_axis
axes[:val_axis]
end
alias :valAxis :val_axis
- # must be one of [:percentStacked, :clustered, :standard, :stacked]
+ # the secondary category axis
+ # @return [sec_cat_axis]
+ def sec_cat_axis
+ axes[:sec_cat_axis]
+ end
+ alias :secCatAxis :sec_cat_axis
+
+ # the secondary values axis
+ # @return [sec_val_axis]
+ def sec_val_axis
+ axes[:sec_val_axis]
+ end
+ alias :secValAxis :sec_val_axis
+
+ # must be one of [:percentStacked, :clustered, :standard, :stacked]
# @return [Symbol]
attr_reader :grouping
@@ -76,24 +90,80 @@ def node_name
# @param [String] str
# @return [String]
def to_xml_string(str = '')
- super(str) do
- str << ("")
- str << ('')
- str << ('')
- @series.each { |ser| ser.to_xml_string(str) }
- @d_lbls.to_xml_string(str) if @d_lbls
- yield if block_given?
- axes.to_xml_string(str, :ids => true)
- str << ("")
- axes.to_xml_string(str)
+ if @series.all? {|s| s.on_primary_axis} then
+ # Only a primary val axis
+ super(str) do
+ str << ("")
+ str << ('')
+ str << ('')
+ @series.each { |ser| ser.to_xml_string(str) }
+ @d_lbls.to_xml_string(str) if @d_lbls
+ yield if block_given?
+ axes.to_xml_string(str, :ids => true)
+ str << ("")
+ axes.to_xml_string(str)
+ end
+ else
+ # Two value axes
+ super(str) do
+ # First axis
+ str << ("")
+ str << ('')
+ str << ('')
+ @series.select {|s| s.on_primary_axis}.each { |s| s.to_xml_string(str) }
+ @d_lbls.to_xml_string(str) if @d_lbls
+ yield if block_given?
+ str << ('')
+ str << ('')
+ str << ("")
+
+ # Secondary axis
+ str << ("")
+ str << ('')
+ str << ('')
+ @series.select {|s| !s.on_primary_axis}.each { |s| s.to_xml_string(str) }
+ @d_lbls.to_xml_string(str) if @d_lbls
+ yield if block_given?
+ str << ('')
+ str << ('')
+ str << ("")
+
+ # The axes
+ axes.to_xml_string(str)
+ end
end
end
# The axes for this chart. LineCharts have a category and value
- # axis.
+ # axis. If any series is on the secondary axis we will have two
+ # category and two value axes.
# @return [Axes]
def axes
- @axes ||= Axes.new(:cat_axis => CatAxis, :val_axis => ValAxis)
+ if @axes.nil? then
+ # add the normal axes
+ @axes = Axes.new(:cat_axis => CatAxis, :val_axis => ValAxis)
+
+ # add the secondary axes if needed
+ if @series.any? {|s| !s.on_primary_axis} then
+ if @axes[:sec_cat_axis].nil? then
+ @axes.add_axis(:sec_cat_axis, Axlsx::CatAxis)
+ sec_cat_axis = @axes[:sec_cat_axis]
+ sec_cat_axis.ax_pos = :b
+ sec_cat_axis.delete = 1
+ sec_cat_axis.gridlines = false
+ end
+ if @axes[:sec_val_axis].nil? then
+ @axes.add_axis(:sec_val_axis, Axlsx::ValAxis)
+ sec_val_axis = @axes[:sec_val_axis]
+ sec_val_axis.ax_pos = :r
+ sec_val_axis.gridlines = false
+ sec_val_axis.crosses = :max
+ end
+ end
+ end
+
+ # return
+ @axes
end
end
end
diff --git a/lib/axlsx/drawing/line_series.rb b/lib/axlsx/drawing/line_series.rb
old mode 100644
new mode 100755
index 666e67c8..da380221
--- a/lib/axlsx/drawing/line_series.rb
+++ b/lib/axlsx/drawing/line_series.rb
@@ -31,6 +31,10 @@ class LineSeries < Series
# @return [Boolean]
attr_reader :smooth
+ # on primary or secondary axis
+ # @return [Boolean]
+ attr_reader :on_primary_axis
+
# Creates a new series
# @option options [Array, SimpleTypedList] data
# @option options [Array, SimpleTypedList] labels
@@ -39,6 +43,7 @@ def initialize(chart, options={})
@show_marker = false
@marker_symbol = options[:marker_symbol] ? options[:marker_symbol] : :default
@smooth = false
+ @on_primary_axis = true
@labels, @data = nil, nil
super(chart, options)
@labels = AxDataSource.new(:data => options[:labels]) unless options[:labels].nil?
@@ -68,6 +73,12 @@ def smooth=(v)
@smooth = v
end
+ # is it on the primary axis?
+ def on_primary_axis=(v)
+ Axlsx::validate_boolean(v)
+ @on_primary_axis = v
+ end
+
# Serializes the object
# @param [String] str
# @return [String]
diff --git a/lib/axlsx/drawing/title.rb b/lib/axlsx/drawing/title.rb
old mode 100644
new mode 100755
index 7f2ff9f4..84a73e6d
--- a/lib/axlsx/drawing/title.rb
+++ b/lib/axlsx/drawing/title.rb
@@ -11,6 +11,10 @@ class Title
# @return [String]
attr_reader :text_size
+ # Text color property
+ # @return [String]
+ attr_reader :text_color
+
# The cell that holds the text for the title. Setting this property will automatically update the text attribute.
# @return [Cell]
attr_reader :cell
@@ -51,6 +55,13 @@ def cell=(v)
v
end
+ # Assigns a text color to the title
+ # colors should be in 6 character rbg format
+ def text_color=(v)
+ DataTypeValidator.validate 'Title.text_color', String, v
+ @text_color = v
+ end
+
# Not implemented at this time.
#def layout=(v) DataTypeValidator.validate 'Title.layout', Layout, v; @layout = v; end
#def overlay=(v) Axlsx::validate_boolean v; @overlay=v; end
@@ -79,7 +90,15 @@ def to_xml_string(str = '')
str << ''
str << ''
str << ''
+ if @text_color.nil? then
str << ('')
+ else
+ str << ('')
+ str << ''
+ str << ('')
+ str << ''
+ str << ''
+ end
str << ('' << @text.to_s << '')
str << ''
str << ''