I've seen the recently updated virtualizing diagram example and want to use it for my code. I made minor modifications to the example to address the situation that I have. I'm using GoXam for Silverlight version 1.3.5.4
My diagram is essentially a tree diagram but, sporadically, there are cases where I want to use a different layout. When such a case comes up, I add an extra node that I declare is a subgraph and give the appropriate nodes a subgraph key. I added a GroupTemplate that uses a grid layout for these nodes.
I modified the virtualizing sample to generate a
nonvirtual diagram that works like my code. Here's a capture (the GroupTemplate has been given a red background):
When I apply this to the virtualizing example, the grid layout for the group template isn't applied. Here's the detail of a particular group. The virtualization produces this:
However, I expected it to produce this:
I'm wondering what I need to do.
--------------------------------------------------
Below is the xaml for my non-virtualizing diagram. To update the virtualizing example, add the two new resources, add the GroupTemplate attribute to the diagram and add the Comparer attribute to the diagram's tree layout.
<UserControl x:Class="VirtualizingExample.NonVirtualGroups"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:go=â€http://schmas.nwoods.com/GoXamâ€
xmlns:golayout="clr-namespace:Northwoods.GoXam.Layout;assembly=Northwoods.GoSilverlight"
xmlns:local="clr-namespace:VirtualizingExample">
<go:NodePanel Sizing="Fixed"
go:Part.SelectionAdorned="True"
go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"
go:Node.LocationSpot="Center">
<go:NodeShape go:NodePanel.Figure="RoundedRectangle"
Width="{Binding Path=Data.Width}"
Height="{Binding Path=Data.Height}"
Fill="{Binding Path=Data.Color}" Stroke="Black"
StrokeThickness="1" />
<TextBlock Text="{Binding Path=Data.Key}" Foreground="Black"
HorizontalAlignment="Center" VerticalAlignment="Center" />
<Border go:Node.LocationElementName="GroupPanel"
BorderBrush="Red" BorderThickness="3"
Background="Red" Opacity="0.3"
go:Group.IsSubGraphExpanded="True">
<golayout:GridLayout
Sorting="Descending"
CellSize="100,0"
Conditions="Standard VisibleChanged"
Comparer="{StaticResource NodeComparer}"/>
<go:Diagram Grid.Row="1" x:Name="myDiagram" Padding="10"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
InitialStretch="UniformToFill"
NodeTemplate="{StaticResource NodeTemplate}"
GroupTemplate="{StaticResource GroupTemplate}">
<go:TreeLayout NodeSpacing="10"
Comparer="{StaticResource NodeComparer}"/>
My only other modificatons were to the methods GenerateNodes and GenerateLinks; this was done to produce an example that demonstrates my issue. I also added a comparer class.
These were all written so that the same code can generate both the virtual and nonvirtual diagrams.
public void GenerateNodes(IList nodes, bool bVirtual = true)
{
int numNodes = bVirtual ? 9999 : 100;
int groupsPerHundred = 10;
Random rand = new Random();
for (int i = 0; i < numNodes; i++)
{
var d = new NodeData()
{
Key = i.ToString(),
// Width and Height could be set based on the Category
// or other information available when creating this node data object
// assume VirtualTreeLayout will assign the Location
Color = String.Format("#{0:X}{1:X}{2:X}", 120 + rand.Next(100),
120 + rand.Next(100), 120 + rand.Next(100))
};
if (i == 0 || bVirtual)
d.Location = new Point(0, 0); // locate root node
if (rand.Next(groupsPerHundred) == 0 && i != 0)
{
// create a group node to contain this node
var g = new NodeData()
{
Key = d.Key + "-G",
Location = new Point(0, 0),
IsSubGraph = true
};
nodes.Add(g);
d.SubGraphKey = g.Key;
}
nodes.Add(d);
}
}
public void GenerateLinks(IList nodes, IList links)
{
int maxLinks = 3;
var available = new HashSet(nodes);
Random rand = new Random();
foreach (NodeData next in nodes)
{
available.Remove(next);
if (next.IsSubGraph)
continue;
int children = rand.Next(maxLinks) + 1;
for (int i = 0; i < children; i++)
{
NodeData to = available.FirstOrDefault(n => (!n.IsSubGraph));
if (to == null)
return;
available.Remove(to);
if (next.SubGraphKey != null && i == children - 1)
to.SubGraphKey = next.SubGraphKey;
links.Add(new LinkData() { From = next.Key, To = to.Key });
}
}
}
// This class provides a comparator of nodes
public class NodeComparer : IComparer, IComparer
{
#region IComparer Members - for nonvirtualizing diagram
public int Compare(Node x, Node y)
{
return Compare(x.Data as NodeData, y.Data as NodeData);
}
#endregion
#region IComparer Members - for virtualizing diagram
public int Compare(TreeVertex x, TreeVertex y)
{
var xVertex = x as VirtualizingTreeVertex;
var yVertex = y as VirtualizingTreeVertex;
if (xVertex == null || yVertex == null)
return 0;
return Compare (xVertex.Data, yVertex.Data);
}
#endregion
private int Compare(NodeData xData, NodeData yData)
{
if (xData == null || yData == null)
return 0;
int xInt;
int yInt;
if (!int.TryParse(xData.Key, out xInt) || !int.TryParse(yData.Key, out yInt))
return 0;
if (xInt == yInt)
return 0;
return xInt < yInt ? 1 : -1;
}
}