twb 4.5.5 → 4.5.7
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/analysis/calculatedfields/calculatedfieldsanalyzer.rb +42 -0
- data/lib/twb/analysis/{CalculatedFields → calculatedfields}/csvemitter.rb +0 -0
- data/lib/twb/analysis/{CalculatedFields → calculatedfields}/groupfieldsanalyzer.rb +0 -0
- data/lib/twb/analysis/{CalculatedFields → calculatedfields}/markdownemitter.rb +0 -0
- data/lib/twb/analysis/{DataSources → datasources}/categoricalcolorcodinganalyzer.rb +0 -0
- data/lib/twb/analysis/{DataSources → datasources}/datasourcefieldscsvemitter.rb +0 -0
- data/lib/twb/analysis/{DataSources → datasources}/datasourceoriginsanalyzer.rb +0 -0
- data/lib/twb/analysis/{DataSources/dataSourcesLocationsAnalyzer.rb → datasources/datasourceslocationsanalyzer.rb} +0 -0
- data/lib/twb/analysis/{DataSources → datasources}/datasourcetablefieldscsvemitter.rb +0 -0
- data/lib/twb/analysis/{DataSources → datasources}/googlesheetdatasourcesanalyzer.rb +0 -0
- data/lib/twb/analysis/{DataSources → datasources}/parametersanalyzer.rb +0 -0
- data/lib/twb/analysis/{DocumentedFieldsCSVEmitter.rb → documentedfieldscsvemitter.rb} +0 -0
- data/lib/twb/analysis/{Sheets/analyzeDashboardSheets.rb → sheets/analyzedashboardsheets.rb} +0 -0
- data/lib/twb/analysis/{Sheets → sheets}/dashsheetsanalyzer.rb +0 -0
- data/lib/twb/analysis/{Sheets → sheets}/sheetfieldsanalyzer.rb +0 -0
- data/lib/twb/analysis/{Sheets → sheets}/sheetfiltersanalyzer.rb +0 -0
- data/lib/twb/analysis/{Sheets/sheetfiltersanalyzerA.rb → sheets/sheetfiltersanalyzera.rb} +0 -0
- data/lib/twb/analysis/{Sheets → sheets}/sheetsourcesanalyzer.rb +0 -0
- data/lib/twb/analysis/{Sheets → sheets}/worksheetdatastructurecsvemitter.rb +0 -0
- data/lib/twb/{findDSFields.rb → finddsfields.rb} +0 -0
- data/lib/twb/{identifyFields.rb → identifyfields.rb} +0 -0
- data/lib/twb/tabtool.rb +12 -10
- data/lib/twb/{TwbTest.rb → twbtest.rb} +0 -0
- data/lib/twb/util/{ftpPublisher.rb → ftppublisher.rb} +0 -0
- data/lib/twb/util/{joinUtilities.rb → joinutilities.rb} +0 -0
- data/lib/twb/util/{twbDashesSheetDataDotBuilder.rb → twbdashessheetdatadotbuilder.rb} +0 -0
- data/lib/twb/util/{twbDashSheetDataDotRenderer.rb → twbdashsheetdatadotrenderer.rb} +0 -0
- data/lib/twb.rb +2 -3
- data/t.rb +18 -65
- metadata +27 -27
- data/lib/twb/analysis/CalculatedFields/calculatedfieldsanalyzer.rb +0 -524
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7eb9fb34a75d4869a2ba63a575e532e3fa0c0a9595e454d33574685bd0083ab6
|
4
|
+
data.tar.gz: ac54f86e1b09b352dcb6052010ba0486a26860aa74ea294ea8872475a05cd509
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1d3ee029ca7dc00e9bef48f80fa6b14e52a9ccf5877fa42ae1be1990f8140dc57a819eb84695b580f1564d6cd3e53b76d5a373ad0103feaec138147ac0844e7
|
7
|
+
data.tar.gz: 0037410ebe36ae0a2f77f671e7d33d004240b486a2999a8ce118c2876e6665e9d9bd267f14b2fe4bdaee981e1b435d808ff7f7af54cc4b71b2355d2ae03f6ec7
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# calculatedfieldsanalyzer.rb - this Ruby script Copyright 2017, 2018 Christopher Gerrard
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require 'twb'
|
17
|
+
|
18
|
+
module Twb
|
19
|
+
module Analysis
|
20
|
+
|
21
|
+
|
22
|
+
class CalculatedFieldsAnalyzer
|
23
|
+
|
24
|
+
include TabTool
|
25
|
+
|
26
|
+
def initialize(**args)
|
27
|
+
end
|
28
|
+
|
29
|
+
def processTWB workbook
|
30
|
+
end
|
31
|
+
|
32
|
+
def metrics
|
33
|
+
Array.new
|
34
|
+
end
|
35
|
+
|
36
|
+
#-- private methods begin here, to end of class
|
37
|
+
|
38
|
+
|
39
|
+
end # class
|
40
|
+
|
41
|
+
end # module Analysis
|
42
|
+
end # module Twb
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/twb/tabtool.rb
CHANGED
@@ -112,7 +112,7 @@ module TabTool
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def docfiles
|
115
|
-
@docfiles ||= @docfiles =
|
115
|
+
@docfiles ||= @docfiles = {}
|
116
116
|
end
|
117
117
|
|
118
118
|
def addDocFile file, name, description
|
@@ -121,15 +121,17 @@ module TabTool
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def closeDocFiles
|
124
|
-
emit
|
125
|
-
@docfiles.
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
124
|
+
emit "Closing doc files"
|
125
|
+
unless @docfiles.nil?
|
126
|
+
@docfiles.each do |dfh|
|
127
|
+
docfile = dfh[:file]
|
128
|
+
fileName = dfh[:name]
|
129
|
+
emit " -- #{dfh}"
|
130
|
+
# system "ls -l '#{fileName}'"
|
131
|
+
docfile.close unless docfile.nil?
|
132
|
+
# system "ls -l '#{fileName}'"
|
133
|
+
# emit true, " -- #{dfh[:name]}"
|
134
|
+
end
|
133
135
|
end
|
134
136
|
emit "-----------------"
|
135
137
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/twb.rb
CHANGED
@@ -52,6 +52,7 @@ require_relative 'twb/util/docprep'
|
|
52
52
|
require_relative 'twb/analysis/documentedfieldsmarkdownemitter'
|
53
53
|
require_relative 'twb/analysis/annotatedfieldscsvemitter'
|
54
54
|
require_relative 'twb/analysis/workbooksummaryanalyzer'
|
55
|
+
require_relative 'twb/analysis/calculatedfields/calculatedfieldsanalyzer'
|
55
56
|
require_relative 'twb/analysis/calculatedfields/groupfieldsanalyzer'
|
56
57
|
require_relative 'twb/analysis/calculatedfields/markdownemitter'
|
57
58
|
require_relative 'twb/analysis/calculatedfields/csvemitter'
|
@@ -66,11 +67,9 @@ require_relative 'twb/analysis/sheets/sheetfiltersanalyzer'
|
|
66
67
|
require_relative 'twb/analysis/sheets/sheetfieldsanalyzer'
|
67
68
|
require_relative 'twb/analysis/sheets/dashsheetsanalyzer'
|
68
69
|
|
69
|
-
# require_relative 'twb/analysis/calculatedfields/calculatedfieldsanalyzer'
|
70
|
-
|
71
70
|
|
72
71
|
# Represents Tableau Workbooks, their contents, and classes that analyze and manipulate them.
|
73
72
|
#
|
74
73
|
module Twb
|
75
|
-
VERSION = '4.5.
|
74
|
+
VERSION = '4.5.7'
|
76
75
|
end
|
data/t.rb
CHANGED
@@ -1,71 +1,24 @@
|
|
1
|
+
system 'cls'
|
2
|
+
|
1
3
|
def checkfile fileName
|
2
|
-
|
3
|
-
qfn = "./lib/#{fileName}.rb"
|
4
|
-
exists = File.exists? qfn
|
4
|
+
exists = File.exists? fileName
|
5
5
|
hasCap = !!(fileName =~ /[A-Z]/)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
isTest = !!(fileName =~ /test/i)
|
7
|
+
if hasCap && !isTest
|
8
|
+
fn_tmp = "#{fileName}.tmp"
|
9
|
+
fn_lc = fileName.downcase
|
10
|
+
puts "-- #{fileName}"
|
11
|
+
puts " %-6s t? %-6s %-7s %-s " % [' ' , isTest, ' ' , fileName]
|
12
|
+
puts " %-6s %-6s %-7s %-s " % [exists, ' ', hasCap, fileName]
|
13
|
+
puts " %-6s %-6s %-7s %-s " % [exists, ' ', hasCap, fn_tmp]
|
14
|
+
puts " %-6s %-6s %-7s %-s " % ['-' , '-', '-' , fn_lc]
|
15
|
+
# File.rename fileName, fn_tmp
|
16
|
+
# File.rename fn_tmp, fn_lc
|
17
|
+
puts " "
|
18
|
+
end
|
15
19
|
end
|
16
20
|
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
checkfile 'twb/dashboard'
|
21
|
-
checkfile 'twb/datasource'
|
22
|
-
checkfile 'twb/connection'
|
23
|
-
checkfile 'twb/docdashboard'
|
24
|
-
checkfile 'twb/dbfield'
|
25
|
-
checkfile 'twb/localfield'
|
26
|
-
checkfile 'twb/metadatafield'
|
27
|
-
checkfile 'twb/storyboard'
|
28
|
-
checkfile 'twb/window'
|
29
|
-
checkfile 'twb/workbook'
|
30
|
-
checkfile 'twb/worksheet'
|
31
|
-
checkfile 'twb/parameter'
|
32
|
-
checkfile 'twb/action'
|
33
|
-
checkfile 'twb/columnfield'
|
34
|
-
checkfile 'twb/calculatedfield'
|
35
|
-
checkfile 'twb/codedfield'
|
36
|
-
checkfile 'twb/groupfield'
|
37
|
-
checkfile 'twb/fieldcalculation'
|
38
|
-
checkfile 'twb/quickfilter'
|
39
|
-
checkfile 'twb/docdashboardimagevert'
|
40
|
-
checkfile 'twb/docdashboardwebvert'
|
41
|
-
checkfile 'twb/util/twbDashSheetDataDotBuilder'
|
42
|
-
checkfile 'twb/util/dotFileRenderer'
|
43
|
-
checkfile 'twb/util/htmllistcollapsible'
|
44
|
-
checkfile 'twb/util/xraydashboards'
|
45
|
-
checkfile 'twb/util/graph'
|
46
|
-
checkfile 'twb/util/graphnode'
|
47
|
-
checkfile 'twb/util/graphedge'
|
48
|
-
checkfile 'twb/util/graphedges'
|
49
|
-
checkfile 'twb/util/gml'
|
50
|
-
checkfile 'twb/util/cypher'
|
51
|
-
checkfile 'twb/util/cypherpython'
|
52
|
-
checkfile 'twb/util/fielddomainloader'
|
53
|
-
checkfile 'twb/util/docprep'
|
54
|
-
checkfile 'twb/analysis/documentedfieldsmarkdownemitter'
|
55
|
-
checkfile 'twb/analysis/annotatedfieldscsvemitter'
|
56
|
-
checkfile 'twb/analysis/WorkbookSummaryAnalyzer'
|
57
|
-
checkfile 'twb/analysis/calculatedfields/calculatedfieldsanalyzer'
|
58
|
-
checkfile 'twb/analysis/calculatedfields/groupfieldsanalyzer'
|
59
|
-
checkfile 'twb/analysis/calculatedfields/markdownemitter'
|
60
|
-
checkfile 'twb/analysis/calculatedfields/csvemitter'
|
61
|
-
checkfile 'twb/analysis/datasources/DataSourceFieldsCSVEmitter'
|
62
|
-
checkfile 'twb/analysis/datasources/DataSourceTableFieldsCSVEmitter'
|
63
|
-
checkfile 'twb/analysis/datasources/categoricalColorCodingAnalyzer'
|
64
|
-
checkfile 'twb/analysis/datasources/googlesheetdatasourcesanalyzer'
|
65
|
-
checkfile 'twb/analysis/datasources/parametersanalyzer'
|
66
|
-
checkfile 'twb/analysis/datasources/DataSourceOriginsAnalyzer'
|
67
|
-
checkfile 'twb/analysis/Sheets/WorksheetDataStructureCSVEmitter'
|
68
|
-
checkfile 'twb/analysis/Sheets/sheetfiltersanalyzer'
|
69
|
-
checkfile 'twb/analysis/Sheets/sheetfieldsanalyzer'
|
70
|
-
checkfile 'twb/analysis/Sheets/dashsheetsanalyzer'
|
22
|
+
Dir.glob('**/*.rb') { |file| puts file if file =~ /[A-Z]/ }
|
23
|
+
|
71
24
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.5.
|
4
|
+
version: 4.5.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Gerrard
|
@@ -59,29 +59,28 @@ extra_rdoc_files: []
|
|
59
59
|
files:
|
60
60
|
- lib/t.rb
|
61
61
|
- lib/twb.rb
|
62
|
-
- lib/twb/TwbTest.rb
|
63
62
|
- lib/twb/action.rb
|
64
|
-
- lib/twb/analysis/CalculatedFields/calculatedfieldsanalyzer.rb
|
65
|
-
- lib/twb/analysis/CalculatedFields/csvemitter.rb
|
66
|
-
- lib/twb/analysis/CalculatedFields/groupfieldsanalyzer.rb
|
67
|
-
- lib/twb/analysis/CalculatedFields/markdownemitter.rb
|
68
|
-
- lib/twb/analysis/DataSources/categoricalcolorcodinganalyzer.rb
|
69
|
-
- lib/twb/analysis/DataSources/dataSourcesLocationsAnalyzer.rb
|
70
|
-
- lib/twb/analysis/DataSources/datasourcefieldscsvemitter.rb
|
71
|
-
- lib/twb/analysis/DataSources/datasourceoriginsanalyzer.rb
|
72
|
-
- lib/twb/analysis/DataSources/datasourcetablefieldscsvemitter.rb
|
73
|
-
- lib/twb/analysis/DataSources/googlesheetdatasourcesanalyzer.rb
|
74
|
-
- lib/twb/analysis/DataSources/parametersanalyzer.rb
|
75
|
-
- lib/twb/analysis/DocumentedFieldsCSVEmitter.rb
|
76
|
-
- lib/twb/analysis/Sheets/analyzeDashboardSheets.rb
|
77
|
-
- lib/twb/analysis/Sheets/dashsheetsanalyzer.rb
|
78
|
-
- lib/twb/analysis/Sheets/sheetfieldsanalyzer.rb
|
79
|
-
- lib/twb/analysis/Sheets/sheetfiltersanalyzer.rb
|
80
|
-
- lib/twb/analysis/Sheets/sheetfiltersanalyzerA.rb
|
81
|
-
- lib/twb/analysis/Sheets/sheetsourcesanalyzer.rb
|
82
|
-
- lib/twb/analysis/Sheets/worksheetdatastructurecsvemitter.rb
|
83
63
|
- lib/twb/analysis/annotatedfieldscsvemitter.rb
|
64
|
+
- lib/twb/analysis/calculatedfields/calculatedfieldsanalyzer.rb
|
65
|
+
- lib/twb/analysis/calculatedfields/csvemitter.rb
|
66
|
+
- lib/twb/analysis/calculatedfields/groupfieldsanalyzer.rb
|
67
|
+
- lib/twb/analysis/calculatedfields/markdownemitter.rb
|
68
|
+
- lib/twb/analysis/datasources/categoricalcolorcodinganalyzer.rb
|
69
|
+
- lib/twb/analysis/datasources/datasourcefieldscsvemitter.rb
|
70
|
+
- lib/twb/analysis/datasources/datasourceoriginsanalyzer.rb
|
71
|
+
- lib/twb/analysis/datasources/datasourceslocationsanalyzer.rb
|
72
|
+
- lib/twb/analysis/datasources/datasourcetablefieldscsvemitter.rb
|
73
|
+
- lib/twb/analysis/datasources/googlesheetdatasourcesanalyzer.rb
|
74
|
+
- lib/twb/analysis/datasources/parametersanalyzer.rb
|
75
|
+
- lib/twb/analysis/documentedfieldscsvemitter.rb
|
84
76
|
- lib/twb/analysis/documentedfieldsmarkdownemitter.rb
|
77
|
+
- lib/twb/analysis/sheets/analyzedashboardsheets.rb
|
78
|
+
- lib/twb/analysis/sheets/dashsheetsanalyzer.rb
|
79
|
+
- lib/twb/analysis/sheets/sheetfieldsanalyzer.rb
|
80
|
+
- lib/twb/analysis/sheets/sheetfiltersanalyzer.rb
|
81
|
+
- lib/twb/analysis/sheets/sheetfiltersanalyzera.rb
|
82
|
+
- lib/twb/analysis/sheets/sheetsourcesanalyzer.rb
|
83
|
+
- lib/twb/analysis/sheets/worksheetdatastructurecsvemitter.rb
|
85
84
|
- lib/twb/analysis/workbooksummaryanalyzer.rb
|
86
85
|
- lib/twb/calculatedfield.rb
|
87
86
|
- lib/twb/codedfield.rb
|
@@ -95,14 +94,14 @@ files:
|
|
95
94
|
- lib/twb/docdashboardwebvert.rb
|
96
95
|
- lib/twb/field.rb
|
97
96
|
- lib/twb/fieldcalculation.rb
|
98
|
-
- lib/twb/
|
97
|
+
- lib/twb/finddsfields.rb
|
99
98
|
- lib/twb/graph.rb
|
100
99
|
- lib/twb/graphedges.rb
|
101
100
|
- lib/twb/graphnode.rb
|
102
101
|
- lib/twb/groupfield.rb
|
103
102
|
- lib/twb/hashtohtml.rb
|
104
103
|
- lib/twb/htmllistcollapsible.rb
|
105
|
-
- lib/twb/
|
104
|
+
- lib/twb/identifyfields.rb
|
106
105
|
- lib/twb/localfield.rb
|
107
106
|
- lib/twb/mappedfield.rb
|
108
107
|
- lib/twb/metadatafield.rb
|
@@ -114,12 +113,13 @@ files:
|
|
114
113
|
- lib/twb/tabtool.rb
|
115
114
|
- lib/twb/there.rb
|
116
115
|
- lib/twb/twbcodedfield.rb
|
116
|
+
- lib/twb/twbtest.rb
|
117
117
|
- lib/twb/util/cypher.rb
|
118
118
|
- lib/twb/util/cypherpython.rb
|
119
119
|
- lib/twb/util/docprep.rb
|
120
120
|
- lib/twb/util/dotfilerenderer.rb
|
121
121
|
- lib/twb/util/fielddomainloader.rb
|
122
|
-
- lib/twb/util/
|
122
|
+
- lib/twb/util/ftppublisher.rb
|
123
123
|
- lib/twb/util/gml.rb
|
124
124
|
- lib/twb/util/gmledge.rb
|
125
125
|
- lib/twb/util/graph.rb
|
@@ -128,11 +128,11 @@ files:
|
|
128
128
|
- lib/twb/util/graphnode.rb
|
129
129
|
- lib/twb/util/hashtohtml.rb
|
130
130
|
- lib/twb/util/htmllistcollapsible.rb
|
131
|
-
- lib/twb/util/
|
131
|
+
- lib/twb/util/joinutilities.rb
|
132
132
|
- lib/twb/util/tabgraph.rb
|
133
|
-
- lib/twb/util/
|
134
|
-
- lib/twb/util/twbDashesSheetDataDotBuilder.rb
|
133
|
+
- lib/twb/util/twbdashessheetdatadotbuilder.rb
|
135
134
|
- lib/twb/util/twbdashsheetdatadotbuilder.rb
|
135
|
+
- lib/twb/util/twbdashsheetdatadotrenderer.rb
|
136
136
|
- lib/twb/util/xraydashboards.rb
|
137
137
|
- lib/twb/window.rb
|
138
138
|
- lib/twb/workbook.rb
|
@@ -1,524 +0,0 @@
|
|
1
|
-
# calculatedfieldsanalyzer.rb - this Ruby script Copyright 2017, 2018 Christopher Gerrard
|
2
|
-
#
|
3
|
-
# This program is free software: you can redistribute it and/or modify
|
4
|
-
# it under the terms of the GNU General Public License as published by
|
5
|
-
# the Free Software Foundation, either version 3 of the License, or
|
6
|
-
# (at your option) any later version.
|
7
|
-
#
|
8
|
-
# This program is distributed in the hope that it will be useful,
|
9
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
-
# GNU General Public License for more details.
|
12
|
-
#
|
13
|
-
# You should have received a copy of the GNU General Public License
|
14
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
-
|
16
|
-
# require 'nokogiri'
|
17
|
-
# require 'twb'
|
18
|
-
# require 'set'
|
19
|
-
require 'csv'
|
20
|
-
|
21
|
-
module Twb
|
22
|
-
module Analysis
|
23
|
-
|
24
|
-
class CalculatedFieldsAnalyzer
|
25
|
-
|
26
|
-
include TabTool
|
27
|
-
include Graph
|
28
|
-
|
29
|
-
attr_reader :calculatedFieldsCount, :referencedFieldsCount, :metrics
|
30
|
-
attr_accessor :ttdocdir
|
31
|
-
|
32
|
-
@@ttlogfile = 'CalculatedFieldsAnalyzer.ttlog'
|
33
|
-
@@gvDotLocation = 'C:\\tech\\graphviz\\Graphviz2.38\\bin\\dot.exe'
|
34
|
-
@@processName = '.CalculatedFields'
|
35
|
-
|
36
|
-
@@calcFieldsCSVFileName = 'CalculatedFields.csv'
|
37
|
-
@@calcFieldsCSVFileHeader = ['Record #',
|
38
|
-
'Workbook',
|
39
|
-
'Workbook Modified',
|
40
|
-
'Data Source', 'Data Source Caption', 'Data Source Name (tech)',
|
41
|
-
'Field Name', 'Field Caption', 'Field Name (tech)',
|
42
|
-
'Data Source + Field Name (tech)',
|
43
|
-
'Data Type', 'Role', 'Type',
|
44
|
-
'Class',
|
45
|
-
'Scope Isolation',
|
46
|
-
'Formula Length',
|
47
|
-
'Formula',
|
48
|
-
'Formula (tech)',
|
49
|
-
'Formula Comments',
|
50
|
-
'Formula LOD?'
|
51
|
-
]
|
52
|
-
|
53
|
-
@@calcLinesCSVFileName = 'CalculatedFieldsFormulaLines.csv'
|
54
|
-
@@calcLinesCSVFileHeader = ['Record #',
|
55
|
-
'Workbook',
|
56
|
-
'Workbook Modified',
|
57
|
-
'Data Source', 'Data Source Caption', 'Data Source Name (tech)',
|
58
|
-
'Field Name', 'Field Caption', 'Field Name (tech)',
|
59
|
-
'Formula', 'Formula Line #', 'Formula Line'
|
60
|
-
]
|
61
|
-
|
62
|
-
@@formFieldsCSVFileName = 'CalculatedFieldsReferenced.csv'
|
63
|
-
@@formFieldsCSVFileHeader = ['Record #',
|
64
|
-
'Workbook',
|
65
|
-
'Workbook Modified',
|
66
|
-
'Data Source',
|
67
|
-
'Field - Calculated',
|
68
|
-
'Formula (tech)',
|
69
|
-
'Formula',
|
70
|
-
'Field - Referenced (tech)',
|
71
|
-
'Field - Referenced',
|
72
|
-
'Data Source + Field - Referenced',
|
73
|
-
'Table'
|
74
|
-
]
|
75
|
-
|
76
|
-
@techUINames = {}
|
77
|
-
@fieldTables = {}
|
78
|
-
|
79
|
-
|
80
|
-
@@dotHeader = <<DOTHEADER
|
81
|
-
digraph g {
|
82
|
-
graph [rankdir="LR" splines=line];
|
83
|
-
node [shape="box" width="2"];
|
84
|
-
|
85
|
-
DOTHEADER
|
86
|
-
|
87
|
-
def initialize(**args)
|
88
|
-
@args = args
|
89
|
-
@recordDir = !@args.nil? && @args[:recordDir] == true
|
90
|
-
@ttdocdir = @args[:ttdocdir]
|
91
|
-
@csvAdd = @args[:csvMode] == :add
|
92
|
-
@csvMode = @csvAdd ? 'a' : 'w'
|
93
|
-
init
|
94
|
-
@funcdoc = {:class=>self.class, :blurb=>'Analyze Calculated Fields', :description=>'Calculated fields can be complex, this tool provides robust coverage.',}
|
95
|
-
#-- CSV records collectors
|
96
|
-
@csvCalculatedFields = Array.new
|
97
|
-
@csvFormulaFields = Array.new
|
98
|
-
@csvFormulaLines = Array.new
|
99
|
-
#-- Counters setup --
|
100
|
-
@twbCount = 0
|
101
|
-
@dataSourcesCount = 0
|
102
|
-
@calculatedFieldsCount = 0
|
103
|
-
@referencedFieldsCount = 0
|
104
|
-
#--
|
105
|
-
@referencedFields = SortedSet.new
|
106
|
-
#--
|
107
|
-
twbdirLabel = @recordDir.nil? ? nil : 'Workbook Dir'
|
108
|
-
@csvCF = initCSV(@@calcFieldsCSVFileName, 'Calculated fields and their formulas.', @@calcFieldsCSVFileHeader )
|
109
|
-
@csvCFLs = initCSV(@@calcLinesCSVFileName, "Calculated fields and their formulas' individual lines.", @@calcLinesCSVFileHeader )
|
110
|
-
@csvFF = initCSV(@@formFieldsCSVFileName, 'Calculated fields and the fields their formulas reference.', @@formFieldsCSVFileHeader )
|
111
|
-
# TODO migrate addition of 'Workbook Dir' to CSV header to TabTool
|
112
|
-
#--
|
113
|
-
@localEmit = false
|
114
|
-
@imageFiles = Array.new
|
115
|
-
#--
|
116
|
-
@doGraph = config(:dograph)
|
117
|
-
end
|
118
|
-
|
119
|
-
def processTWB workbook
|
120
|
-
@twb = workbook.is_a?(String) ? Twb::Workbook.new(workbook) : workbook
|
121
|
-
throw Exception unless @twb.is_a? Twb::Workbook
|
122
|
-
emit "- Workbook: #{workbook}"
|
123
|
-
emit " version: #{@twb.version}"
|
124
|
-
@twbDir = @twb.dir #File.dirname(File.expand_path(workbook))
|
125
|
-
@modTime = @twb.modtime
|
126
|
-
@edges = Set.new
|
127
|
-
#-- processing
|
128
|
-
dss = @twb.datasources
|
129
|
-
# puts " # data sources: #{dss.length}"
|
130
|
-
@twbRootFields = Set.new
|
131
|
-
@twbFields = Hash.new { |h,k| h[k] = [] }
|
132
|
-
@nodes = Set.new
|
133
|
-
dss.each do |ds|
|
134
|
-
@dataSourcesCount += 1
|
135
|
-
# puts "\t\t - #{ds.uiname} \t\t #{ds.calculatedFields.length}"
|
136
|
-
next if ds.Parameters? # don't process the Parameters data source - Parameters' fields aren't Calculated fields for our purposes
|
137
|
-
# dataSourceNode = Twb::Util::Graphnode.new(name: ds.uiname, id: ds.id, type: ds, properties: {workbook: workbook})
|
138
|
-
# @nodes.add dataSourceNode
|
139
|
-
# ds.calculatedFields.each do |calcField|
|
140
|
-
# end
|
141
|
-
processDataSource ds
|
142
|
-
end
|
143
|
-
mapTwb
|
144
|
-
emitGml
|
145
|
-
@twbCount += 1
|
146
|
-
finis
|
147
|
-
end
|
148
|
-
|
149
|
-
def metrics
|
150
|
-
@metrics ||= loadMetrics
|
151
|
-
end
|
152
|
-
|
153
|
-
def loadMetrics
|
154
|
-
@metrics = {
|
155
|
-
'# of Workbooks' => @twbCount,
|
156
|
-
'# of Data Sources' => @dataSourcesCount,
|
157
|
-
'# of Calculated Fields' => @calculatedFieldsCount,
|
158
|
-
'# of Referenced Fields' => @referencedFieldsCount,
|
159
|
-
}
|
160
|
-
end
|
161
|
-
|
162
|
-
#-- private methods begin here, to end of class
|
163
|
-
|
164
|
-
private
|
165
|
-
|
166
|
-
def emitGml
|
167
|
-
gml = Twb::Util::GML.new
|
168
|
-
gml.fileName = @twb.name
|
169
|
-
gml.nodes = @nodes
|
170
|
-
gml.edges = @edges
|
171
|
-
gml.render
|
172
|
-
end
|
173
|
-
|
174
|
-
def processDataSource ds
|
175
|
-
emit "======= DATA SOURCE: #{ds.uiname} ====== "
|
176
|
-
dsNodes = Set.new
|
177
|
-
dsEdges = Set.new
|
178
|
-
dsFields = {}
|
179
|
-
@twbFields[ds.uiname] = dsFields
|
180
|
-
calculatedFields = SortedSet.new
|
181
|
-
fieldFormulaLines = Array.new
|
182
|
-
referencedFields = SortedSet.new
|
183
|
-
# if @doGraph
|
184
|
-
dataSourceNode = Twb::Util::Graphnode.new(name: ds.uiname, id: ds.id, type: ds, properties: {workbook: @twb.name})
|
185
|
-
@nodes.add dataSourceNode
|
186
|
-
# end
|
187
|
-
#-- process Calculatred Fields
|
188
|
-
ds.calculatedFields.each do |calcField|
|
189
|
-
emit "Calculated Field: #{calcField}"
|
190
|
-
calculatedFields.add calcField.id
|
191
|
-
dsFields[calcField.uiname] = calcField
|
192
|
-
# if @doGraph
|
193
|
-
calcFieldNode = Twb::Util::Graphnode.new(name: calcField.uiname, id: calcField.id, type: calcField, properties: {:DataSource => ds.uiname})
|
194
|
-
@nodes.add calcFieldNode
|
195
|
-
dsFieldEdge = Twb::Util::Graphedge.new(from: dataSourceNode, to: calcFieldNode, relationship: 'contains')
|
196
|
-
@edges.add dsFieldEdge
|
197
|
-
# end
|
198
|
-
calculation = calcField.calculation
|
199
|
-
if calculation.has_formula
|
200
|
-
#-- collect field formulas as single lines
|
201
|
-
@csvCalculatedFields.push [
|
202
|
-
@calculatedFieldsCount += 1,
|
203
|
-
@twb.name,
|
204
|
-
@modTime,
|
205
|
-
ds.uiname,
|
206
|
-
ds.caption,
|
207
|
-
ds.name,
|
208
|
-
calcField.uiname,
|
209
|
-
calcField.caption,
|
210
|
-
calcField.name,
|
211
|
-
ds.name + '::' + calcField.name,
|
212
|
-
calcField.datatype,
|
213
|
-
calcField.role,
|
214
|
-
calcField.type,
|
215
|
-
calculation.class,
|
216
|
-
calculation.scopeIsolation,
|
217
|
-
calculation.formulaFlat.length,
|
218
|
-
calculation.formulaFlatResolved,
|
219
|
-
calculation.formulaFlat,
|
220
|
-
calculation.comments,
|
221
|
-
calculation.is_lod
|
222
|
-
]
|
223
|
-
#-- collect individual formula lines
|
224
|
-
flnum = 0
|
225
|
-
emit "@@ calcField.uiname: #{calcField.uiname}"
|
226
|
-
calculation.formulaResolvedLines.each do |fl|
|
227
|
-
emit "@@ resolved line:: => '#{fl}'"
|
228
|
-
fieldFormulaLines << [ @calculatedFieldsCount, # 'Calc Field #',
|
229
|
-
@twb.name, # 'Workbook',
|
230
|
-
@modTime,
|
231
|
-
ds.uiname, # 'Data Source',
|
232
|
-
ds.caption, # 'Data Source Caption',
|
233
|
-
ds.name, # 'Data Source Name (tech)',
|
234
|
-
calcField.uiname, # 'Field Name',
|
235
|
-
calcField.caption, # 'Field Caption',
|
236
|
-
calcField.name, # 'Field Name (tech)',
|
237
|
-
calcField.calculation.formulaFlatResolved, # 'Formula'
|
238
|
-
flnum += 1, # 'Formula Line #',
|
239
|
-
fl.start_with?(" ") ? "'#{fl}" : fl # 'Formula Line' - THIS IS A STUPID HACK NEEDED BECAUSE TABLEAU STRIPS LEADING BLANKS FROM CSV VALUES
|
240
|
-
]
|
241
|
-
end
|
242
|
-
#-- collect fields referenced in formula
|
243
|
-
emit "# Calculated Fields: #{calculation.calcFields.length}"
|
244
|
-
calculation.calcFields.each do |rf|
|
245
|
-
emit " referenced field ::'#{rf}'"
|
246
|
-
emit " referenced field.name ::'#{rf.name.nil?}' :: '#{rf.name}'"
|
247
|
-
emit " referenced field.uiname::'#{rf.uiname}'"
|
248
|
-
# if @doGraph
|
249
|
-
unless rf.uiname.nil?
|
250
|
-
properties = {'DataSource' => ds.uiname, 'DataSourceReference' => 'local', :source => rf}
|
251
|
-
refFieldNode = Twb::Util::Graphnode.new(name: rf.uiname, id: rf.id, type: rf.type, properties: properties)
|
252
|
-
@nodes.add refFieldNode
|
253
|
-
fieldFieldEdge = Twb::Util::Graphedge.new(from: calcFieldNode, to: refFieldNode, relationship: 'references')
|
254
|
-
@edges.add fieldFieldEdge
|
255
|
-
end
|
256
|
-
# end
|
257
|
-
referencedFields.add rf.id
|
258
|
-
refFieldTable = ds.fieldTable(rf.name)
|
259
|
-
emit "refFieldTable.nil? : #{refFieldTable.nil?}"
|
260
|
-
unless refFieldTable.nil?
|
261
|
-
tableID = refFieldTable + ':::' + ds.uiname
|
262
|
-
tableName = "||#{refFieldTable}||"
|
263
|
-
# if @doGraph
|
264
|
-
tableNode = Twb::Util::Graphnode.new(name: tableName, id: tableID, type: :DBTable, properties: properties)
|
265
|
-
@nodes.add tableNode
|
266
|
-
fieldFieldEdge = Twb::Util::Graphedge.new(from: refFieldNode, to: tableNode, relationship: 'is a field in')
|
267
|
-
@edges.add fieldFieldEdge
|
268
|
-
# end
|
269
|
-
# fldToDsNode = tableNode
|
270
|
-
end
|
271
|
-
@csvFormulaFields << [
|
272
|
-
@referencedFieldsCount += 1,
|
273
|
-
@twb.name,
|
274
|
-
@modTime,
|
275
|
-
ds.uiname,
|
276
|
-
calcField.uiname,
|
277
|
-
calculation.formulaFlat,
|
278
|
-
calculation.formulaFlatResolved,
|
279
|
-
rf.name,
|
280
|
-
rf.uiname,
|
281
|
-
rf.id,
|
282
|
-
refFieldTable
|
283
|
-
]
|
284
|
-
end # resolvedFields.each do
|
285
|
-
end # if calculation.has_formula
|
286
|
-
end # ds.calculatedFields.each
|
287
|
-
|
288
|
-
dsRootFields = calculatedFields - referencedFields
|
289
|
-
@referencedFields.merge referencedFields
|
290
|
-
@twbRootFields.merge dsRootFields
|
291
|
-
if @doGraph
|
292
|
-
cypher @twb.name
|
293
|
-
cypherPy @twb.name
|
294
|
-
end
|
295
|
-
emit "#######################"
|
296
|
-
#--
|
297
|
-
#-- record calculated fields
|
298
|
-
twbDirCSV = @recordDir.nil? ? nil : @twbDir
|
299
|
-
emit "@@ record calculated fields ds: #{ds.uiname}"
|
300
|
-
@csvCalculatedFields.each do |r|
|
301
|
-
@csvCF << r
|
302
|
-
end
|
303
|
-
#-- record individual formula lines
|
304
|
-
emit "@@ individual formula lines ds: #{ds.uiname}"
|
305
|
-
fieldFormulaLines.each do |ffl|
|
306
|
-
@csvCFLs << ffl
|
307
|
-
end
|
308
|
-
#-- record formula-referenced fields
|
309
|
-
emit "@@ formula-referenced fields ds: #{ds.uiname}"
|
310
|
-
@csvFormulaFields.each do |r|
|
311
|
-
@csvFF << r
|
312
|
-
end
|
313
|
-
#--
|
314
|
-
return @imageFiles
|
315
|
-
end # def processDataSource
|
316
|
-
|
317
|
-
def emitCalcfield calcField
|
318
|
-
emit "\t FIELD cap :: #{calcField.caption} "
|
319
|
-
emit "\t tname:: #{calcField.name}"
|
320
|
-
emit "\t uiname:: #{calcField.uiname}"
|
321
|
-
emit "\t formula:: #{calculation.formulaFlat}"
|
322
|
-
end
|
323
|
-
|
324
|
-
def mapTwb
|
325
|
-
twb = @twb.name
|
326
|
-
rootFields = @twbRootFields
|
327
|
-
dotStuff = initDot twb
|
328
|
-
dotFile = dotStuff[:file]
|
329
|
-
dotFileName = dotStuff[:name]
|
330
|
-
dotFile.puts "\n // subgraph cluster_1 {"
|
331
|
-
dotFile.puts " // color= grey;"
|
332
|
-
dotFile.puts ""
|
333
|
-
edgesAsStrings = SortedSet.new
|
334
|
-
# this two step process coalesces the edges into a unique set, avoiding duplicating the dot
|
335
|
-
# file entries, and can be shrunk when graph edges expose the bits necessary for management by Set
|
336
|
-
emit "\n========================\nLoading Edges\n========================\n From DC? Referenced? Edge \n %s %s %s" % ['--------', '-----------', '-'*45]
|
337
|
-
@edges.each do |e|
|
338
|
-
# don't want to emit edge which is from a Data Connection to a
|
339
|
-
# Calculated Field which is also referenced by another calculated field
|
340
|
-
isFromDC = e.from.type == :TwbDataConnection
|
341
|
-
isRefField = @referencedFields.include?(e.to.id)
|
342
|
-
edgesAsStrings.add(e.dot) unless isFromDC && isRefField
|
343
|
-
# emit " ES #{e.dot}"
|
344
|
-
# emit " ES from #{e.from}"
|
345
|
-
# emit " ES to #{e.to}"
|
346
|
-
end
|
347
|
-
emit "------------------------\n "
|
348
|
-
edgesAsStrings.each do |es|
|
349
|
-
dotFile.puts " #{es}"
|
350
|
-
end
|
351
|
-
emit "========================\n "
|
352
|
-
dotFile.puts ""
|
353
|
-
dotFile.puts " // }"
|
354
|
-
dotFile.puts "\n\n // 4 NODES --------------------------------------------------------------------"
|
355
|
-
@nodes.each do |n|
|
356
|
-
dotFile.puts n.dotLabel
|
357
|
-
end
|
358
|
-
dotFile.puts "\n\n // 5--------------------------------------------------------------------"
|
359
|
-
emitTypes( dotFile )
|
360
|
-
closeDot( dotFile, twb )
|
361
|
-
emit "Rendering DOT file - #{twb}"
|
362
|
-
renderDot(twb,dotFileName,'pdf')
|
363
|
-
renderDot(twb,dotFileName,'png')
|
364
|
-
renderDot(twb,dotFileName,'svg')
|
365
|
-
# emitEdges
|
366
|
-
end
|
367
|
-
|
368
|
-
def cypher twbName
|
369
|
-
if @doGraph
|
370
|
-
cypher = Twb::Util::Cypher.new
|
371
|
-
cypher.fileName = "#{twbName}.calcFields"
|
372
|
-
cypher.nodes = @nodes
|
373
|
-
cypher.edges = @edges
|
374
|
-
cypher.render
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
378
|
-
def cypherPy twbName
|
379
|
-
if @doGraph
|
380
|
-
cypher = Twb::Util::CypherPython.new
|
381
|
-
cypher.fileName = "#{twbName}.calcFields"
|
382
|
-
cypher.nodes = @nodes
|
383
|
-
cypher.edges = @edges
|
384
|
-
cypher.render
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
|
-
# def graphEdges twb
|
389
|
-
# # graphFile = File.new(twb + '.cypher', 'w')
|
390
|
-
# # # graphFile.puts "OKEY DOKE, graphing away"
|
391
|
-
# # cypherCode = Set.new
|
392
|
-
# # @edges.each do |edge|
|
393
|
-
# # cypherCode.add edge.from.cypherCreate
|
394
|
-
# # cypherCode.add edge.to.cypherCreate
|
395
|
-
# # cypherCode.add edge.cypherCreate
|
396
|
-
# # end
|
397
|
-
# # cypherCode.each do |cc|
|
398
|
-
# # graphFile.puts cc
|
399
|
-
# # end
|
400
|
-
# # graphFile.puts "\nreturn *"
|
401
|
-
# # graphFile.close unless graphFile.nil?
|
402
|
-
# # @imageFiles << File.basename(graphFile)
|
403
|
-
# end
|
404
|
-
|
405
|
-
def emitEdges
|
406
|
-
emit " %-15s %s" % ['type', 'Edge']
|
407
|
-
emit " %-15s %s" % ['-'*15, '-'*35]
|
408
|
-
@edges.each do |edge|
|
409
|
-
emit " %-15s %s" % [edge.from.type, edge.from]
|
410
|
-
emit " %-15s %s" % [edge.to.type, edge.to]
|
411
|
-
emit "\n "
|
412
|
-
end
|
413
|
-
end
|
414
|
-
|
415
|
-
def emitTypes dotFile
|
416
|
-
typedNodes = {}
|
417
|
-
dotFile.puts "\n\n // 2--------------------------------------------------------------------"
|
418
|
-
@edges.each do |edge|
|
419
|
-
emit " EDGE :: #{edge}"
|
420
|
-
loadNodeType typedNodes, edge.from
|
421
|
-
loadNodeType typedNodes, edge.to
|
422
|
-
end
|
423
|
-
typedNodes.each do |type, nodes|
|
424
|
-
# emit "+++++++++ typedNodes of '#{type}'' "
|
425
|
-
# nodes.each do |node|
|
426
|
-
# emit " -n- #{node}"
|
427
|
-
# end
|
428
|
-
rankSame(dotFile, type, nodes) unless type.eql? 'CalculatedField' # == :CalculatedField
|
429
|
-
end
|
430
|
-
# labelTypes dotFile, edges
|
431
|
-
end
|
432
|
-
|
433
|
-
def loadNodeType set, node
|
434
|
-
type = node.type
|
435
|
-
set[type] = Set.new unless set.include? type
|
436
|
-
set[type].add node
|
437
|
-
end
|
438
|
-
|
439
|
-
@@unrankedTypes = ['CalculationField']
|
440
|
-
def rankSame dotFile, type, nodes
|
441
|
-
return if @@unrankedTypes.include? type.to_s
|
442
|
-
@lines = SortedSet.new
|
443
|
-
nodes.each do |node|
|
444
|
-
@lines << node.id
|
445
|
-
end
|
446
|
-
dotFile.puts "\n // '#{type}' --------------------------------------------------------------------"
|
447
|
-
dotFile.puts "\n {rank=same "
|
448
|
-
@lines.each do |line|
|
449
|
-
dotFile.puts " \"#{line}\""
|
450
|
-
end
|
451
|
-
dotFile.puts " }"
|
452
|
-
end
|
453
|
-
|
454
|
-
def rankRootFields dotFile, dsRootFields
|
455
|
-
dotFile.puts "\n // Unreferenced (root) Calculated Fields -----------------------------------------"
|
456
|
-
dotFile.puts "\n {rank=same "
|
457
|
-
dsRootFields.each do |rf|
|
458
|
-
emit "ROOT FIELD: #{rf.class} :: #{rf}"
|
459
|
-
dotFile.puts " \"#{rf}\""
|
460
|
-
end
|
461
|
-
dotFile.puts " }"
|
462
|
-
end
|
463
|
-
|
464
|
-
def labelTypes dotFile
|
465
|
-
fromTos = Set.new
|
466
|
-
@edges.each do |edge|
|
467
|
-
# fromTos.add "\"Alien Data Source\" -> \"Alien Data Source\""
|
468
|
-
fromTos.add "\"#{edge.from.type}\""
|
469
|
-
fromTos.add "\"#{edge.to.type}\""
|
470
|
-
end
|
471
|
-
return if fromTos.empty?
|
472
|
-
dotFile.puts "\n // 3--------------------------------------------------------------------"
|
473
|
-
dotFile.puts ' subgraph cluster_0 {'
|
474
|
-
dotFile.puts ' color=white;'
|
475
|
-
dotFile.puts ' node [shape="box3d" style="filled" ];'
|
476
|
-
fromTos.each do |ft|
|
477
|
-
dotFile.puts " #{ft}"
|
478
|
-
end
|
479
|
-
dotFile.puts ' }'
|
480
|
-
end
|
481
|
-
|
482
|
-
def initDot twb
|
483
|
-
dotFileName = docFile("#{twb}#{@@processName}.dot")
|
484
|
-
dotFile = File.open(dotFileName,'w')
|
485
|
-
dotFile.puts @@dotHeader
|
486
|
-
return {:file => dotFile, :name => dotFileName}
|
487
|
-
end
|
488
|
-
|
489
|
-
def closeDot dotFile, twb
|
490
|
-
dotFile.puts ' '
|
491
|
-
dotFile.puts '// -------------------------------------------------------------'
|
492
|
-
dotFile.puts ' '
|
493
|
-
dotFile.puts ' subgraph cluster_1 {'
|
494
|
-
# dotFile.puts ' color=white;'
|
495
|
-
dotFile.puts ' style=invis;'
|
496
|
-
# dotFile.puts ' border=0;'
|
497
|
-
dotFile.puts ' node [border=blue];'
|
498
|
-
dotFile.puts ' '
|
499
|
-
dotFile.puts ' "" [style=invis]'
|
500
|
-
dotFile.puts " \"Tableau Tools\\nCalculated Fields Map\\nWorkbook '#{twb}'\\n#{Time.new.ctime}\" [penwidth=0]"
|
501
|
-
# dotFile.puts " \"Tableau Tools Workbook Calculated Fields Map\\n#{Time.new.ctime}\" -> \"\" [style=invis]"
|
502
|
-
dotFile.puts ' '
|
503
|
-
dotFile.puts ' }'
|
504
|
-
dotFile.puts ' '
|
505
|
-
dotFile.puts '}'
|
506
|
-
dotFile.close
|
507
|
-
end
|
508
|
-
|
509
|
-
|
510
|
-
def renderDot twb, dot, format
|
511
|
-
imageType = '-T' + format
|
512
|
-
imageFile = './ttdoc/' + twb + @@processName + 'Graph.' + format
|
513
|
-
imageParam = '-o"' + imageFile + '"'
|
514
|
-
emit "system #{@@gvDotLocation} #{imageType} #{imageParam} \"#{dot}\""
|
515
|
-
system "#{@@gvDotLocation} #{imageType} #{imageParam} \"#{dot}\""
|
516
|
-
emit " - #{imageFile}"
|
517
|
-
@imageFiles << imageFile
|
518
|
-
return imageFile
|
519
|
-
end
|
520
|
-
|
521
|
-
end # class
|
522
|
-
|
523
|
-
end # module Analysis
|
524
|
-
end # module Twb
|