summaryrefslogtreecommitdiffhomepage
path: root/lib/axlsx/drawing/drawing.rb
blob: 1267d22ea7327a80b0cf89cc76b48e833e1396f0 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# encoding: UTF-8
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/scatter_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/named_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/scatter_chart.rb'

  require 'axlsx/drawing/picture_locking.rb'
  require 'axlsx/drawing/pic.rb'
  require 'axlsx/drawing/hyperlink.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 hyperlink objects associated with this drawings images
    # @return [Array]
    def hyperlinks
      links = self.images.select { |a| a.hyperlink.is_a?(Hyperlink) }
      links.map { |a| a.hyperlink }
    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
      hyperlinks.each do |hyperlink|
        r << Relationship.new(HYPERLINK_R, hyperlink.href, :target_mode => :External)
      end
      r
    end

    # Serializes the object
    # @param [String] str
    # @return [String]
    def to_xml_string(str = '')
      str << '<?xml version="1.0" encoding="UTF-8"?>'
      str << '<xdr:wsDr xmlns:xdr="' << XML_NS_XDR << '" xmlns:a="' << XML_NS_A << '" xmlns:c="' << XML_NS_C << '">'
      anchors.each { |anchor| anchor.to_xml_string(str) }
      str << '</xdr:wsDr>'
    end

  end
end