writeexcel 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. data/README +26 -31
  2. data/examples/a_simple.rb +42 -42
  3. data/examples/{autofilters.rb → autofilter.rb} +264 -266
  4. data/examples/bigfile.rb +29 -0
  5. data/examples/chart_area.rb +120 -0
  6. data/examples/chart_bar.rb +119 -0
  7. data/examples/chart_column.rb +119 -0
  8. data/examples/chart_line.rb +119 -0
  9. data/examples/chart_pie.rb +107 -0
  10. data/examples/chart_scatter.rb +120 -0
  11. data/examples/chart_stock.rb +147 -0
  12. data/examples/copyformat.rb +51 -51
  13. data/examples/data_validate.rb +278 -278
  14. data/examples/date_time.rb +86 -86
  15. data/examples/defined_name.rb +31 -0
  16. data/examples/demo.rb +120 -118
  17. data/examples/diag_border.rb +35 -35
  18. data/examples/formats.rb +489 -489
  19. data/examples/header.rb +136 -136
  20. data/examples/hidden.rb +28 -28
  21. data/examples/hyperlink.rb +42 -42
  22. data/examples/images.rb +52 -52
  23. data/examples/merge1.rb +39 -39
  24. data/examples/merge2.rb +44 -44
  25. data/examples/merge3.rb +65 -65
  26. data/examples/merge4.rb +82 -82
  27. data/examples/merge5.rb +79 -79
  28. data/examples/properties.rb +33 -0
  29. data/examples/properties_jp.rb +32 -0
  30. data/examples/protection.rb +46 -46
  31. data/examples/regions.rb +52 -52
  32. data/examples/repeat.rb +42 -42
  33. data/examples/stats.rb +75 -75
  34. data/examples/stocks.rb +80 -80
  35. data/examples/tab_colors.rb +30 -30
  36. data/examples/write_arrays.rb +82 -0
  37. data/lib/writeexcel.rb +1134 -18
  38. data/lib/writeexcel/biffwriter.rb +273 -260
  39. data/lib/writeexcel/chart.rb +2306 -217
  40. data/lib/writeexcel/charts/area.rb +152 -0
  41. data/lib/writeexcel/charts/bar.rb +177 -0
  42. data/lib/writeexcel/charts/column.rb +156 -0
  43. data/lib/writeexcel/charts/external.rb +61 -0
  44. data/lib/writeexcel/charts/line.rb +152 -0
  45. data/lib/writeexcel/charts/pie.rb +169 -0
  46. data/lib/writeexcel/charts/scatter.rb +192 -0
  47. data/lib/writeexcel/charts/stock.rb +211 -0
  48. data/lib/writeexcel/excelformulaparser.rb +208 -195
  49. data/lib/writeexcel/format.rb +1697 -1108
  50. data/lib/writeexcel/formula.rb +1050 -986
  51. data/lib/writeexcel/olewriter.rb +322 -322
  52. data/lib/writeexcel/properties.rb +251 -250
  53. data/lib/writeexcel/storage_lite.rb +968 -0
  54. data/lib/writeexcel/workbook.rb +3294 -2630
  55. data/lib/writeexcel/worksheet.rb +9012 -6377
  56. data/test/excelfile/Chart1.xls +0 -0
  57. data/test/excelfile/Chart2.xls +0 -0
  58. data/test/excelfile/Chart3.xls +0 -0
  59. data/test/excelfile/Chart4.xls +0 -0
  60. data/test/excelfile/Chart5.xls +0 -0
  61. data/test/perl_output/Chart1.xls.data +0 -0
  62. data/test/perl_output/Chart2.xls.data +0 -0
  63. data/test/perl_output/Chart3.xls.data +0 -0
  64. data/test/perl_output/Chart4.xls.data +0 -0
  65. data/test/perl_output/Chart5.xls.data +0 -0
  66. data/test/perl_output/a_simple.xls +0 -0
  67. data/test/perl_output/autofilter.xls +0 -0
  68. data/test/perl_output/chart_area.xls +0 -0
  69. data/test/perl_output/chart_bar.xls +0 -0
  70. data/test/perl_output/chart_column.xls +0 -0
  71. data/test/perl_output/chart_line.xls +0 -0
  72. data/test/perl_output/data_validate.xls +0 -0
  73. data/test/perl_output/date_time.xls +0 -0
  74. data/test/perl_output/demo.xls +0 -0
  75. data/test/perl_output/demo101.bin +0 -0
  76. data/test/perl_output/demo201.bin +0 -0
  77. data/test/perl_output/demo301.bin +0 -0
  78. data/test/perl_output/demo401.bin +0 -0
  79. data/test/perl_output/demo501.bin +0 -0
  80. data/test/perl_output/diag_border.xls +0 -0
  81. data/test/perl_output/headers.xls +0 -0
  82. data/test/perl_output/hyperlink.xls +0 -0
  83. data/test/perl_output/images.xls +0 -0
  84. data/test/perl_output/merge1.xls +0 -0
  85. data/test/perl_output/merge2.xls +0 -0
  86. data/test/perl_output/merge3.xls +0 -0
  87. data/test/perl_output/merge4.xls +0 -0
  88. data/test/perl_output/merge5.xls +0 -0
  89. data/test/perl_output/protection.xls +0 -0
  90. data/test/perl_output/regions.xls +0 -0
  91. data/test/perl_output/stats.xls +0 -0
  92. data/test/perl_output/stocks.xls +0 -0
  93. data/test/perl_output/tab_colors.xls +0 -0
  94. data/test/perl_output/unicode_cyrillic.xls +0 -0
  95. data/test/perl_output/workbook1.xls +0 -0
  96. data/test/perl_output/workbook2.xls +0 -0
  97. data/test/tc_all.rb +32 -31
  98. data/test/tc_biff.rb +104 -104
  99. data/test/tc_chart.rb +22 -22
  100. data/test/tc_example_match.rb +1944 -1280
  101. data/test/tc_format.rb +1254 -1267
  102. data/test/tc_formula.rb +63 -63
  103. data/test/tc_ole.rb +110 -110
  104. data/test/tc_storage_lite.rb +149 -0
  105. data/test/tc_workbook.rb +140 -115
  106. data/test/tc_worksheet.rb +115 -115
  107. data/test/test_00_IEEE_double.rb +14 -14
  108. data/test/test_01_add_worksheet.rb +12 -12
  109. data/test/test_02_merge_formats.rb +58 -58
  110. data/test/test_04_dimensions.rb +397 -397
  111. data/test/test_05_rows.rb +182 -182
  112. data/test/test_06_extsst.rb +80 -80
  113. data/test/test_11_date_time.rb +484 -484
  114. data/test/test_12_date_only.rb +506 -506
  115. data/test/test_13_date_seconds.rb +486 -486
  116. data/test/test_21_escher.rb +642 -629
  117. data/test/test_22_mso_drawing_group.rb +750 -739
  118. data/test/test_23_note.rb +78 -78
  119. data/test/test_24_txo.rb +80 -80
  120. data/test/test_25_position_object.rb +82 -0
  121. data/test/test_26_autofilter.rb +327 -327
  122. data/test/test_27_autofilter.rb +144 -144
  123. data/test/test_28_autofilter.rb +174 -174
  124. data/test/test_29_process_jpg.rb +681 -131
  125. data/test/test_30_validation_dval.rb +82 -82
  126. data/test/test_31_validation_dv_strings.rb +131 -131
  127. data/test/test_32_validation_dv_formula.rb +211 -211
  128. data/test/test_40_property_types.rb +191 -191
  129. data/test/test_41_properties.rb +238 -238
  130. data/test/test_42_set_properties.rb +442 -419
  131. data/test/test_50_name_stored.rb +305 -0
  132. data/test/test_51_name_print_area.rb +363 -0
  133. data/test/test_52_name_print_titles.rb +460 -0
  134. data/test/test_53_autofilter.rb +209 -0
  135. data/test/test_60_chart_generic.rb +576 -0
  136. data/test/test_61_chart_subclasses.rb +97 -0
  137. data/test/test_62_chart_formats.rb +270 -0
  138. data/test/test_63_chart_area_formats.rb +647 -0
  139. data/test/test_chartex.rb +35 -0
  140. data/test/ts_all.rb +46 -34
  141. data/writeexcel.gemspec +18 -0
  142. data/writeexcel.rdoc +583 -0
  143. metadata +162 -108
