# -*- encoding: utf-8 -*- require 'write_xlsx/package/xml_writer_simple' require 'write_xlsx/utility' require 'write_xlsx/chart/caption' module Writexlsx class Chart class Axis < Caption include Writexlsx::Utility attr_accessor :defaults attr_accessor :min, :max, :num_format, :position attr_accessor :major_tick_mark, :minor_tick_mark attr_reader :minor_unit, :major_unit, :minor_unit_type, :major_unit_type attr_reader :display_units_visible, :display_units attr_reader :log_base, :crossing, :position_axis, :label_position, :visible attr_reader :num_format_linked, :num_font, :layout, :interval_unit attr_reader :interval_tick, :major_gridlines, :minor_gridlines, :reverse attr_reader :line, :fill, :text_axis, :label_align # # Convert user defined axis values into axis instance. # def merge_with_hash(params) # :nodoc: super args = (defaults || {}).merge(params) [ :reverse, :min, :max, :minor_unit, :major_unit, :minor_unit_type, :major_unit_type, :log_base, :crossing, :position_axis, :label_position, :num_format, :num_format_linked, :interval_unit, :interval_tick, :line, :fill, :label_align ].each { |val| instance_variable_set("@#{val}", args[val]) } set_major_minor_gridlines(args) @visible = args[:visible] || 1 set_display_units(args) set_display_units_visible(args) set_position(args) set_position_axis set_font_properties(args) set_axis_name_layout(args) set_axis_line(args) set_axis_fill(args) if ptrue?(args[:text_axis]) @chart.date_category = false @text_axis = true end # Set the tick marker types. @major_tick_mark = get_tick_type(params[:major_tick_mark]) @minor_tick_mark = get_tick_type(params[:minor_tick_mark]) end # # Write the element. Note: It is assumed that if a user # defined number format is supplied (i.e., non-default) then the sourceLinked # attribute is 0. The user can override this if required. # def write_number_format(writer) # :nodoc: writer.empty_tag('c:numFmt', num_fmt_attributes) end # # Write the element. Special case handler for category axes which # don't always have a number format. # def write_cat_number_format(writer, cat_has_num_fmt) return unless user_defined_num_fmt_set? || cat_has_num_fmt writer.empty_tag('c:numFmt', num_fmt_attributes) end private def user_defined_num_fmt_set? @defaults && @num_format != @defaults[:num_format] end def source_linked value = 1 value = 0 if user_defined_num_fmt_set? value = 1 if @num_format_linked value end def num_fmt_attributes [ ['formatCode', @num_format], ['sourceLinked', source_linked] ] end def set_major_minor_gridlines(args) # Map major/minor_gridlines properties. [:major_gridlines, :minor_gridlines].each do |lines| if args[lines] && ptrue?(args[lines][:visible]) instance_variable_set("@#{lines}", Gridline.new(args[lines])) else instance_variable_set("@#{lines}", nil) end end end # # # Convert user defined display units to internal units. # def get_display_units(display_units) return unless ptrue?(display_units) types = { 'hundreds' => 'hundreds', 'thousands' => 'thousands', 'ten_thousands' => 'tenThousands', 'hundred_thousands' => 'hundredThousands', 'millions' => 'millions', 'ten_millions' => 'tenMillions', 'hundred_millions' => 'hundredMillions', 'billions' => 'billions', 'trillions' => 'trillions' } if types[display_units] return types[display_units] else # warn "Unknown display_units type '$display_units'\n" return end end # # Convert user tick types to internal units. # def get_tick_type(tick_type) return if !ptrue?(tick_type) types = { 'outside' => 'out', 'inside' => 'in', 'none' => 'none', 'cross' => 'cross' } if(types[tick_type]) return types[tick_type] else raise "Unknown tick_type type '#{tick_type}'\n" end end def set_display_units(args) @display_units = get_display_units(args[:display_units]) end def set_display_units_visible(args) if args[:display_units_visible] @display_units_visible = args[:display_units_visible] else @display_units_visible = 1 end end def set_position(args) # Only use the first letter of bottom, top, left or right. @position = args[:position] @position = @position.downcase[0, 1] if @position end def set_position_axis # Set the position for a category axis on or between the tick marks. if @position_axis if @position_axis == 'on_tick' @position_axis = 'midCat' elsif @position_axis == 'between' # Doesn't neet to be modified. else # Otherwise use the default value. @position_axis = nil end end end def set_font_properties(args) @num_font = convert_font_args(args[:num_font]) @name_font = convert_font_args(args[:name_font]) end def set_axis_name_layout(args) @layout = @chart.layout_properties(args[:name_layout], 1) end def set_axis_line(args) @line = @chart.line_properties(args[:line]) end def set_axis_fill(args) @fill = @chart.fill_properties(args[:fill]) end end end end