twb 3.9.7 → 4.3.1
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.
- 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
|