Skip to content

Instantly share code, notes, and snippets.

@hedgehog
Created July 27, 2015 05:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hedgehog/94506446158864545348 to your computer and use it in GitHub Desktop.
Save hedgehog/94506446158864545348 to your computer and use it in GitHub Desktop.
Minimal reproducible example: Parent node labels mssing
strict digraph structs {
graph [bb="0,0,582,464"];
node [label="\N"];
subgraph cluster_h1a_h1c {
graph [bb="8,8,252,456",
label="Host (h1d):h1a",
lheight=0.21,
lp="130,444.5",
lwidth=1.14
];
subgraph cluster_h1a_h1c_1 {
graph [bb="16,16,238,343",
label="Type: 4",
lheight=0.21,
lp="127,331.5",
lwidth=0.60
];
h1a_1_a [height=0.5,
label=h1a_1_a,
pos="108,294",
width=1.1152];
h1a_1_b [height=0.5,
label=h1a_1_b,
pos="180,165",
width=1.1243];
h1a_1_a -> h1a_1_b [label="aa to\naa \n(Relation 900)",
lp="89.5,229",
pos="e,152.02,178.1 80.531,280.85 68.886,274.15 56.52,264.59 50,252 40.6,233.84 37.342,222.05 50,206 71.223,179.08 92.334,198.39 125,\
188 130.71,186.18 136.68,184.05 142.48,181.84"];
h1a_1_b -> h1a_1_a [label="at to\nat \n(Relation 901)",
lp="190.5,229",
pos="e,116.69,276.3 167.17,182.28 161.86,189.37 155.82,197.89 151,206 139.41,225.48 139.06,231.69 129,252 126.58,256.89 123.96,262.09 \
121.41,267.08"];
h1a_1_c [height=0.5,
label=h1a_1_c,
pos="107,42",
width=1.1152];
h1a_1_b -> h1a_1_c [label="at to\nat \n(Relation 902)",
lp="190.5,101",
pos="e,117.92,59.5 167.17,147.72 161.86,140.63 155.82,132.11 151,124 139.41,104.52 139.94,97.848 129,78 127.2,74.727 125.22,71.338 123.21,\
68.015"];
h1a_1_c -> h1a_1_a [label="aa to\naa \n(Relation 905)",
lp="73.5,165",
pos="e,76.67,282.72 72.034,50.981 57.676,56.165 42.461,64.559 34,78 23.108,95.301 33.681,103.56 34,124 34.889,180.91 8.928,203.07 38,\
252 44.755,263.37 55.972,271.91 67.469,278.18"];
h1a_1_c -> h1a_1_b [label="aa to\naa \n(Relation 906)",
lp="85.5,101",
pos="e,152.04,151.84 75.395,53.432 64.059,58.875 52.486,66.8 46,78 35.754,95.692 33.25,108.02 46,124 68.458,152.15 90.622,131.28 125,\
142 130.72,143.78 136.69,145.9 142.5,148.1"];
}
h1a_h1c_1 [height=0.74639,
label="1\n[Engine: h1c]",
pos="180,398",
width=1.7826];
h1a_h1c_1 -> h1a_1_a [pos="e,119.59,311.42 162.39,372.05 151.15,356.12 136.64,335.57 125.43,319.69"];
h1a_h1c_1 -> h1a_1_b [pos="e,205.29,179.15 191.27,371.31 210.26,326.33 245.27,235.32 231,206 227.07,197.93 220.64,191 213.64,185.29"];
h1a_h1c_1 -> h1a_1_c [pos="e,144.63,48.377 202.85,372.84 210.02,364.05 217.28,353.64 222,343 238.65,305.46 234.43,292.91 238,252 242.11,204.89 239.47,84.953 \
234,78 224.02,65.308 186.4,55.968 154.68,50.144"];
}
subgraph cluster_h2a_h2c {
graph [bb="278,260,422,456",
label="Host (h2d):h2a",
lheight=0.21,
lp="350,444.5",
lwidth=1.14
];
subgraph cluster_h2a_h2c_2 {
graph [bb="305,268,395,343",
label="Type: 2",
lheight=0.21,
lp="350,331.5",
lwidth=0.60
];
h2a_2_d [height=0.5,
label="Child d",
pos="350,294",
width=1.0284];
}
h2a_h2c_2 [height=0.74639,
label="2\n[Engine: h2c]",
pos="350,398",
width=1.7826];
h2a_h2c_2 -> h2a_2_d [pos="e,350,312.3 350,371 350,356.18 350,337.62 350,322.55"];
}
subgraph cluster_h3a_h3c {
graph [bb="430,363,574,456",
label="Host (h3d):h3a",
lheight=0.21,
lp="502,444.5",
lwidth=1.14
];
h3a_h3c_3 [height=0.74639,
label="3\n[Engine: h3c]",
pos="502,398",
width=1.7826];
}
h1a_1_b -> h2a_2_d [label="at to\nat \n(Relation 907)",
lp="303.5,229",
pos="e,318.76,284.32 207.79,178.13 220.51,184.83 234.95,194.2 245,206 259.34,222.84 248.78,235.95 264,252 276.25,264.92 293.41,274.23 \
309.18,280.67"];
h2a_2_d -> h1a_1_a [label="l to\nl \n(Relation 904)",
lp="230.48,319.5",
pos="e,148.23,294 312.85,294 271.48,294 204.36,294 158.3,294"];
h2a_2_d -> h1a_1_b [label="l to\nl \n(Relation 903)",
lp="397.5,229",
pos="e,219.23,169.96 354.95,275.85 359.38,256.61 362.97,225.54 347,206 332.24,187.94 273.15,177.01 229.42,171.25"];
}
#!/usr/bin/env ruby
$stdout.sync = true
## Adapted from:
## http://www.omninerd.com/articles/Automating_Data_Visualization_with_Ruby_and_Graphviz
##
require 'ruby-graphviz'
#require 'graphviz/dsl'
require 'awesome_print' # usage #ap ....
# Constants defining file names and paths
pd = ::Pathname.new(__FILE__).dirname
OutputPath = pd
# expand_path
# load 3 arrays with CSV data
tables = [['1.a','1'],
['1.b','2'],
['1.c','3'],
['2.d','4']]
hosts = [['h1a','1','h1c','h1d'],
['h2a','2','h2c','h2d'],
['h3a','3','h3c','h3d']]
relations = [
[900,'aa','1.a','aa','1.b'],
[901,'at','1.b','at','1.a'],
[902,'at','1.b','at','1.c'],
[903,'l','2.d','l','1.b'],
[904,'l','2.d','l','1.a'],
[905,'aa','1.c','aa','1.a'],
[906,'aa','1.c','aa','1.b'],
[907,'at','1.b','at','2.d'],
]
# initialize new Graphviz graph
# g = ::GraphViz::new( 'structs' )
g = strict('structs')
#g[:rankdir] = 'LR'
# # set global node options
# g.node[:color] = '#ddaa66'
# g.node[:style] = 'filled'
# g.node[:shape] = 'box'
# g.node[:penwidth] = '1'
# g.node[:fontname] = 'Trebuchet MS'
# g.node[:fontsize] = '8'
# g.node[:fillcolor]= '#ffeecc'
# g.node[:fontcolor]= '#775500'
# g.node[:margin] = '0.0'
#
# # set global edge options
# g.edge[:color] = '#999999'
# g.edge[:weight] = '1'
# g.edge[:fontsize] = '6'
# g.edge[:fontcolor]= '#444444'
# g.edge[:fontname] = 'Verdana'
# g.edge[:dir] = 'forward'
# g.edge[:arrowsize]= '0.5'
#
# draw our clusters of graphs, i.e. hosts
hosts.each do |hosts|
host = hosts[0]
schema = hosts[1]
engine = hosts[2]
os = hosts[3]
g.add_graph("cluster_#{host}_#{engine}",:label => "Host (#{os}):" + host) do |gg|
gg.add_node("#{host}_#{engine}_#{schema}").label = "#{schema}\n[Engine: #{engine}]"
end
end
# brute force, but simple function to find a type record by schema.table
def find_type(tables_array, material_number)
tables_array.collect{|m| m[1] unless m.index(material_number).nil?}.compact[0]
end
# brute force, but simple function to find a host record by schema
def find_host(hosts_array, schema_name)
hosts_array.collect{|m| m[0] unless m.index(schema_name).nil?}.compact[0]
end
# brute force, but simple function to find a engine record by schema
def find_engine(hosts_array, schema_name)
hosts_array.collect{|m| m[2] unless m.index(schema_name).nil?}.compact[0]
end
# connect the nodes with our recipes, add labels from material data
relations.each do |relation|
#puts relation.inspect
ps = relation[2].split('.')[0] # parent schema
cs = relation[4].split('.')[0] # child schema
pe = relation[2].split('.')[1] # parent entity
ce = relation[4].split('.')[1] # child entity
pf = relation[1] # parent field
cf = relation[3] # child field
ct = find_type(tables, relation[2]) # parent type
pt = find_type(tables, relation[4]) # child type
ph = find_host( hosts, ps )
ch = find_host( hosts, cs )
peg = find_engine( hosts, ps )
ceg = find_engine( hosts, cs )
ptn_id = "#{ph}_#{ps}_#{pe}" # parent entity (table, etc.) node ID
ctn_id = "#{ch}_#{cs}_#{ce}" # child entity (table, etc.) node ID
psn_id = "#{ph}_#{peg}_#{ps}"
csn_id = "#{ch}_#{ceg}_#{cs}"
pc = g.get_graph( "cluster_#{ph}_#{peg}" ) # parent host cluster
cc = g.get_graph( "cluster_#{ch}_#{ceg}" ) # child host cluster
psn = pc.get_node(psn_id) # Node representing parent schema
csn = cc.get_node(csn_id) # Node representing child schema
pcs = pc.add_graph("cluster_#{ph}_#{peg}_#{ps}", :label => "Type: #{pt}")
ccs = cc.add_graph("cluster_#{ch}_#{ceg}_#{cs}", :label => "Type: #{ct}")
ccs.add_node( ctn_id, :label=> "Child #{ce}" )
pcs.add_node( ptn_id, :label=> "Parent #{pe}" )
g.add_edge(psn_id,ptn_id)
g.add_edge(csn_id,ctn_id)
# This works
g.add_edge(ptn_id, ctn_id).label= "#{pf} to\n#{cf} \n(Relation #{relation[0]})"
end
output = g.output( :dot => OutputPath + 'mre.dot' )
g.output( :svg => OutputPath + 'mre.svg' )
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment