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.
- data/README +26 -31
- data/examples/a_simple.rb +42 -42
- data/examples/{autofilters.rb → autofilter.rb} +264 -266
- data/examples/bigfile.rb +29 -0
- data/examples/chart_area.rb +120 -0
- data/examples/chart_bar.rb +119 -0
- data/examples/chart_column.rb +119 -0
- data/examples/chart_line.rb +119 -0
- data/examples/chart_pie.rb +107 -0
- data/examples/chart_scatter.rb +120 -0
- data/examples/chart_stock.rb +147 -0
- data/examples/copyformat.rb +51 -51
- data/examples/data_validate.rb +278 -278
- data/examples/date_time.rb +86 -86
- data/examples/defined_name.rb +31 -0
- data/examples/demo.rb +120 -118
- data/examples/diag_border.rb +35 -35
- data/examples/formats.rb +489 -489
- data/examples/header.rb +136 -136
- data/examples/hidden.rb +28 -28
- data/examples/hyperlink.rb +42 -42
- data/examples/images.rb +52 -52
- data/examples/merge1.rb +39 -39
- data/examples/merge2.rb +44 -44
- data/examples/merge3.rb +65 -65
- data/examples/merge4.rb +82 -82
- data/examples/merge5.rb +79 -79
- data/examples/properties.rb +33 -0
- data/examples/properties_jp.rb +32 -0
- data/examples/protection.rb +46 -46
- data/examples/regions.rb +52 -52
- data/examples/repeat.rb +42 -42
- data/examples/stats.rb +75 -75
- data/examples/stocks.rb +80 -80
- data/examples/tab_colors.rb +30 -30
- data/examples/write_arrays.rb +82 -0
- data/lib/writeexcel.rb +1134 -18
- data/lib/writeexcel/biffwriter.rb +273 -260
- data/lib/writeexcel/chart.rb +2306 -217
- data/lib/writeexcel/charts/area.rb +152 -0
- data/lib/writeexcel/charts/bar.rb +177 -0
- data/lib/writeexcel/charts/column.rb +156 -0
- data/lib/writeexcel/charts/external.rb +61 -0
- data/lib/writeexcel/charts/line.rb +152 -0
- data/lib/writeexcel/charts/pie.rb +169 -0
- data/lib/writeexcel/charts/scatter.rb +192 -0
- data/lib/writeexcel/charts/stock.rb +211 -0
- data/lib/writeexcel/excelformulaparser.rb +208 -195
- data/lib/writeexcel/format.rb +1697 -1108
- data/lib/writeexcel/formula.rb +1050 -986
- data/lib/writeexcel/olewriter.rb +322 -322
- data/lib/writeexcel/properties.rb +251 -250
- data/lib/writeexcel/storage_lite.rb +968 -0
- data/lib/writeexcel/workbook.rb +3294 -2630
- data/lib/writeexcel/worksheet.rb +9012 -6377
- data/test/excelfile/Chart1.xls +0 -0
- data/test/excelfile/Chart2.xls +0 -0
- data/test/excelfile/Chart3.xls +0 -0
- data/test/excelfile/Chart4.xls +0 -0
- data/test/excelfile/Chart5.xls +0 -0
- data/test/perl_output/Chart1.xls.data +0 -0
- data/test/perl_output/Chart2.xls.data +0 -0
- data/test/perl_output/Chart3.xls.data +0 -0
- data/test/perl_output/Chart4.xls.data +0 -0
- data/test/perl_output/Chart5.xls.data +0 -0
- data/test/perl_output/a_simple.xls +0 -0
- data/test/perl_output/autofilter.xls +0 -0
- data/test/perl_output/chart_area.xls +0 -0
- data/test/perl_output/chart_bar.xls +0 -0
- data/test/perl_output/chart_column.xls +0 -0
- data/test/perl_output/chart_line.xls +0 -0
- data/test/perl_output/data_validate.xls +0 -0
- data/test/perl_output/date_time.xls +0 -0
- data/test/perl_output/demo.xls +0 -0
- data/test/perl_output/demo101.bin +0 -0
- data/test/perl_output/demo201.bin +0 -0
- data/test/perl_output/demo301.bin +0 -0
- data/test/perl_output/demo401.bin +0 -0
- data/test/perl_output/demo501.bin +0 -0
- data/test/perl_output/diag_border.xls +0 -0
- data/test/perl_output/headers.xls +0 -0
- data/test/perl_output/hyperlink.xls +0 -0
- data/test/perl_output/images.xls +0 -0
- data/test/perl_output/merge1.xls +0 -0
- data/test/perl_output/merge2.xls +0 -0
- data/test/perl_output/merge3.xls +0 -0
- data/test/perl_output/merge4.xls +0 -0
- data/test/perl_output/merge5.xls +0 -0
- data/test/perl_output/protection.xls +0 -0
- data/test/perl_output/regions.xls +0 -0
- data/test/perl_output/stats.xls +0 -0
- data/test/perl_output/stocks.xls +0 -0
- data/test/perl_output/tab_colors.xls +0 -0
- data/test/perl_output/unicode_cyrillic.xls +0 -0
- data/test/perl_output/workbook1.xls +0 -0
- data/test/perl_output/workbook2.xls +0 -0
- data/test/tc_all.rb +32 -31
- data/test/tc_biff.rb +104 -104
- data/test/tc_chart.rb +22 -22
- data/test/tc_example_match.rb +1944 -1280
- data/test/tc_format.rb +1254 -1267
- data/test/tc_formula.rb +63 -63
- data/test/tc_ole.rb +110 -110
- data/test/tc_storage_lite.rb +149 -0
- data/test/tc_workbook.rb +140 -115
- data/test/tc_worksheet.rb +115 -115
- data/test/test_00_IEEE_double.rb +14 -14
- data/test/test_01_add_worksheet.rb +12 -12
- data/test/test_02_merge_formats.rb +58 -58
- data/test/test_04_dimensions.rb +397 -397
- data/test/test_05_rows.rb +182 -182
- data/test/test_06_extsst.rb +80 -80
- data/test/test_11_date_time.rb +484 -484
- data/test/test_12_date_only.rb +506 -506
- data/test/test_13_date_seconds.rb +486 -486
- data/test/test_21_escher.rb +642 -629
- data/test/test_22_mso_drawing_group.rb +750 -739
- data/test/test_23_note.rb +78 -78
- data/test/test_24_txo.rb +80 -80
- data/test/test_25_position_object.rb +82 -0
- data/test/test_26_autofilter.rb +327 -327
- data/test/test_27_autofilter.rb +144 -144
- data/test/test_28_autofilter.rb +174 -174
- data/test/test_29_process_jpg.rb +681 -131
- data/test/test_30_validation_dval.rb +82 -82
- data/test/test_31_validation_dv_strings.rb +131 -131
- data/test/test_32_validation_dv_formula.rb +211 -211
- data/test/test_40_property_types.rb +191 -191
- data/test/test_41_properties.rb +238 -238
- data/test/test_42_set_properties.rb +442 -419
- data/test/test_50_name_stored.rb +305 -0
- data/test/test_51_name_print_area.rb +363 -0
- data/test/test_52_name_print_titles.rb +460 -0
- data/test/test_53_autofilter.rb +209 -0
- data/test/test_60_chart_generic.rb +576 -0
- data/test/test_61_chart_subclasses.rb +97 -0
- data/test/test_62_chart_formats.rb +270 -0
- data/test/test_63_chart_area_formats.rb +647 -0
- data/test/test_chartex.rb +35 -0
- data/test/ts_all.rb +46 -34
- data/writeexcel.gemspec +18 -0
- data/writeexcel.rdoc +583 -0
- metadata +162 -108
data/lib/writeexcel/chart.rb
CHANGED
@@ -1,217 +1,2306 @@
|
|
1
|
-
###############################################################################
|
2
|
-
#
|
3
|
-
# Chart - A writer class for Excel Charts.
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# Used in conjunction with
|
7
|
-
#
|
8
|
-
# Copyright 2000-
|
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/
|
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
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
#
|
163
|
-
#
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
#
|
176
|
-
#
|
177
|
-
#
|
178
|
-
#
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
#
|
209
|
-
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
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
|