Say I start with this:
graph {
graph [splines=ortho]
node [fontname="Sans-Serif" shape=record]
rankdir=LR
"Parent" -- "Child 1"
"Parent" -- "Child 2"
"Parent" -- "Child 3"
"Parent" -- "Child 4 and then some"
}
This yields:
What do I need to change to get this instead (and so on for subequent levels)?
Thanks!
Surprisingly difficult. Ortho replaced by DIY ortho-like edges, using pseudo-invisible nodes.
graph {
// note: renaming the nodes was optional
graph [splines=false ] // was ortho
node [fontname="Sans-Serif" shape=rect ] // record features unused
rankdir=LR // ranks are now vertical!
{ // non-visible nodes (i1 i2 i3 i4) used to connect edges
rank=same
node [label="" peripheries=0] // keep same size as other nodes,
// but do not draw (peripheries)
edge [headclip=false tailclip=false] // draw center-to-center
i1:c -- i2:c -- i3:c -- i4:c
}
{node [group=T] P C1} //group used to place "child 1" w/ parent
P [label="Parent"]
{
rank=same
C1 [label="Child 1"]
C2 [label="Child 2"]
C3 [label="Child 3"]
C4 [label="Child 4 and then some"]
}
P -- i1 [headclip=false]
edge [tailclip=false]
i1 -- C1
i2 -- C2
i3 -- C3
i4 -- C4
}
Giving:
I will be as simple as possible , i have the below template.ftl
B E G L E I T Z E T T E L Intern
FUER DATEI: ${content.fileName}
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
ERZ. SYSTEM: ${content.system}
INITIATOR: ${content.initiator}
DATEI ID: ${content.fileID}
And i want to output :
B E G L E I T Z E T T E L Intern
FUER DATEI: FileName
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
ERZ. SYSTEM: SYSTEMX
INITIATOR: Initiator
DATEI ID: FileID
But what i get instead ... let's say for the above example is :
B E G L E I T Z E T T E L Intern
FUER DATEI: FileName
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
ERZ. SYSTEM: SYSTEMX
INITIATOR: Initiator
DATEI ID: FileID
In other words the column is not properly aligned
How can i fix this problem in FreeMarker :) ?
Add <#rt> for trimming right spaces
B E G L E I T Z E T T E L Intern
FUER DATEI: ${content.fileName}<#rt>
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
ERZ. SYSTEM: ${content.system}<#rt>
INITIATOR: ${content.initiator}<#rt>
DATEI ID: ${content.fileID}<#rt>
rt (for right trim): Ignore all trailing white-space in this line.
Notice to add new lines between lines, for example:
B E G L E I T Z E T T E L Intern
FUER DATEI: ${content.fileName}<#rt>
--------------------------------------------------------------------------------
Here is the answer , i used something not very complex:
<#assign lineWidth = 80>
B E G L E I T Z E T T E L Intern
<#compress>FUER DATEI: </#compress>${content.fileName?left_pad(lineWidth-"FUER DATEI:"?length," ")}
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
<#compress>ERZ. SYSTEM: </#compress>${content.system?left_pad(lineWidth-"ERZ. SYSTEM:"?length," ")}
<#compress>INITIATOR: </#compress>${content.initiator?left_pad(lineWidth-"INITIATOR:"?length," ")}
<#compress>DATEI ID: </#compress>${content.fileID?left_pad(lineWidth-"DATEI ID:"?length," ")}
So let's take the 3 first lines of code :
<#assign lineWidth = 80>
B E G L E I T Z E T T E L Intern
<#compress>FUER DATEI: </#compress>${content.fileName?left_pad(lineWidth-"FUER DATEI:"?length," ")}
1. Firstly i assign a variable lineWidth which represents the maximum line width of the file.
2. Then for each line i eat all the spaces using <#compress>
3. Then i added the value and left added the needed spaces in a way that everything aligns right.
----- BOSS LEVEL BELOW - using functions -----
<#assign lineWidth = 80>
<#function createLine prefix value >
<#return prefix + value?left_pad(lineWidth - prefix?length," ")>
</#function>
B E G L E I T Z E T T E L Intern
${createLine("FUER DATEI:",content.fileName)}
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
${createLine("ERZ. SYSTEM:",content.system)}
${createLine("INITIATOR:",content.initiator)}
${createLine("DATEI ID:",content.fileID)}
${createLine("SAMMELREFERENZ ID:",content.referenceID)}
${createLine("RSTELLUNGSDATUM:",content.creationDate)}
I'm trying to draw a tree but have a problem with the following approach:
Use of 'invisible' nodes to connect levels of tree,
Use 'rank same' to draw nodes on the same level
Using this code I get following result
graph G{
edge [arrowhead = none];
splines = ortho;
rankdir = LR;
node [ shape="box" fixedsize = true width = 4 height = 1];
{ rank = same; "C" }
{ rank = same;
"B"
"A"
}
{ rank = same;
"F"
"D"
"E"
}
node [ shape="cricle" width = 0 height = 0 style=invis];
{ rank = same;
"B_Inv_Parent_1"
"C_Inv_Even_Children_0"
"A_Inv_Parent_1"
}
{ rank = same;
"F_Inv_Parent_2"
"D_Inv_Parent_2"
"A_Inv_Even_Children_1"
"E_Inv_Parent_2"
}
"C" -- "C_Inv_Even_Children_0";
"B_Inv_Parent_1" -- "C_Inv_Even_Children_0" -- "A_Inv_Parent_1";
"B_Inv_Parent_1" -- "B";
"A_Inv_Parent_1" -- "A";
"B" -- "F_Inv_Parent_2";
"F_Inv_Parent_2" -- "F";
"A" -- "A_Inv_Even_Children_1";
"D_Inv_Parent_2" -- "A_Inv_Even_Children_1" -- "E_Inv_Parent_2";
"D_Inv_Parent_2" -- "D";
"E_Inv_Parent_2" -- "E";
}
I have a problem in the 3rd level: D is drawn on top of the picture thus making a connection with E not ideal.
I would like to have the same results as with C, B and A.
I think the problem is with the order of nodes definition however, I can't manage to get it working whatever order I define them in.
Can anyone spot another problem with my code and suggest a fix?
I have cleaned up your code and re-arranged a few lines - after all, I think that introducing
F_Inv_Parent_2 -- D_Inv_Parent_2 -- A_Inv_Even_Children_1 -- E_Inv_Parent_2;
has been the key. You don't need to define edge arrows since you don't have a directed graph, and there is a typo in shape="cricle".
Here my edited version
graph G
{
splines = ortho;
rankdir = LR;
// node definitions
node [ shape="box" fixedsize = true width = 4 height = 1];
C
{ rank = same; B A }
{ rank = same; F D E }
node [ shape="point" width = 0 height = 0 ];
{ rank = same;
B_Inv_Parent_1
C_Inv_Even_Children_0
A_Inv_Parent_1 }
{ rank = same;
F_Inv_Parent_2
D_Inv_Parent_2
A_Inv_Even_Children_1
E_Inv_Parent_2 }
// edges
C -- C_Inv_Even_Children_0;
B_Inv_Parent_1 -- C_Inv_Even_Children_0 -- A_Inv_Parent_1;
B_Inv_Parent_1 -- B -- F_Inv_Parent_2;
A_Inv_Parent_1 -- A -- A_Inv_Even_Children_1;
F_Inv_Parent_2 -- D_Inv_Parent_2 -- A_Inv_Even_Children_1 -- E_Inv_Parent_2;
F_Inv_Parent_2 -- F;
D_Inv_Parent_2 -- D;
E_Inv_Parent_2 -- E;
}
and the result:
EDIT: I may have misunderstood your intention how you want to connect the third level - if so, replace
F_Inv_Parent_2 -- D_Inv_Parent_2 -- A_Inv_Even_Children_1 -- E_Inv_Parent_2;
with
F_Inv_Parent_2 -- D_Inv_Parent_2[ style = invis ];
D_Inv_Parent_2 -- A_Inv_Even_Children_1 -- E_Inv_Parent_2;
which gives you
EDIT No. 2, in response to yr comment:
Adding weight to the edge helps straightening it - I give the full code even though only two lines have changed (plus comments), for easier copy & paste:
graph G
{
splines = ortho;
rankdir = LR;
// node definitions
node [ shape="box" fixedsize = true width = 4 height = 1];
C
{ rank = same; B A }
{ rank = same; F D E }
node [ shape="point" width = 0 height = 0 ];
{ rank = same;
B_Inv_Parent_1
C_Inv_Even_Children_0
A_Inv_Parent_1 }
{ rank = same;
F_Inv_Parent_2
D_Inv_Parent_2
A_Inv_Even_Children_1
E_Inv_Parent_2 }
// edges
C -- C_Inv_Even_Children_0;
B_Inv_Parent_1 -- C_Inv_Even_Children_0 -- A_Inv_Parent_1;
// add extra weight to the continouous connection between four levels:
B_Inv_Parent_1 -- B -- F_Inv_Parent_2 -- F[ weight = 10 ];
// no weight here:
A_Inv_Parent_1 -- A -- A_Inv_Even_Children_1;
F_Inv_Parent_2 -- D_Inv_Parent_2[ style = invis ];
D_Inv_Parent_2 -- A_Inv_Even_Children_1 -- E_Inv_Parent_2;
// F_Inv_Parent_2 -- F; ### moved
D_Inv_Parent_2 -- D;
E_Inv_Parent_2 -- E;
}
Which gives you the disired straight line from B via F_Inv_Parent_2 to F which is actually the grandchild:
Is there a way to group edges together into a single bus in DOT/Graphviz, while still fraying the edges near nodes?
Eg:
Changing this:
graph my_graph {
rankdir=LR
A -- B;
A -- B;
A -- B;
A -- B;
A -- B;
A -- B;
A -- B;
A -- B;
A -- B;
A -- C;
}
into something like this:
One way to do it is with dummy [shape=point] nodes, like so:
graph my_graph {
rankdir=LR;
{rank = same; B; C;}
aa [ shape=point ];
bb [ shape=point ];
A -- aa;
A -- aa;
A -- aa;
A -- aa;
A -- aa;
A -- aa;
A -- aa;
A -- aa;
A -- aa;
aa -- bb [ penwidth=4.0];
bb -- B;
bb -- B;
bb -- B;
bb -- B;
bb -- B;
bb -- B;
bb -- B;
bb -- B;
bb -- B;
A -- C;
}
This has some downsides though:
it doubles the number of edges in your source file, and makes it hard to manage.
If you have head and tail labels, then you need to place them accordingly.
It mucks up your node ranks, so you have to manually adjust all the other nodes.
The frayed ends are still rounded and taking up a lot of space. This might be fixable by setting the splines attribute, but I haven't been able to get it to work (it seems like no multiple edges between two nodes are always shown as splines no matter what the value of splines is).
Another option:
There's also the concentrate attribute, but this will only collect lines going to the same point. It will not 1) fray ends or 2) increase line thickness to represent the bus:
graph my_graph {
rankdir=LR
concentrate=true;
A -- B;
A -- B;
A -- B;
A -- B;
A -- B;
A -- B;
A -- B;
A -- B;
A -- B;
A -- C;
}
I need another set of eyes to tell me what is wrong with my Eiffel implementation of Burnikel and Ziegler's division, specifically "Algorithm 2 - 3n/2n". The Eiffel feature is shown below. The type "like Current" is an ARRAYED_LIST [NATURAL_8]. In other words, the implementation uses digits (i.e. limbs) containing 8-bit values, so numbers are in base-256. A manual trace of a failing call follows. (Sorry the arguments are so large, but I cannot reproduce the error with shorter values.) Execution follows step 3b in this case.
Here's the problem. The algorithm seems to be fine to Step 5, where the remainder "r" ends up with more digits then the divisor. I believe the error is in step 3b, perhaps with the call to feature `ones' which is "supposed" to supply a value that is "Beta^n - 1". (Maybe I do not understand B&Z's "Beta^n" notation.
Here is the Eiffel code:
three_by_two_divide (a, a3, b: like Current): TUPLE [quot, rem: like Current]
-- Called by `two_by_one_divide'. It has similar structure as
-- `div_three_halves_by_two_halfs', but the arguments to this
-- function have type {JJ_BIG_NATURAL} instead of like `digit'.
-- See Burnikel & Zieler, "Fast Recursive Division", pp 4-8,
-- Algorithm 2.
require
n_not_odd: b.count >= div_limit and b.count \\ 2 = 0
b_has_2n_digits: b.count = a3.count * 2
a_has_2n_digits: a.count = a3.count * 2
local
n: INTEGER
a1, a2: like Current
b1, b2: like Current
tup: TUPLE [quot, rem: like Current]
q, q1, q2, r, r1: like Current
c, d: like Current
do
n := b.count // 2
-- 1) Split `a'
a1 := new_sub_number (n + 1, a.count, a)
a2 := new_sub_number (1, n.max (1), a)
-- 2) Split `b'.
b1 := new_sub_number (n + 1, b.count, b)
b2 := new_sub_number (1, n.max (1), b)
-- 3) Distinguish cases.
if a1 < b1 then
-- 3a) compute Q = floor ([A1,A2] / B1 with remainder.
if b1.count < div_limit then
tup := school_divide (a, b1)
else
tup := two_by_one_divide (a, b1)
end
q := tup.quot
r1 := tup.rem
else
-- 3b) Q = beta^n - 1 and ...
q := ones (n)
-- ... R1 = [A1,A2] - [B1,0] + [0,B1] = [A1,A2] - QB1.
r1 := a + b1
if n > 1 then
b1.shift_left (n)
else
b1.bit_shift_left (zero_digit.bit_count // 2)
end
r1.subtract (b1)
end
-- 4) D = Q * B2
d := q * b2
-- 5) R1 * B^n + A3 - D. (The paper says "a4".)
r1.shift_left (n)
r := r1 + a3 - d
-- 6) As long as R < 0, repeat
from
until not r.is_negative
loop
r := r + b
q.decrement
end
check
remainder_small_enough: r.count <= b.count
-- because remainder must be less than divisor.
end
Result := [q, r]
ensure
-- n_digit_remainder: Result.rem.count = b.count // 2
quotient_has_correct_count: Result.quot.count <= b.count // 2
end
In the trace, the arrow points to a line I believe is bad, but I don't know what to do with it. Here is the trace:
three_by_two_divide (a = [227,26,41,95,169,93,135,110],
a3 = [92,164,19,39],
b = [161,167,158,41,164,0,0,0])
n := b.count // 2 = 4
-- 1) Split `a'.
a1 := new_sub_number (n + 1, a.count, a) = [227,26,41,95]
a2 := new_sub_number (1, n.max (1), a) = [169,93,135,110]
-- 2) Split `b'.
b1 := new_sub_number (n + 1, b.count, b) = [161,167,158,41]
b2 := new_sub_number (1, n.max (1), b) = [164,0,0,0]
-- 3b) Q = beta^n -1 and ...
--> q := ones (4) = [255,255,255,255] <-- Is this the error?
-- ... R1 = [A1,A2] - [B1,0] + [0,B1].
r1 := a + b1 = [227,26,41,96,75,5,37,151]
b1.shift_left (n) = [161,167,158,41,0,0,0,0]
r1.subtract (b1) = [65,114,139,55,75,5,37,151]
d := q * b2 = [163,255,255,255,92,0,0,0]
r1.shift_left (n) = [227,25,135,184,172,220,37,151,0,0,0,0] -- too big!
r := r1 + a3 - d -= [227,25,135,184,8,220,37,152,0,164,19,39] -- too big!
I know this is long, but any help is appreciated.
I would suggest to check that r1 = [65,114,139,55,75,5,37,151] is still the same before doing r1.shift_left (n). There are two options:
d := q * b2 affects r1 while it should not. Most probably there is some aliasing, i.e. r1 is aliased with some other variable that is updated and this aliasing should be removed.
r1 is still the same after d := q * b2. The issue is with shift_left that fails to (re)initialize some data or uses global data that it should not.