twb 3.9.7 → 4.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/twb.rb +5 -2
- data/lib/twb/analysis/CalculatedFields/CalculatedFieldsAnalyzer.rb +54 -34
- data/lib/twb/analysis/CalculatedFields/MarkdownEmitter.rb +24 -2
- data/lib/twb/analysis/DataSources/categoricalColorCodingAnalyzer.rb +99 -0
- data/lib/twb/analysis/DataSources/dataSourceOriginsAnalyzer.rb +71 -0
- data/lib/twb/analysis/DataSources/dataSourcesLocationsAnalyzer.rb +122 -0
- data/lib/twb/analysis/DataSources/googlesheetdatasourcesanalyzer.rb +6 -5
- data/lib/twb/analysis/Sheets/dashsheetsanalyzer.rb +7 -5
- data/lib/twb/analysis/Sheets/sheetfieldsanalyzer.rb +90 -8
- data/lib/twb/analysis/Sheets/sheetfiltersanalyzer.rb +6 -5
- data/lib/twb/analysis/Sheets/sheetsourcesanalyzer.rb +122 -0
- data/lib/twb/codedfield.rb +1 -1
- data/lib/twb/connection.rb +104 -2
- data/lib/twb/datasource.rb +35 -4
- data/lib/twb/fieldcalculation.rb +4 -15
- data/lib/twb/quickfilter.rb +10 -9
- data/lib/twb/tabtool.rb +39 -11
- data/lib/twb/workbook.rb +49 -12
- data/lib/twb/worksheet.rb +70 -7
- metadata +6 -2
data/lib/twb/datasource.rb
CHANGED
@@ -42,8 +42,11 @@ module Twb
|
|
42
42
|
|
43
43
|
attr_reader :workbook
|
44
44
|
attr_reader :name, :caption, :uiname
|
45
|
+
attr_reader :attributes
|
45
46
|
attr_reader :dsclass, :isExtract
|
46
|
-
attr_reader :connection, :connections, :connHash,
|
47
|
+
attr_reader :connection, :connections, :connHash, :connAttributes
|
48
|
+
attr_reader :isPublished
|
49
|
+
attr_reader :uuid
|
47
50
|
attr_reader :tables, :joinPairs
|
48
51
|
attr_reader :localFields, :localFieldNames, :localField, :hasField
|
49
52
|
attr_reader :columnFields
|
@@ -73,6 +76,24 @@ module Twb
|
|
73
76
|
return self
|
74
77
|
end
|
75
78
|
|
79
|
+
def attributes
|
80
|
+
@attributes ||= @attributes = loadAttributes(@node)
|
81
|
+
end
|
82
|
+
|
83
|
+
def connAttributes
|
84
|
+
@connAttributes ||= @connAttributes = loadAttributes(@connection)
|
85
|
+
end
|
86
|
+
|
87
|
+
def loadAttributes node
|
88
|
+
attributes = {}
|
89
|
+
unless node.nil?
|
90
|
+
node.attributes.each do |k,v|
|
91
|
+
attributes[k] = v.text
|
92
|
+
end
|
93
|
+
end
|
94
|
+
return attributes
|
95
|
+
end
|
96
|
+
|
76
97
|
def id
|
77
98
|
@id ||= @id = @name
|
78
99
|
end
|
@@ -145,6 +166,14 @@ module Twb
|
|
145
166
|
@isExtract ||= @isExtract = !@node.at_xpath('./extract').nil?
|
146
167
|
end
|
147
168
|
|
169
|
+
def isPublished
|
170
|
+
@isPublished ||= loadIsPublished
|
171
|
+
end
|
172
|
+
|
173
|
+
def loadIsPublished
|
174
|
+
@isPublished = !node.at_xpath('./repository-location').nil?
|
175
|
+
end
|
176
|
+
|
148
177
|
def loadTables connection
|
149
178
|
@tables = {}
|
150
179
|
nodes = connection.xpath(".//relation[@type='table']")
|
@@ -269,8 +298,10 @@ module Twb
|
|
269
298
|
end
|
270
299
|
|
271
300
|
def fieldAlias fieldName, value
|
272
|
-
|
273
|
-
|
301
|
+
emit "fieldAlias: #{fieldName.class} -> #{value.class}"
|
302
|
+
loadAliases if @aliases.nil?
|
303
|
+
return value if @aliases.nil? || @aliases[fieldName].nil? # unless fieldHasAliases(fieldName)
|
304
|
+
fldAlias = @aliases[fieldName][value]
|
274
305
|
fldAlias.nil? ? value : fldAlias
|
275
306
|
end
|
276
307
|
|
@@ -336,7 +367,7 @@ module Twb
|
|
336
367
|
|
337
368
|
def fieldUIName fieldName
|
338
369
|
loadFieldUINames if @fieldUINames.nil?
|
339
|
-
@fieldUINames[fieldName]
|
370
|
+
@fieldUINames[fieldName].nil? ? fieldName : @fieldUINames[fieldName]
|
340
371
|
end
|
341
372
|
|
342
373
|
def fieldUINames
|
data/lib/twb/fieldcalculation.rb
CHANGED
@@ -38,7 +38,7 @@ module Twb
|
|
38
38
|
attr_reader :fields, :remoteFields, :calcFields
|
39
39
|
attr_reader :comments, :uuid
|
40
40
|
|
41
|
-
attr_accessor :ttlogfile
|
41
|
+
# attr_accessor :ttlogfile
|
42
42
|
|
43
43
|
@@tableCalcs = [ 'FIRST', 'INDEX', 'LAST', 'SIZE',
|
44
44
|
'LOOKUP', 'PREVIOUS_VALUE',
|
@@ -53,16 +53,15 @@ module Twb
|
|
53
53
|
'WINDOW_VAR', 'WINDOW_VARP'
|
54
54
|
]
|
55
55
|
|
56
|
-
@ttlogfile =
|
57
|
-
|
58
56
|
def initialize(calcField, datasource=nil)
|
59
57
|
raise ArgumentError.new("FieldCalculation must be initialized with a CalculatedField, has been provided with a #{calcField.class}") if calcField.class != Twb::CalculatedField
|
58
|
+
init
|
60
59
|
# initLogger
|
61
60
|
@field = calcField
|
62
61
|
calcNode = calcField.node
|
63
62
|
@istableCalc = false
|
64
63
|
# @localEmit = false
|
65
|
-
|
64
|
+
emit "FieldCalculation calcNode.nil? :: #{calcNode.nil?} "
|
66
65
|
unless calcNode.nil?
|
67
66
|
@node = calcNode.at_xpath('./calculation')
|
68
67
|
@fieldNode = calcField.node
|
@@ -94,7 +93,7 @@ module Twb
|
|
94
93
|
@has_formula = @node.has_attribute?('formula')
|
95
94
|
if @has_formula
|
96
95
|
@formula = @node.attribute('formula').text.gsub(/\r\n/,"\n")
|
97
|
-
|
96
|
+
emit "\n-- init: #{@formula}"
|
98
97
|
@formulaUC = @formula.upcase
|
99
98
|
@formulaLines = formula.split(/\n|\r\n/)
|
100
99
|
@formulaFlat = flattenFormula(@formulaLines)
|
@@ -108,12 +107,6 @@ module Twb
|
|
108
107
|
end
|
109
108
|
end
|
110
109
|
|
111
|
-
# def initLogger(logfile=nil)
|
112
|
-
# logfilename = docFile(logfile.nil? ? @ttlogfile : logfile)
|
113
|
-
# @logger = Logger.new(logfilename)
|
114
|
-
# @logger.level = Logger::DEBUG
|
115
|
-
# end
|
116
|
-
|
117
110
|
def id
|
118
111
|
@id ||= @id = @formulaFlat.hash + calcField.hash
|
119
112
|
end
|
@@ -122,10 +115,6 @@ module Twb
|
|
122
115
|
@uuid ||= @uuid = Digest::MD5.hexdigest(@formula)
|
123
116
|
end
|
124
117
|
|
125
|
-
# def assessTableCalc formula
|
126
|
-
# @@tableCalcs.any? { |tc| string.include?(tc) }
|
127
|
-
# end
|
128
|
-
|
129
118
|
def attribText(node, attribute)
|
130
119
|
node.attribute(attribute).nil? ? nil : node.attribute(attribute).text
|
131
120
|
end
|
data/lib/twb/quickfilter.rb
CHANGED
@@ -23,7 +23,7 @@ module Twb
|
|
23
23
|
include TabTool
|
24
24
|
|
25
25
|
attr_reader :field, :name, :uiname
|
26
|
-
attr_reader :type
|
26
|
+
attr_reader :type, :kind
|
27
27
|
attr_reader :dataSource
|
28
28
|
attr_reader :node, :values
|
29
29
|
attr_reader :inexclude, :inexMode, :includeNull
|
@@ -32,8 +32,9 @@ module Twb
|
|
32
32
|
init
|
33
33
|
emit "\nFILTER:\n#{node}\n====="
|
34
34
|
@node = node
|
35
|
-
filterClass = node['class']
|
35
|
+
filterClass = @node['class']
|
36
36
|
@type = filterClass.gsub('-',' ').capitalize
|
37
|
+
@kind = @node['kind']
|
37
38
|
fieldCode = node['column']
|
38
39
|
codedField = Twb::CodedField.new(fieldCode)
|
39
40
|
fieldTech = codedField.name
|
@@ -83,7 +84,7 @@ module Twb
|
|
83
84
|
when 'quantitative' then resolveQuantitative
|
84
85
|
when 'categorical' then resolveCategoricalValues
|
85
86
|
end
|
86
|
-
end
|
87
|
+
end # def initialize
|
87
88
|
|
88
89
|
def to_s
|
89
90
|
"%s => %s" % [uiname, values]
|
@@ -93,7 +94,7 @@ module Twb
|
|
93
94
|
|
94
95
|
def recordValue value, valias=nil
|
95
96
|
# puts "recordValue--: #{value} :: @'#{valias}'"
|
96
|
-
valias = value if valias.nil?
|
97
|
+
# valias = value if valias.nil?
|
97
98
|
@values << {:value => value, :alias => valias}
|
98
99
|
# puts "recordValue--: done"
|
99
100
|
end
|
@@ -194,9 +195,8 @@ module Twb
|
|
194
195
|
# <filter class='categorical' column='[Sample - Superstore - English (Extract)].[none:Region:nk]'>
|
195
196
|
# <groupfilter from='"East"' function='range' level='[none:Region:nk]' to='"West"' user:ui-domain='relevant' user:ui-enumeration='inclusive' user:ui-marker='enumerate' />
|
196
197
|
# </filter>
|
197
|
-
#--
|
198
198
|
def resolveCategoricalValues
|
199
|
-
emit "resolveCategoricalValues"
|
199
|
+
emit "########################## resolveCategoricalValues"
|
200
200
|
emit "@measureNames: #{@measureNames}"
|
201
201
|
if @node.element_children.empty?
|
202
202
|
# <filter class='categorical' column='[Sample - Superstore].[Top Customers by Profit (copy)]' />
|
@@ -337,8 +337,8 @@ module Twb
|
|
337
337
|
recordValue range, range
|
338
338
|
end
|
339
339
|
t.each do |name,alia|
|
340
|
-
# emit "
|
341
|
-
recordValue name, @dataSource.fieldAlias(@uiname,name)
|
340
|
+
# emit true, "++++ range Name: %-20s ALIAS: %-s " % [name, alia]
|
341
|
+
# recordValue name, @dataSource.fieldAlias(@uiname,name)
|
342
342
|
end
|
343
343
|
end
|
344
344
|
end
|
@@ -346,6 +346,7 @@ module Twb
|
|
346
346
|
end
|
347
347
|
|
348
348
|
def filtersFromRangeNode node
|
349
|
+
emit "########################## filtersFromRangeNode"
|
349
350
|
unless @twbDomainsLoaded
|
350
351
|
loadDomains
|
351
352
|
end
|
@@ -368,7 +369,7 @@ module Twb
|
|
368
369
|
end
|
369
370
|
|
370
371
|
def filtersInRange from, to
|
371
|
-
emit "filtersInRange"
|
372
|
+
emit "########################## filtersInRange"
|
372
373
|
# results = {}
|
373
374
|
dsFields = @twbFielddomains[@dataSource.uiname]
|
374
375
|
emit "dsFields : #{dsFields}"
|
data/lib/twb/tabtool.rb
CHANGED
@@ -16,12 +16,14 @@
|
|
16
16
|
require 'logger'
|
17
17
|
require 'nokogiri'
|
18
18
|
require 'digest/md5'
|
19
|
+
require 'yaml'
|
19
20
|
|
20
21
|
module TabTool
|
21
22
|
|
22
23
|
@@licensed = false
|
23
24
|
|
24
|
-
TTDOCDIR
|
25
|
+
@@TTDOCDIR = './ttdoc'
|
26
|
+
@configFile = './ttconfig.yml'
|
25
27
|
|
26
28
|
attr_accessor :ttdocdir, :logger, :loglevel, :logfilename
|
27
29
|
attr_accessor :uuid, :type, :id, :properties
|
@@ -42,9 +44,9 @@ module TabTool
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def initDocDir
|
45
|
-
# return if TTDOCDIR.nil?
|
46
|
-
# return if ''.eql?($ttdocdir) && ''.eql?(TTDOCDIR)
|
47
|
-
@docDir = TTDOCDIR
|
47
|
+
# return if @@TTDOCDIR.nil?
|
48
|
+
# return if ''.eql?($ttdocdir) && ''.eql?(@@TTDOCDIR)
|
49
|
+
@docDir = @@TTDOCDIR
|
48
50
|
return if Dir.exists?(@docDir)
|
49
51
|
if File.exists? @docDir
|
50
52
|
@docDir = ''
|
@@ -55,9 +57,12 @@ module TabTool
|
|
55
57
|
end
|
56
58
|
|
57
59
|
def initLogger
|
58
|
-
|
59
|
-
|
60
|
-
|
60
|
+
@logger = nil
|
61
|
+
if config(:log)
|
62
|
+
logFileName = docFile("#{self.class.to_s.split('::').last}.ttlog")
|
63
|
+
@logger = Logger.new(logFileName)
|
64
|
+
@logger.level = Logger::DEBUG
|
65
|
+
end
|
61
66
|
return @logger
|
62
67
|
end
|
63
68
|
|
@@ -77,6 +82,23 @@ module TabTool
|
|
77
82
|
@funcdoc.nil? ? {:class=>'n/a', :blurb=>'generic TabTool blurb', :description=>'A useful Tableau Tool.'} : @funcdoc
|
78
83
|
end
|
79
84
|
|
85
|
+
def hasConfig param
|
86
|
+
loadConfig if @configParams.nil?
|
87
|
+
@configParams[param] ? true : false
|
88
|
+
end
|
89
|
+
|
90
|
+
def config param
|
91
|
+
hasConfig(param) ? @configParams[param] : nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def loadConfig
|
95
|
+
@configParams = if File.exist?('./ttconfig.yml')
|
96
|
+
YAML.load( File.open('./ttconfig.yml').read )
|
97
|
+
else
|
98
|
+
{}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
80
102
|
def docfiles
|
81
103
|
@docfiles ||= @docfiles = []
|
82
104
|
end
|
@@ -95,21 +117,28 @@ module TabTool
|
|
95
117
|
return maxlen
|
96
118
|
end
|
97
119
|
|
98
|
-
def docfilesdoc
|
120
|
+
def docfilesdoc(pad=' ',desc='For documentation and generated data see the following:')
|
99
121
|
lines = SortedSet.new
|
122
|
+
paddesc = "#{pad}#{desc}"
|
100
123
|
unless @docfiles.nil? || @docfiles.empty?
|
101
124
|
nameLen = docFileMaxNameLen
|
102
125
|
docfiles.each do |dfi|
|
103
|
-
lines << "
|
126
|
+
lines << "#{pad}- %-#{nameLen}s %-s " % [ dfi[:name], dfi[:description] ]
|
104
127
|
end
|
105
128
|
end
|
106
|
-
docLines = lines.empty? ? [] : [' ',
|
129
|
+
docLines = lines.empty? || paddesc =~ /^[ ]+/ ? [] : [' ',"#{pad}#{desc}"]
|
107
130
|
lines.each do |l|
|
108
131
|
docLines << l
|
109
132
|
end
|
110
133
|
return docLines
|
111
134
|
end
|
112
135
|
|
136
|
+
def docfilesdocto_s(pad=' ',desc='For documentation and generated data see the following:')
|
137
|
+
str = ''
|
138
|
+
docfilesdoc(pad,desc).each { |l| str += "#{l}\n"}
|
139
|
+
return str
|
140
|
+
end
|
141
|
+
|
113
142
|
# def metrics
|
114
143
|
# {}
|
115
144
|
# end
|
@@ -154,6 +183,5 @@ module TabTool
|
|
154
183
|
# @logger.close unless @logger.nil? || @logger.closed?
|
155
184
|
end
|
156
185
|
|
157
|
-
|
158
186
|
end # module TabTool
|
159
187
|
|
data/lib/twb/workbook.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
# Copyright (C) 2014, 2018 Chris Gerrard
|
3
2
|
#
|
4
3
|
# This program is free software: you can redistribute it and/or modify
|
@@ -25,11 +24,14 @@ module Twb
|
|
25
24
|
#
|
26
25
|
class Workbook < TabClass
|
27
26
|
|
28
|
-
attr_reader :workbooknode
|
29
|
-
attr_reader :name, :dir
|
27
|
+
attr_reader :workbooknode, :node
|
28
|
+
attr_reader :name, :dir, :type
|
30
29
|
attr_reader :modtime, :version, :build
|
30
|
+
#--
|
31
31
|
attr_reader :datasources, :datasource
|
32
32
|
attr_reader :datasourceNames, :datasourceUINames, :dataSourceNamesMap
|
33
|
+
attr_reader :orphanDataSources # i.e. not referenced in any Worksheet
|
34
|
+
#--
|
33
35
|
attr_reader :dashboards, :storyboards, :worksheets
|
34
36
|
attr_reader :parameters, :actions
|
35
37
|
attr_reader :valid, :ndoc
|
@@ -66,18 +68,21 @@ module Twb
|
|
66
68
|
Zip::File.open(twbxWithDir) do |zip_file|
|
67
69
|
twb = zip_file.glob('*.twb').first
|
68
70
|
@ndoc = Nokogiri::XML(twb.get_input_stream)
|
71
|
+
@type = :twbx
|
69
72
|
processDoc
|
70
73
|
end
|
71
74
|
end
|
72
75
|
|
73
76
|
def processTWB(twbFile)
|
74
|
-
@ndoc
|
77
|
+
@ndoc = Nokogiri::XML(open(twbFile))
|
78
|
+
@type = :twb
|
75
79
|
processDoc
|
76
80
|
end
|
77
81
|
|
78
82
|
def processDoc
|
79
|
-
@
|
80
|
-
@
|
83
|
+
@node = @ndoc.at_xpath('//workbook')
|
84
|
+
@workbooknode = @node
|
85
|
+
@version = @node.nil? ? nil : @node["version"]
|
81
86
|
loaddatasources
|
82
87
|
loadWorksheets
|
83
88
|
loadDashboards
|
@@ -204,6 +209,20 @@ module Twb
|
|
204
209
|
@dashboards[name]
|
205
210
|
end
|
206
211
|
|
212
|
+
def orphanDataSources
|
213
|
+
@orphanDataSources ||= identifyOrphandatasoUrceS
|
214
|
+
end
|
215
|
+
|
216
|
+
def identifyOrphandatasoUrceS
|
217
|
+
sheetDataSources = Set.new
|
218
|
+
@worksheets.values.each do |sheet|
|
219
|
+
sheet.datasources.each do |ds|
|
220
|
+
sheetDataSources << ds.uiname
|
221
|
+
end
|
222
|
+
end
|
223
|
+
@orphanDataSources = @datasourceUINames - sheetDataSources
|
224
|
+
end
|
225
|
+
|
207
226
|
def storyboards
|
208
227
|
@storyboards.values
|
209
228
|
end
|
@@ -283,12 +302,15 @@ module Twb
|
|
283
302
|
# Write the TWB to a file, with an optional name.
|
284
303
|
# Can be used to write over the existing TWB (dangerous), or to a new file (preferred).
|
285
304
|
def write(name=@name)
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
305
|
+
case @type
|
306
|
+
when :twb
|
307
|
+
writeTwb(name)
|
308
|
+
when :twbx
|
309
|
+
writeTwbx(name)
|
310
|
+
else
|
311
|
+
emit "Cannot write this Workbook - it has an invalid type: #{@type}"
|
312
|
+
raise "Cannot write this Workbook - it has an invalid type: #{@type}"
|
290
313
|
end
|
291
|
-
return name
|
292
314
|
end
|
293
315
|
|
294
316
|
# Write the TWB to a file, appending the base name with the provided string.
|
@@ -298,7 +320,22 @@ module Twb
|
|
298
320
|
write newName
|
299
321
|
end
|
300
322
|
|
301
|
-
private
|
323
|
+
private
|
324
|
+
|
325
|
+
def writeTwb(name=@name)
|
326
|
+
$f = File.open(name,'w')
|
327
|
+
if $f
|
328
|
+
$f.puts @ndoc
|
329
|
+
$f.close
|
330
|
+
end
|
331
|
+
return name
|
332
|
+
end
|
333
|
+
|
334
|
+
def writeTwbx(name=@name)
|
335
|
+
emit "Writing the Workbook, need implementation"
|
336
|
+
end
|
337
|
+
|
338
|
+
|
302
339
|
|
303
340
|
def loadParameters
|
304
341
|
@parameters = {}
|
data/lib/twb/worksheet.rb
CHANGED
@@ -24,16 +24,20 @@ module Twb
|
|
24
24
|
|
25
25
|
@@hasher = Digest::SHA256.new
|
26
26
|
|
27
|
+
@fieldEncodingsXPath = './table/panes/pane//encodings'
|
28
|
+
|
27
29
|
attr_reader :node, :name, :datasourcenames, :datasources
|
28
30
|
attr_reader :panesCount
|
29
|
-
attr_reader :fields, :rowFields, :colFields, :paneFields, :datasourceFields
|
31
|
+
attr_reader :fields, :rowFields, :colFields, :paneFields, :datasourceFields, :pageFields, :encodedFields
|
30
32
|
attr_reader :filters
|
33
|
+
attr_reader :tooltip
|
31
34
|
attr_reader :hidden, :visible
|
32
35
|
|
33
36
|
def initialize sheetNode, twb
|
34
37
|
@twb = twb
|
35
38
|
@node = sheetNode
|
36
|
-
@name = @node
|
39
|
+
@name = @node['name']
|
40
|
+
emit "########################## Worksheet initialize name: #{@name}"
|
37
41
|
loadDataSourceNames
|
38
42
|
loadFields
|
39
43
|
return self
|
@@ -77,6 +81,10 @@ module Twb
|
|
77
81
|
@filters ||= loadFilters
|
78
82
|
end
|
79
83
|
|
84
|
+
def tooltip
|
85
|
+
@tooltip ||= loadTooltip
|
86
|
+
end
|
87
|
+
|
80
88
|
def hidden
|
81
89
|
@hidden ||= resolveHidden
|
82
90
|
end
|
@@ -105,8 +113,39 @@ module Twb
|
|
105
113
|
@fields[:rows] = @rowFields
|
106
114
|
@colFields ||= loadRowColFields(:cols) # returns map of data source => (Set of) field names
|
107
115
|
@fields[:cols] = @colFields
|
116
|
+
loadFieldEncodings
|
117
|
+
end
|
118
|
+
|
119
|
+
def loadFieldEncodings
|
120
|
+
@encodedFields = Hash.new { |h,k| h[k] = [] }
|
121
|
+
enodes = node.xpath('.//table/panes/pane/encodings')
|
122
|
+
enodes.each do |enode|
|
123
|
+
enode.children.each do |child|
|
124
|
+
unless child['column'].nil?
|
125
|
+
@encodedFields[child.name] << CodedField.new(child['column'])
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
@encodedFields.each do |type, fields|
|
130
|
+
@fields[type] = fields
|
131
|
+
end
|
108
132
|
end
|
109
133
|
|
134
|
+
# def loadFieldEncodings node
|
135
|
+
# $encodedFields = Hash.new { |h,k| h[k] = [] }
|
136
|
+
# enodes = node.xpath('.//table/panes/pane/encodings')
|
137
|
+
# enodes.each do |enode|
|
138
|
+
# enode.children.each do |child|
|
139
|
+
# unless child['column'].nil?
|
140
|
+
# $encodedFields[child.name] << CodedField.new(child['column'])
|
141
|
+
# end
|
142
|
+
# end
|
143
|
+
# end
|
144
|
+
# $encodedFields.each do |type, fields|
|
145
|
+
# $fields[type] = fields
|
146
|
+
# end
|
147
|
+
# end
|
148
|
+
|
110
149
|
def addDSFields fields, usage
|
111
150
|
fields.each do
|
112
151
|
end
|
@@ -119,12 +158,16 @@ module Twb
|
|
119
158
|
def loadRowColFields(type)
|
120
159
|
fields = []
|
121
160
|
xpath = case type
|
122
|
-
when :rows then '
|
123
|
-
when :cols then '
|
161
|
+
when :rows then './table/rows'
|
162
|
+
when :cols then './table/cols'
|
124
163
|
end
|
125
164
|
return fields if xpath.nil?
|
126
165
|
node = @node.at_xpath(xpath)
|
127
|
-
|
166
|
+
emit "def loadRowColFields:: type: #{type} \t node: #{node.class} \t path: #{node.nil? ? '<<nil>>' : node.path }"
|
167
|
+
emit "node : #{node.inspect}"
|
168
|
+
nodeFields = RowsColsSplitter.new(node).fields
|
169
|
+
emit "nodeFields: #{nodeFields}"
|
170
|
+
nodeFields.each do |fcode|
|
128
171
|
fields << CodedField.new(fcode)
|
129
172
|
end
|
130
173
|
return fields
|
@@ -139,18 +182,32 @@ module Twb
|
|
139
182
|
panes = @node.xpath('.//pane')
|
140
183
|
end
|
141
184
|
|
185
|
+
def pageFields
|
186
|
+
@pageFields ||= loadpageFields
|
187
|
+
end
|
188
|
+
|
189
|
+
def loadpageFields
|
190
|
+
@pageFields = [] # { |h,k| h[k] = [] }
|
191
|
+
nodes = node.xpath('.//table/pages/column')
|
192
|
+
nodes.each do |node|
|
193
|
+
@pageFields << CodedField.new(node.text)
|
194
|
+
end
|
195
|
+
return @pageFields
|
196
|
+
end
|
197
|
+
|
142
198
|
def datasourcenames
|
143
199
|
@datasources.keys
|
144
200
|
end
|
145
201
|
|
146
202
|
def resolveHidden
|
147
|
-
windowNode = node.at_xpath("//windows/window[@name
|
203
|
+
windowNode = node.at_xpath("//windows/window[@name=\"#{@name}\"]")
|
148
204
|
@hidden = !windowNode.nil? && 'true' == windowNode['hidden']
|
149
205
|
end
|
150
206
|
|
151
207
|
private
|
152
208
|
|
153
209
|
def loadFilters
|
210
|
+
emit ""########################## loadFilters"
|
154
211
|
@filters = []
|
155
212
|
filterNodes = @node.xpath('./table/view//filter[@column]')
|
156
213
|
filterNodes.each do |fnode|
|
@@ -159,6 +216,10 @@ module Twb
|
|
159
216
|
end
|
160
217
|
return @filters
|
161
218
|
end
|
219
|
+
|
220
|
+
def loadTooltip
|
221
|
+
@tooltip = @node.xpath('./table/panes/pane/customized-tooltip')
|
222
|
+
end
|
162
223
|
|
163
224
|
end # class Worksheet
|
164
225
|
|
@@ -201,7 +262,9 @@ module Twb
|
|
201
262
|
return fields if node.nil?
|
202
263
|
unless node.text.nil?
|
203
264
|
codes = node.text.split(/[\])] [\/+*] [(]?\[/)
|
204
|
-
codes.each
|
265
|
+
codes.each do |c|
|
266
|
+
@fields << c.gsub(/^[(]*[\[]*|[)\]]*$/,'')
|
267
|
+
end
|
205
268
|
end
|
206
269
|
end
|
207
270
|
end # class RowsColsSplitter
|