summaryrefslogtreecommitdiffhomepage
path: root/lib/axlsx/drawing/drawing.rb
blob: 6d779f7aa2281a0e18388e378c7589cb9153119f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
module Axlsx
  require 'axlsx/drawing/title.rb'
  require 'axlsx/drawing/series_title.rb'
  require 'axlsx/drawing/series.rb'
  require 'axlsx/drawing/pie_series.rb'
  require 'axlsx/drawing/bar_series.rb'  
  require 'axlsx/drawing/line_series.rb'  

  require 'axlsx/drawing/scaling.rb'
  require 'axlsx/drawing/axis.rb'
  require 'axlsx/drawing/ser_axis.rb'
  require 'axlsx/drawing/cat_axis.rb'
  require 'axlsx/drawing/val_axis.rb'

  require 'axlsx/drawing/cat_axis_data.rb'
  require 'axlsx/drawing/val_axis_data.rb'

  require 'axlsx/drawing/marker.rb'
 
  require 'axlsx/drawing/one_cell_anchor.rb'
  require 'axlsx/drawing/two_cell_anchor.rb'
  require 'axlsx/drawing/graphic_frame.rb'

  require 'axlsx/drawing/view_3D.rb'
  require 'axlsx/drawing/chart.rb'
  require 'axlsx/drawing/pie_3D_chart.rb'
  require 'axlsx/drawing/bar_3D_chart.rb'
  require 'axlsx/drawing/line_3D_chart.rb'

  require 'axlsx/drawing/picture_locking.rb'
  require 'axlsx/drawing/pic.rb'

  # A Drawing is a canvas for charts. Each worksheet has a single drawing that manages anchors.
  # The anchors reference the charts via graphical frames. This is not a trivial relationship so please do follow the advice in the note.
  # @note The recommended way to manage drawings is to use the Worksheet.add_chart method.
  # @see Worksheet#add_chart
  # @see Chart
  # see README for an example of how to create a chart.
  class Drawing

    # The worksheet that owns the drawing
    # @return [Worksheet]
    attr_reader :worksheet
   
    # A collection of anchors for this drawing
    # only TwoCellAnchors are supported in this version
    # @return [SimpleTypedList]
    attr_reader :anchors

    # Creates a new Drawing object
    # @param [Worksheet] worksheet The worksheet that owns this drawing
    def initialize(worksheet)
      DataTypeValidator.validate "Drawing.worksheet", Worksheet, worksheet
      @worksheet = worksheet
      @worksheet.workbook.drawings << self
      @anchors = SimpleTypedList.new [TwoCellAnchor, OneCellAnchor]
    end

    # Adds an image to the chart
    # @note The recommended way to manage images is to use Worksheet.add_image. Please refer to that method for documentation.
    # @see Worksheet#add_image
    def add_image(options={})
      OneCellAnchor.new(self, options)
      @anchors.last.object
    end

    # Adds a chart to the drawing.
    # @note The recommended way to manage charts is to use Worksheet.add_chart. Please refer to that method for documentation.
    # @see Worksheet#add_chart
    def add_chart(chart_type, options={})
      TwoCellAnchor.new(self, options)
      @anchors.last.add_chart(chart_type, options)
    end

    # An array of charts that are associated with this drawing's anchors
    # @return [Array]
    def charts
      charts = @anchors.select { |a| a.object.is_a?(GraphicFrame) }
      charts.map { |a| a.object.chart }
    end

    # An array of image objects that are associated with this drawing's anchors
    # @return [Array]
    def images
      images = @anchors.select { |a| a.object.is_a?(Pic) }
      images.map { |a| a.object }
    end

    # The index of this drawing in the owning workbooks's drawings collection.
    # @return [Integer]
    def index
      @worksheet.workbook.drawings.index(self)
    end

    # The relation reference id for this drawing
    # @return [String]
    def rId
      "rId#{index+1}"
    end

    # The part name for this drawing
    # @return [String]
    def pn
      "#{DRAWING_PN % (index+1)}"
    end

    # The relational part name for this drawing
    # @return [String]
    def rels_pn
      "#{DRAWING_RELS_PN % (index+1)}"
    end

    # The drawing's relationships.
    # @return [Relationships]
    def relationships
      r = Relationships.new
      charts.each do |chart|
        r << Relationship.new(CHART_R, "../#{chart.pn}")
      end
      images.each do |image|
        r << Relationship.new(IMAGE_R, "../#{image.pn}")
      end
      r
    end

    # Serializes the drawing
    # @return [String]
    def to_xml
      builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
        xml.send('xdr:wsDr', :'xmlns:xdr'=>XML_NS_XDR, :'xmlns:a'=>XML_NS_A, :'xmlns:c'=>XML_NS_C) {
          anchors.each {|anchor| anchor.to_xml(xml) }
        }        
      end
      builder.to_xml
    end
  end
end