@@ -1,217 +1,2306 @@
1
- ###############################################################################
2
- #
3
- # Chart - A writer class for Excel Charts.
4
- #
5
- #
6
- # Used in conjunction with Spreadsheet::WriteExcel
7
- #
8
- # Copyright 2000-2008, John McNamara, jmcnamara@cpan.org
9
- #
10
- # original written in Perl by John McNamara
11
- # converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
12
- #
13
-
14
- require 'writeexcel/biffwriter'
15
-
16
- class Chart
17
-
18
-
19
- attr_reader :name
20
-
21
-
22
- ###############################################################################
23
- #
24
- # new()
25
- #
26
- # Constructor. Creates a new Chart object from a BIFFwriter object
27
- #
28
- def initialize(filename, name, index, encoding, activesheet, firstsheet)
29
- @filename = filename
30
- @name = name
31
- @index = index
32
- @encoding = encoding
33
- @activesheet = activesheet
34
- @firstsheet = firstsheet
35
-
36
- @type = 0x0200
37
- @ext_sheets = []
38
- @using_tmpfile = 1
39
- @filehandle = ""
40
- @fileclosed = false
41
- @offset = 0
42
- @xls_rowmax = 0
43
- @xls_colmax = 0
44
- @xls_strmax = 0
45
- @dim_rowmin = 0
46
- @dim_rowmax = 0
47
- @dim_colmin = 0
48
- @dim_colmax = 0
49
- @dim_changed = 0
50
- @colinfo = []
51
- @selection = [0, 0]
52
- @panes = []
53
- @active_pane = 3
54
- @frozen = 0
55
- @selected = 0
56
- @hidden = 0
57
-
58
- @paper_size = 0x0
59
- @orientation = 0x1
60
- @header = ''
61
- @footer = ''
62
- @hcenter = 0
63
- @vcenter = 0
64
- @margin_head = 0.50
65
- @margin_foot = 0.50
66
- @margin_left = 0.75
67
- @margin_right = 0.75
68
- @margin_top = 1.00
69
- @margin_bottom = 1.00
70
-
71
- @title_rowmin = nil
72
- @title_rowmax = nil
73
- @title_colmin = nil
74
- @title_colmax = nil
75
- @print_rowmin = nil
76
- @print_rowmax = nil
77
- @print_colmin = nil
78
- @print_colmax = nil
79
-
80
- @print_gridlines = 1
81
- @screen_gridlines = 1
82
- @print_headers = 0
83
-
84
- @fit_page = 0
85
- @fit_width = 0
86
- @fit_height = 0
87
-
88
- @hbreaks = []
89
- @vbreaks = []
90
-
91
- @protect = 0
92
- @password = nil
93
-
94
- @col_sizes = {}
95
- @row_sizes = {}
96
-
97
- @col_formats = {}
98
- @row_formats = {}
99
-
100
- @zoom = 100
101
- @print_scale = 100
102
-
103
- @leading_zeros = 0
104
-
105
- @outline_row_level = 0
106
- @outline_style = 0
107
- @outline_below = 1
108
- @outline_right = 1
109
- @outline_on = 1
110
-
111
- _initialize
112
- end
113
-
114
- ###############################################################################
115
- #
116
- # get_data().
117
- #
118
- # Retrieves data from memory in one chunk, or from disk in $buffer
119
- # sized chunks.
120
- #
121
- def get_data
122
- buffer = 4096
123
-
124
- return tmp if read(@filehandle, tmp, buffer)
125
-
126
- # No data to return
127
- return nil
128
- end
129
-
130
-
131
- ###############################################################################
132
- #
133
- # select()
134
- #
135
- # Set this worksheet as a selected worksheet, i.e. the worksheet has its tab
136
- # highlighted.
137
- #
138
- def select
139
- @hidden = 0 # Selected worksheet can't be hidden.
140
- @selected = 1
141
- end
142
-
143
-
144
- ###############################################################################
145
- #
146
- # activate()
147
- #
148
- # Set this worksheet as the active worksheet, i.e. the worksheet that is
149
- # displayed when the workbook is opened. Also set it as selected.
150
- #
151
- def activate
152
- @hidden = 0 # Active worksheet can't be hidden.
153
- @selected = 1
154
- @activesheet = @index
155
- end
156
-
157
-
158
- ###############################################################################
159
- #
160
- # hide()
161
- #
162
- # Hide this worksheet.
163
- #
164
- def hide
165
- @hidd = 1
166
-
167
- # A hidden worksheet shouldn't be active or selected.
168
- @selecte = 0
169
- @activesheet = 0
170
- @firstsheet = 0
171
- end
172
-
173
-
174
- ###############################################################################
175
- #
176
- # set_first_sheet()
177
- #
178
- # Set this worksheet as the first visible sheet. This is necessary
179
- # when there are a large number of worksheets and the activated
180
- # worksheet is not visible on the screen.
181
- #
182
- def set_first_sheet
183
- hidden = 0 # Active worksheet can't be hidden.
184
- firstsheet = index
185
- end
186
-
187
-
188
-
189
- ###############################################################################
190
-
191
- private
192
-
193
- ###############################################################################
194
-
195
-
196
- ###############################################################################
197
- #
198
- # _initialize()
199
- #
200
- def _initialize
201
- filehandle = open(@filename, "rb") or
202
- die "Couldn't open #{@filename} in add_chart_ext(): $!.\n"
203
- @filehandle = filehandle
204
- @datasize = File.Stat.size(@filename)
205
- end
206
-
207
- ###############################################################################
208
- #
209
- # _close()
210
- #
211
- # Add data to the beginning of the workbook (note the reverse order)
212
- # and to the end of the workbook.
213
- #
214
- def _close
215
- end
216
-
217
- end
1
+ ###############################################################################
2
+ #
3
+ # Chart - A writer class for Excel Charts.
4
+ #
5
+ #
6
+ # Used in conjunction with WriteExcel
7
+ #
8
+ # Copyright 2000-2010, John McNamara, jmcnamara@cpan.org
9
+ #
10
+ # original written in Perl by John McNamara
11
+ # converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
12
+ #
13
+
14
+ require 'writeexcel/worksheet'
15
+
16
+ ###############################################################################
17
+ #
18
+ # Formatting information.
19
+ #
20
+ # perltidy with options: -mbl=2 -pt=0 -nola
21
+ #
22
+ # Any camel case Hungarian notation style variable names in the BIFF record
23
+ # writing sub-routines below are for similarity with names used in the Excel
24
+ # documentation. Otherwise lowercase underscore style names are used.
25
+ #
26
+
27
+
28
+ ###############################################################################
29
+ #
30
+ # The chart class hierarchy is as follows. Chart.pm acts as a factory for the
31
+ # sub-classes.
32
+ #
33
+ #
34
+ # Spreadsheet::WriteExcel::BIFFwriter
35
+ # ^
36
+ # |
37
+ # Spreadsheet::WriteExcel::Worksheet
38
+ # ^
39
+ # |
40
+ # Spreadsheet::WriteExcel::Chart
41
+ # ^
42
+ # |
43
+ # Spreadsheet::WriteExcel::Chart::* (sub-types)
44
+ #
45
+
46
+ #
47
+ # = Chart
48
+ # Chart - A writer class for Excel Charts.
49
+ #
50
+ class Chart < Worksheet
51
+ NonAscii = /[^!"#\$%&'\(\)\*\+,\-\.\/\:\;<=>\?@0-9A-Za-z_\[\\\]^` ~\0\n]/ # :nodoc:
52
+
53
+ ###############################################################################
54
+ #
55
+ # factory()
56
+ #
57
+ # Factory method for returning chart objects based on their class type.
58
+ #
59
+ def self.factory(klass, *args) #:nodoc:
60
+ klass.new(*args)
61
+ end
62
+
63
+ ###############################################################################
64
+ #
65
+ # :call-seq:
66
+ # new(filename, name, index, encoding, activesheet, firstsheet, external_bin = nil)
67
+ #
68
+ # Default constructor for sub-classes.
69
+ #
70
+ def initialize(*args) #:nodoc:
71
+ super
72
+
73
+ @sheet_type = 0x0200
74
+ @orientation = 0x0
75
+ @series = []
76
+ @embedded = false
77
+
78
+ @external_bin = false
79
+ @x_axis_formula = nil
80
+ @x_axis_name = nil
81
+ @y_axis_formula = nil
82
+ @y_axis_name = nil
83
+ @title_name = nil
84
+ @title_formula = nil
85
+ @vary_data_color = 0
86
+ set_default_properties
87
+ set_default_config_data
88
+ end
89
+
90
+ #
91
+ # Add a series and it's properties to a chart.
92
+ #
93
+ # In an Excel chart a "series" is a collection of information such as values,
94
+ # x-axis labels and the name that define which data is plotted. These
95
+ # settings are displayed when you select the Chart -> Source Data... menu
96
+ # option.
97
+ #
98
+ # With a WriteExcel chart object the add_series() method is used to set the
99
+ # properties for a series:
100
+ #
101
+ # chart.add_series(
102
+ # :categories => '=Sheet1!$A$2:$A$10',
103
+ # :values => '=Sheet1!$B$2:$B$10',
104
+ # :name => 'Series name',
105
+ # :name_formula => '=Sheet1!$B$1'
106
+ # )
107
+ #
108
+ # The properties that can be set are:
109
+ #
110
+ # :values (required)
111
+ # :categories (optional for most chart types)
112
+ # :name (optional)
113
+ # :name_formula (optional)
114
+ #
115
+ # * :values
116
+ #
117
+ # This is the most important property of a series and must be set for
118
+ # every chart object. It links the chart with the worksheet data that
119
+ # it displays.
120
+ #
121
+ # chart.add_series(:values => '=Sheet1!$B$2:$B$10')
122
+ #
123
+ # Note the format that should be used for the formula. It is the same
124
+ # as is used in Excel. You must also add the worksheet that you are
125
+ # referring to before you link to it, via the workbook
126
+ # add_worksheet() method.
127
+ #
128
+ # * :categories
129
+ #
130
+ # This sets the chart category labels. The category is more or less
131
+ # the same as the X-axis. In most chart types the categories property
132
+ # is optional and the chart will just assume a sequential series
133
+ # from 1 .. n.
134
+ #
135
+ # chart.add_series(
136
+ # :categories => '=Sheet1!$A$2:$A$10',
137
+ # :values => '=Sheet1!$B$2:$B$10'
138
+ # )
139
+ #
140
+ # * :name
141
+ #
142
+ # Set the name for the series. The name is displayed in the chart
143
+ # legend and in the formula bar. The name property is optional and
144
+ # if it isn't supplied will default to Series 1 .. n.
145
+ #
146
+ # chart.add_series(
147
+ # ...
148
+ # :name => 'Series name'
149
+ # )
150
+ #
151
+ # * :name_formula
152
+ #
153
+ # Optional, can be used to link the name to a worksheet cell.
154
+ # See "Chart names and links".
155
+ #
156
+ # chart.add_series(
157
+ # ...
158
+ # :name => 'Series name',
159
+ # :name_formula => '=Sheet1!$B$1'
160
+ # )
161
+ #
162
+ # You can add more than one series to a chart. The series numbering and
163
+ # order in the final chart is the same as the order in which that are added.
164
+ #
165
+ # # Add the first series.
166
+ # chart.add_series(
167
+ # :categories => '=Sheet1!$A$2:$A$7',
168
+ # :values => '=Sheet1!$B$2:$B$7',
169
+ # :name => 'Test data series 1'
170
+ # )
171
+ #
172
+ # # Add another series. Category is the same but values are different.
173
+ # chart.add_series(
174
+ # :categories => '=Sheet1!$A$2:$A$7',
175
+ # :values => '=Sheet1!$C$2:$C$7',
176
+ # :name => 'Test data series 2'
177
+ # )
178
+ #
179
+ def add_series(params)
180
+ raise "Must specify 'values' in add_series()" if params[:values].nil?
181
+
182
+ # Parse the ranges to validate them and extract salient information.
183
+ value_data = parse_series_formula(params[:values])
184
+ category_data = parse_series_formula(params[:categories])
185
+ name_formula = parse_series_formula(params[:name_formula])
186
+
187
+ # Default category count to the same as the value count if not defined.
188
+ category_data[1] = value_data[1] if category_data.size < 2
189
+
190
+ # Add the parsed data to the user supplied data.
191
+ params[:values] = value_data
192
+ params[:categories] = category_data
193
+ params[:name_formula] = name_formula
194
+
195
+ # Encode the Series name.
196
+ name, encoding = encode_utf16(params[:name], params[:name_encoding])
197
+
198
+ params[:name] = name
199
+ params[:name_encoding] = encoding
200
+
201
+ @series << params
202
+ end
203
+
204
+ #
205
+ # Set the properties of the X-axis.
206
+ #
207
+ # The set_x_axis() method is used to set properties of the X axis.
208
+ #
209
+ # chart.set_x_axis(:name => 'Sample length (m)' )
210
+ #
211
+ # The properties that can be set are:
212
+ #
213
+ # :name (optional)
214
+ # :name_formula (optional)
215
+ #
216
+ # * :name
217
+ #
218
+ # Set the name (title or caption) for the axis. The name is displayed
219
+ # below the X axis. This property is optional. The default is to have
220
+ # no axis name.
221
+ #
222
+ # chart.set_x_axis( :name => 'Sample length (m)' )
223
+ #
224
+ # * :name_formula
225
+ #
226
+ # Optional, can be used to link the name to a worksheet cell.
227
+ # See "Chart names and links".
228
+ #
229
+ # chart.set_x_axis(
230
+ # :name => 'Sample length (m)',
231
+ # :name_formula => '=Sheet1!$A$1'
232
+ # )
233
+ #
234
+ # Additional axis properties such as range, divisions and ticks will be made
235
+ # available in later releases.
236
+ def set_x_axis(params)
237
+ name, encoding = encode_utf16(params[:name], params[:name_encoding])
238
+ formula = parse_series_formula(params[:name_formula])
239
+
240
+ @x_axis_name = name
241
+ @x_axis_encoding = encoding
242
+ @x_axis_formula = formula
243
+ end
244
+
245
+ #
246
+ # Set the properties of the Y-axis.
247
+ #
248
+ # The set_y_axis() method is used to set properties of the Y axis.
249
+ #
250
+ # chart.set_y_axis(:name => 'Sample weight (kg)' )
251
+ #
252
+ # The properties that can be set are:
253
+ #
254
+ # :name (optional)
255
+ # :name_formula (optional)
256
+ #
257
+ # * :name
258
+ #
259
+ # Set the name (title or caption) for the axis. The name is displayed
260
+ # to the left of the Y axis. This property is optional. The default
261
+ # is to have no axis name.
262
+ #
263
+ # chart.set_y_axis(:name => 'Sample weight (kg)' )
264
+ #
265
+ # * :name_formula
266
+ #
267
+ # Optional, can be used to link the name to a worksheet cell.
268
+ # See "Chart names and links".
269
+ #
270
+ # chart.set_y_axis(
271
+ # :name => 'Sample weight (kg)',
272
+ # :name_formula => '=Sheet1!$B$1'
273
+ # )
274
+ #
275
+ # Additional axis properties such as range, divisions and ticks will be made
276
+ # available in later releases.
277
+ #
278
+ def set_y_axis(params)
279
+ name, encoding = encode_utf16(params[:name], params[:name_encoding])
280
+ formula = parse_series_formula(params[:name_formula])
281
+
282
+ @y_axis_name = name
283
+ @y_axis_encoding = encoding
284
+ @y_axis_formula = formula
285
+ end
286
+
287
+ #
288
+ # The set_title() method is used to set properties of the chart title.
289
+ #
290
+ # chart.set_title(:name => 'Year End Results')
291
+ #
292
+ # The properties that can be set are:
293
+ #
294
+ # :name (optional)
295
+ # :name_formula (optional)
296
+ #
297
+ # * :name
298
+ #
299
+ # Set the name (title) for the chart. The name is displayed above the
300
+ # chart. This property is optional. The default is to have no chart
301
+ # title.
302
+ #
303
+ # chart.set_title(:name => 'Year End Results')
304
+ #
305
+ # * :name_formula
306
+ #
307
+ # Optional, can be used to link the name to a worksheet cell.
308
+ # See "Chart names and links".
309
+ #
310
+ # chart.set_title(
311
+ # :name => 'Year End Results',
312
+ # :name_formula => '=Sheet1!$C$1'
313
+ # )
314
+ #
315
+ def set_title(params)
316
+ name, encoding = encode_utf16( params[:name], params[:name_encoding])
317
+
318
+ formula = parse_series_formula(params[:name_formula])
319
+
320
+ @title_name = name
321
+ @title_encoding = encoding
322
+ @title_formula = formula
323
+ end
324
+
325
+ ###############################################################################
326
+ #
327
+ # set_legend()
328
+ #
329
+ # Set the properties of the chart legend.
330
+ #
331
+ def set_legend(params = {})
332
+ if params.has_key?(:position)
333
+ if params[:position].downcase == 'none'
334
+ legend[:visible] = 0
335
+ end
336
+ end
337
+ end
338
+
339
+ ###############################################################################
340
+ #
341
+ # set_plotarea()
342
+ #
343
+ # Set the properties of the chart plotarea.
344
+ #
345
+ def set_plotarea(params = {})
346
+ return if params.empty?
347
+
348
+ area = @plotarea
349
+
350
+ # Set the plotarea visibility.
351
+ if params.has_key?(:visible)
352
+ area[:visible] = params[:visible]
353
+ return if area[:visible] == 0
354
+ end
355
+
356
+ # TODO. could move this out of if statement.
357
+ area[:bg_color_index] = 0x08
358
+
359
+ # Set the chart background colour.
360
+ if params.has_key?(:color)
361
+ index, rgb = get_color_indices(params[:color])
362
+ if !index.nil?
363
+ area[:fg_color_index] = index
364
+ area[:fg_color_rgb] = rgb
365
+ area[:bg_color_index] = 0x08
366
+ area[:bg_color_rgb] = 0x000000
367
+ end
368
+ end
369
+
370
+ # Set the border line colour.
371
+ if params.has_key?(:line_color)
372
+ index, rgb = get_color_indices(params[:line_color])
373
+ if !index.nil?
374
+ area[:line_color_index] = index
375
+ area[:line_color_rgb] = rgb
376
+ end
377
+ end
378
+
379
+ # Set the border line pattern.
380
+ if params.has_key?(:line_pattern)
381
+ pattern = get_line_pattern(params[:line_pattern])
382
+ area[:line_pattern] = pattern
383
+ end
384
+
385
+ # Set the border line weight.
386
+ if params.has_key?(:line_weight)
387
+ weight = get_line_weight(params[:line_weight])
388
+ area[:line_weight] = weight
389
+ end
390
+ end
391
+
392
+ ###############################################################################
393
+ #
394
+ # set_chartarea()
395
+ #
396
+ # Set the properties of the chart chartarea.
397
+ #
398
+ def set_chartarea(params = {})
399
+ return if params.empty?
400
+
401
+ area = @chartarea
402
+
403
+ # Embedded automatic line weight has a different default value.
404
+ area[:line_weight] = 0xFFFF if @embedded
405
+
406
+ # Set the chart background colour.
407
+ if params.has_key?(:color)
408
+ index, rgb = get_color_indices(params[:color])
409
+ if !index.nil?
410
+ area[:fg_color_index] = index
411
+ area[:fg_color_rgb] = rgb
412
+ area[:bg_color_index] = 0x08
413
+ area[:bg_color_rgb] = 0x000000
414
+ area[:area_pattern] = 1
415
+ area[:area_options] = 0x0000 if @embedded
416
+ area[:visible] = 1
417
+ end
418
+ end
419
+
420
+ # Set the border line colour.
421
+ if params.has_key?(:line_color)
422
+ index, rgb = get_color_indices(params[:line_color])
423
+ if !index.nil?
424
+ area[:line_color_index] = index
425
+ area[:line_color_rgb] = rgb
426
+ area[:line_pattern] = 0x00
427
+ area[:line_options] = 0x0000
428
+ area[:visible] = 1
429
+ end
430
+ end
431
+
432
+ # Set the border line pattern.
433
+ if params.has_key?(:line_pattern)
434
+ pattern = get_line_pattern(params[:line_pattern])
435
+ area[:line_pattern] = pattern
436
+ area[:line_options] = 0x0000
437
+ area[:line_color_index] = 0x4F unless params.has_key?(:line_color)
438
+ area[:visible] = 1
439
+ end
440
+
441
+ # Set the border line weight.
442
+ if params.has_key?(:line_weight)
443
+ weight = get_line_weight(params[:line_weight])
444
+ area[:line_weight] = weight
445
+ area[:line_options] = 0x0000
446
+ area[:line_pattern] = 0x00 unless params.has_key?(:line_pattern)
447
+ area[:line_color_index] = 0x4F unless params.has_key?(:line_color)
448
+ area[:visible] = 1
449
+ end
450
+ end
451
+
452
+
453
+
454
+ def using_tmpfile=(val) # :nodoc:
455
+ @using_tmpfile = val
456
+ end
457
+
458
+ def data=(val) # :nodoc:
459
+ @data = val
460
+ end
461
+
462
+ def embedded # :nodoc:
463
+ @embedded
464
+ end
465
+
466
+ def embedded=(val) # :nodoc:
467
+ @embedded = val
468
+ end
469
+
470
+ ###############################################################################
471
+ #
472
+ # _prepend(), overridden.
473
+ #
474
+ # The parent Worksheet class needs to store some data in memory and some in
475
+ # temporary files for efficiency. The Chart* classes don't need to do this
476
+ # since they are dealing with smaller amounts of data so we override
477
+ # _prepend() to turn it into an _append() method. This allows for a more
478
+ # natural method calling order.
479
+ #
480
+ def prepend(*args) # :nodoc:
481
+ @using_tmpfile = false
482
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
483
+ append(*args)
484
+ end
485
+
486
+ ###############################################################################
487
+ #
488
+ # _close(), overridden.
489
+ #
490
+ # Create and store the Chart data structures.
491
+ #
492
+ def close # :nodoc:
493
+ # Ignore any data that has been written so far since it is probably
494
+ # from unwanted Worksheet method calls.
495
+ @data = ''
496
+
497
+ # TODO. Check for charts without a series?
498
+
499
+ # Store the chart BOF.
500
+ store_bof(0x0020)
501
+
502
+ # Store the page header
503
+ store_header
504
+
505
+ # Store the page footer
506
+ store_footer
507
+
508
+ # Store the page horizontal centering
509
+ store_hcenter
510
+
511
+ # Store the page vertical centering
512
+ store_vcenter
513
+
514
+ # Store the left margin
515
+ store_margin_left
516
+
517
+ # Store the right margin
518
+ store_margin_right
519
+
520
+ # Store the top margin
521
+ store_margin_top
522
+
523
+ # Store the bottom margin
524
+ store_margin_bottom
525
+
526
+ # Store the page setup
527
+ store_setup
528
+
529
+ # Store the sheet password
530
+ store_password
531
+
532
+ # Start of Chart specific records.
533
+
534
+ # Store the FBI font records.
535
+ store_fbi(*@config[:font_numbers])
536
+ store_fbi(*@config[:font_series])
537
+ store_fbi(*@config[:font_title])
538
+ store_fbi(*@config[:font_axes])
539
+
540
+ # Ignore UNITS record.
541
+
542
+ # Store the Chart sub-stream.
543
+ store_chart_stream
544
+
545
+ # Append the sheet dimensions
546
+ store_dimensions
547
+
548
+ # TODO add SINDEX and NUMBER records.
549
+
550
+ store_window2 unless @embedded
551
+
552
+ store_eof
553
+ end
554
+
555
+ ###############################################################################
556
+ #
557
+ # _store_window2(), overridden.
558
+ #
559
+ # Write BIFF record Window2. Note, this overrides the parent Worksheet
560
+ # record because the Chart version of the record is smaller and is used
561
+ # mainly to indicate if the chart tab is selected or not.
562
+ #
563
+ def store_window2 # :nodoc:
564
+ record = 0x023E # Record identifier
565
+ length = 0x000A # Number of bytes to follow
566
+ grbit = 0x0000 # Option flags
567
+ rwTop = 0x0000 # Top visible row
568
+ colLeft = 0x0000 # Leftmost visible column
569
+ rgbHdr = 0x0000 # Row/col heading, grid color
570
+
571
+ # The options flags that comprise grbit
572
+ fDspFmla = 0 # 0 - bit
573
+ fDspGrid = 0 # 1
574
+ fDspRwCol = 0 # 2
575
+ fFrozen = 0 # 3
576
+ fDspZeros = 0 # 4
577
+ fDefaultHdr = 0 # 5
578
+ fArabic = 0 # 6
579
+ fDspGuts = 0 # 7
580
+ fFrozenNoSplit = 0 # 0 - bit
581
+ fSelected = @selected # 1
582
+ fPaged = 0 # 2
583
+ fBreakPreview = 0 # 3
584
+
585
+ #<<< Perltidy ignore this.
586
+ grbit = fDspFmla
587
+ grbit |= fDspGrid << 1
588
+ grbit |= fDspRwCol << 2
589
+ grbit |= fFrozen << 3
590
+ grbit |= fDspZeros << 4
591
+ grbit |= fDefaultHdr << 5
592
+ grbit |= fArabic << 6
593
+ grbit |= fDspGuts << 7
594
+ grbit |= fFrozenNoSplit << 8
595
+ grbit |= fSelected << 9
596
+ grbit |= fPaged << 10
597
+ grbit |= fBreakPreview << 11
598
+ #>>>
599
+
600
+ header = [record, length].pack("vv")
601
+ data = [grbit, rwTop, colLeft, rgbHdr].pack("vvvV")
602
+
603
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
604
+ append(header, data)
605
+ end
606
+
607
+ ###############################################################################
608
+ #
609
+ # _parse_series_formula()
610
+ #
611
+ # Parse the formula used to define a series. We also extract some range
612
+ # information required for _store_series() and the SERIES record.
613
+ #
614
+ def parse_series_formula(formula) # :nodoc:
615
+ encoding = 0
616
+ length = 0
617
+ count = 0
618
+ tokens = []
619
+
620
+ return [''] if formula.nil?
621
+
622
+ # Strip the = sign at the beginning of the formula string
623
+ formula = formula.sub(/^=/, '')
624
+
625
+ # Parse the formula using the parser in Formula.pm
626
+ parser = @parser
627
+
628
+ # In order to raise formula errors from the point of view of the calling
629
+ # program we use an eval block and re-raise the error from here.
630
+ #
631
+ tokens = parser.parse_formula(formula)
632
+
633
+ # Force ranges to be a reference class.
634
+ tokens.collect! { |t| t.gsub(/_ref3d/, '_ref3dR') }
635
+ tokens.collect! { |t| t.gsub(/_range3d/, '_range3dR') }
636
+ tokens.collect! { |t| t.gsub(/_name/, '_nameR') }
637
+
638
+ # Parse the tokens into a formula string.
639
+ formula = parser.parse_tokens(tokens)
640
+
641
+ # Return formula for a single cell as used by title and series name.
642
+ return formula if formula[0] == 0x3A
643
+
644
+ # Extract the range from the parse formula.
645
+ if formula[0] == 0x3B
646
+ ptg, ext_ref, row_1, row_2, col_1, col_2 = formula.unpack('Cv5')
647
+
648
+ # TODO. Remove high bit on relative references.
649
+ count = row_2 - row_1 + 1
650
+ end
651
+
652
+ [formula, count]
653
+ end
654
+
655
+ ###############################################################################
656
+ #
657
+ # _encode_utf16()
658
+ #
659
+ # Convert UTF8 strings used in the chart to UTF16.
660
+ #
661
+ def encode_utf16(str, encoding = 0) # :nodoc:
662
+ # Exit if the $string isn't defined, i.e., hasn't been set by user.
663
+ return [nil, nil] if str.nil?
664
+
665
+ string = str.dup
666
+ # Return if encoding is set, i.e., string has been manually encoded.
667
+ #return ( undef, undef ) if $string == 1;
668
+
669
+ # Handle utf8 strings in perl 5.8.
670
+ if string =~ NonAscii
671
+ string = NKF.nkf('-w16B0 -m0 -W', string)
672
+ encoding = 1
673
+ end
674
+
675
+ # Chart strings are limited to 255 characters.
676
+ limit = encoding != 0 ? 255 * 2 : 255
677
+
678
+ if string.length >= limit
679
+ # truncate the string and raise a warning.
680
+ string = string[0, limit]
681
+ end
682
+
683
+ [string, encoding]
684
+ end
685
+
686
+ ###############################################################################
687
+ #
688
+ # _get_color_indices()
689
+ #
690
+ # Convert the user specified colour index or string to an colour index and
691
+ # RGB colour number.
692
+ #
693
+ def get_color_indices(color) # :nodoc:
694
+ return [nil, nil] if color.nil?
695
+
696
+ colors = {
697
+ :aqua => 0x0F,
698
+ :cyan => 0x0F,
699
+ :black => 0x08,
700
+ :blue => 0x0C,
701
+ :brown => 0x10,
702
+ :magenta => 0x0E,
703
+ :fuchsia => 0x0E,
704
+ :gray => 0x17,
705
+ :grey => 0x17,
706
+ :green => 0x11,
707
+ :lime => 0x0B,
708
+ :navy => 0x12,
709
+ :orange => 0x35,
710
+ :pink => 0x21,
711
+ :purple => 0x14,
712
+ :red => 0x0A,
713
+ :silver => 0x16,
714
+ :white => 0x09,
715
+ :yellow => 0x0D,
716
+ }
717
+
718
+ # Check for the various supported colour index/name possibilities.
719
+ color = color.downcase.to_sym if color.kind_of?(String)
720
+ if color.kind_of?(Symbol)
721
+ if colors.has_key?(color)
722
+ # Colour matches one of the supported colour names.
723
+ index = colors[color]
724
+ else
725
+ return [nil, nil]
726
+ end
727
+ elsif color < 8 || color > 63
728
+ # Return undef if index is out of range.
729
+ return [nil, nil]
730
+ else
731
+ # We should have a valid color index in a valid range.
732
+ index = color
733
+ end
734
+
735
+ rgb = get_color_rbg(index)
736
+ return [index, rgb]
737
+ end
738
+
739
+ ###############################################################################
740
+ #
741
+ # _get_color_rbg()
742
+ #
743
+ # Get the RedGreenBlue number for the colour index from the Workbook palette.
744
+ #
745
+ def get_color_rbg(index) # :nodoc:
746
+ # Adjust colour index from 8-63 (user range) to 0-55 (Excel range).
747
+ index -= 8
748
+
749
+ red_green_blue = @palette[index]
750
+ red_green_blue.pack('C*').unpack('V')[0]
751
+ end
752
+
753
+ ###############################################################################
754
+ #
755
+ # _get_line_pattern()
756
+ #
757
+ # Get the Excel chart index for line pattern that corresponds to the user
758
+ # defined value.
759
+ #
760
+ def get_line_pattern(value) # :nodoc:
761
+ value = value.downcase if value.kind_of?(String)
762
+ default = 0
763
+
764
+ patterns = {
765
+ 0 => 5,
766
+ 1 => 0,
767
+ 2 => 1,
768
+ 3 => 2,
769
+ 4 => 3,
770
+ 5 => 4,
771
+ 6 => 7,
772
+ 7 => 6,
773
+ 8 => 8,
774
+ 'solid' => 0,
775
+ 'dash' => 1,
776
+ 'dot' => 2,
777
+ 'dash-dot' => 3,
778
+ 'dash-dot-dot' => 4,
779
+ 'none' => 5,
780
+ 'dark-gray' => 6,
781
+ 'medium-gray' => 7,
782
+ 'light-gray' => 8,
783
+ }
784
+
785
+ if patterns.has_key?(value)
786
+ patterns[value]
787
+ else
788
+ default
789
+ end
790
+ end
791
+
792
+ ###############################################################################
793
+ #
794
+ # _get_line_weight()
795
+ #
796
+ # Get the Excel chart index for line weight that corresponds to the user
797
+ # defined value.
798
+ #
799
+ def get_line_weight(value) # :nodoc:
800
+ value = value.downcase if value.kind_of?(String)
801
+ default = 0
802
+
803
+ weights = {
804
+ 1 => -1,
805
+ 2 => 0,
806
+ 3 => 1,
807
+ 4 => 2,
808
+ 'hairline' => -1,
809
+ 'narrow' => 0,
810
+ 'medium' => 1,
811
+ 'wide' => 2,
812
+ }
813
+
814
+ if weights.has_key?(value)
815
+ weights[value]
816
+ else
817
+ default
818
+ end
819
+ end
820
+
821
+ ###############################################################################
822
+ #
823
+ # _store_chart_stream()
824
+ #
825
+ # Store the CHART record and it's substreams.
826
+ #
827
+ def store_chart_stream # :nodoc:
828
+ store_chart(*@config[:chart])
829
+ store_begin
830
+
831
+ # Store the chart SCL record.
832
+ store_plotgrowth
833
+
834
+ if @chartarea[:visible] != 0
835
+ store_chartarea_frame_stream
836
+ end
837
+
838
+ # Store SERIES stream for each series.
839
+ index = 0
840
+ @series.each do |series|
841
+ store_series_stream(
842
+ :index => index,
843
+ :value_formula => series[:values][0],
844
+ :value_count => series[:values][1],
845
+ :category_count => series[:categories][1],
846
+ :category_formula => series[:categories][0],
847
+ :name => series[:name],
848
+ :name_encoding => series[:name_encoding],
849
+ :name_formula => series[:name_formula]
850
+ )
851
+ index += 1
852
+ end
853
+
854
+ store_shtprops
855
+
856
+ # Write the TEXT streams.
857
+ (5..6).each do |font_index|
858
+ store_defaulttext
859
+ store_series_text_stream(font_index)
860
+ end
861
+
862
+ store_axesused(1)
863
+ store_axisparent_stream
864
+
865
+ if !@title_name.nil? || !@title_formula.nil?
866
+ store_title_text_stream
867
+ end
868
+
869
+ store_end
870
+ end
871
+
872
+ def _formula_type_from_param(t, f, params, key) # :nodoc:
873
+ if params.has_key?(key)
874
+ v = params[key]
875
+ (v.nil? || v == [""] || v == '' || v == 0) ? f : t
876
+ end
877
+ end
878
+ private :_formula_type_from_param
879
+
880
+ ###############################################################################
881
+ #
882
+ # _store_series_stream()
883
+ #
884
+ # Write the SERIES chart substream.
885
+ #
886
+ def store_series_stream(params) # :nodoc:
887
+ name_type = _formula_type_from_param(2, 1, params, :name_formula)
888
+ value_type = _formula_type_from_param(2, 0, params, :value_formula)
889
+ category_type = _formula_type_from_param(2, 0, params, :category_formula)
890
+
891
+ store_series(params[:value_count], params[:category_count])
892
+
893
+ store_begin
894
+
895
+ # Store the Series name AI record.
896
+ store_ai(0, name_type, params[:name_formula])
897
+ unless params[:name].nil?
898
+ store_seriestext(params[:name], params[:name_encoding])
899
+ end
900
+
901
+ store_ai(1, value_type, params[:value_formula])
902
+ store_ai(2, category_type, params[:category_formula])
903
+ store_ai(3, 1, '' )
904
+
905
+ store_dataformat_stream(params[:index])
906
+ store_sertocrt
907
+ store_end
908
+ end
909
+
910
+ ###############################################################################
911
+ #
912
+ # _store_dataformat_stream()
913
+ #
914
+ # Write the DATAFORMAT chart substream.
915
+ #
916
+ def store_dataformat_stream(series_index) # :nodoc:
917
+ store_dataformat(series_index, series_index, 0xFFFF)
918
+
919
+ store_begin
920
+ store_3dbarshape
921
+ store_end
922
+ end
923
+
924
+ ###############################################################################
925
+ #
926
+ # _store_series_text_stream()
927
+ #
928
+ # Write the series TEXT substream.
929
+ #
930
+ def store_series_text_stream(font_index) # :nodoc:
931
+ store_text(*@config[:series_text])
932
+
933
+ store_begin
934
+ store_pos(*@config[:series_text_pos])
935
+ store_fontx( font_index )
936
+ store_ai( 0, 1, '' )
937
+ store_end
938
+ end
939
+
940
+ def _formula_type(t, f, formula) # :nodoc:
941
+ (formula.nil? || formula == [""] || formula == '' || formula == 0) ? f : t
942
+ end
943
+ private :_formula_type
944
+
945
+ ###############################################################################
946
+ #
947
+ # _store_x_axis_text_stream()
948
+ #
949
+ # Write the X-axis TEXT substream.
950
+ #
951
+ def store_x_axis_text_stream # :nodoc:
952
+ formula = @x_axis_formula.nil? ? '' : @x_axis_formula
953
+ ai_type = _formula_type(2, 1, formula)
954
+
955
+ store_text(*@config[:x_axis_text])
956
+
957
+ store_begin
958
+ store_pos(*@config[:x_axis_text_pos])
959
+ store_fontx(8)
960
+ store_ai(0, ai_type, formula)
961
+
962
+ unless @x_axis_name.nil?
963
+ store_seriestext(@x_axis_name, @x_axis_encoding)
964
+ end
965
+
966
+ store_objectlink(3)
967
+ store_end
968
+ end
969
+
970
+ ###############################################################################
971
+ #
972
+ # _store_y_axis_text_stream()
973
+ #
974
+ # Write the Y-axis TEXT substream.
975
+ #
976
+ def store_y_axis_text_stream # :nodoc:
977
+ formula = @y_axis_formula
978
+ ai_type = _formula_type(2, 1, formula)
979
+
980
+ store_text(*@config[:y_axis_text])
981
+
982
+ store_begin
983
+ store_pos(*@config[:y_axis_text_pos])
984
+ store_fontx(8)
985
+ store_ai(0, ai_type, formula)
986
+
987
+ unless @y_axis_name.nil?
988
+ store_seriestext(@y_axis_name, @y_axis_encoding)
989
+ end
990
+
991
+ store_objectlink(2)
992
+ store_end
993
+ end
994
+
995
+ ###############################################################################
996
+ #
997
+ # _store_legend_text_stream()
998
+ #
999
+ # Write the legend TEXT substream.
1000
+ #
1001
+ def store_legend_text_stream # :nodoc:
1002
+ store_text(*@config[:legend_text])
1003
+
1004
+ store_begin
1005
+ store_pos(*@config[:legend_text_pos])
1006
+ store_ai(0, 1, '')
1007
+
1008
+ store_end
1009
+ end
1010
+
1011
+ ###############################################################################
1012
+ #
1013
+ # _store_title_text_stream()
1014
+ #
1015
+ # Write the title TEXT substream.
1016
+ #
1017
+ def store_title_text_stream # :nodoc:
1018
+ formula = @title_formula
1019
+ ai_type = _formula_type(2, 1, formula)
1020
+
1021
+ store_text(*@config[:title_text])
1022
+
1023
+ store_begin
1024
+ store_pos(*@config[:title_text_pos])
1025
+ store_fontx(7)
1026
+ store_ai(0, ai_type, formula)
1027
+
1028
+ unless @title_name.nil?
1029
+ store_seriestext(@title_name, @title_encoding)
1030
+ end
1031
+
1032
+ store_objectlink(1)
1033
+ store_end
1034
+ end
1035
+
1036
+ ###############################################################################
1037
+ #
1038
+ # _store_axisparent_stream()
1039
+ #
1040
+ # Write the AXISPARENT chart substream.
1041
+ #
1042
+ def store_axisparent_stream # :nodoc:
1043
+ store_axisparent(*@config[:axisparent])
1044
+
1045
+ store_begin
1046
+ store_pos(*@config[:axisparent_pos])
1047
+ store_axis_category_stream
1048
+ store_axis_values_stream
1049
+
1050
+ if !@x_axis_name.nil? || !@x_axis_formula.nil?
1051
+ store_x_axis_text_stream
1052
+ end
1053
+
1054
+ if !@y_axis_name.nil? || !@y_axis_formula.nil?
1055
+ store_y_axis_text_stream();
1056
+ end
1057
+
1058
+ if @plotarea[:visible] != 0
1059
+ store_plotarea
1060
+ store_plotarea_frame_stream
1061
+ end
1062
+ store_chartformat_stream
1063
+ store_end
1064
+ end
1065
+
1066
+ ###############################################################################
1067
+ #
1068
+ # _store_axis_category_stream()
1069
+ #
1070
+ # Write the AXIS chart substream for the chart category.
1071
+ #
1072
+ def store_axis_category_stream # :nodoc:
1073
+ store_axis(0)
1074
+
1075
+ store_begin
1076
+ store_catserrange
1077
+ store_axcext
1078
+ store_tick
1079
+ store_end
1080
+ end
1081
+
1082
+ ###############################################################################
1083
+ #
1084
+ # _store_axis_values_stream()
1085
+ #
1086
+ # Write the AXIS chart substream for the chart values.
1087
+ #
1088
+ def store_axis_values_stream # :nodoc:
1089
+ store_axis(1)
1090
+
1091
+ store_begin
1092
+ store_valuerange
1093
+ store_tick
1094
+ store_axislineformat
1095
+ store_lineformat(0x00000000, 0x0000, 0xFFFF, 0x0009, 0x004D)
1096
+ store_end
1097
+ end
1098
+
1099
+ ###############################################################################
1100
+ #
1101
+ # _store_plotarea_frame_stream()
1102
+ #
1103
+ # Write the FRAME chart substream.
1104
+ #
1105
+ def store_plotarea_frame_stream # :nodoc:
1106
+ area = @plotarea
1107
+
1108
+ store_frame(0x00, 0x03)
1109
+ store_begin
1110
+
1111
+ store_lineformat(
1112
+ area[:line_color_rgb], area[:line_pattern],
1113
+ area[:line_weight], area[:line_options],
1114
+ area[:line_color_index]
1115
+ )
1116
+
1117
+ store_areaformat(
1118
+ area[:fg_color_rgb], area[:bg_color_rgb],
1119
+ area[:area_pattern], area[:area_options],
1120
+ area[:fg_color_index], area[:bg_color_index]
1121
+ )
1122
+
1123
+ store_end
1124
+ end
1125
+
1126
+ ###############################################################################
1127
+ #
1128
+ # _store_chartarea_frame_stream()
1129
+ #
1130
+ # Write the FRAME chart substream for and embedded chart.
1131
+ #
1132
+ def store_chartarea_frame_stream # :nodoc:
1133
+ area = @chartarea
1134
+
1135
+ store_frame(0x00, 0x02)
1136
+ store_begin
1137
+
1138
+ store_lineformat(
1139
+ area[:line_color_rgb], area[:line_pattern],
1140
+ area[:line_weight], area[:line_options],
1141
+ area[:line_color_index]
1142
+ )
1143
+
1144
+ store_areaformat(
1145
+ area[:fg_color_rgb], area[:bg_color_rgb],
1146
+ area[:area_pattern], area[:area_options],
1147
+ area[:fg_color_index], area[:bg_color_index]
1148
+ )
1149
+
1150
+ store_end
1151
+ end
1152
+
1153
+ ###############################################################################
1154
+ #
1155
+ # _store_chartformat_stream()
1156
+ #
1157
+ # Write the CHARTFORMAT chart substream.
1158
+ #
1159
+ def store_chartformat_stream # :nodoc:
1160
+ # The _vary_data_color is set by classes that need it, like Pie.
1161
+ store_chartformat(@vary_data_color)
1162
+
1163
+ store_begin
1164
+
1165
+ # Store the BIFF record that will define the chart type.
1166
+ store_chart_type
1167
+
1168
+ # Note, the CHARTFORMATLINK record is only written by Excel.
1169
+
1170
+ if @legend[:visible]
1171
+ store_legend_stream
1172
+ end
1173
+
1174
+ store_marker_dataformat_stream
1175
+ store_end
1176
+ end
1177
+
1178
+ ###############################################################################
1179
+ #
1180
+ # _store_chart_type()
1181
+ #
1182
+ # This is an abstract method that is overridden by the sub-classes to define
1183
+ # the chart types such as Column, Line, Pie, etc.
1184
+ #
1185
+ def store_chart_type # :nodoc:
1186
+
1187
+ end
1188
+
1189
+ ###############################################################################
1190
+ #
1191
+ # _store_marker_dataformat_stream()
1192
+ #
1193
+ # This is an abstract method that is overridden by the sub-classes to define
1194
+ # properties of markers, linetypes, pie formats and other.
1195
+ #
1196
+ def store_marker_dataformat_stream # :nodoc:
1197
+
1198
+ end
1199
+
1200
+ ###############################################################################
1201
+ #
1202
+ # _store_legend_stream()
1203
+ #
1204
+ # Write the LEGEND chart substream.
1205
+ #
1206
+ def store_legend_stream # :nodoc:
1207
+ store_legend(*@config[:legend])
1208
+
1209
+ store_begin
1210
+ store_pos(*@config[:legend_pos])
1211
+ store_legend_text_stream
1212
+ store_end
1213
+ end
1214
+
1215
+ ###############################################################################
1216
+ #
1217
+ # BIFF Records.
1218
+ #
1219
+ ###############################################################################
1220
+
1221
+ ###############################################################################
1222
+ #
1223
+ # _store_3dbarshape()
1224
+ #
1225
+ # Write the 3DBARSHAPE chart BIFF record.
1226
+ #
1227
+ def store_3dbarshape # :nodoc:
1228
+ record = 0x105F # Record identifier.
1229
+ length = 0x0002 # Number of bytes to follow.
1230
+ riser = 0x00 # Shape of base.
1231
+ taper = 0x00 # Column taper type.
1232
+
1233
+ header = [record, length].pack('vv')
1234
+ data = [riser].pack('C')
1235
+ data += [taper].pack('C')
1236
+
1237
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1238
+ append(header, data)
1239
+ end
1240
+
1241
+ ###############################################################################
1242
+ #
1243
+ # _store_ai()
1244
+ #
1245
+ # Write the AI chart BIFF record.
1246
+ #
1247
+ def store_ai(id, type, formula, format_index = 0) # :nodoc:
1248
+ formula = '' if formula == [""]
1249
+
1250
+ record = 0x1051 # Record identifier.
1251
+ length = 0x0008 # Number of bytes to follow.
1252
+ # id # Link index.
1253
+ # type # Reference type.
1254
+ # formula # Pre-parsed formula.
1255
+ # format_index # Num format index.
1256
+ grbit = 0x0000 # Option flags.
1257
+
1258
+ formula_length = formula.length
1259
+ length += formula_length
1260
+
1261
+ header = [record, length].pack('vv')
1262
+ data = [id].pack('C')
1263
+ data += [type].pack('C')
1264
+ data += [grbit].pack('v')
1265
+ data += [format_index].pack('v')
1266
+ data += [formula_length].pack('v')
1267
+ data += formula[0].kind_of?(String) ? formula[0] : formula
1268
+
1269
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1270
+ append(header, data)
1271
+ end
1272
+
1273
+ ###############################################################################
1274
+ #
1275
+ # _store_areaformat()
1276
+ #
1277
+ # Write the AREAFORMAT chart BIFF record. Contains the patterns and colours
1278
+ # of a chart area.
1279
+ #
1280
+ def store_areaformat(rgbFore, rgbBack, pattern, grbit, indexFore, indexBack) # :nodoc:
1281
+ record = 0x100A # Record identifier.
1282
+ length = 0x0010 # Number of bytes to follow.
1283
+ # rgbFore # Foreground RGB colour.
1284
+ # rgbBack # Background RGB colour.
1285
+ # pattern # Pattern.
1286
+ # grbit # Option flags.
1287
+ # indexFore # Index to Foreground colour.
1288
+ # indexBack # Index to Background colour.
1289
+
1290
+ header = [record, length].pack('vv')
1291
+ data = [rgbFore].pack('V')
1292
+ data += [rgbBack].pack('V')
1293
+ data += [pattern].pack('v')
1294
+ data += [grbit].pack('v')
1295
+ data += [indexFore].pack('v')
1296
+ data += [indexBack].pack('v')
1297
+
1298
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1299
+ append(header, data)
1300
+ end
1301
+
1302
+ ###############################################################################
1303
+ #
1304
+ # _store_axcext()
1305
+ #
1306
+ # Write the AXCEXT chart BIFF record.
1307
+ #
1308
+ def store_axcext # :nodoc:
1309
+ record = 0x1062 # Record identifier.
1310
+ length = 0x0012 # Number of bytes to follow.
1311
+ catMin = 0x0000 # Minimum category on axis.
1312
+ catMax = 0x0000 # Maximum category on axis.
1313
+ catMajor = 0x0001 # Value of major unit.
1314
+ unitMajor = 0x0000 # Units of major unit.
1315
+ catMinor = 0x0001 # Value of minor unit.
1316
+ unitMinor = 0x0000 # Units of minor unit.
1317
+ unitBase = 0x0000 # Base unit of axis.
1318
+ catCrossDate = 0x0000 # Crossing point.
1319
+ grbit = 0x00EF # Option flags.
1320
+
1321
+ header = [record, length].pack('vv')
1322
+ data = [catMin].pack('v')
1323
+ data += [catMax].pack('v')
1324
+ data += [catMajor].pack('v')
1325
+ data += [unitMajor].pack('v')
1326
+ data += [catMinor].pack('v')
1327
+ data += [unitMinor].pack('v')
1328
+ data += [unitBase].pack('v')
1329
+ data += [catCrossDate].pack('v')
1330
+ data += [grbit].pack('v')
1331
+
1332
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1333
+ append(header, data)
1334
+ end
1335
+
1336
+ ###############################################################################
1337
+ #
1338
+ # _store_axesused()
1339
+ #
1340
+ # Write the AXESUSED chart BIFF record.
1341
+ #
1342
+ def store_axesused(num_axes) # :nodoc:
1343
+ record = 0x1046 # Record identifier.
1344
+ length = 0x0002 # Number of bytes to follow.
1345
+ # num_axes # Number of axes used.
1346
+
1347
+ header = [record, length].pack('vv')
1348
+ data = [num_axes].pack('v')
1349
+
1350
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1351
+ append(header, data)
1352
+ end
1353
+
1354
+ ###############################################################################
1355
+ #
1356
+ # _store_axis()
1357
+ #
1358
+ # Write the AXIS chart BIFF record to define the axis type.
1359
+ #
1360
+ def store_axis(type) # :nodoc:
1361
+ record = 0x101D # Record identifier.
1362
+ length = 0x0012 # Number of bytes to follow.
1363
+ # type # Axis type.
1364
+ reserved1 = 0x00000000 # Reserved.
1365
+ reserved2 = 0x00000000 # Reserved.
1366
+ reserved3 = 0x00000000 # Reserved.
1367
+ reserved4 = 0x00000000 # Reserved.
1368
+
1369
+ header = [record, length].pack('vv')
1370
+ data = [type].pack('v')
1371
+ data += [reserved1].pack('V')
1372
+ data += [reserved2].pack('V')
1373
+ data += [reserved3].pack('V')
1374
+ data += [reserved4].pack('V')
1375
+
1376
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1377
+ append(header, data)
1378
+ end
1379
+
1380
+ ###############################################################################
1381
+ #
1382
+ # _store_axislineformat()
1383
+ #
1384
+ # Write the AXISLINEFORMAT chart BIFF record.
1385
+ #
1386
+ def store_axislineformat # :nodoc:
1387
+ record = 0x1021 # Record identifier.
1388
+ length = 0x0002 # Number of bytes to follow.
1389
+ line_format = 0x0001 # Axis line format.
1390
+
1391
+ header = [record, length].pack('vv')
1392
+ data = [line_format].pack('v')
1393
+
1394
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1395
+ append(header, data)
1396
+ end
1397
+
1398
+ ###############################################################################
1399
+ #
1400
+ # _store_axisparent()
1401
+ #
1402
+ # Write the AXISPARENT chart BIFF record.
1403
+ #
1404
+ def store_axisparent(iax, x, y, dx, dy) # :nodoc:
1405
+ record = 0x1041 # Record identifier.
1406
+ length = 0x0012 # Number of bytes to follow.
1407
+ # iax # Axis index.
1408
+ # x # X-coord.
1409
+ # y # Y-coord.
1410
+ # dx # Length of x axis.
1411
+ # dy # Length of y axis.
1412
+
1413
+ header = [record, length].pack('vv')
1414
+ data = [iax].pack('v')
1415
+ data += [x].pack('V')
1416
+ data += [y].pack('V')
1417
+ data += [dx].pack('V')
1418
+ data += [dy].pack('V')
1419
+
1420
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1421
+ append(header, data)
1422
+ end
1423
+
1424
+ ###############################################################################
1425
+ #
1426
+ # _store_begin()
1427
+ #
1428
+ # Write the BEGIN chart BIFF record to indicate the start of a sub stream.
1429
+ #
1430
+ def store_begin # :nodoc:
1431
+ record = 0x1033 # Record identifier.
1432
+ length = 0x0000 # Number of bytes to follow.
1433
+
1434
+ header = [record, length].pack('vv')
1435
+
1436
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1437
+ append(header)
1438
+ end
1439
+
1440
+ ###############################################################################
1441
+ #
1442
+ # _store_catserrange()
1443
+ #
1444
+ # Write the CATSERRANGE chart BIFF record.
1445
+ #
1446
+ def store_catserrange # :nodoc:
1447
+ record = 0x1020 # Record identifier.
1448
+ length = 0x0008 # Number of bytes to follow.
1449
+ catCross = 0x0001 # Value/category crossing.
1450
+ catLabel = 0x0001 # Frequency of labels.
1451
+ catMark = 0x0001 # Frequency of ticks.
1452
+ grbit = 0x0001 # Option flags.
1453
+
1454
+ header = [record, length].pack('vv')
1455
+ data = [catCross].pack('v')
1456
+ data += [catLabel].pack('v')
1457
+ data += [catMark].pack('v')
1458
+ data += [grbit].pack('v')
1459
+
1460
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1461
+ append(header, data)
1462
+ end
1463
+
1464
+ ###############################################################################
1465
+ #
1466
+ # _store_chart()
1467
+ #
1468
+ # Write the CHART BIFF record. This indicates the start of the chart sub-stream
1469
+ # and contains dimensions of the chart on the display. Units are in 1/72 inch
1470
+ # and are 2 byte integer with 2 byte fraction.
1471
+ #
1472
+ def store_chart(x_pos, y_pos, dx, dy) # :nodoc:
1473
+ record = 0x1002 # Record identifier.
1474
+ length = 0x0010 # Number of bytes to follow.
1475
+ # x_pos # X pos of top left corner.
1476
+ # y_pos # Y pos of top left corner.
1477
+ # dx # X size.
1478
+ # dy # Y size.
1479
+
1480
+ header = [record, length].pack('vv')
1481
+ data = [x_pos].pack('V')
1482
+ data += [y_pos].pack('V')
1483
+ data += [dx].pack('V')
1484
+ data += [dy].pack('V')
1485
+
1486
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1487
+ append(header, data)
1488
+ end
1489
+
1490
+ ###############################################################################
1491
+ #
1492
+ # _store_chartformat()
1493
+ #
1494
+ # Write the CHARTFORMAT chart BIFF record. The parent record for formatting
1495
+ # of a chart group.
1496
+ #
1497
+ def store_chartformat(grbit = 0) # :nodoc:
1498
+ record = 0x1014 # Record identifier.
1499
+ length = 0x0014 # Number of bytes to follow.
1500
+ reserved1 = 0x00000000 # Reserved.
1501
+ reserved2 = 0x00000000 # Reserved.
1502
+ reserved3 = 0x00000000 # Reserved.
1503
+ reserved4 = 0x00000000 # Reserved.
1504
+ # grbit # Option flags.
1505
+ icrt = 0x0000 # Drawing order.
1506
+
1507
+ header = [record, length].pack('vv')
1508
+ data = [reserved1].pack('V')
1509
+ data += [reserved2].pack('V')
1510
+ data += [reserved3].pack('V')
1511
+ data += [reserved4].pack('V')
1512
+ data += [grbit].pack('v')
1513
+ data += [icrt].pack('v')
1514
+
1515
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1516
+ append(header, data)
1517
+ end
1518
+
1519
+ ###############################################################################
1520
+ #
1521
+ # _store_chartline()
1522
+ #
1523
+ # Write the CHARTLINE chart BIFF record.
1524
+ #
1525
+ def store_chartline # :nodoc:
1526
+ record = 0x101C # Record identifier.
1527
+ length = 0x0002 # Number of bytes to follow.
1528
+ type = 0x0001 # Drop/hi-lo line type.
1529
+
1530
+ header = [record, length].pack('vv')
1531
+ data = [type].pack('v')
1532
+
1533
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1534
+ append(header, data)
1535
+ end
1536
+
1537
+ ###############################################################################
1538
+ #
1539
+ # _store_charttext()
1540
+ #
1541
+ # Write the TEXT chart BIFF record.
1542
+ #
1543
+ def store_charttext # :nodoc:
1544
+ record = 0x1025 # Record identifier.
1545
+ length = 0x0020 # Number of bytes to follow.
1546
+ horz_align = 0x02 # Horizontal alignment.
1547
+ vert_align = 0x02 # Vertical alignment.
1548
+ bg_mode = 0x0001 # Background display.
1549
+ text_color_rgb = 0x00000000 # Text RGB colour.
1550
+ text_x = 0xFFFFFF46 # Text x-pos.
1551
+ text_y = 0xFFFFFF06 # Text y-pos.
1552
+ text_dx = 0x00000000 # Width.
1553
+ text_dy = 0x00000000 # Height.
1554
+ grbit1 = 0x00B1 # Options
1555
+ text_color_index = 0x004D # Auto Colour.
1556
+ grbit2 = 0x0000 # Data label placement.
1557
+ rotation = 0x0000 # Text rotation.
1558
+
1559
+ header = [record, length].pack('vv')
1560
+ data = [horz_align].pack('C')
1561
+ data += [vert_align].pack('C')
1562
+ data += [bg_mode].pack('v')
1563
+ data += [text_color_rgb].pack('V')
1564
+ data += [text_x].pack('V')
1565
+ data += [text_y].pack('V')
1566
+ data += [text_dx].pack('V')
1567
+ data += [text_dy].pack('V')
1568
+ data += [grbit1].pack('v')
1569
+ data += [text_color_index].pack('v')
1570
+ data += [grbit2].pack('v')
1571
+ data += [rotation].pack('v')
1572
+
1573
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1574
+ append(header, data)
1575
+ end
1576
+
1577
+ ###############################################################################
1578
+ #
1579
+ # _store_dataformat()
1580
+ #
1581
+ # Write the DATAFORMAT chart BIFF record. This record specifies the series
1582
+ # that the subsequent sub stream refers to.
1583
+ #
1584
+ def store_dataformat(series_index, series_number, point_number) # :nodoc:
1585
+ record = 0x1006 # Record identifier.
1586
+ length = 0x0008 # Number of bytes to follow.
1587
+ # series_index # Series index.
1588
+ # series_number # Series number. (Same as index).
1589
+ # point_number # Point number.
1590
+ grbit = 0x0000 # Format flags.
1591
+
1592
+ header = [record, length].pack('vv')
1593
+ data = [point_number].pack('v')
1594
+ data += [series_index].pack('v')
1595
+ data += [series_number].pack('v')
1596
+ data += [grbit].pack('v')
1597
+
1598
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1599
+ append(header, data)
1600
+ end
1601
+
1602
+ ###############################################################################
1603
+ #
1604
+ # _store_defaulttext()
1605
+ #
1606
+ # Write the DEFAULTTEXT chart BIFF record. Identifier for subsequent TEXT
1607
+ # record.
1608
+ #
1609
+ def store_defaulttext # :nodoc:
1610
+ record = 0x1024 # Record identifier.
1611
+ length = 0x0002 # Number of bytes to follow.
1612
+ type = 0x0002 # Type.
1613
+
1614
+ header = [record, length].pack('vv')
1615
+ data = [type].pack('v')
1616
+
1617
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1618
+ append(header, data)
1619
+ end
1620
+
1621
+ ###############################################################################
1622
+ #
1623
+ # _store_dropbar()
1624
+ #
1625
+ # Write the DROPBAR chart BIFF record.
1626
+ #
1627
+ def store_dropbar # :nodoc:
1628
+ record = 0x103D # Record identifier.
1629
+ length = 0x0002 # Number of bytes to follow.
1630
+ percent_gap = 0x0096 # Drop bar width gap (%).
1631
+
1632
+ header = [record, length].pack('vv')
1633
+ data = [percent_gap].pack('v')
1634
+
1635
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1636
+ append(header, data)
1637
+ end
1638
+
1639
+ ###############################################################################
1640
+ #
1641
+ # _store_end()
1642
+ #
1643
+ # Write the END chart BIFF record to indicate the end of a sub stream.
1644
+ #
1645
+ def store_end # :nodoc:
1646
+ record = 0x1034 # Record identifier.
1647
+ length = 0x0000 # Number of bytes to follow.
1648
+
1649
+ header = [record, length].pack('vv')
1650
+
1651
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1652
+ append(header)
1653
+ end
1654
+
1655
+ ###############################################################################
1656
+ # _store_fbi()
1657
+ #
1658
+ # Write the FBI chart BIFF record. Specifies the font information at the time
1659
+ # it was applied to the chart.
1660
+ #
1661
+ def store_fbi(index, height, width_basis, height_basis, scale_basis) # :nodoc:
1662
+ record = 0x1060 # Record identifier.
1663
+ length = 0x000A # Number of bytes to follow.
1664
+ # index # Font index.
1665
+ height = height * 20 # Default font height in twips.
1666
+ # width_basis # Width basis, in twips.
1667
+ # height_basis # Height basis, in twips.
1668
+ # scale_basis # Scale by chart area or plot area.
1669
+
1670
+ header = [record, length].pack('vv')
1671
+ data = [width_basis].pack('v')
1672
+ data += [height_basis].pack('v')
1673
+ data += [height].pack('v')
1674
+ data += [scale_basis].pack('v')
1675
+ data += [index].pack('v')
1676
+
1677
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1678
+ append(header, data)
1679
+ end
1680
+
1681
+ ###############################################################################
1682
+ #
1683
+ # _store_fontx()
1684
+ #
1685
+ # Write the FONTX chart BIFF record which contains the index of the FONT
1686
+ # record in the Workbook.
1687
+ #
1688
+ def store_fontx(index) # :nodoc:
1689
+ record = 0x1026 # Record identifier.
1690
+ length = 0x0002 # Number of bytes to follow.
1691
+ # index # Font index.
1692
+
1693
+ header = [record, length].pack('vv')
1694
+ data = [index].pack('v')
1695
+
1696
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1697
+ append(header, data)
1698
+ end
1699
+
1700
+ ###############################################################################
1701
+ #
1702
+ # _store_frame()
1703
+ #
1704
+ # Write the FRAME chart BIFF record.
1705
+ #
1706
+ def store_frame(frame_type, grbit) # :nodoc:
1707
+ record = 0x1032 # Record identifier.
1708
+ length = 0x0004 # Number of bytes to follow.
1709
+ # frame_type # Frame type.
1710
+ # grbit # Option flags.
1711
+
1712
+ header = [record, length].pack('vv')
1713
+ data = [frame_type].pack('v')
1714
+ data += [grbit].pack('v')
1715
+
1716
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1717
+ append(header, data)
1718
+ end
1719
+
1720
+ ###############################################################################
1721
+ #
1722
+ # _store_legend()
1723
+ #
1724
+ # Write the LEGEND chart BIFF record. The Marcus Horan method.
1725
+ #
1726
+ def store_legend(x, y, width, height, wType, wSpacing, grbit) # :nodoc:
1727
+ record = 0x1015 # Record identifier.
1728
+ length = 0x0014 # Number of bytes to follow.
1729
+ # x # X-position.
1730
+ # y # Y-position.
1731
+ # width # Width.
1732
+ # height # Height.
1733
+ # wType # Type.
1734
+ # wSpacing # Spacing.
1735
+ # grbit # Option flags.
1736
+
1737
+ header = [record, length].pack('vv')
1738
+ data = [x].pack('V')
1739
+ data += [y].pack('V')
1740
+ data += [width].pack('V')
1741
+ data += [height].pack('V')
1742
+ data += [wType].pack('C')
1743
+ data += [wSpacing].pack('C')
1744
+ data += [grbit].pack('v')
1745
+
1746
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1747
+ append(header, data)
1748
+ end
1749
+
1750
+ ###############################################################################
1751
+ #
1752
+ # _store_lineformat()
1753
+ #
1754
+ # Write the LINEFORMAT chart BIFF record.
1755
+ #
1756
+ def store_lineformat(rgb, lns, we, grbit, index) # :nodoc:
1757
+ record = 0x1007 # Record identifier.
1758
+ length = 0x000C # Number of bytes to follow.
1759
+ # rgb # Line RGB colour.
1760
+ # lns # Line pattern.
1761
+ # we # Line weight.
1762
+ # grbit # Option flags.
1763
+ # index # Index to colour of line.
1764
+
1765
+ header = [record, length].pack('vv')
1766
+ data = [rgb].pack('V')
1767
+ data += [lns].pack('v')
1768
+ data += [we].pack('v')
1769
+ data += [grbit].pack('v')
1770
+ data += [index].pack('v')
1771
+
1772
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1773
+ append(header, data)
1774
+ end
1775
+
1776
+ ###############################################################################
1777
+ #
1778
+ # _store_markerformat()
1779
+ #
1780
+ # Write the MARKERFORMAT chart BIFF record.
1781
+ #
1782
+ def store_markerformat(rgbFore, rgbBack, marker, grbit, icvFore, icvBack, miSize)# :nodoc:
1783
+ record = 0x1009 # Record identifier.
1784
+ length = 0x0014 # Number of bytes to follow.
1785
+ # rgbFore # Foreground RGB color.
1786
+ # rgbBack # Background RGB color.
1787
+ # marker # Type of marker.
1788
+ # grbit # Format flags.
1789
+ # icvFore # Color index marker border.
1790
+ # icvBack # Color index marker fill.
1791
+ # miSize # Size of line markers.
1792
+
1793
+ header = [record, length].pack('vv')
1794
+ data = [rgbFore].pack('V')
1795
+ data += [rgbBack].pack('V')
1796
+ data += [marker].pack('v')
1797
+ data += [grbit].pack('v')
1798
+ data += [icvFore].pack('v')
1799
+ data += [icvBack].pack('v')
1800
+ data += [miSize].pack('V')
1801
+
1802
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1803
+ append(header, data)
1804
+ end
1805
+
1806
+ ###############################################################################
1807
+ #
1808
+ # _store_objectlink()
1809
+ #
1810
+ # Write the OBJECTLINK chart BIFF record.
1811
+ #
1812
+ def store_objectlink(link_type) # :nodoc:
1813
+ record = 0x1027 # Record identifier.
1814
+ length = 0x0006 # Number of bytes to follow.
1815
+ # link_type # Object text link type.
1816
+ link_index1 = 0x0000 # Link index 1.
1817
+ link_index2 = 0x0000 # Link index 2.
1818
+
1819
+ header = [record, length].pack('vv')
1820
+ data = [link_type].pack('v')
1821
+ data += [link_index1].pack('v')
1822
+ data += [link_index2].pack('v')
1823
+
1824
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1825
+ append(header, data)
1826
+ end
1827
+
1828
+ ###############################################################################
1829
+ #
1830
+ # _store_pieformat()
1831
+ #
1832
+ # Write the PIEFORMAT chart BIFF record.
1833
+ #
1834
+ def store_pieformat # :nodoc:
1835
+ record = 0x100B # Record identifier.
1836
+ length = 0x0002 # Number of bytes to follow.
1837
+ percent = 0x0000 # Distance % from center.
1838
+
1839
+ header = [record, length].pack('vv')
1840
+ data = [percent].pack('v')
1841
+
1842
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1843
+ append(header, data)
1844
+ end
1845
+
1846
+ ###############################################################################
1847
+ #
1848
+ # _store_plotarea()
1849
+ #
1850
+ # Write the PLOTAREA chart BIFF record. This indicates that the subsequent
1851
+ # FRAME record belongs to a plot area.
1852
+ #
1853
+ def store_plotarea # :nodoc:
1854
+ record = 0x1035 # Record identifier.
1855
+ length = 0x0000 # Number of bytes to follow.
1856
+
1857
+ header = [record, length].pack('vv')
1858
+
1859
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1860
+ append(header)
1861
+ end
1862
+
1863
+ ###############################################################################
1864
+ #
1865
+ # _store_plotgrowth()
1866
+ #
1867
+ # Write the PLOTGROWTH chart BIFF record.
1868
+ #
1869
+ def store_plotgrowth # :nodoc:
1870
+ record = 0x1064 # Record identifier.
1871
+ length = 0x0008 # Number of bytes to follow.
1872
+ dx_plot = 0x00010000 # Horz growth for font scale.
1873
+ dy_plot = 0x00010000 # Vert growth for font scale.
1874
+
1875
+ header = [record, length].pack('vv')
1876
+ data = [dx_plot].pack('V')
1877
+ data += [dy_plot].pack('V')
1878
+
1879
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1880
+ append(header, data)
1881
+ end
1882
+
1883
+ ###############################################################################
1884
+ #
1885
+ # _store_pos()
1886
+ #
1887
+ # Write the POS chart BIFF record. Generally not required when using
1888
+ # automatic positioning.
1889
+ #
1890
+ def store_pos(mdTopLt, mdBotRt, x1, y1, x2, y2) # :nodoc:
1891
+ record = 0x104F # Record identifier.
1892
+ length = 0x0014 # Number of bytes to follow.
1893
+ # mdTopLt # Top left.
1894
+ # mdBotRt # Bottom right.
1895
+ # x1 # X coordinate.
1896
+ # y1 # Y coordinate.
1897
+ # x2 # Width.
1898
+ # y2 # Height.
1899
+
1900
+ header = [record, length].pack('vv')
1901
+ data = [mdTopLt].pack('v')
1902
+ data += [mdBotRt].pack('v')
1903
+ data += [x1].pack('V')
1904
+ data += [y1].pack('V')
1905
+ data += [x2].pack('V')
1906
+ data += [y2].pack('V')
1907
+
1908
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1909
+ append(header, data)
1910
+ end
1911
+
1912
+ ###############################################################################
1913
+ #
1914
+ # _store_serauxtrend()
1915
+ #
1916
+ # Write the SERAUXTREND chart BIFF record.
1917
+ #
1918
+ def store_serauxtrend(reg_type, poly_order, equation, r_squared) # :nodoc:
1919
+ record = 0x104B # Record identifier.
1920
+ length = 0x001C # Number of bytes to follow.
1921
+ # reg_type # Regression type.
1922
+ # poly_order # Polynomial order.
1923
+ # equation # Display equation.
1924
+ # r_squared # Display R-squared.
1925
+ # intercept # Forced intercept.
1926
+ # forecast # Forecast forward.
1927
+ # backcast # Forecast backward.
1928
+
1929
+ # TODO. When supported, intercept needs to be NAN if not used.
1930
+ # Also need to reverse doubles.
1931
+ intercept = ['FFFFFFFF0001FFFF'].pack('H*')
1932
+ forecast = ['0000000000000000'].pack('H*')
1933
+ backcast = ['0000000000000000'].pack('H*')
1934
+
1935
+ header = [record, length].pack('vv')
1936
+ data = [reg_type].pack('C')
1937
+ data += [poly_order].pack('C')
1938
+ data += intercept
1939
+ data += [equation].pack('C')
1940
+ data += [r_squared].pack('C')
1941
+ data += forecast
1942
+ data += backcast
1943
+
1944
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1945
+ append(header, data)
1946
+ end
1947
+
1948
+ ###############################################################################
1949
+ #
1950
+ # _store_series()
1951
+ #
1952
+ # Write the SERIES chart BIFF record.
1953
+ #
1954
+ def store_series(category_count, value_count) # :nodoc:
1955
+ record = 0x1003 # Record identifier.
1956
+ length = 0x000C # Number of bytes to follow.
1957
+ category_type = 0x0001 # Type: category.
1958
+ value_type = 0x0001 # Type: value.
1959
+ # category_count # Num of categories.
1960
+ # value_count # Num of values.
1961
+ bubble_type = 0x0001 # Type: bubble.
1962
+ bubble_count = 0x0000 # Num of bubble values.
1963
+
1964
+ header = [record, length].pack('vv')
1965
+ data = [category_type].pack('v')
1966
+ data += [value_type].pack('v')
1967
+ data += [category_count].pack('v')
1968
+ data += [value_count].pack('v')
1969
+ data += [bubble_type].pack('v')
1970
+ data += [bubble_count].pack('v')
1971
+
1972
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
1973
+ append(header, data)
1974
+ end
1975
+
1976
+ ###############################################################################
1977
+ #
1978
+ # _store_seriestext()
1979
+ #
1980
+ # Write the SERIESTEXT chart BIFF record.
1981
+ #
1982
+ def store_seriestext(str, encoding) # :nodoc:
1983
+ record = 0x100D # Record identifier.
1984
+ length = 0x0000 # Number of bytes to follow.
1985
+ id = 0x0000 # Text id.
1986
+ # str # Text.
1987
+ # encoding # String encoding.
1988
+ cch = str.length # String length.
1989
+
1990
+ encoding ||= 0
1991
+
1992
+ # Character length is num of chars not num of bytes
1993
+ cch /= 2 if encoding != 0
1994
+
1995
+ # Change the UTF-16 name from BE to LE
1996
+ str = str.unpack('v*').pack('n*') if encoding != 0
1997
+
1998
+ length = 4 + str.length
1999
+
2000
+ header = [record, length].pack('vv')
2001
+ data = [id].pack('v')
2002
+ data += [cch].pack('C')
2003
+ data += [encoding].pack('C')
2004
+
2005
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
2006
+ append(header, data, str)
2007
+ end
2008
+
2009
+ ###############################################################################
2010
+ #
2011
+ # _store_serparent()
2012
+ #
2013
+ # Write the SERPARENT chart BIFF record.
2014
+ #
2015
+ def store_serparent(series) # :nodoc:
2016
+ record = 0x104A # Record identifier.
2017
+ length = 0x0002 # Number of bytes to follow.
2018
+ # series # Series parent.
2019
+
2020
+ header = [record, length].pack('vv')
2021
+ data = [series].pack('v')
2022
+
2023
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
2024
+ append(header, data)
2025
+ end
2026
+
2027
+ ###############################################################################
2028
+ #
2029
+ # _store_sertocrt()
2030
+ #
2031
+ # Write the SERTOCRT chart BIFF record to indicate the chart group index.
2032
+ #
2033
+ def store_sertocrt # :nodoc:
2034
+ record = 0x1045 # Record identifier.
2035
+ length = 0x0002 # Number of bytes to follow.
2036
+ chartgroup = 0x0000 # Chart group index.
2037
+
2038
+ header = [record, length].pack('vv')
2039
+ data = [chartgroup].pack('v')
2040
+
2041
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
2042
+ append(header, data)
2043
+ end
2044
+
2045
+ ###############################################################################
2046
+ #
2047
+ # _store_shtprops()
2048
+ #
2049
+ # Write the SHTPROPS chart BIFF record.
2050
+ #
2051
+ def store_shtprops # :nodoc:
2052
+ record = 0x1044 # Record identifier.
2053
+ length = 0x0004 # Number of bytes to follow.
2054
+ grbit = 0x000E # Option flags.
2055
+ empty_cells = 0x0000 # Empty cell handling.
2056
+
2057
+ grbit = 0x000A if @embedded
2058
+
2059
+ header = [record, length].pack('vv')
2060
+ data = [grbit].pack('v')
2061
+ data += [empty_cells].pack('v')
2062
+
2063
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
2064
+ append(header, data)
2065
+ end
2066
+
2067
+ ###############################################################################
2068
+ #
2069
+ # _store_text()
2070
+ #
2071
+ # Write the TEXT chart BIFF record.
2072
+ #
2073
+ def store_text(x, y, dx, dy, grbit1, grbit2, rotation = 0x00)# :nodoc:
2074
+ record = 0x1025 # Record identifier.
2075
+ length = 0x0020 # Number of bytes to follow.
2076
+ at = 0x02 # Horizontal alignment.
2077
+ vat = 0x02 # Vertical alignment.
2078
+ wBkgMode = 0x0001 # Background display.
2079
+ rgbText = 0x0000 # Text RGB colour.
2080
+ # x # Text x-pos.
2081
+ # y # Text y-pos.
2082
+ # dx # Width.
2083
+ # dy # Height.
2084
+ # grbit1 # Option flags.
2085
+ icvText = 0x004D # Auto Colour.
2086
+ # grbit2 # Show legend.
2087
+ # rotation # Show value.
2088
+
2089
+ header = [record, length].pack('vv')
2090
+ data = [at].pack('C')
2091
+ data += [vat].pack('C')
2092
+ data += [wBkgMode].pack('v')
2093
+ data += [rgbText].pack('V')
2094
+ data += [x].pack('V')
2095
+ data += [y].pack('V')
2096
+ data += [dx].pack('V')
2097
+ data += [dy].pack('V')
2098
+ data += [grbit1].pack('v')
2099
+ data += [icvText].pack('v')
2100
+ data += [grbit2].pack('v')
2101
+ data += [rotation].pack('v')
2102
+
2103
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
2104
+ append(header, data)
2105
+ end
2106
+
2107
+ ###############################################################################
2108
+ #
2109
+ # _store_tick()
2110
+ #
2111
+ # Write the TICK chart BIFF record.
2112
+ #
2113
+ def store_tick # :nodoc:
2114
+ record = 0x101E # Record identifier.
2115
+ length = 0x001E # Number of bytes to follow.
2116
+ tktMajor = 0x02 # Type of major tick mark.
2117
+ tktMinor = 0x00 # Type of minor tick mark.
2118
+ tlt = 0x03 # Tick label position.
2119
+ wBkgMode = 0x01 # Background mode.
2120
+ rgb = 0x00000000 # Tick-label RGB colour.
2121
+ reserved1 = 0x00000000 # Reserved.
2122
+ reserved2 = 0x00000000 # Reserved.
2123
+ reserved3 = 0x00000000 # Reserved.
2124
+ reserved4 = 0x00000000 # Reserved.
2125
+ grbit = 0x0023 # Option flags.
2126
+ index = 0x004D # Colour index.
2127
+ reserved5 = 0x0000 # Reserved.
2128
+
2129
+ header = [record, length].pack('vv')
2130
+ data = [tktMajor].pack('C')
2131
+ data += [tktMinor].pack('C')
2132
+ data += [tlt].pack('C')
2133
+ data += [wBkgMode].pack('C')
2134
+ data += [rgb].pack('V')
2135
+ data += [reserved1].pack('V')
2136
+ data += [reserved2].pack('V')
2137
+ data += [reserved3].pack('V')
2138
+ data += [reserved4].pack('V')
2139
+ data += [grbit].pack('v')
2140
+ data += [index].pack('v')
2141
+ data += [reserved5].pack('v')
2142
+
2143
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
2144
+ append(header, data)
2145
+ end
2146
+
2147
+ ###############################################################################
2148
+ #
2149
+ # _store_valuerange()
2150
+ #
2151
+ # Write the VALUERANGE chart BIFF record.
2152
+ #
2153
+ def store_valuerange # :nodoc:
2154
+ record = 0x101F # Record identifier.
2155
+ length = 0x002A # Number of bytes to follow.
2156
+ numMin = 0x00000000 # Minimum value on axis.
2157
+ numMax = 0x00000000 # Maximum value on axis.
2158
+ numMajor = 0x00000000 # Value of major increment.
2159
+ numMinor = 0x00000000 # Value of minor increment.
2160
+ numCross = 0x00000000 # Value where category axis crosses.
2161
+ grbit = 0x011F # Format flags.
2162
+
2163
+ # TODO. Reverse doubles when they are handled.
2164
+
2165
+ header = [record, length].pack('vv')
2166
+ data = [numMin].pack('d')
2167
+ data += [numMax].pack('d')
2168
+ data += [numMajor].pack('d')
2169
+ data += [numMinor].pack('d')
2170
+ data += [numCross].pack('d')
2171
+ data += [grbit].pack('v')
2172
+
2173
+ print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
2174
+ append(header, data)
2175
+ end
2176
+
2177
+
2178
+ ###############################################################################
2179
+ #
2180
+ # Config data.
2181
+ #
2182
+ ###############################################################################
2183
+
2184
+ ###############################################################################
2185
+ #
2186
+ # _set_default_properties()
2187
+ #
2188
+ # Setup the default properties for a chart.
2189
+ #
2190
+ def set_default_properties # :nodoc:
2191
+ @legend = {
2192
+ :visible => 1,
2193
+ :position => 0,
2194
+ :vertical => 0,
2195
+ }
2196
+
2197
+ @chartarea = {
2198
+ :visible => 0,
2199
+ :fg_color_index => 0x4E,
2200
+ :fg_color_rgb => 0xFFFFFF,
2201
+ :bg_color_index => 0x4D,
2202
+ :bg_color_rgb => 0x000000,
2203
+ :area_pattern => 0x0000,
2204
+ :area_options => 0x0000,
2205
+ :line_pattern => 0x0005,
2206
+ :line_weight => 0xFFFF,
2207
+ :line_color_index => 0x4D,
2208
+ :line_color_rgb => 0x000000,
2209
+ :line_options => 0x0008,
2210
+ }
2211
+
2212
+ @plotarea = {
2213
+ :visible => 1,
2214
+ :fg_color_index => 0x16,
2215
+ :fg_color_rgb => 0xC0C0C0,
2216
+ :bg_color_index => 0x4F,
2217
+ :bg_color_rgb => 0x000000,
2218
+ :area_pattern => 0x0001,
2219
+ :area_options => 0x0000,
2220
+ :line_pattern => 0x0000,
2221
+ :line_weight => 0x0000,
2222
+ :line_color_index => 0x17,
2223
+ :line_color_rgb => 0x808080,
2224
+ :line_options => 0x0000,
2225
+ }
2226
+ end
2227
+
2228
+ ###############################################################################
2229
+ #
2230
+ # _set_default_config_data()
2231
+ #
2232
+ # Setup the default configuration data for a chart.
2233
+ #
2234
+ def set_default_config_data # :nodoc:
2235
+ #<<< Perltidy ignore this.
2236
+ @config = {
2237
+ :axisparent => [ 0, 0x00F8, 0x01F5, 0x0E7F, 0x0B36 ],
2238
+ :axisparent_pos => [ 2, 2, 0x008C, 0x01AA, 0x0EEA, 0x0C52 ],
2239
+ :chart => [ 0x0000, 0x0000, 0x02DD51E0, 0x01C2B838 ],
2240
+ :font_numbers => [ 5, 10, 0x38B8, 0x22A1, 0x0000 ],
2241
+ :font_series => [ 6, 10, 0x38B8, 0x22A1, 0x0001 ],
2242
+ :font_title => [ 7, 12, 0x38B8, 0x22A1, 0x0000 ],
2243
+ :font_axes => [ 8, 10, 0x38B8, 0x22A1, 0x0001 ],
2244
+ :legend => [ 0x05F9, 0x0EE9, 0x047D, 0x9C, 0x00, 0x01, 0x0F ],
2245
+ :legend_pos => [ 5, 2, 0x05F9, 0x0EE9, 0, 0 ],
2246
+ :legend_text => [ 0xFFFFFF46, 0xFFFFFF06, 0, 0, 0x00B1, 0x0000 ],
2247
+ :legend_text_pos => [ 2, 2, 0, 0, 0, 0 ],
2248
+ :series_text => [ 0xFFFFFF46, 0xFFFFFF06, 0, 0, 0x00B1, 0x1020 ],
2249
+ :series_text_pos => [ 2, 2, 0, 0, 0, 0 ],
2250
+ :title_text => [ 0x06E4, 0x0051, 0x01DB, 0x00C4, 0x0081, 0x1030 ],
2251
+ :title_text_pos => [ 2, 2, 0, 0, 0x73, 0x1D ],
2252
+ :x_axis_text => [ 0x07E1, 0x0DFC, 0xB2, 0x9C, 0x0081, 0x0000 ],
2253
+ :x_axis_text_pos => [ 2, 2, 0, 0, 0x2B, 0x17 ],
2254
+ :y_axis_text => [ 0x002D, 0x06AA, 0x5F, 0x1CC, 0x0281, 0x00, 90 ],
2255
+ :y_axis_text_pos => [ 2, 2, 0, 0, 0x17, 0x44 ],
2256
+ } #>>>
2257
+ end
2258
+
2259
+ ###############################################################################
2260
+ #
2261
+ # _set_embedded_config_data()
2262
+ #
2263
+ # Setup the default configuration data for an embedded chart.
2264
+ #
2265
+ def set_embedded_config_data # :nodoc:
2266
+ @embedded = true
2267
+
2268
+ @chartarea = {
2269
+ :visible => 1,
2270
+ :fg_color_index => 0x4E,
2271
+ :fg_color_rgb => 0xFFFFFF,
2272
+ :bg_color_index => 0x4D,
2273
+ :bg_color_rgb => 0x000000,
2274
+ :area_pattern => 0x0001,
2275
+ :area_options => 0x0001,
2276
+ :line_pattern => 0x0000,
2277
+ :line_weight => 0x0000,
2278
+ :line_color_index => 0x4D,
2279
+ :line_color_rgb => 0x000000,
2280
+ :line_options => 0x0009,
2281
+ }
2282
+
2283
+ #<<< Perltidy ignore this.
2284
+ @config = {
2285
+ :axisparent => [ 0, 0x01D8, 0x031D, 0x0D79, 0x07E9 ],
2286
+ :axisparent_pos => [ 2, 2, 0x010C, 0x0292, 0x0E46, 0x09FD ],
2287
+ :chart => [ 0x0000, 0x0000, 0x01847FE8, 0x00F47FE8 ],
2288
+ :font_numbers => [ 5, 10, 0x1DC4, 0x1284, 0x0000 ],
2289
+ :font_series => [ 6, 10, 0x1DC4, 0x1284, 0x0001 ],
2290
+ :font_title => [ 7, 12, 0x1DC4, 0x1284, 0x0000 ],
2291
+ :font_axes => [ 8, 10, 0x1DC4, 0x1284, 0x0001 ],
2292
+ :legend => [ 0x044E, 0x0E4A, 0x088D, 0x0123, 0x0, 0x1, 0xF ],
2293
+ :legend_pos => [ 5, 2, 0x044E, 0x0E4A, 0, 0 ],
2294
+ :legend_text => [ 0xFFFFFFD9, 0xFFFFFFC1, 0, 0, 0x00B1, 0x0000 ],
2295
+ :legend_text_pos => [ 2, 2, 0, 0, 0, 0 ],
2296
+ :series_text => [ 0xFFFFFFD9, 0xFFFFFFC1, 0, 0, 0x00B1, 0x1020 ],
2297
+ :series_text_pos => [ 2, 2, 0, 0, 0, 0 ],
2298
+ :title_text => [ 0x060F, 0x004C, 0x038A, 0x016F, 0x0081, 0x1030 ],
2299
+ :title_text_pos => [ 2, 2, 0, 0, 0x73, 0x1D ],
2300
+ :x_axis_text => [ 0x07EF, 0x0C8F, 0x153, 0x123, 0x81, 0x00 ],
2301
+ :x_axis_text_pos => [ 2, 2, 0, 0, 0x2B, 0x17 ],
2302
+ :y_axis_text => [ 0x0057, 0x0564, 0xB5, 0x035D, 0x0281, 0x00, 90 ],
2303
+ :y_axis_text_pos => [ 2, 2, 0, 0, 0x17, 0x44 ],
2304
+ } #>>>
2305
+ end
2306
+ end