From 64163c710adb032cefea6bf4fde6e698d9a49d15 Mon Sep 17 00:00:00 2001 From: Alexander Smirnov Date: Wed, 20 May 2015 02:16:12 +0300 Subject: [PATCH] Many changes. See changelog.txt --- Documents/CHANGELOG.txt | 26 +- Documents/TODO.txt | 7 +- Examples/METRO.SimpleGraph/App.xaml | 2 +- .../Common/debug_template.xaml | 212 ++++++++++ .../METRO.SimpleGraph/Common/templates.xaml | 27 +- .../METRO.SimpleGraph.csproj | 12 + Examples/METRO.SimpleGraph/MainPageDebug.xaml | 66 ++++ .../METRO.SimpleGraph/MainPageDebug.xaml.cs | 362 ++++++++++++++++++ Examples/ShowcaseApp.WPF/App.config | 6 +- .../ExampleModels/DataVertex.cs | 3 +- .../ExampleModels/GraphExample.cs | 2 +- .../ShowcaseApp.WPF/ExampleModels/OrthEr.cs | 47 +++ Examples/ShowcaseApp.WPF/MainWindow.xaml | 2 +- .../ShowcaseApp.WPF/Models/ShowcaseHelper.cs | 7 +- .../ShowcaseApp.WPF/Pages/DebugGraph.xaml.cs | 40 +- .../Pages/EdgeRoutingGraph.xaml | 3 + .../ShowcaseApp.WPF/Pages/GeneralGraph.xaml | 7 +- .../ShowcaseApp.WPF/Pages/ThemedGraph.xaml | 7 +- .../Properties/Resources.Designer.cs | 44 +-- .../Properties/Settings.Designer.cs | 24 +- .../ShowcaseApp.WPF/ShowcaseApp.WPF.csproj | 6 +- .../Templates/ERGraphXTemplates.xaml | 4 +- .../Templates/GeneralTemplate.xaml | 2 +- .../Templates/TestTemplates.xaml | 29 +- ExternalDlls/FirstFloor.ModernUI.dll | Bin 232448 -> 231936 bytes GraphX.Controls/Controls/EdgeControl.cs | 83 ++-- .../Controls/EdgePointers/EdgePointerImage.cs | 12 +- .../Controls/EdgePointers/EdgePointerPath.cs | 164 ++++++++ GraphX.Controls/Controls/GraphArea.cs | 9 +- GraphX.Controls/Controls/Misc/IEdgePointer.cs | 5 +- .../Controls/Misc/IVertexConnectionPoint.cs | 26 ++ .../StaticVertexConnectionPoint.cs | 94 +++++ GraphX.Controls/Controls/VertexControl.cs | 25 ++ .../ZoomControl/Helpers/VisualTreeHelperEx.cs | 242 ++++++------ GraphX.Controls/GraphX.WPF.Controls.csproj | 9 +- GraphX.Controls/Themes/Generic.xaml | 1 + GraphX.Controls/TypeExtensions.cs | 25 ++ GraphX.METRO.Controls/Controls/EdgeControl.cs | 90 +++-- .../Controls/EdgePointers/EdgePointerImage.cs | 26 +- .../Controls/EdgePointers/EdgePointerPath.cs | 170 ++++++++ GraphX.METRO.Controls/Controls/GraphArea.cs | 4 +- .../Controls/Misc/IEdgePointer.cs | 2 +- .../Controls/Misc/IVertexConnectionPoint.cs | 26 ++ .../StaticVertexConnectionPoint.cs | 116 ++++++ .../Controls/VertexControl.cs | 24 ++ .../ZoomControl/Helpers/VisualTreeHelperEx.cs | 236 +++++++----- .../GraphX.METRO.Controls.csproj | 3 + GraphX.METRO.Controls/TypeExtensions.cs | 6 + GraphX.PCL.Common/Enums/VertexShape.cs | 3 +- GraphX.PCL.Common/GraphX.PCL.Common.csproj | 3 +- GraphX.PCL.Common/Interfaces/IGXLogicCore.cs | 4 + GraphX.PCL.Common/Interfaces/IGraphXEdge.cs | 24 +- .../Interfaces/ILayoutEdgeRouting.cs | 18 + GraphX.PCL.Common/Interfaces/IWeightedEdge.cs | 3 + GraphX.PCL.Common/Models/EdgeBase.cs | 21 +- .../PathFinderER/PathFinderEdgeRouting.cs | 92 +++-- ...amaLayoutAlgorithm.HorizontalAssignment.cs | 41 +- .../EfficientSugiyamaLayoutAlgorithm.cs | 40 +- .../EfficientSugiyamaLayoutParameters.cs | 10 +- .../Algorithms/OverlapRemoval/FSAAlgorithm.cs | 39 +- GraphX.PCL.Logic/GraphX.PCL.Logic.csproj | 2 +- GraphX.PCL.Logic/packages.config | 2 +- 62 files changed, 2151 insertions(+), 496 deletions(-) create mode 100644 Examples/METRO.SimpleGraph/Common/debug_template.xaml create mode 100644 Examples/METRO.SimpleGraph/MainPageDebug.xaml create mode 100644 Examples/METRO.SimpleGraph/MainPageDebug.xaml.cs create mode 100644 Examples/ShowcaseApp.WPF/ExampleModels/OrthEr.cs create mode 100644 GraphX.Controls/Controls/EdgePointers/EdgePointerPath.cs create mode 100644 GraphX.Controls/Controls/Misc/IVertexConnectionPoint.cs create mode 100644 GraphX.Controls/Controls/VertexConnectionPoints/StaticVertexConnectionPoint.cs create mode 100644 GraphX.METRO.Controls/Controls/EdgePointers/EdgePointerPath.cs create mode 100644 GraphX.METRO.Controls/Controls/Misc/IVertexConnectionPoint.cs create mode 100644 GraphX.METRO.Controls/Controls/VertexConnectionPoints/StaticVertexConnectionPoint.cs create mode 100644 GraphX.PCL.Common/Interfaces/ILayoutEdgeRouting.cs diff --git a/Documents/CHANGELOG.txt b/Documents/CHANGELOG.txt index fdd996e..08ed091 100644 --- a/Documents/CHANGELOG.txt +++ b/Documents/CHANGELOG.txt @@ -1,13 +1,34 @@ -RELEASE 2.1.9 +RELEASE 2.1.9 WIP +NEW TERMS: + VAESPS - vertex and edge skip processing support + VCP - vertex connection point + +HIGHLIGHTS: + I. As new edge pointers logic has been added (image/path based pointers) the old logic that utilizes direct Path object in EdgeControl template will be removed in GraphX 2.2.0 + II. VCPs has been added into GraphX making edge endpoint fixation(binding) possible. By default GraphX automaticaly calculates edge endpoint position relative to vertex dimensions + and approximate math shape, but with this feature on you'll be able to bind edge endpoint to a separate customizable object. This will allow you to create static edge fixation + endpoints on the vertex and give you full control over edge endpoints positioning. + III. Now you can easily customize edge pointers with the help of EdgePointerImage and EdgePointerPath classes. Changes include more precious edge endpoint calculations so the edge + will overlap with the edge pointer no more. + +DETAILED CHANGELOG: ++ Added support for custom VCP [WPF, METRO] + * New control class added: StaticVertexConnectionPoint + * VCP support the same math shapes as VertexShape property or can use VertexShape::None value to disable roundtrip calculations + Added vertex and edge skip processing support to METRO version (VAESPS) [METRO] + Added VAESPS for following algorithms: Circular [ALL] ++ Added VertexShape::None enum option, currently affecting only VCP logic [ALL] ++ Added different layout options to EfficientSugiyama algorithm using new Direction param [ALL] ++ Added true orthogonal edge routing for EfficientSugiyama algorithm using EdgeRouting param [ALL] + Refactored almost all of the GraphX code for improvements and code quality. Changed many namespaces for better name reflection [ALL] + Fixed layout algorithm calculations to always receive actual vertex positions as input parameter This will fix VAESPS for default algorithms. [WPF, METRO] ++ Fixed outdated edge rendering in some cases when vertex coordinates are changed manualy [WPF, METRO] ++ Fixed edge overlapping edge pointers (image, path) [WPF, METRO] + Adjusted FR and BoundedFR default values for random initial positions [All] + Fixed some algorithm calculation problems, especial FR [ALL] -!BREAKING CHANGES +BREAKING CHANGES: !!!WARNING!!! This GraphX version has fallen under the heavy hand of code refactoring and along with the numerous code improvements almost ALL of the namespaces has been changed to better reflect PCL and multiplatform library versioning. Also i've get rid of the several different XAML xmlns usings in favor of single one that reflects library platform. I'm very sorry that this changes will @@ -19,6 +40,7 @@ - All base models and interfaces are now in GraphX.PCL.Common.Models namespace - All GraphX primitives (Point, Rect, etc.) are left in GraphX.Measure for better code readability in cases when they are intersected with System.Windows namespace twins +IGXLogicCore now include ExternalLayoutAlgorithm, ExternalOverlapRemovalAlgorithm, ExternalEdgeRoutingAlgorithm for simplier external algo assignment RELEASE 2.1.8 + Added basic support for Image based edge pointers. Introduced new object for EdgeControl template: [WPF, METRO(bugged)] diff --git a/Documents/TODO.txt b/Documents/TODO.txt index 900c03c..2eccbd3 100644 --- a/Documents/TODO.txt +++ b/Documents/TODO.txt @@ -1,7 +1,6 @@ - - New things: - 1. Sizes logic. Now matters only GraphArea::ContentSize - 2. Now all vertices and edges positioned in GraphArea using TOP-LEFT corner as the position coordinates (previously coordinates was pointing at the object center) +TODO +1. CUT source ep edge also + Add edge labels - labels on path diff --git a/Examples/METRO.SimpleGraph/App.xaml b/Examples/METRO.SimpleGraph/App.xaml index 308df30..276b313 100644 --- a/Examples/METRO.SimpleGraph/App.xaml +++ b/Examples/METRO.SimpleGraph/App.xaml @@ -2,7 +2,7 @@ x:Class="METRO.SimpleGraph.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:local="using:METRO.SimpleGraph"> + > diff --git a/Examples/METRO.SimpleGraph/Common/debug_template.xaml b/Examples/METRO.SimpleGraph/Common/debug_template.xaml new file mode 100644 index 0000000..8f633c6 --- /dev/null +++ b/Examples/METRO.SimpleGraph/Common/debug_template.xaml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/METRO.SimpleGraph/Common/templates.xaml b/Examples/METRO.SimpleGraph/Common/templates.xaml index f9259be..f86e305 100644 --- a/Examples/METRO.SimpleGraph/Common/templates.xaml +++ b/Examples/METRO.SimpleGraph/Common/templates.xaml @@ -111,22 +111,23 @@ - - + + --> App.xaml + + MainPageDebug.xaml + MainPage.xaml @@ -161,6 +164,15 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + MSBuild:Compile Designer diff --git a/Examples/METRO.SimpleGraph/MainPageDebug.xaml b/Examples/METRO.SimpleGraph/MainPageDebug.xaml new file mode 100644 index 0000000..e16fd69 --- /dev/null +++ b/Examples/METRO.SimpleGraph/MainPageDebug.xaml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/METRO.SimpleGraph/MainPageDebug.xaml.cs b/Examples/METRO.SimpleGraph/MainPageDebug.xaml.cs new file mode 100644 index 0000000..30706e9 --- /dev/null +++ b/Examples/METRO.SimpleGraph/MainPageDebug.xaml.cs @@ -0,0 +1,362 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Navigation; +using GraphX.METRO.Controls.Animations; +using GraphX.METRO.Controls.Models; +using GraphX.PCL.Common.Enums; +using GraphX.PCL.Logic.Algorithms.LayoutAlgorithms; +using GraphX.PCL.Logic.Algorithms.OverlapRemoval; + +// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 + +namespace METRO.SimpleGraph +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class MainPageDebug : Page + { + public MainPageDebug() + { + InitializeComponent(); + + cboxLayout.ItemsSource = Enum.GetValues(typeof(LayoutAlgorithmTypeEnum)).Cast();//.Where(a=> a != LayoutAlgorithmTypeEnum.FR && a != LayoutAlgorithmTypeEnum.BoundedFR).ToArray(); + cboxOverlap.ItemsSource = Enum.GetValues(typeof(OverlapRemovalAlgorithmTypeEnum)).Cast(); + cboxEdgeRouting.ItemsSource = Enum.GetValues(typeof(EdgeRoutingAlgorithmTypeEnum)).Cast(); + + cboxLayout.SelectedItem = LayoutAlgorithmTypeEnum.LinLog; + cboxOverlap.SelectedItem = OverlapRemovalAlgorithmTypeEnum.FSA; + cboxEdgeRouting.SelectedItem = EdgeRoutingAlgorithmTypeEnum.None; + + cboxLayout.SelectionChanged += cboxLayout_SelectionChanged; + cboxOverlap.SelectionChanged += cboxOverlap_SelectionChanged; + cboxEdgeRouting.SelectionChanged += cboxEdgeRouting_SelectionChanged; + + butRelayout.Click += butRelayout_Click; + butGenerate.Click += butGenerate_Click; + graph.GenerateGraphFinished += OnFinishedLayout; + graph.RelayoutFinished += OnFinishedLayout; + graph.AlignAllEdgesLabels(); + Loaded += MainPage_Loaded; + } + + void OnFinishedLayout(object sender, EventArgs e) + { + zc.ZoomToFill(); + + var count = 0; + + } + + private async void butGenerate_Click(object sender, RoutedEventArgs e) + { + GraphAreaExample_Setup(); + + try + { + await graph.GenerateGraphAsync(true); + } + catch (OperationCanceledException) + { + // User may have canceled + } + } + + async void butRelayout_Click(object sender, RoutedEventArgs e) + { + try + { + var t0 = DateTime.Now; + await graph.RelayoutGraphAsync(); + Debug.WriteLine("Time elapsed: {0}", DateTime.Now - t0); + } + catch (OperationCanceledException) + { + // User may have canceled + } + } + + void cboxEdgeRouting_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (graph.LogicCore == null) return; + graph.LogicCore.DefaultEdgeRoutingAlgorithm = (EdgeRoutingAlgorithmTypeEnum)cboxEdgeRouting.SelectedItem; + } + + void cboxOverlap_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (graph.LogicCore == null) return; + graph.LogicCore.DefaultOverlapRemovalAlgorithm = (OverlapRemovalAlgorithmTypeEnum)cboxOverlap.SelectedItem; + } + + void cboxLayout_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if(graph.LogicCore == null) return; + var late = (LayoutAlgorithmTypeEnum) cboxLayout.SelectedItem; + graph.LogicCore.DefaultLayoutAlgorithm = late; + if (late == LayoutAlgorithmTypeEnum.BoundedFR) + graph.LogicCore.DefaultLayoutAlgorithmParams + = graph.LogicCore.AlgorithmFactory.CreateLayoutParameters(LayoutAlgorithmTypeEnum.BoundedFR); + if (late == LayoutAlgorithmTypeEnum.FR) + graph.LogicCore.DefaultLayoutAlgorithmParams + = graph.LogicCore.AlgorithmFactory.CreateLayoutParameters(LayoutAlgorithmTypeEnum.FR); + } + + async void MainPage_Loaded(object sender, RoutedEventArgs e) + { + InitialSetup(); + GraphAreaExample_Setup(); + + try + { + //await graph.GenerateGraphAsync(true); + graph.PreloadVertexes(graph.LogicCore.Graph); + var count = 0; + foreach (var item in graph.VertexList.Values.ToList()) + { + if (count == 0) + item.SetPosition(0, 0); + if (count == 1) + item.SetPosition(400, 0); + + count++; + } + graph.GenerateAllEdges(); + graph.SetVerticesDrag(true); + } + catch (OperationCanceledException) + { + // User may have canceled + } + + //graph.RelayoutGraph(true); + //zc.ZoomToFill(); + //graph.VertexList.Values.ToList()[0].SetPosition(new Point(0, 0)); + //graph.VertexList.Values.ToList()[1].SetPosition(new Point(100, 0)); + } + + /// + /// Invoked when this page is about to be displayed in a Frame. + /// + /// Event data that describes how this page was reached. The Parameter + /// property is typically used to configure the page. + protected override void OnNavigatedTo(NavigationEventArgs e) + { + } + + private void AddEdge(GraphExample igraph, int index1, int index2, IReadOnlyList vlist) + { + var dataEdge = new DataEdge(vlist[index1], vlist[index2]) + { + Text = string.Format("Edge {0}{1}", vlist[index1].ID, vlist[index2].ID), + VisualEdgeThickness = _rnd.Next(1, 4), + VisualEdgeTransparency = 1.0, + VisualColor = "#ffffff" + }; + igraph.AddEdge(dataEdge); + } + + private readonly Random _rnd = new Random(); + private GraphExample GraphExample_Setup() + { + var dataGraph = new GraphExample(); + + //debug + + + dataGraph.AddVertex(new DataVertex("MyVertex " + 1) { ID = 1, VisualDiameter = 10, VisualInnerDiameter = 10 }); + dataGraph.AddVertex(new DataVertex("MyVertex " + 2) { ID = 2, VisualDiameter = 10, VisualInnerDiameter = 10 }); + var vlist = dataGraph.Vertices.ToList(); + AddEdge(dataGraph, 0, 1, vlist); + return dataGraph; + + + + switch ((LayoutAlgorithmTypeEnum)cboxLayout.SelectedItem) + { + case LayoutAlgorithmTypeEnum.EfficientSugiyama: + case LayoutAlgorithmTypeEnum.Sugiyama: + case LayoutAlgorithmTypeEnum.BoundedFR: + case LayoutAlgorithmTypeEnum.FR: + case LayoutAlgorithmTypeEnum.Tree: + for (int i = 1; i < 14; i++) + { + var dataVertex = new DataVertex("MyVertex " + i) { ID = i, VisualDiameter = _rnd.Next(25, 50), VisualInnerDiameter = _rnd.Next(10, 22) }; + dataGraph.AddVertex(dataVertex); + } + vlist = dataGraph.Vertices.ToList(); + AddEdge(dataGraph, 0, 1, vlist); + AddEdge(dataGraph, 0, 2, vlist); + AddEdge(dataGraph, 1, 3, vlist); + AddEdge(dataGraph, 1, 4, vlist); + AddEdge(dataGraph, 2, 5, vlist); + AddEdge(dataGraph, 2, 6, vlist); + AddEdge(dataGraph, 2, 7, vlist); + + AddEdge(dataGraph, 8, 9, vlist); + AddEdge(dataGraph, 9, 10, vlist); + AddEdge(dataGraph, 10, 7, vlist); + AddEdge(dataGraph, 10, 11, vlist); + AddEdge(dataGraph, 10, 12, vlist); + + break; + default: + for (var i = 1; i < 11; i++) + { + var dataVertex = new DataVertex("MyVertex " + i) { ID = i, VisualDiameter = _rnd.Next(50, 100), VisualInnerDiameter = _rnd.Next(20, 45) }; + if (i == 2) + dataVertex.LabelText += "\nMultiline!"; + dataGraph.AddVertex(dataVertex); + } + vlist = dataGraph.Vertices.ToList(); + AddEdge(dataGraph, 0, 1, vlist); + + AddEdge(dataGraph, 1, 2, vlist); + AddEdge(dataGraph, 1, 3, vlist); + AddEdge(dataGraph, 1, 4, vlist); + + AddEdge(dataGraph, 4, 5, vlist); + AddEdge(dataGraph, 4, 6, vlist); + + AddEdge(dataGraph, 2, 7, vlist); + AddEdge(dataGraph, 2, 8, vlist); + + AddEdge(dataGraph, 8, 9, vlist); + + //add some cross references + AddEdge(dataGraph, 4, 2, vlist); + AddEdge(dataGraph, 4, 8, vlist); + AddEdge(dataGraph, 9, 2, vlist); + + break; + } + + /* foreach (var item in graph.EdgesList) + { + //item.Value.LabelVerticalOffset = -40; + item.Value.LabelAngle = 45; + }*/ + + + return dataGraph; + + /*ManipulationDelta += MainPage_ManipulationDelta; + ManipulationMode = ManipulationModes.Scale; + + for (int i = 1; i < 10; i++) + { + var dataVertex = new DataVertex("MyVertex " + i) { ID = i }; + dataGraph.AddVertex(dataVertex); + } + + var vlist = dataGraph.Vertices.ToList(); + //var dataEdge = new DataEdge(vlist[0], vlist[1]) { Text = string.Format("{0} -> {1}", vlist[0], vlist[1]) }; + //dataGraph.AddEdge(dataEdge); + var dataEdge = new DataEdge(vlist[2], vlist[3]) { Text = "23" }; + dataGraph.AddEdge(dataEdge); + dataEdge = new DataEdge(vlist[3], vlist[2]) { Text = "32" }; + dataGraph.AddEdge(dataEdge); + + return dataGraph;*/ + } + + void MainPage_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) + { + + } + + private void InitialSetup() + { + var logicCore = new GXLogicCoreExample(); + graph.LogicCore = logicCore; + + var layParams = new LinLogLayoutParameters { IterationCount = 100 }; + logicCore.DefaultLayoutAlgorithm = LayoutAlgorithmTypeEnum.SimpleRandom; + logicCore.DefaultLayoutAlgorithmParams = layParams; + + logicCore.DefaultOverlapRemovalAlgorithmParams = logicCore.AlgorithmFactory.CreateOverlapRemovalParameters(OverlapRemovalAlgorithmTypeEnum.FSA); + ((OverlapRemovalParameters)logicCore.DefaultOverlapRemovalAlgorithmParams).HorizontalGap = 50; + ((OverlapRemovalParameters)logicCore.DefaultOverlapRemovalAlgorithmParams).VerticalGap = 50; + + graph.MoveAnimation = AnimationFactory.CreateMoveAnimation(MoveAnimation.Move, TimeSpan.FromMilliseconds(500)); + graph.MoveAnimation.Completed += MoveAnimation_Completed; + } + + private void GraphAreaExample_Setup() + { + + var logicCore = graph.GetLogicCore(); + var dataGraph = GraphExample_Setup(); + logicCore.Graph = dataGraph; + + + /*LogicCore.DefaultLayoutAlgorithmParams = LogicCore.AlgorithmFactory.CreateLayoutParameters(GraphX.LayoutAlgorithmTypeEnum.KK); + ((KKLayoutParameters)LogicCore.DefaultLayoutAlgorithmParams).MaxIterations = 100; + cboxOverlap.SelectedItem = OverlapRemovalAlgorithmTypeEnum.FSA; + + cboxEdgeRouting.SelectedItem = EdgeRoutingAlgorithmTypeEnum.SimpleER; + LogicCore.AsyncAlgorithmCompute = false; + + graph.SetVerticesHighlight(true, GraphControlType.VertexAndEdge, EdgesType.All); + graph.SetEdgesHighlight(true, GraphControlType.VertexAndEdge); + + + + */ + + switch ((LayoutAlgorithmTypeEnum) cboxLayout.SelectedItem) + { + case LayoutAlgorithmTypeEnum.EfficientSugiyama: + logicCore.DefaultLayoutAlgorithmParams = new EfficientSugiyamaLayoutParameters { VertexDistance = 50 }; + break; + } + + + switch ((LayoutAlgorithmTypeEnum)cboxLayout.SelectedItem) + { + case LayoutAlgorithmTypeEnum.EfficientSugiyama: + case LayoutAlgorithmTypeEnum.Sugiyama: + case LayoutAlgorithmTypeEnum.BoundedFR: + case LayoutAlgorithmTypeEnum.FR: + case LayoutAlgorithmTypeEnum.Tree: + cboxEdgeRouting.SelectedItem = EdgeRoutingAlgorithmTypeEnum.SimpleER; + break; + default: + cboxEdgeRouting.SelectedItem = EdgeRoutingAlgorithmTypeEnum.SimpleER; + break; + } + + logicCore.EnableParallelEdges = true; + logicCore.ParallelEdgeDistance = 25; + logicCore.EdgeCurvingEnabled = true; + + graph.SetVerticesDrag(true, true); + graph.SetVerticesMathShape(VertexShape.Circle); + graph.ShowAllVerticesLabels(); + graph.ShowAllEdgesLabels(); + + //DEBUG + graph.UseLayoutRounding = false; + zc.UseLayoutRounding = false; + + graph.ShowAllEdgesLabels(false); + graph.LogicCore.ExternalEdgeRoutingAlgorithm = null; + graph.LogicCore.DefaultEdgeRoutingAlgorithm = EdgeRoutingAlgorithmTypeEnum.None; + graph.SetVerticesMathShape(VertexShape.Rectangle); + //graph.MouseOverAnimation = AnimationFactory.CreateMouseOverAnimation(MouseOverAnimation.Scale); + + /*cboxLayout_SelectionChanged(null, null); + cboxOverlap_SelectionChanged(null, null); + cboxEdgeRouting_SelectionChanged(null, null);*/ + } + + void MoveAnimation_Completed(object sender, EventArgs e) + { + zc.ZoomToFill(); + } + } +} diff --git a/Examples/ShowcaseApp.WPF/App.config b/Examples/ShowcaseApp.WPF/App.config index a101ef9..74ade9d 100644 --- a/Examples/ShowcaseApp.WPF/App.config +++ b/Examples/ShowcaseApp.WPF/App.config @@ -1,6 +1,6 @@ - + - + - \ No newline at end of file + diff --git a/Examples/ShowcaseApp.WPF/ExampleModels/DataVertex.cs b/Examples/ShowcaseApp.WPF/ExampleModels/DataVertex.cs index 04561ac..b3ba87c 100644 --- a/Examples/ShowcaseApp.WPF/ExampleModels/DataVertex.cs +++ b/Examples/ShowcaseApp.WPF/ExampleModels/DataVertex.cs @@ -1,4 +1,5 @@ -using GraphX; +using System.Windows.Media; +using GraphX; using GraphX.PCL.Common.Models; namespace ShowcaseApp.WPF diff --git a/Examples/ShowcaseApp.WPF/ExampleModels/GraphExample.cs b/Examples/ShowcaseApp.WPF/ExampleModels/GraphExample.cs index 8768509..84115ca 100644 --- a/Examples/ShowcaseApp.WPF/ExampleModels/GraphExample.cs +++ b/Examples/ShowcaseApp.WPF/ExampleModels/GraphExample.cs @@ -2,7 +2,7 @@ using QuickGraph; namespace ShowcaseApp.WPF { - public class GraphExample : BidirectionalGraph + public class GraphExample : BidirectionalGraph, IMutableBidirectionalGraph { } diff --git a/Examples/ShowcaseApp.WPF/ExampleModels/OrthEr.cs b/Examples/ShowcaseApp.WPF/ExampleModels/OrthEr.cs new file mode 100644 index 0000000..32b0eda --- /dev/null +++ b/Examples/ShowcaseApp.WPF/ExampleModels/OrthEr.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.Threading; +using GraphX.Measure; +using GraphX.PCL.Common.Interfaces; +using GraphX.PCL.Logic.Algorithms.EdgeRouting; +using QuickGraph; + +namespace ShowcaseApp.WPF.ExampleModels +{ + public class OrthEr : EdgeRoutingAlgorithmBase + where TGraph : class, IMutableBidirectionalGraph + where TEdge : class, IGraphXEdge + where TVertex : class, IGraphXVertex + { + + public OrthEr(TGraph graph, IDictionary vertexPositions, IDictionary vertexSizes, IEdgeRoutingParameters parameters = null) : + base(graph, vertexPositions, vertexSizes, parameters) + { + + } + + + public override void Compute(CancellationToken cancellationToken) + { + foreach (var edge in Graph.Edges) + { + var sourcePosition = VertexPositions[edge.Source]; + var targetPosition = VertexPositions[edge.Target]; + var sourceSize = VertexSizes[edge.Source]; + var targetSize = VertexSizes[edge.Target]; + + if (sourcePosition.X != targetPosition.X ) + { + EdgeRoutes.Add( + edge, + new[] + { + new Point(0, 0), + new Point(targetPosition.X + targetSize.Width / 2, sourcePosition.Y + sourceSize.Height / 2), + new Point(0, 0) + }); + } + + } + } + } +} diff --git a/Examples/ShowcaseApp.WPF/MainWindow.xaml b/Examples/ShowcaseApp.WPF/MainWindow.xaml index 97f19bf..3cdec75 100644 --- a/Examples/ShowcaseApp.WPF/MainWindow.xaml +++ b/Examples/ShowcaseApp.WPF/MainWindow.xaml @@ -6,7 +6,7 @@ TextOptions.TextFormattingMode ="Ideal" UseLayoutRounding="False" ContentSource="/Pages/Introduction.xaml" - Height="600" Width="999"> + Height="720" Width="1280"> diff --git a/Examples/ShowcaseApp.WPF/Models/ShowcaseHelper.cs b/Examples/ShowcaseApp.WPF/Models/ShowcaseHelper.cs index a9c2b53..ce797d5 100644 --- a/Examples/ShowcaseApp.WPF/Models/ShowcaseHelper.cs +++ b/Examples/ShowcaseApp.WPF/Models/ShowcaseHelper.cs @@ -31,11 +31,13 @@ namespace ShowcaseApp.WPF.Models } #region GenerateDataGraph + /// /// Generate example graph data /// /// Items count - public static GraphExample GenerateDataGraph(int count) + /// + public static GraphExample GenerateDataGraph(int count, bool addEdges = true) { var graph = new GraphExample(); @@ -44,6 +46,9 @@ namespace ShowcaseApp.WPF.Models var vlist = graph.Vertices.ToList(); var cnt = 1; + + if (!addEdges) return graph; + foreach (var item in vlist) { if (Rand.Next(0, 50) > 25) continue; diff --git a/Examples/ShowcaseApp.WPF/Pages/DebugGraph.xaml.cs b/Examples/ShowcaseApp.WPF/Pages/DebugGraph.xaml.cs index f78e20b..a1dba30 100644 --- a/Examples/ShowcaseApp.WPF/Pages/DebugGraph.xaml.cs +++ b/Examples/ShowcaseApp.WPF/Pages/DebugGraph.xaml.cs @@ -2,13 +2,14 @@ using System.Linq; using System.Windows; using System.Windows.Controls; -using GraphX; using GraphX.PCL.Common.Enums; +using GraphX.PCL.Logic.Algorithms.LayoutAlgorithms; using GraphX.PCL.Logic.Algorithms.OverlapRemoval; using GraphX.WPF.Controls.Animations; using GraphX.WPF.Controls.Models; +using QuickGraph; +using ShowcaseApp.WPF.ExampleModels; using ShowcaseApp.WPF.Models; -using Point = GraphX.Measure.Point; namespace ShowcaseApp.WPF.Pages { @@ -49,20 +50,37 @@ namespace ShowcaseApp.WPF.Pages dg_Area.AlignAllEdgesLabels(true); dg_Area.GenerateGraph(true);*/ - var logicCore = new LogicCoreExample() { Graph = ShowcaseHelper.GenerateDataGraph(25) }; - foreach (var item in logicCore.Graph.Vertices.Take(4)) - { - item.SkipProcessing = ProcessingOptionEnum.Freeze; - } + var logicCore = new LogicCoreExample { Graph = ShowcaseHelper.GenerateDataGraph(5, false) }; + + var vlist = logicCore.Graph.Vertices.ToList(); + var edge = new DataEdge(vlist[0], vlist[1]);//{ SourceConnectionPointId = 2, TargetConnectionPointId = 1 }; + logicCore.Graph.AddEdge(edge); + edge = new DataEdge(vlist[0], vlist[2]);//{ SourceConnectionPointId = 3, TargetConnectionPointId = 1 }; + logicCore.Graph.AddEdge(edge); + edge = new DataEdge(vlist[2], vlist[3]); + logicCore.Graph.AddEdge(edge); + edge = new DataEdge(vlist[2], vlist[4]); + logicCore.Graph.AddEdge(edge); + + + //edge = new DataEdge(vlist[1], vlist[2]) { SourceConnectionPointId = 3, TargetConnectionPointId = 2 }; + //logicCore.Graph.AddEdge(edge); + + logicCore.DefaultLayoutAlgorithm = LayoutAlgorithmTypeEnum.EfficientSugiyama; + logicCore.DefaultLayoutAlgorithmParams = logicCore.AlgorithmFactory.CreateLayoutParameters(LayoutAlgorithmTypeEnum.EfficientSugiyama); + ((EfficientSugiyamaLayoutParameters)logicCore.DefaultLayoutAlgorithmParams).Direction = LayoutDirection.RightToLeft; + ((EfficientSugiyamaLayoutParameters)logicCore.DefaultLayoutAlgorithmParams).EdgeRouting = SugiyamaEdgeRoutings.Orthogonal; + ((EfficientSugiyamaLayoutParameters)logicCore.DefaultLayoutAlgorithmParams).LayerDistance = 100; + ((EfficientSugiyamaLayoutParameters) logicCore.DefaultLayoutAlgorithmParams).VertexDistance = 50; + //logicCore.ExternalEdgeRoutingAlgorithm = new OrthEr>(logicCore.Graph, null, null); - logicCore.DefaultLayoutAlgorithm = LayoutAlgorithmTypeEnum.Circular; logicCore.DefaultOverlapRemovalAlgorithm = OverlapRemovalAlgorithmTypeEnum.FSA; logicCore.DefaultOverlapRemovalAlgorithmParams = logicCore.AlgorithmFactory.CreateOverlapRemovalParameters(OverlapRemovalAlgorithmTypeEnum.FSA); ((OverlapRemovalParameters)logicCore.DefaultOverlapRemovalAlgorithmParams).HorizontalGap = 50; ((OverlapRemovalParameters)logicCore.DefaultOverlapRemovalAlgorithmParams).VerticalGap = 50; - logicCore.DefaultEdgeRoutingAlgorithm = EdgeRoutingAlgorithmTypeEnum.SimpleER; + logicCore.DefaultEdgeRoutingAlgorithm = EdgeRoutingAlgorithmTypeEnum.None; logicCore.AsyncAlgorithmCompute = false; - logicCore.EdgeCurvingEnabled = true; + logicCore.EdgeCurvingEnabled = false; dg_Area.LogicCore = logicCore; dg_Area.MoveAnimation = AnimationFactory.CreateMoveAnimation(MoveAnimation.Move, TimeSpan.FromSeconds(0.5)); @@ -75,7 +93,7 @@ namespace ShowcaseApp.WPF.Pages dg_Area.GenerateGraph(true); foreach (var item in logicCore.Graph.Vertices.Take(4)) { - dg_Area.VertexList[item].SetPosition(new System.Windows.Point()); + // dg_Area.VertexList[item].SetPosition(new Point()); } //dg_Area.RelayoutGraph(); diff --git a/Examples/ShowcaseApp.WPF/Pages/EdgeRoutingGraph.xaml b/Examples/ShowcaseApp.WPF/Pages/EdgeRoutingGraph.xaml index ed9a036..c155f2a 100644 --- a/Examples/ShowcaseApp.WPF/Pages/EdgeRoutingGraph.xaml +++ b/Examples/ShowcaseApp.WPF/Pages/EdgeRoutingGraph.xaml @@ -19,12 +19,15 @@ + + + diff --git a/Examples/ShowcaseApp.WPF/Pages/GeneralGraph.xaml b/Examples/ShowcaseApp.WPF/Pages/GeneralGraph.xaml index 4289916..386c588 100644 --- a/Examples/ShowcaseApp.WPF/Pages/GeneralGraph.xaml +++ b/Examples/ShowcaseApp.WPF/Pages/GeneralGraph.xaml @@ -10,8 +10,9 @@ d:DesignHeight="300" d:DesignWidth="600"> - + + @@ -40,7 +41,9 @@