August 21, 2010
DGML Simplified – Debugging
Consider the simplest graph:
node node
The generated DGML is as follows:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’node’ Label=’node’ />
</Nodes>
</DirectedGraph>
<!–
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’_nodes_’ Label=’nodes’ Group=’Expanded’ />
<Node Id=’_labels_’ Label=’labels’ Group=’Expanded’ />
<Node Id=’_roots_’ Label=’roots’ Group=’Expanded’ />
<Node Id=’node_node’ Label=’node’ Category=’node’ />
<Node Id=’label_node’ Label=’node’ Category=’label’ />
<Node Id=’root_node’ Label=’node’ Category=’root’ />
</Nodes>
<Links>
<Link Source=’_nodes_’ Target=’node_node’ Category=’Contains’ />
<Link Source=’_labels_’ Target=’label_node’ Category=’Contains’ />
<Link Source=’node_node’ Target=’label_node’ />
<Link Source=’_roots_’ Target=’root_node’ Category=’Contains’ />
<Link Source=’root_node’ Target=’node_node’ />
</Links>
<Categories>
<Category Id=’node’ Background=’#FF808000′ />
<Category Id=’label’ Background=’#FF804000′ />
<Category Id=’category’ Background=’#FF404000′ />
<Category Id=’nodecategory’ Background=’#FF606000′ />
<Category Id=’group’ Background=’#FF008080′ />
<Category Id=’parent’ Background=’#FF800080′ />
<Category Id=’child’ Background=’#FF600060′ />
<Category Id=’root’ Background=’#FF800020′ />
<Category Id=’leaf’ Background=’#FF800040′ />
<Category Id=’intermediate’ Background=’#FF800060′ />
<Category Id=’link’ Background=’#FF000080′ />
</Categories>
</DirectedGraph>
–>
Notice that there is an XML comment appended to the DGML; it represents debugging information for the graph. If it is commented-out it will draw the metadata of the graph in DGML:
It can also be considered as a tool for learning DGML.
Here is another graph:
Elizabeth –> Charles
category Elizabeth(Queen)
category Charles(Prince)
categorycolor Queen(#FF800000)
It’s debug information is as follows:
Now let’s introduce an error:
Elizabeth –> Charles
category Elizabeth{Queen}
category Charles(Prince)
categorycolor Queen(#FF800000)
We do not have the Queen in Red:
We can see that Elizabeth became a category and there is no Queen category anymore:
DGML Simplified – Design
Directed Graph Markup Language
Here is the design of the DGML DSL (written in itself):
Source:
default shape RoundedRectangle
label low (dgml_lowlevel.gawk)
label dsm(Data Structure Manipulation)
label compute(Compute defaults, roots, leaves, intermediates)
label hbf(Print header, body, footer)
label pdebug(Print debug information)
dgml_print.gawk->Printing
dgml_lib.gawk->dsm
group dgml.gawk
dgml.gawk->{ begin; compute ; hbf ; pdebug; end }
group compute(collapsed)
compute->{computedefaults; computeroots; computeleaves; computeintermediates}
begin->compute
computeintermediates->hbf->pdebug->end
{hbf;pdebug}->dgml_print.gawk
end->{ low ; dgml_print.gawk }
group low(collapsed)
low->Parsing
Parsing->dgml_lib.gawk
group Printing(collapsed)
group dsm(collapsed)
dsm->{addnode;addlink;addlabel;addcategory;addgroup;addcolor;addtextcolor;addshape;addstroke;addwidth}
Printing->{printnode;printnodes;printlinks;printcategories}
addlink->addnode
shape addnode(button)
shape addlink(button)
shape addlabel(button)
shape addcategory(button)
shape addgroup(button)
shape addcolor(button)
shape addtextcolor(button)
shape addshape(button)
shape addstroke(button)
shape printnode(button)
shape printnodes(button)
shape printlinks(button)
shape printcategories(button)
shape begin(button)
shape end(button)
icon Printing(printer)
icon dsm(table)
icon dgml.gawk(script)
icon dgml_lib.gawk(script)
icon low(script)
icon dgml_print.gawk(script)
Expanded view:
Generated DGML:
<?xml version=’1.0′ encoding=’utf-8′?>
<DirectedGraph xmlns="http://schemas.microsoft.com/vs/2009/dgml">
<Nodes>
<Node Id="Parsing" Label="Parsing" NodeRadius="4" />
<Node Id="Printing" Group="Expanded" Icon="pack://application:,,,/Microsoft.VisualStudio.Progression.GraphControl;component/Icons/printer.png" Label="Printing" NodeRadius="4" />
<Node Id="addcategory" Label="addcategory" />
<Node Id="addcolor" Label="addcolor" />
<Node Id="addgroup" Label="addgroup" />
<Node Id="addlabel" Label="addlabel" />
<Node Id="addlink" Label="addlink" />
<Node Id="addnode" Label="addnode" />
<Node Id="addshape" Label="addshape" />
<Node Id="addstroke" Label="addstroke" />
<Node Id="addtextcolor" Label="addtextcolor" />
<Node Id="addwidth" Label="addwidth" NodeRadius="4" />
<Node Id="begin" Label="begin" />
<Node Id="compute" Group="Collapsed" Label="Compute defaults, roots, leaves, intermediates" NodeRadius="4" />
<Node Id="computedefaults" Label="computedefaults" NodeRadius="4" />
<Node Id="computeintermediates" Label="computeintermediates" NodeRadius="4" />
<Node Id="computeleaves" Label="computeleaves" NodeRadius="4" />
<Node Id="computeroots" Label="computeroots" NodeRadius="4" />
<Node Id="dgml.gawk" Group="Expanded" Icon="pack://application:,,,/Microsoft.VisualStudio.Progression.GraphControl;component/Icons/script.png" Label="dgml.gawk" NodeRadius="4" />
<Node Id="dgml_lib.gawk" Icon="pack://application:,,,/Microsoft.VisualStudio.Progression.GraphControl;component/Icons/script.png" Label="dgml_lib.gawk" NodeRadius="4" />
<Node Id="dgml_print.gawk" Icon="pack://application:,,,/Microsoft.VisualStudio.Progression.GraphControl;component/Icons/script.png" Label="dgml_print.gawk" NodeRadius="4" />
<Node Id="dsm" Group="Expanded" Icon="pack://application:,,,/Microsoft.VisualStudio.Progression.GraphControl;component/Icons/table.png" Label="Data Structure Manipulation" NodeRadius="4" />
<Node Id="end" Label="end" />
<Node Id="hbf" Label="Print header, body, footer" NodeRadius="4" />
<Node Id="low" Group="Expanded" Icon="pack://application:,,,/Microsoft.VisualStudio.Progression.GraphControl;component/Icons/script.png" Label="dgml_lowlevel.gawk" NodeRadius="4" />
<Node Id="pdebug" Label="Print debug information" NodeRadius="4" />
<Node Id="printcategories" Label="printcategories" />
<Node Id="printlinks" Label="printlinks" />
<Node Id="printnode" Label="printnode" />
<Node Id="printnodes" Label="printnodes" />
</Nodes>
<Links>
<Link Source="Parsing" Target="dgml_lib.gawk" />
<Link Source="Printing" Target="printcategories" Category="Contains" />
<Link Source="Printing" Target="printlinks" Category="Contains" />
<Link Source="Printing" Target="printnode" Category="Contains" />
<Link Source="Printing" Target="printnodes" Category="Contains" />
<Link Source="addlink" Target="addnode" />
<Link Source="begin" Target="compute" />
<Link Source="compute" Target="computedefaults" Category="Contains" />
<Link Source="compute" Target="computeintermediates" Category="Contains" />
<Link Source="compute" Target="computeleaves" Category="Contains" />
<Link Source="compute" Target="computeroots" Category="Contains" />
<Link Source="computeintermediates" Target="hbf" />
<Link Source="dgml.gawk" Target="begin" Category="Contains" />
<Link Source="dgml.gawk" Target="compute" Category="Contains" />
<Link Source="dgml.gawk" Target="end" Category="Contains" />
<Link Source="dgml.gawk" Target="hbf" Category="Contains" />
<Link Source="dgml.gawk" Target="pdebug" Category="Contains" />
<Link Source="dgml_lib.gawk" Target="dsm" />
<Link Source="dgml_print.gawk" Target="Printing" />
<Link Source="dsm" Target="addcategory" Category="Contains" />
<Link Source="dsm" Target="addcolor" Category="Contains" />
<Link Source="dsm" Target="addgroup" Category="Contains" />
<Link Source="dsm" Target="addlabel" Category="Contains" />
<Link Source="dsm" Target="addlink" Category="Contains" />
<Link Source="dsm" Target="addnode" Category="Contains" />
<Link Source="dsm" Target="addshape" Category="Contains" />
<Link Source="dsm" Target="addstroke" Category="Contains" />
<Link Source="dsm" Target="addtextcolor" Category="Contains" />
<Link Source="dsm" Target="addwidth" Category="Contains" />
<Link Source="end" Target="dgml_print.gawk" />
<Link Source="end" Target="low" />
<Link Source="hbf" Target="dgml_print.gawk" />
<Link Source="hbf" Target="pdebug" />
<Link Source="low" Target="Parsing" Category="Contains" />
<Link Source="pdebug" Target="dgml_print.gawk" />
<Link Source="pdebug" Target="end" />
</Links>
<Categories>
<Category Id="Contains" Label="Contains" CanBeDataDriven="False" CanLinkedNodesBeDataDriven="True" IncomingActionLabel="Contained By" IsContainment="True" OutgoingActionLabel="Contains" />
</Categories>
<Properties>
<Property Id="CanBeDataDriven" Label="CanBeDataDriven" Description="CanBeDataDriven" DataType="System.Boolean" />
<Property Id="CanLinkedNodesBeDataDriven" Label="CanLinkedNodesBeDataDriven" Description="CanLinkedNodesBeDataDriven" DataType="System.Boolean" />
<Property Id="Group" Label="Group" Description="Display the node as a group" DataType="Microsoft.VisualStudio.Progression.GraphModel.GroupStyle" />
<Property Id="Icon" Label="Icon" Description="Icon" DataType="System.String" />
<Property Id="IncomingActionLabel" Label="IncomingActionLabel" Description="IncomingActionLabel" DataType="System.String" />
<Property Id="IsContainment" DataType="System.Boolean" />
<Property Id="Label" Label="Label" Description="Displayable label of an Annotatable object" DataType="System.String" />
<Property Id="NodeRadius" DataType="System.Double" />
<Property Id="OutgoingActionLabel" Label="OutgoingActionLabel" Description="OutgoingActionLabel" DataType="System.String" />
</Properties>
</DirectedGraph>
DGML Simplified – Icons
Directed Graph Markup Language
You may also use icons in your script:
default shape None
node Audio
icon Audio(Audio)
node Blog
icon Blog(Blog)
etc …
node Users
icon Users(Users)
node ValueType
icon ValueType(ValueType)
Here is the generated DGML:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’Script’ Label=’Script’ Shape=’None’ Icon=’pack://application:,,,/Microsoft.VisualStudio.Progression.GraphControl;component/Icons/Script.png’ />
<Node Id=’cut’ Label=’cut’ Shape=’None’ Icon=’pack://application:,,,/Microsoft.VisualStudio.Progression.GraphControl;component/Icons/cut.png’ />
etc …
<Node Id=’ExtensionMethod’ Label=’ExtensionMethod’ Shape=’None’ Icon=’pack://application:,,,/Microsoft.VisualStudio.Progression.GraphControl;component/Icons/ExtensionMethod.png’ />
</Nodes>
</DirectedGraph>
DGML Simplified – Groups
Directed Graph Markup Language
Let’s go back to our numbers example:
2->{4;6;8;10;12;14;16}
3->{6;9;12;15}
4->{8;16}
5->{10;15}
6->12
7->14
8->16
If we want to see all odd numbers in a glance, we can group them:
2->{4;6;8;10;12;14;16}
3->{6;9;12;15}
4->{8;16}
5->{10;15}
6->12
7->14
8->16
group Odd
Odd->{3;5;7;9;15}
We haven’t lost the ability to see individual divisors:
Here is the DGML:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’4′ Label=’4′ />
<Node Id=’5′ Label=’5′ />
<Node Id=’6′ Label=’6′ />
<Node Id=’7′ Label=’7′ />
<Node Id=’8′ Label=’8′ />
<Node Id=’9′ Label=’9′ />
<Node Id=’10’ Label=’10’ />
<Node Id=’12’ Label=’12’ />
<Node Id=’Odd’ Label=’Odd’ Group=’Expanded’ />
<Node Id=’14’ Label=’14’ />
<Node Id=’15’ Label=’15’ />
<Node Id=’2′ Label=’2′ />
<Node Id=’3′ Label=’3′ />
<Node Id=’16’ Label=’16’ />
</Nodes>
<Links>
<Link Source=’3′ Target=’12’ />
<Link Source=’2′ Target=’14’ />
<Link Source=’7′ Target=’14’ />
<Link Source=’5′ Target=’10’ />
<Link Source=’3′ Target=’9′ />
<Link Source=’2′ Target=’16’ />
<Link Source=’3′ Target=’15’ />
<Link Source=’Odd’ Target=’3′ Category=’Contains’ />
<Link Source=’8′ Target=’16’ />
<Link Source=’2′ Target=’4′ />
<Link Source=’6′ Target=’12’ />
<Link Source=’4′ Target=’16’ />
<Link Source=’4′ Target=’8′ />
<Link Source=’Odd’ Target=’5′ Category=’Contains’ />
<Link Source=’5′ Target=’15’ />
<Link Source=’2′ Target=’6′ />
<Link Source=’Odd’ Target=’15’ Category=’Contains’ />
<Link Source=’Odd’ Target=’7′ Category=’Contains’ />
<Link Source=’2′ Target=’10’ />
<Link Source=’2′ Target=’8′ />
<Link Source=’Odd’ Target=’9′ Category=’Contains’ />
<Link Source=’2′ Target=’12’ />
<Link Source=’3′ Target=’6′ />
</Links>
</DirectedGraph>
DGML Simplified – Categories
Directed Graph Markup Language
If we want to identify princes and princesses (independent of color!), we can proceed as follows:
{Elizabeth;Philip}->{Charles;Anne;Andrew;Edward}
{Diana;Charles}->{Henry;William}
category Charles(prince)
category Andrew(prince)
category Edward(prince)
category Henry(prince)
category William(prince)
category Anne(princess)
category Elizabeth(queen)
border Elizabeth(Transparent)
categorycolor prince(Blue)
categorycolor princess(Red)
categorycolor queen(Gold)
Now, the code may be longer, but it gives you additional flexibility in manipulating the royal family’s colors (or even icons) in the DGML viewer:
Here is the horrendous DGML that is generated, by the way:
<DirectedGraph xmlns="http://schemas.microsoft.com/vs/2009/dgml">
<Nodes>
<Node Id="Andrew" Category="Prince" Label="Andrew" />
<Node Id="Anne" Category="Princess" Label="Anne" />
<Node Id="Charles" Category="Prince" Label="Charles" />
<Node Id="Diana" Label="Diana" />
<Node Id="Edward" Category="Prince" Label="Edward" />
<Node Id="Elizabeth" Category="Queen" Label="Elizabeth" Stroke="#00FFFFFF" />
<Node Id="Henry" Category="Prince" Label="Henry" />
<Node Id="Philip" Label="Philip" />
<Node Id="William" Category="Prince" Label="William" />
</Nodes>
<Links>
<Link Source="Charles" Target="Henry" />
<Link Source="Charles" Target="William" />
<Link Source="Diana" Target="Henry" />
<Link Source="Diana" Target="William" />
<Link Source="Elizabeth" Target="Andrew" />
<Link Source="Elizabeth" Target="Anne" />
<Link Source="Elizabeth" Target="Charles" />
<Link Source="Elizabeth" Target="Edward" />
<Link Source="Philip" Target="Andrew" />
<Link Source="Philip" Target="Anne" />
<Link Source="Philip" Target="Charles" />
<Link Source="Philip" Target="Edward" />
</Links>
<Categories>
<Category Id="Prince" Background="#FF0000FF" />
<Category Id="Princess" Background="#FFFF0000" />
<Category Id="Queen" Background="#FFFFD700" />
</Categories>
<Properties>
<Property Id="Background" Label="Background" Description="The background color" DataType="System.Windows.Media.Brush" />
<Property Id="Label" Label="Label" Description="Displayable label of an Annotatable object" DataType="System.String" />
<Property Id="Stroke" DataType="System.Windows.Media.Brush" />
</Properties>
<Styles>
<Style TargetType="Node" GroupLabel="Queen" ValueLabel="True">
<Condition Expression="HasCategory(‘Queen’)" />
<Setter Property="Background" Value="#FFFFD700" />
</Style>
<Style TargetType="Node" GroupLabel="Princess" ValueLabel="True">
<Condition Expression="HasCategory(‘Princess’)" />
<Setter Property="Background" Value="#FFFF0000" />
</Style>
<Style TargetType="Node" GroupLabel="Prince" ValueLabel="True">
<Condition Expression="HasCategory(‘Prince’)" />
<Setter Property="Background" Value="#FF0000FF" />
</Style>
</Styles>
</DirectedGraph>
Next, grouping…
DGML Simplified – Examples
Directed Graph Markup Language
Here are some examples based on what we have learned so far. They are all based on drawing the syntax of the DGML DSL as a syntax bootstrapper.
First off, we have: a –> b; how do we draw it?
a -> → -> b
Because DGML (actually WPF) interprets character entity references correctly.
If we re-arrange a little bit…
a -> rightarrow -> b
label rightarrow(→)
label a(node)
label b(node)
color a(Red)
color b(Red)
color rightarrow(Blue)
…we get the syntax for a simple relation (or link).
Maybe I should consolidate labels and colors to make the syntax shorter.
Anyhow, here is the DGML:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’rightarrow’ Label=’→’ Background=’Blue’ />
<Node Id=’a’ Label=’node’ Background=’Red’ />
<Node Id=’b’ Label=’node’ Background=’Red’ />
</Nodes>
<Links>
<Link Source=’rightarrow’ Target=’b’ />
<Link Source=’a’ Target=’rightarrow’ />
</Links>
</DirectedGraph>
What about “a –> b –> c –> d” ? Can you draw it? (as a syntax diagram, that is)
Maybe this is not what we are used to see in textbooks, but it means what it means; here is the code in the DGML DSL:
a->s1->ra->b->s2->s1
label a(node)
label b(node)
label s1(.)
label s2(.)
shape s1(None)
shape s2(None)
label ra(→)
color a(Red)
color b(Red)
color ra(Blue)
I called the junctions as s1 & s2 (as separators).
Exercises:
- Draw the syntax diagram of “a->{b;c}” in DGML DSL
- Draw the syntax diagram of “{a;b}->end” in DGML DSL
- Draw the syntax diagram of “{a;b}->{x;y}” in DGML DSL
How about changing the subject? How about the Royal Family?
We can write it with two lines of code:
{Elizabeth;Philip}->{Charles;Anne;Andrew;Edward}
{Diana;Charles}->{Henry;William}
Almost everybody here is either a prince or a princess, but we don’t know unless we color them:
{Elizabeth;Philip}->{Charles;Anne;Andrew;Edward}
{Diana;Charles}->{Henry;William}
color Charles(blue)
color Andrew(blue)
color Edward(blue)
color Henry(blue)
color William(blue)
color Anne(Red)
And who is the Monarch?
{Elizabeth;Philip}->{Charles;Anne;Andrew;Edward}
{Diana;Charles}->{Henry;William}
color Charles(blue)
color Andrew(blue)
color Edward(blue)
color Henry(blue)
color William(blue)
color Anne(Red)
color Elizabeth(Gold)
border Elizabeth(Transparent)
Here is the DGML:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’Elizabeth’ Label=’Elizabeth’ Background=’Gold’ Stroke=’Transparent’ />
<Node Id=’William’ Label=’William’ Background=’Blue’ />
<Node Id=’Diana’ Label=’Diana’ />
<Node Id=’Edward’ Label=’Edward’ Background=’Blue’ />
<Node Id=’Andrew’ Label=’Andrew’ Background=’Blue’ />
<Node Id=’Anne’ Label=’Anne’ Background=’Red’ />
<Node Id=’Charles’ Label=’Charles’ Background=’Blue’ />
<Node Id=’Philip’ Label=’Philip’ />
<Node Id=’Henry’ Label=’Henry’ Background=’Blue’ />
</Nodes>
<Links>
<Link Source=’Charles’ Target=’William’ />
<Link Source=’Philip’ Target=’Charles’ />
<Link Source=’Charles’ Target=’Henry’ />
<Link Source=’Elizabeth’ Target=’Charles’ />
<Link Source=’Elizabeth’ Target=’Edward’ />
<Link Source=’Elizabeth’ Target=’Andrew’ />
<Link Source=’Elizabeth’ Target=’Anne’ />
<Link Source=’Philip’ Target=’Edward’ />
<Link Source=’Philip’ Target=’Andrew’ />
<Link Source=’Philip’ Target=’Anne’ />
<Link Source=’Diana’ Target=’Henry’ />
<Link Source=’Diana’ Target=’William’ />
</Links>
</DirectedGraph>
In the end, all this color business is tiring; we should be able to specify if somebody is a prince or a princess.
DGML Simplified – Colors
Directed Graph Markup Language
Suppose we want to display the divisibility of numbers up to 16 among themselves:
2->{4;6;8;10;12;14;16}
3->{6;9;12;15}
4->{8;16}
5->{10;15}
6->12
7->14
8->16
Now suppose that we want to display the most dividers (2) in red and the most divided (12 & 16) in green:
Here is the DSL code:
2->{4;6;8;10;12;14;16}
3->{6;9;12;15}
4->{8;16}
5->{10;15}
6->12
7->14
8->16
color 2(#FF800000)
color 12(green)
color 16(green)
and here is the DGML:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’4′ Label=’4′ />
<Node Id=’5′ Label=’5′ />
<Node Id=’6′ Label=’6′ />
<Node Id=’7′ Label=’7′ />
<Node Id=’8′ Label=’8′ />
<Node Id=’9′ Label=’9′ />
<Node Id=’10’ Label=’10’ />
<Node Id=’12’ Label=’12’ Background=’Green’ />
<Node Id=’14’ Label=’14’ />
<Node Id=’15’ Label=’15’ />
<Node Id=’2′ Label=’2′ Background=’Red’ />
<Node Id=’3′ Label=’3′ />
<Node Id=’16’ Label=’16’ Background=’Green’ />
</Nodes>
<Links>
<Link Source=’3′ Target=’12’ />
<Link Source=’2′ Target=’14’ />
<Link Source=’7′ Target=’14’ />
<Link Source=’5′ Target=’10’ />
<Link Source=’3′ Target=’9′ />
<Link Source=’2′ Target=’16’ />
<Link Source=’3′ Target=’15’ />
<Link Source=’8′ Target=’16’ />
<Link Source=’2′ Target=’4′ />
<Link Source=’6′ Target=’12’ />
<Link Source=’4′ Target=’16’ />
<Link Source=’4′ Target=’8′ />
<Link Source=’5′ Target=’15’ />
<Link Source=’2′ Target=’6′ />
<Link Source=’2′ Target=’10’ />
<Link Source=’2′ Target=’8′ />
<Link Source=’2′ Target=’12’ />
<Link Source=’3′ Target=’6′ />
</Links>
</DirectedGraph>
And if we want to accentuate the prime numbers:
2->{4;6;8;10;12;14;16}
3->{6;9;12;15}
4->{8;16}
5->{10;15}
6->12
7->14
8->16
color 2(#FF800000)
color 12(green)
color 16(green)
border 2(Navy 2)
border 3(Navy 2)
border 5(Navy 2)
border 7(Navy 2)
The “2” in “Navy 2” is the thickness of the border (by the way you can use “outline” instead of “border” as MSDN documentation uses it).
Here is the DGML:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’4′ Label=’4′ />
<Node Id=’5′ Label=’5′ Stroke=’Navy’ StrokeThickness=’2′ />
<Node Id=’6′ Label=’6′ />
<Node Id=’7′ Label=’7′ Stroke=’Navy’ StrokeThickness=’2′ />
<Node Id=’8′ Label=’8′ />
<Node Id=’9′ Label=’9′ />
<Node Id=’10’ Label=’10’ />
<Node Id=’12’ Label=’12’ Background=’Green’ />
<Node Id=’14’ Label=’14’ />
<Node Id=’15’ Label=’15’ />
<Node Id=’2′ Label=’2′ Background=’#ff800000′ Stroke=’Navy’ StrokeThickness=’2′ />
<Node Id=’3′ Label=’3′ Stroke=’Navy’ StrokeThickness=’2′ />
<Node Id=’16’ Label=’16’ Background=’Green’ />
</Nodes>
<Links>
<Link Source=’3′ Target=’12’ />
<Link Source=’2′ Target=’14’ />
<Link Source=’7′ Target=’14’ />
<Link Source=’5′ Target=’10’ />
<Link Source=’3′ Target=’9′ />
<Link Source=’2′ Target=’16’ />
<Link Source=’3′ Target=’15’ />
<Link Source=’8′ Target=’16’ />
<Link Source=’2′ Target=’4′ />
<Link Source=’6′ Target=’12’ />
<Link Source=’4′ Target=’16’ />
<Link Source=’4′ Target=’8′ />
<Link Source=’5′ Target=’15’ />
<Link Source=’2′ Target=’6′ />
<Link Source=’2′ Target=’10’ />
<Link Source=’2′ Target=’8′ />
<Link Source=’2′ Target=’12’ />
<Link Source=’3′ Target=’6′ />
</Links>
</DirectedGraph>
And if we want to isolate the lone guy (9) and attract some attention to the maximum (16):
2->{4;6;8;10;12;14;16}
3->{6;9;12;15}
4->{8;16}
5->{10;15}
6->12
7->14
8->16
color 2(#FF800000)
color 12(green)
color 16(green)
border 2(Navy 2)
border 3(Navy 2)
border 5(Navy 2)
border 7(Navy 2)
border 9(1.5 #FF800080 Dashed)
color 9(Transparent)
border 16(2.5 dotted Red)
With the corresponding DGML:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’4′ Label=’4′ />
<Node Id=’5′ Label=’5′ Stroke=’Navy’ StrokeThickness=’2′ />
<Node Id=’6′ Label=’6′ />
<Node Id=’7′ Label=’7′ Stroke=’Navy’ StrokeThickness=’2′ />
<Node Id=’8′ Label=’8′ />
<Node Id=’9′ Label=’9′ Background=’Transparent’ Stroke=’#FF800080′ StrokeThickness=’1.5′ StrokeDashArray=’3 1′ />
<Node Id=’10’ Label=’10’ />
<Node Id=’12’ Label=’12’ Background=’Green’ />
<Node Id=’14’ Label=’14’ />
<Node Id=’15’ Label=’15’ />
<Node Id=’2′ Label=’2′ Background=’#ff800000′ Stroke=’Navy’ StrokeThickness=’2′ />
<Node Id=’3′ Label=’3′ Stroke=’Navy’ StrokeThickness=’2′ />
<Node Id=’16’ Label=’16’ Background=’Green’ Stroke=’Red’ StrokeThickness=’2.5′ StrokeDashArray=’1 1′ />
</Nodes>
<Links>
<Link Source=’3′ Target=’12’ />
<Link Source=’2′ Target=’14’ />
<Link Source=’7′ Target=’14’ />
<Link Source=’5′ Target=’10’ />
<Link Source=’3′ Target=’9′ />
<Link Source=’2′ Target=’16’ />
<Link Source=’3′ Target=’15’ />
<Link Source=’8′ Target=’16’ />
<Link Source=’2′ Target=’4′ />
<Link Source=’6′ Target=’12’ />
<Link Source=’4′ Target=’16’ />
<Link Source=’4′ Target=’8′ />
<Link Source=’5′ Target=’15’ />
<Link Source=’2′ Target=’6′ />
<Link Source=’2′ Target=’10’ />
<Link Source=’2′ Target=’8′ />
<Link Source=’2′ Target=’12’ />
<Link Source=’3′ Target=’6′ />
</Links>
</DirectedGraph>
Next, I will build a set of examples.
DGML Simplified – Shapes
Directed Graph Markup Language
The previous entry finished with the following file describing how to use the DSL:
default shape Rectangle
dgml.bat usage.txt -> usage.dgml
But we don’t want the command line to be in a rectangle:
default shape Rectangle
dgml.bat usage.txt -> usage.dgml
shape dgml.bat usage.txt(None)
Notice that “dgml.bat usage.txt” is a valid node name but it is not safe to be typed multiple times; we can define an abbreviated node name for it (command) and specify that node’s label to be “dgml.bat usage.txt”:
default shape Rectangle
command -> usage.dgml
shape command(None)
label command(dgml.bat usage.txt)
Notice that there is no requirement to define a label for a shape before using the shape itself.
And here is the DGML that corresponds to it:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’usage.dgml’ Label=’usage.dgml’ NodeRadius=’0′ />
<Node Id=’command’ Label=’dgml.bat usage.txt’ Shape=’None’ />
</Nodes>
<Links>
<Link Source=’command’ Target=’usage.dgml’ />
</Links>
</DirectedGraph>
Now we can enumerate the available shapes in the DGML DSL itself:
Shapes->{Button; Rectangle; RoundedRectangle; None}
shape Rectangle(Rectangle)
shape RoundedRectangle(RoundedRectangle)
shape None(None)
Here is the DGML:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’Button’ Label=’Button’ />
<Node Id=’None’ Label=’None’ Shape=’None’ />
<Node Id=’RoundedRectangle’ Label=’RoundedRectangle’ NodeRadius=’4′ />
<Node Id=’Rectangle’ Label=’Rectangle’ NodeRadius=’0′ />
<Node Id=’Shapes’ Label=’Shapes’ />
</Nodes>
<Links>
<Link Source=’Shapes’ Target=’None’ />
<Link Source=’Shapes’ Target=’Button’ />
<Link Source=’Shapes’ Target=’Rectangle’ />
<Link Source=’Shapes’ Target=’RoundedRectangle’ />
</Links>
</DirectedGraph>
Notice that there is no shape specification for Button because by default it looks like it; but if our default shape is something else then we must specify it (and there is no “Button” shape attribute for a node in DGML).
default shape None
Shapes->{Button; Rectangle; RoundedRectangle; None}
shape Button(Button)
shape Rectangle(Rectangle)
shape RoundedRectangle(RoundedRectangle)
And here is the DGML:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’Button’ Label=’Button’ />
<Node Id=’None’ Label=’None’ Shape=’None’ />
<Node Id=’RoundedRectangle’ Label=’RoundedRectangle’ NodeRadius=’4′ />
<Node Id=’Rectangle’ Label=’Rectangle’ NodeRadius=’0′ />
<Node Id=’Shapes’ Label=’Shapes’ Shape=’None’ />
</Nodes>
<Links>
<Link Source=’Shapes’ Target=’None’ />
<Link Source=’Shapes’ Target=’Button’ />
<Link Source=’Shapes’ Target=’Rectangle’ />
<Link Source=’Shapes’ Target=’RoundedRectangle’ />
</Links>
</DirectedGraph>
Note that specifying “shape nodename(Button)” has the effect of taking the Shape specification out of the DGML! (or rather of not putting it there in the first place).
Next time I will continue with colors.
August 20, 2010
DGML Simplified
Directed Graph Markup Language simplified … just a little bit
Although DGML is simple enough, coding in it (in XML) is tedious; so I developed a DSL to do the DGML generation for me.
Suppose that you want to show a relationship between a and b; you would naturally write:
a –> b
which gives:
or:
depending on your orientation preference.
If you prefer raw DGML here is how it looks like:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Links>
<Link Source=’a’ Target=’b’ />
</Links>
</DirectedGraph>
If you have multiple relations, you could write:
a –> b
b –> c
c –> d
which gives:
But wouldn’t you rather write:
a –> b –> c –> d ?
If you have multiple relations stemming from a common root, you could write:
a –> b
a –> c
a –> d
which gives:
But the root node (a) is related to a set of nodes; so the preferred syntax is:
a –> { b; c; d }
Contrast this with the raw DGML:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Links>
<Link Source=’a’ Target=’b’ />
<Link Source=’a’ Target=’c’ />
<Link Source=’a’ Target=’d’ />
</Links>
</DirectedGraph>
And, of course, you sometimes have multiple nodes leading to an “end” node:
a –> end
b –> end
c –> end
which gives:
Again, this is set of nodes (namely { a; b; c }) that leads to the same “end” node:
{ a; b; c } –> end
But how is this thing used? In self-referential terms, like this:
where usage.txt contains:
dgml.bat usage.txt –> usage.dgml
Now that’s OK but I don’t want that button look around the command line and the output file, so I modify usage.txt as follows:
dgml.bat usage.txt -> usage.dgml
shape dgml.bat usage.txt(Rectangle)
shape usage.dgml(Rectangle)
which gives:
Remember that in DGML there are no pre-defined shapes such as Rectangle, RoundedRectangle etc.; the generated DGML looks like this:
<DirectedGraph xmlns=’http://schemas.microsoft.com/vs/2009/dgml’>
<Nodes>
<Node Id=’usage.dgml’ NodeRadius=’0′ />
<Node Id=’dgml.bat usage.txt’ NodeRadius=’0′ />
</Nodes>
<Links>
<Link Source=’dgml.bat usage.txt’ Target=’usage.dgml’ />
</Links>
</DirectedGraph>
So you have to remember that a rectangle has no corner radius (called NodeRadius) and declare the nodes explicitly just to give them the NodeRadius attribute.
But the code above (repeated here):
dgml.bat usage.txt -> usage.dgml
shape dgml.bat usage.txt(Rectangle)
shape usage.dgml(Rectangle)
is a bit redundant; why do we have to give a shape to each node explicitly? We could just specify a default shape for all nodes:
default shape Rectangle
dgml.bat usage.txt -> usage.dgml
And the output is the same:
I know this gets boring with the “usage” pattern, so I will continue with another post on shapes and other trivia.