зеркало из https://github.com/stride3d/GraphX.git
+ AttachedLabels and stuff
This commit is contained in:
Родитель
199b9c299c
Коммит
271ca09de3
|
@ -5,6 +5,11 @@ HIGHLIGHTS:
|
|||
Currently there are two modes supoported:
|
||||
- Layout groups to predefined bounds, when you can specify rectangular bounds in which vertices are layed (Bounds must be supported by algorithm used to layout vertices group)
|
||||
- Generate bounds from groups, when each group is layouted using its algorithm and bounds are automatically calculated to fit all vertices in the group and then group bounds overlaps can be removed.
|
||||
* Added two new label controls AttachedEdgeLabelControl and AttachedVertexLabelControl which acts like separate entities in GraphArea visual tree and have weak references to graphx controls. Default EdgeLableControl and VertexLabelControl are designed to act as the part of their parent classes and this approach impacts their customization possibilities when these parent classes are limited in size. So with the new labels you can mitigate following restrictions:
|
||||
- No more label cuts when vertex is strictly limited in width or height
|
||||
- No more jerky edge endpoints when edge label is too large
|
||||
- No more labels behind edges or vertices. You can control how to inject them.
|
||||
To use new labels you have to add them using to GraphArea::AddCustomChildControl() method and assign either VertexControl or EdgeControl for them using label::Attach() method.
|
||||
|
||||
DETAILED CHANGELOG:
|
||||
+ Added GroupId property to IGraphXVertex interface
|
||||
|
@ -12,10 +17,16 @@ DETAILED CHANGELOG:
|
|||
+ Added two methods to EdgeControl: GetEdgePointerForSource() and GetEdgePointerForTarget() which allows to get to edge pointer objects manualy
|
||||
+ Added VertexShape.Ellipse math shape
|
||||
+ Added support for reversing the geometry. This is required for animating shapes along a path where the direction needs to be reversed without using the Storyboard.AutoReverse property (thanks to bleibold)
|
||||
+ Added two new attached label classes for Edge and Vertex controls.
|
||||
+ Added EdgeControl::LabelMouseDown event
|
||||
+ Added separate ID counter for edges while autoresolving missing id
|
||||
+ Added EdgeControl.UpdateLabel() method to be able to update attached edge label manually (tech means to overcome some template quizes)
|
||||
+ Fixed an exception in ZoomControl caused by Ctrl + Alt + DblClick combination (thanks to persalmi)
|
||||
+ Fixed NaN result for FR algorithms calc (thanks to bleibold)
|
||||
+ Fixed edge bundling in the case when empty Control points are present that would sometimes cause exceptions.(thanks to bleibold)
|
||||
+ Fixed bindings to DefaultEdgePointer::Visibility property
|
||||
+ Fixed numerous event issues with graphX controls where events wasn't passed down the hierarchy tree
|
||||
+ Improved styles flexibility by working with dependency values instead of straight assignment in some places
|
||||
+ Improved overall graph cleaning in different areas allowing to easily clean graph data and fix potentional memory leaks
|
||||
+ Improved random layout algorithm randomness by seeding new Guid hash whcih fixes some odd behaviour in rare cases
|
||||
+ Implemented edge cut logic for EdgePointer placed at edge 'source' to gain better visual quality like its 'target' counterpart
|
||||
|
@ -25,6 +36,7 @@ DETAILED CHANGELOG:
|
|||
BREAKING CHANGES:
|
||||
* IExternalLayoutAlgorithm interface now demands TEdge generic specification and have one new method ResetGraph().
|
||||
* All built-in algorithms now use IMutableVertexAndEdgeSet<TVertex, TEdge> for TGraph generic specification to be able to modify Graph data on demand.
|
||||
* Made Vertex and Edge ID Int64 be default. Was Int32.
|
||||
|
||||
|
||||
RELEASE 2.2.0
|
||||
|
|
|
@ -11,6 +11,8 @@ namespace ShowcaseApp.WPF
|
|||
public int Age { get; set; }
|
||||
public int ImageId { get; set; }
|
||||
|
||||
public bool IsBlue { get; set; }
|
||||
|
||||
#region Calculated or static props
|
||||
|
||||
public override string ToString()
|
||||
|
|
|
@ -190,6 +190,7 @@ namespace ShowcaseApp.WPF.Pages
|
|||
{
|
||||
CreateNewArea();
|
||||
dg_Area.LogicCore.Graph = ShowcaseHelper.GenerateDataGraph(5, false);
|
||||
dg_Area.LogicCore.Graph.Vertices.First().IsBlue = true;
|
||||
var vlist = dg_Area.LogicCore.Graph.Vertices.ToList();
|
||||
dg_Area.LogicCore.Graph.AddEdge(new DataEdge(vlist[0], vlist[1]) { ArrowTarget = true});
|
||||
dg_Area.LogicCore.Graph.AddEdge(new DataEdge(vlist[0], vlist[2]) { ArrowTarget = true });
|
||||
|
|
|
@ -20,17 +20,33 @@
|
|||
|
||||
|
||||
<Style TargetType="{x:Type controls:VertexControl}">
|
||||
<Setter Property="Background" Value="Yellow"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:VertexControl}">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}" Width="20" Height="20" BorderThickness="1">
|
||||
BorderBrush="{TemplateBinding BorderBrush}" Width="20" Height="20" BorderThickness="1">
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsBlue}" Value="True">
|
||||
<DataTrigger.Setters>
|
||||
<Setter Property="Background" Value="Blue"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:VertexControl}">
|
||||
<Ellipse Width="50" Height="50" Fill="{TemplateBinding Background}"/>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger.Setters>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
|
||||
<controls:VisibilityToBoolConverter x:Key="VisibilityToBoolConverter" Inverted="True" />
|
||||
<controls:VisibilityToBoolConverter x:Key="VisibilityToBoolConverterNot" Inverted="True" Not="True"/>
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Shapes;
|
||||
using GraphX.Controls.Models;
|
||||
|
@ -63,6 +64,20 @@ namespace GraphX.Controls
|
|||
((EdgeControl)d).ActivateTargetListener();
|
||||
}
|
||||
|
||||
public event EdgeLabelEventHandler LabelMouseDown;
|
||||
protected void OnLabelMouseDown(MouseButtonEventArgs mArgs, ModifierKeys keys)
|
||||
{
|
||||
if (LabelMouseDown != null)
|
||||
LabelMouseDown(this, new EdgeLabelSelectedEventArgs(EdgeLabelControl, this, mArgs, keys));
|
||||
}
|
||||
|
||||
protected override void OnEdgeLabelUpdated()
|
||||
{
|
||||
if (EdgeLabelControl is Control)
|
||||
((Control) EdgeLabelControl).MouseDown += (sender, args) => OnLabelMouseDown(args, Keyboard.Modifiers);
|
||||
}
|
||||
|
||||
public object TargetObj { get { return Target; } }
|
||||
|
||||
#region public Clean()
|
||||
public override void Clean()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Input;
|
||||
using GraphX.Controls.Models;
|
||||
using GraphX.PCL.Common.Enums;
|
||||
using GraphX.PCL.Common.Exceptions;
|
||||
|
@ -40,6 +41,8 @@ namespace GraphX.Controls
|
|||
|
||||
#region Properties & Fields
|
||||
|
||||
|
||||
|
||||
public abstract bool IsSelfLooped { get; protected set; }
|
||||
public abstract void Dispose();
|
||||
public abstract void Clean();
|
||||
|
@ -318,10 +321,11 @@ namespace GraphX.Controls
|
|||
/// </summary>
|
||||
protected Path LinePathObject;
|
||||
|
||||
private IEdgeLabelControl _edgeLabelControl;
|
||||
/// <summary>
|
||||
/// Templated label control to display labels
|
||||
/// </summary>
|
||||
protected IEdgeLabelControl EdgeLabelControl;
|
||||
protected IEdgeLabelControl EdgeLabelControl { get { return _edgeLabelControl; } set { _edgeLabelControl = value; OnEdgeLabelUpdated(); } }
|
||||
|
||||
protected IEdgePointer EdgePointerForSource;
|
||||
protected IEdgePointer EdgePointerForTarget;
|
||||
|
@ -364,6 +368,21 @@ namespace GraphX.Controls
|
|||
set { SetValue(EdgeProperty, value); }
|
||||
}
|
||||
|
||||
internal void InjectEdgeLable(IEdgeLabelControl ctrl)
|
||||
{
|
||||
EdgeLabelControl = ctrl;
|
||||
UpdateLabelLayout();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update edge label if any
|
||||
/// </summary>
|
||||
public void UpdateLabel()
|
||||
{
|
||||
if(_edgeLabelControl != null && ShowLabel)
|
||||
UpdateLabelLayout(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Position methods
|
||||
|
@ -445,6 +464,9 @@ namespace GraphX.Controls
|
|||
{
|
||||
get { return LinePathObject != null; }
|
||||
}
|
||||
|
||||
protected virtual void OnEdgeLabelUpdated() { }
|
||||
|
||||
#if WPF
|
||||
public override void OnApplyTemplate()
|
||||
#elif METRO
|
||||
|
@ -461,7 +483,8 @@ namespace GraphX.Controls
|
|||
if (this.FindDescendantByName("PART_edgeArrowPath") != null)
|
||||
throw new GX_ObsoleteException("PART_edgeArrowPath is obsolete! Please use new DefaultEdgePointer object in your EdgeControlBase template!");
|
||||
|
||||
EdgeLabelControl = GetTemplatePart("PART_edgeLabel") as IEdgeLabelControl;
|
||||
EdgeLabelControl = EdgeLabelControl ?? GetTemplatePart("PART_edgeLabel") as IEdgeLabelControl;
|
||||
|
||||
|
||||
EdgePointerForSource = GetTemplatePart("PART_EdgePointerForSource") as IEdgePointer;
|
||||
EdgePointerForTarget = GetTemplatePart("PART_EdgePointerForTarget") as IEdgePointer;
|
||||
|
@ -472,7 +495,7 @@ namespace GraphX.Controls
|
|||
{
|
||||
if (SelfLoopIndicator != null) SelfLoopIndicator.Arrange(_selfLoopedEdgeLastKnownRect);
|
||||
};
|
||||
|
||||
var x = this.ShowLabel;
|
||||
MeasureChild(EdgePointerForSource as UIElement);
|
||||
MeasureChild(EdgePointerForTarget as UIElement);
|
||||
MeasureChild(SelfLoopIndicator);
|
||||
|
@ -784,7 +807,8 @@ namespace GraphX.Controls
|
|||
if (gEdge.ReversePath)
|
||||
routePoints.Reverse();
|
||||
|
||||
var pcol = new PointCollection(routePoints);
|
||||
var pcol = new PointCollection();
|
||||
routePoints.ForEach(a=> pcol.Add(a));
|
||||
|
||||
lineFigure = new PathFigure { StartPoint = p1, Segments = new PathSegmentCollection { new PolyLineSegment { Points = pcol } }, IsClosed = false };
|
||||
}
|
||||
|
@ -848,10 +872,10 @@ namespace GraphX.Controls
|
|||
EdgeLabelControl.SetSize(rect);
|
||||
}
|
||||
|
||||
internal virtual void UpdateLabelLayout()
|
||||
internal virtual void UpdateLabelLayout(bool force = false)
|
||||
{
|
||||
EdgeLabelControl.Show();
|
||||
if (EdgeLabelControl.GetSize() == SysRect.Empty)
|
||||
if (EdgeLabelControl.GetSize() == SysRect.Empty || force)
|
||||
|
||||
{
|
||||
EdgeLabelControl.UpdateLayout();
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
#if WPF
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using DefaultEventArgs = System.EventArgs;
|
||||
#elif METRO
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using DefaultEventArgs = System.Object;
|
||||
#endif
|
||||
using GraphX.PCL.Common.Exceptions;
|
||||
|
||||
namespace GraphX.Controls
|
||||
{
|
||||
#if METRO
|
||||
[Bindable]
|
||||
#endif
|
||||
public class AttachableEdgeLabelControl : EdgeLabelControl
|
||||
{
|
||||
public EdgeControl AttachNode { get { return (EdgeControl) GetValue(AttachNodeProperty); } private set {SetValue(AttachNodeProperty, value);} }
|
||||
|
||||
public static readonly DependencyProperty AttachNodeProperty = DependencyProperty.Register("AttachNode", typeof(EdgeControl), typeof(AttachableEdgeLabelControl),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
|
||||
public AttachableEdgeLabelControl()
|
||||
{
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
public void Attach(EdgeControl node)
|
||||
{
|
||||
AttachNode = node;
|
||||
node.InjectEdgeLable(this);
|
||||
}
|
||||
|
||||
protected override EdgeControl GetEdgeControl(DependencyObject parent)
|
||||
{
|
||||
if(AttachNode == null)
|
||||
throw new GX_InvalidDataException("AttachableEdgeLabelControl node is not attached!");
|
||||
return AttachNode;
|
||||
}
|
||||
|
||||
/* public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
// var container = Template.FindName("PART_container", this) as ContentPresenter;
|
||||
//container.Content = AttachNode.Vertex;
|
||||
}*/
|
||||
}
|
||||
}
|
|
@ -111,7 +111,7 @@ namespace GraphX.Controls
|
|||
|
||||
private EdgeControl _edgeControl;
|
||||
|
||||
private static EdgeControl GetEdgeControl(DependencyObject parent)
|
||||
protected virtual EdgeControl GetEdgeControl(DependencyObject parent)
|
||||
{
|
||||
while (parent != null)
|
||||
{
|
||||
|
@ -125,12 +125,20 @@ namespace GraphX.Controls
|
|||
public void Show()
|
||||
{
|
||||
if (EdgeControl.IsSelfLooped && !DisplayForSelfLoopedEdges) return;
|
||||
#if WPF
|
||||
SetCurrentValue(UIElement.VisibilityProperty, Visibility.Visible);
|
||||
#else
|
||||
SetValue(UIElement.VisibilityProperty, Visibility.Visible);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
#if WPF
|
||||
SetCurrentValue(UIElement.VisibilityProperty, Visibility.Collapsed);
|
||||
#else
|
||||
SetValue(UIElement.VisibilityProperty, Visibility.Collapsed);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -53,12 +53,20 @@ namespace GraphX.Controls
|
|||
|
||||
public void Show()
|
||||
{
|
||||
#if WPF
|
||||
SetCurrentValue(UIElement.VisibilityProperty, Visibility.Visible);
|
||||
#else
|
||||
SetValue(UIElement.VisibilityProperty, Visibility.Visible);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
#if WPF
|
||||
SetCurrentValue(UIElement.VisibilityProperty, Visibility.Collapsed);
|
||||
#else
|
||||
SetValue(UIElement.VisibilityProperty, Visibility.Collapsed);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static EdgeControl GetEdgeControl(DependencyObject parent)
|
||||
|
|
|
@ -348,7 +348,7 @@ namespace GraphX.Controls
|
|||
public void AddVertex(TVertex vertexData, VertexControl vertexControl)
|
||||
{
|
||||
if (AutoAssignMissingDataId && vertexData.ID == -1)
|
||||
vertexData.ID = GetNextUniqueId();
|
||||
vertexData.ID = GetNextUniqueId(true);
|
||||
InternalAddVertex(vertexData, vertexControl);
|
||||
if (EnableVisualPropsApply && vertexControl != null)
|
||||
ReapplySingleVertexVisualProperties(vertexControl);
|
||||
|
@ -371,7 +371,7 @@ namespace GraphX.Controls
|
|||
public void AddEdge(TEdge edgeData, EdgeControl edgeControl)
|
||||
{
|
||||
if (AutoAssignMissingDataId && edgeData.ID == -1)
|
||||
edgeData.ID = GetNextUniqueId();
|
||||
edgeData.ID = GetNextUniqueId(false);
|
||||
InternalAddEdge(edgeData, edgeControl);
|
||||
if (EnableVisualPropsApply && edgeControl != null)
|
||||
ReapplySingleEdgeVisualProperties(edgeControl);
|
||||
|
@ -395,7 +395,7 @@ namespace GraphX.Controls
|
|||
public void InsertEdge(TEdge edgeData, EdgeControl edgeControl, int num = 0)
|
||||
{
|
||||
if (AutoAssignMissingDataId && edgeData.ID == -1)
|
||||
edgeData.ID = GetNextUniqueId();
|
||||
edgeData.ID = GetNextUniqueId(false);
|
||||
InternalInsertEdge(edgeData, edgeControl, num);
|
||||
if (EnableVisualPropsApply && edgeControl != null)
|
||||
ReapplySingleEdgeVisualProperties(edgeControl);
|
||||
|
@ -425,17 +425,30 @@ namespace GraphX.Controls
|
|||
|
||||
#region Automatic data ID storage and resolving
|
||||
private int _dataIdCounter = 1;
|
||||
private int GetNextUniqueId()
|
||||
private int _edgeDataIdCounter = 1;
|
||||
|
||||
private int GetNextUniqueId(bool isVertex)
|
||||
{
|
||||
while (_dataIdsCollection.Contains(_dataIdCounter))
|
||||
if (isVertex)
|
||||
{
|
||||
_dataIdCounter++;
|
||||
while (_dataIdsCollection.Contains(_dataIdCounter))
|
||||
{
|
||||
_dataIdCounter++;
|
||||
}
|
||||
_dataIdsCollection.Add(_dataIdCounter);
|
||||
return _dataIdCounter;
|
||||
}
|
||||
_dataIdsCollection.Add(_dataIdCounter);
|
||||
return _dataIdCounter;
|
||||
while (_edgeDataIdsCollection.Contains(_edgeDataIdCounter))
|
||||
{
|
||||
_edgeDataIdCounter++;
|
||||
}
|
||||
_edgeDataIdsCollection.Add(_edgeDataIdCounter);
|
||||
return _edgeDataIdCounter;
|
||||
}
|
||||
|
||||
private readonly HashSet<int> _dataIdsCollection = new HashSet<int>();
|
||||
private readonly HashSet<long> _dataIdsCollection = new HashSet<long>();
|
||||
private readonly HashSet<long> _edgeDataIdsCollection = new HashSet<long>();
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -833,7 +846,9 @@ namespace GraphX.Controls
|
|||
if (graph == null) return;
|
||||
|
||||
_dataIdsCollection.Clear();
|
||||
_edgeDataIdsCollection.Clear();
|
||||
_dataIdCounter = 1;
|
||||
_edgeDataIdCounter = 1;
|
||||
|
||||
// First, rebuild data ID collection for all vertices and edges that already have assigned IDs.
|
||||
foreach (var item in graph.Vertices.Where(a => a.ID != -1))
|
||||
|
@ -843,15 +858,15 @@ namespace GraphX.Controls
|
|||
}
|
||||
foreach (var item in graph.Edges.Where(a => a.ID != -1))
|
||||
{
|
||||
bool added = _dataIdsCollection.Add(item.ID);
|
||||
bool added = _edgeDataIdsCollection.Add(item.ID);
|
||||
Debug.Assert(added, "Duplicate ID found", string.Format("Duplicate ID '{0}' found while adding an edge ID during rebuild of data ID collection.", item.ID));
|
||||
}
|
||||
|
||||
// Generate unique IDs for all vertices and edges that don't already have a unique ID.
|
||||
foreach (var item in graph.Vertices.Where(a => a.ID == -1))
|
||||
item.ID = GetNextUniqueId();
|
||||
item.ID = GetNextUniqueId(true);
|
||||
foreach (var item in graph.Edges.Where(a => a.ID == -1))
|
||||
item.ID = GetNextUniqueId();
|
||||
item.ID = GetNextUniqueId(false);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -1109,7 +1124,7 @@ namespace GraphX.Controls
|
|||
/// </summary>
|
||||
public void UpdateParallelEdgesData()
|
||||
{
|
||||
var usedIds = _edgeslist.Count > 20 ? new HashSet<int>() as ICollection<int> : new List<int>();
|
||||
var usedIds = _edgeslist.Count > 20 ? new HashSet<long>() as ICollection<long> : new List<long>();
|
||||
|
||||
//clear IsParallel flag
|
||||
EdgesList.Values.ForEach(a => a.IsParallel = false);
|
||||
|
|
|
@ -52,12 +52,20 @@ namespace GraphX.Controls
|
|||
|
||||
public void Show()
|
||||
{
|
||||
#if WPF
|
||||
SetCurrentValue(UIElement.VisibilityProperty, Visibility.Visible);
|
||||
#else
|
||||
SetValue(UIElement.VisibilityProperty, Visibility.Visible);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
#if WPF
|
||||
SetCurrentValue(UIElement.VisibilityProperty, Visibility.Collapsed);
|
||||
#else
|
||||
SetValue(UIElement.VisibilityProperty, Visibility.Collapsed);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static VertexControl GetVertexControl(DependencyObject parent)
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Windows.Input;
|
|||
using GraphX.PCL.Common.Enums;
|
||||
using GraphX.PCL.Common.Exceptions;
|
||||
using GraphX.Controls.Models;
|
||||
using GraphX.PCL.Common.Interfaces;
|
||||
|
||||
namespace GraphX.Controls
|
||||
{
|
||||
|
@ -23,6 +24,15 @@ namespace GraphX.Controls
|
|||
DefaultStyleKeyProperty.OverrideMetadata(typeof(VertexControl), new FrameworkPropertyMetadata(typeof(VertexControl)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Vertex data as specified class
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Class</typeparam>
|
||||
public T GetDataVertex<T>() where T: IGraphXVertex
|
||||
{
|
||||
return (T)Vertex;
|
||||
}
|
||||
|
||||
#region Position trace feature
|
||||
|
||||
|
||||
|
@ -84,6 +94,15 @@ namespace GraphX.Controls
|
|||
EventOptions = new VertexEventOptions(this) { PositionChangeNotification = tracePositionChange };
|
||||
foreach(var item in Enum.GetValues(typeof(EventType)).Cast<EventType>())
|
||||
UpdateEventhandling(item);
|
||||
|
||||
SizeChanged += VertexControl_SizeChanged;
|
||||
}
|
||||
|
||||
void VertexControl_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
/*if (ShowLabel && VertexLabelControl != null)
|
||||
VertexLabelControl.UpdatePosition();
|
||||
OnPositionChanged(new Point(), GetPosition());*/
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
|
||||
#if WPF
|
||||
using System.Windows;
|
||||
using DefaultEventArgs = System.EventArgs;
|
||||
using System.Windows.Controls;
|
||||
#elif METRO
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using DefaultEventArgs = System.Object;
|
||||
#endif
|
||||
using GraphX.PCL.Common.Exceptions;
|
||||
|
||||
namespace GraphX.Controls
|
||||
{
|
||||
#if METRO
|
||||
[Bindable]
|
||||
#endif
|
||||
public class AttachableVertexLabelControl : VertexLabelControl
|
||||
{
|
||||
public VertexControl AttachNode { get { return (VertexControl) GetValue(AttachNodeProperty); } private set {SetValue(AttachNodeProperty, value);} }
|
||||
|
||||
public static readonly DependencyProperty AttachNodeProperty = DependencyProperty.Register("AttachNode", typeof(VertexControl), typeof(AttachableVertexLabelControl),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
|
||||
public AttachableVertexLabelControl()
|
||||
{
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
public void Attach(VertexControl node)
|
||||
{
|
||||
AttachNode = node;
|
||||
}
|
||||
|
||||
protected override VertexControl GetVertexControl(DependencyObject parent)
|
||||
{
|
||||
if(AttachNode == null)
|
||||
throw new GX_InvalidDataException("AttachableVertexLabelControl node is not attached!");
|
||||
return AttachNode;
|
||||
}
|
||||
|
||||
/* public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
var container = Template.FindName("PART_container", this) as ContentPresenter;
|
||||
container.Content = AttachNode.Vertex;
|
||||
}*/
|
||||
|
||||
public override void UpdatePosition()
|
||||
{
|
||||
if (double.IsNaN(DesiredSize.Width) || DesiredSize.Width == 0) return;
|
||||
|
||||
var vc = GetVertexControl(GetParent());
|
||||
if (vc == null) return;
|
||||
|
||||
if (LabelPositionMode == VertexLabelPositionMode.Sides)
|
||||
{
|
||||
var vcPos = vc.GetPosition();
|
||||
Point pt;
|
||||
switch (LabelPositionSide)
|
||||
{
|
||||
case VertexLabelPositionSide.TopRight:
|
||||
pt = new Point(vcPos.X + vc.DesiredSize.Width, vcPos.Y + -DesiredSize.Height);
|
||||
break;
|
||||
case VertexLabelPositionSide.BottomRight:
|
||||
pt = new Point(vcPos.X + vc.DesiredSize.Width, vcPos.Y + vc.DesiredSize.Height);
|
||||
break;
|
||||
case VertexLabelPositionSide.TopLeft:
|
||||
pt = new Point(vcPos.X + -DesiredSize.Width, vcPos.Y + -DesiredSize.Height);
|
||||
break;
|
||||
case VertexLabelPositionSide.BottomLeft:
|
||||
pt = new Point(vcPos.X + -DesiredSize.Width, vcPos.Y + vc.DesiredSize.Height);
|
||||
break;
|
||||
case VertexLabelPositionSide.Top:
|
||||
pt = new Point(vcPos.X + vc.DesiredSize.Width * .5 - DesiredSize.Width * .5, vcPos.Y + -DesiredSize.Height);
|
||||
break;
|
||||
case VertexLabelPositionSide.Bottom:
|
||||
pt = new Point(vcPos.X + vc.DesiredSize.Width * .5 - DesiredSize.Width * .5, vcPos.Y + vc.DesiredSize.Height);
|
||||
break;
|
||||
case VertexLabelPositionSide.Left:
|
||||
pt = new Point(vcPos.X + -DesiredSize.Width, vcPos.Y + vc.DesiredSize.Height * .5f - DesiredSize.Height * .5);
|
||||
break;
|
||||
case VertexLabelPositionSide.Right:
|
||||
pt = new Point(vcPos.X + vc.DesiredSize.Width, vcPos.Y + vc.DesiredSize.Height * .5f - DesiredSize.Height * .5);
|
||||
break;
|
||||
default:
|
||||
throw new GX_InvalidDataException("UpdatePosition() -> Unknown vertex label side!");
|
||||
}
|
||||
LastKnownRectSize = new Rect(pt, DesiredSize);
|
||||
}
|
||||
else LastKnownRectSize = new Rect(LabelPosition, DesiredSize);
|
||||
|
||||
Arrange(LastKnownRectSize);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -112,7 +112,7 @@ namespace GraphX.Controls
|
|||
VerticalAlignment = VerticalAlignment.Top;
|
||||
}
|
||||
|
||||
private static VertexControl GetVertexControl(DependencyObject parent)
|
||||
protected virtual VertexControl GetVertexControl(DependencyObject parent)
|
||||
{
|
||||
while (parent != null)
|
||||
{
|
||||
|
@ -126,7 +126,7 @@ namespace GraphX.Controls
|
|||
|
||||
public virtual void UpdatePosition()
|
||||
{
|
||||
if (double.IsNaN(DesiredSize.Width) || DesiredSize.Width == 0) return;
|
||||
if (double.IsNaN(DesiredSize.Width) || DesiredSize.Width == 0) return;
|
||||
|
||||
var vc = GetVertexControl(GetParent());
|
||||
if (vc == null) return;
|
||||
|
@ -172,12 +172,20 @@ namespace GraphX.Controls
|
|||
|
||||
public void Hide()
|
||||
{
|
||||
#if WPF
|
||||
SetCurrentValue(UIElement.VisibilityProperty, Visibility.Collapsed);
|
||||
#else
|
||||
SetValue(UIElement.VisibilityProperty, Visibility.Collapsed);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Show()
|
||||
{
|
||||
#if WPF
|
||||
SetCurrentValue(UIElement.VisibilityProperty, Visibility.Visible);
|
||||
#else
|
||||
SetValue(UIElement.VisibilityProperty, Visibility.Visible);
|
||||
#endif
|
||||
}
|
||||
|
||||
void VertexLabelControl_LayoutUpdated(object sender, DefaultEventArgs e)
|
||||
|
@ -187,7 +195,7 @@ namespace GraphX.Controls
|
|||
UpdatePosition();
|
||||
}
|
||||
|
||||
DependencyObject GetParent()
|
||||
protected virtual DependencyObject GetParent()
|
||||
{
|
||||
#if WPF
|
||||
return VisualParent;
|
||||
|
|
|
@ -106,12 +106,14 @@
|
|||
<Compile Include="Behaviours\DragBehaviour.cs" />
|
||||
<Compile Include="Behaviours\HighlightBehaviour.cs" />
|
||||
<Compile Include="Controls\EdgeControlBase.cs" />
|
||||
<Compile Include="Controls\EdgeLabels\AttachableEdgeLabelControl.cs" />
|
||||
<Compile Include="Controls\Misc\ControlDrawOrder.cs" />
|
||||
<Compile Include="Controls\Misc\IPositionChangeNotify.cs" />
|
||||
<Compile Include="Controls\Misc\IVertexConnectionPoint.cs" />
|
||||
<Compile Include="Controls\VertexConnectionPoints\StaticVertexConnectionPoint.cs" />
|
||||
<Compile Include="Controls\EdgePointers\DefaultEdgePointer.cs" />
|
||||
<Compile Include="Controls\VertexControlBase.cs" />
|
||||
<Compile Include="Controls\VertexLabels\AttachableVertexLabelControl.cs" />
|
||||
<Compile Include="Controls\VertexLabels\VertexLabelControl.cs" />
|
||||
<Compile Include="ExceptionExtensions.cs" />
|
||||
<Compile Include="Controls\Misc\IEdgeLabelControl.cs" />
|
||||
|
|
|
@ -2,7 +2,7 @@ using System.Windows.Input;
|
|||
|
||||
namespace GraphX.Controls.Models
|
||||
{
|
||||
public sealed class EdgeSelectedEventArgs : System.EventArgs
|
||||
public class EdgeSelectedEventArgs : System.EventArgs
|
||||
{
|
||||
public EdgeControl EdgeControl { get; set; }
|
||||
public ModifierKeys Modifiers { get; set; }
|
||||
|
@ -15,4 +15,16 @@ namespace GraphX.Controls.Models
|
|||
MouseArgs = e;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class EdgeLabelSelectedEventArgs : EdgeSelectedEventArgs
|
||||
{
|
||||
public IEdgeLabelControl EdgeLabelControl { get; set; }
|
||||
|
||||
|
||||
public EdgeLabelSelectedEventArgs(IEdgeLabelControl label, EdgeControl ec, MouseButtonEventArgs e, ModifierKeys keys)
|
||||
:base(ec,e,keys)
|
||||
{
|
||||
EdgeLabelControl = label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace GraphX.Controls.Models
|
||||
{
|
||||
public delegate void EdgeSelectedEventHandler(object sender, EdgeSelectedEventArgs args);
|
||||
|
||||
public delegate void EdgeLabelEventHandler(object sender, EdgeLabelSelectedEventArgs args);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using GraphX.Controls.Models;
|
||||
using GraphX.PCL.Common.Enums;
|
||||
|
@ -112,6 +113,19 @@ namespace GraphX.Controls
|
|||
_targetWatcher = this.WatchProperty("Target", TargetChanged);
|
||||
}
|
||||
|
||||
public event EdgeLabelEventHandler LabelMouseDown;
|
||||
protected void OnLabelMouseDown(PointerRoutedEventArgs mArgs)
|
||||
{
|
||||
if (LabelMouseDown != null)
|
||||
LabelMouseDown(this, new EdgeLabelSelectedEventArgs(EdgeLabelControl, this, mArgs));
|
||||
}
|
||||
|
||||
protected override void OnEdgeLabelUpdated()
|
||||
{
|
||||
if (EdgeLabelControl is Control)
|
||||
((Control)EdgeLabelControl).PointerPressed += (sender, args) => OnLabelMouseDown(args);
|
||||
}
|
||||
|
||||
#region Position tracing
|
||||
|
||||
private void TargetChanged(object sender, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
||||
|
|
|
@ -333,7 +333,7 @@ namespace GraphX.Controls
|
|||
public void AddVertex(TVertex vertexData, VertexControl vertexControl)
|
||||
{
|
||||
if (AutoAssignMissingDataId && vertexData.ID == -1)
|
||||
vertexData.ID = GetNextUniqueId();
|
||||
vertexData.ID = GetNextUniqueId(true);
|
||||
InternalAddVertex(vertexData, vertexControl);
|
||||
if (EnableVisualPropsApply && vertexControl != null)
|
||||
ReapplySingleVertexVisualProperties(vertexControl);
|
||||
|
@ -356,7 +356,7 @@ namespace GraphX.Controls
|
|||
public void AddEdge(TEdge edgeData, EdgeControl edgeControl)
|
||||
{
|
||||
if (AutoAssignMissingDataId && edgeData.ID == -1)
|
||||
edgeData.ID = GetNextUniqueId();
|
||||
edgeData.ID = GetNextUniqueId(false);
|
||||
InternalAddEdge(edgeData, edgeControl);
|
||||
if (EnableVisualPropsApply && edgeControl != null)
|
||||
ReapplySingleEdgeVisualProperties(edgeControl);
|
||||
|
@ -380,7 +380,7 @@ namespace GraphX.Controls
|
|||
public void InsertEdge(TEdge edgeData, EdgeControl edgeControl, int num = 0)
|
||||
{
|
||||
if (AutoAssignMissingDataId && edgeData.ID == -1)
|
||||
edgeData.ID = GetNextUniqueId();
|
||||
edgeData.ID = GetNextUniqueId(false);
|
||||
InternalInsertEdge(edgeData, edgeControl, num);
|
||||
if (EnableVisualPropsApply && edgeControl != null)
|
||||
ReapplySingleEdgeVisualProperties(edgeControl);
|
||||
|
@ -409,18 +409,29 @@ namespace GraphX.Controls
|
|||
#endregion
|
||||
|
||||
#region Automatic data ID storage and resolving
|
||||
private int _dataIdCounter;
|
||||
private int GetNextUniqueId()
|
||||
private int _dataIdCounter = 1;
|
||||
private int _edgeDataIdCounter = 1;
|
||||
private int GetNextUniqueId(bool isVertex)
|
||||
{
|
||||
while (_dataIdsCollection.Contains(_dataIdCounter))
|
||||
if (isVertex)
|
||||
{
|
||||
_dataIdCounter++;
|
||||
while (_dataIdsCollection.Contains(_dataIdCounter))
|
||||
{
|
||||
_dataIdCounter++;
|
||||
}
|
||||
_dataIdsCollection.Add(_dataIdCounter);
|
||||
return _dataIdCounter;
|
||||
}
|
||||
_dataIdsCollection.Add(_dataIdCounter);
|
||||
return _dataIdCounter;
|
||||
while (_edgeDataIdsCollection.Contains(_edgeDataIdCounter))
|
||||
{
|
||||
_edgeDataIdCounter++;
|
||||
}
|
||||
_edgeDataIdsCollection.Add(_edgeDataIdCounter);
|
||||
return _edgeDataIdCounter;
|
||||
}
|
||||
|
||||
private readonly HashSet<int> _dataIdsCollection = new HashSet<int>();
|
||||
private readonly HashSet<long> _dataIdsCollection = new HashSet<long>();
|
||||
private readonly HashSet<long> _edgeDataIdsCollection = new HashSet<long>();
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -495,8 +506,9 @@ namespace GraphX.Controls
|
|||
{
|
||||
if (VertexList.ContainsKey(item.Key))
|
||||
VertexList[item.Key].SetPosition(item.Value);
|
||||
if (showObjectsIfPosSpecified)
|
||||
VertexList[item.Key].Visibility = Visibility.Visible;
|
||||
//if (showObjectsIfPosSpecified)
|
||||
// VertexList[item.Key].Visibility = Visibility.Visible;
|
||||
VertexList[item.Key].SetCurrentValue(GraphAreaBase.PositioningCompleteProperty, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,6 +541,7 @@ namespace GraphX.Controls
|
|||
var vc = ControlFactory.CreateVertexControl(it);
|
||||
vc.DataContext = dataContextToDataItem ? it : null;
|
||||
vc.Visibility = Visibility.Visible; // make them invisible (there is no layout positions yet calculated)
|
||||
vc.SetCurrentValue(GraphAreaBase.PositioningCompleteProperty, false); // Style can make them invisible until positioning is complete (after layout positions are calculated)
|
||||
InternalAddVertex(it, vc);
|
||||
}
|
||||
if (forceVisPropRecovery)
|
||||
|
@ -599,7 +612,8 @@ namespace GraphX.Controls
|
|||
if (MoveAnimation == null || double.IsNaN(GetX(vc)))
|
||||
vc.SetPosition(item.Value.X, item.Value.Y, false);
|
||||
else MoveAnimation.AddVertexData(vc, item.Value);
|
||||
vc.Visibility = Visibility.Visible; //show vertexes with layout positions assigned
|
||||
//vc.Visibility = Visibility.Visible; //show vertexes with layout positions assigned
|
||||
vc.SetCurrentValue(GraphAreaBase.PositioningCompleteProperty, true); // Style can show vertexes with layout positions assigned
|
||||
}
|
||||
if (MoveAnimation != null)
|
||||
{
|
||||
|
@ -736,6 +750,8 @@ namespace GraphX.Controls
|
|||
|
||||
_dataIdsCollection.Clear();
|
||||
_dataIdCounter = 1;
|
||||
_edgeDataIdsCollection.Clear();
|
||||
_edgeDataIdCounter = 1;
|
||||
|
||||
// First, rebuild data ID collection for all vertices and edges that already have assigned IDs.
|
||||
foreach (var item in graph.Vertices.Where(a => a.ID != -1))
|
||||
|
@ -745,15 +761,15 @@ namespace GraphX.Controls
|
|||
}
|
||||
foreach (var item in graph.Edges.Where(a => a.ID != -1))
|
||||
{
|
||||
bool added = _dataIdsCollection.Add(item.ID);
|
||||
bool added = _edgeDataIdsCollection.Add(item.ID);
|
||||
Debug.Assert(added, string.Format("Duplicate ID '{0}' found while adding an edge ID during rebuild of data ID collection.", item.ID));
|
||||
}
|
||||
|
||||
// Generate unique IDs for all vertices and edges that don't already have a unique ID.
|
||||
foreach (var item in graph.Vertices.Where(a => a.ID == -1))
|
||||
item.ID = GetNextUniqueId();
|
||||
item.ID = GetNextUniqueId(true);
|
||||
foreach (var item in graph.Edges.Where(a => a.ID == -1))
|
||||
item.ID = GetNextUniqueId();
|
||||
item.ID = GetNextUniqueId(false);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -1012,7 +1028,7 @@ namespace GraphX.Controls
|
|||
/// </summary>
|
||||
public void UpdateParallelEdgesData()
|
||||
{
|
||||
var usedIds = _edgeslist.Count > 20 ? new HashSet<int>() as ICollection<int> : new List<int>();
|
||||
var usedIds = _edgeslist.Count > 20 ? new HashSet<long>() as ICollection<long> : new List<long>();
|
||||
|
||||
//clear IsParallel flag
|
||||
EdgesList.Values.ForEach(a=> a.IsParallel = false);
|
||||
|
|
|
@ -111,7 +111,15 @@ namespace GraphX.Controls
|
|||
obj.SetValue(FinalYProperty, value);
|
||||
}
|
||||
|
||||
public static bool GetPositioningComplete(DependencyObject obj)
|
||||
{
|
||||
return (bool)obj.GetValue(PositioningCompleteProperty);
|
||||
}
|
||||
|
||||
public static void SetPositioningComplete(DependencyObject obj, bool value)
|
||||
{
|
||||
obj.SetValue(PositioningCompleteProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DP - ExternalSettings
|
||||
|
@ -185,6 +193,9 @@ namespace GraphX.Controls
|
|||
public static readonly DependencyProperty MouseOverAnimationProperty =
|
||||
DependencyProperty.Register("MouseOverAnimation", typeof(IBidirectionalControlAnimation), typeof(GraphAreaBase), new PropertyMetadata(null));
|
||||
|
||||
public static readonly DependencyProperty PositioningCompleteProperty =
|
||||
DependencyProperty.RegisterAttached("PositioningComplete", typeof(bool), typeof(GraphAreaBase), new PropertyMetadata(true));
|
||||
|
||||
#endregion
|
||||
|
||||
#region Child EVENTS
|
||||
|
|
|
@ -161,6 +161,9 @@
|
|||
<Compile Include="..\GraphX.Controls\Controls\EdgeControlBase.cs">
|
||||
<Link>Controls\EdgeControlBase.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\GraphX.Controls\Controls\EdgeLabels\AttachableEdgeLabelControl.cs">
|
||||
<Link>Controls\EdgeLabels\AttachableEdgeLabelControl.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\GraphX.Controls\Controls\EdgeLabels\EdgeLabelControl.cs">
|
||||
<Link>Controls\EdgeLabels\EdgeLabelControl.cs</Link>
|
||||
</Compile>
|
||||
|
@ -209,6 +212,9 @@
|
|||
<Compile Include="..\GraphX.Controls\Controls\VertexControlBase.cs">
|
||||
<Link>Controls\VertexControlBase.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\GraphX.Controls\Controls\VertexLabels\AttachableVertexLabelControl.cs">
|
||||
<Link>Controls\VertexLabels\AttachableVertexLabelControl.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\GraphX.Controls\Controls\VertexLabels\VertexLabelControl.cs">
|
||||
<Link>Controls\VertexLabels\VertexLabelControl.cs</Link>
|
||||
</Compile>
|
||||
|
@ -315,18 +321,18 @@
|
|||
<Content Include="Images\help_black.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="QuickGraph">
|
||||
<Reference Include="QuickGraph, Version=3.6.61114.0, Culture=neutral, PublicKeyToken=f3fb40175eec2af3, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\QuickGraphPCL.3.6.61114.2\lib\portable-win+net4+sl5+wp8+win8+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\QuickGraph.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="QuickGraph.Graphviz">
|
||||
<Reference Include="QuickGraph.Graphviz, Version=3.6.61114.0, Culture=neutral, PublicKeyToken=f3fb40175eec2af3, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\QuickGraphPCL.3.6.61114.2\lib\portable-win+net4+sl5+wp8+win8+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\QuickGraph.Graphviz.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
||||
<VisualStudioVersion>12.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -2,7 +2,7 @@ using Windows.UI.Xaml.Input;
|
|||
|
||||
namespace GraphX.Controls.Models
|
||||
{
|
||||
public sealed class EdgeSelectedEventArgs : System.EventArgs
|
||||
public class EdgeSelectedEventArgs : System.EventArgs
|
||||
{
|
||||
public EdgeControl EdgeControl { get; set; }
|
||||
public PointerRoutedEventArgs Args { get; set; }
|
||||
|
@ -14,4 +14,16 @@ namespace GraphX.Controls.Models
|
|||
Args = e;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class EdgeLabelSelectedEventArgs : EdgeSelectedEventArgs
|
||||
{
|
||||
public IEdgeLabelControl EdgeLabelControl { get; set; }
|
||||
|
||||
|
||||
public EdgeLabelSelectedEventArgs(IEdgeLabelControl label, EdgeControl ec, PointerRoutedEventArgs e)
|
||||
: base(ec, e)
|
||||
{
|
||||
EdgeLabelControl = label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,14 @@
|
|||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
CornerRadius="10,10,10,10"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="Common">
|
||||
<VisualState x:Name="Snapped">
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
|
@ -135,7 +142,13 @@
|
|||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<!-- TODO - HIDE vertices when layout not finished yet -->
|
||||
<!--<Style.Triggers>
|
||||
<Trigger Property="graphxRoot:GraphAreaBase.PositioningComplete" Value="False">
|
||||
<Setter Property="Visibility" Value="Hidden"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>-->
|
||||
</Style>
|
||||
<!-- ENDREGION -->
|
||||
|
||||
<!-- REGION EDGE CONTROL -->
|
||||
|
|
|
@ -2,11 +2,21 @@
|
|||
using System.Collections.Generic;
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#if METRO
|
||||
using Windows.UI.Xaml;
|
||||
#endif
|
||||
|
||||
namespace GraphX.Controls
|
||||
{
|
||||
public static class TypeExtensions
|
||||
{
|
||||
#if METRO
|
||||
public static void SetCurrentValue(this FrameworkElement el, DependencyProperty p, object value)
|
||||
{
|
||||
el.SetValue(p, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static void Offset(this Point point, Point value)
|
||||
{
|
||||
point.X = point.X + value.X;
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace GraphX.PCL.Common.Interfaces
|
|||
/// <summary>
|
||||
/// Unique object identifier
|
||||
/// </summary>
|
||||
int ID { get; set; }
|
||||
long ID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Skip object in algorithm calc and visual control generation
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace GraphX.PCL.Common.Models
|
|||
/// <summary>
|
||||
/// Unique edge ID
|
||||
/// </summary>
|
||||
public int ID { get; set; }
|
||||
public long ID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if Source vertex equals Target vertex
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace GraphX.PCL.Common.Models
|
|||
/// <summary>
|
||||
/// Unique vertex ID
|
||||
/// </summary>
|
||||
public int ID { get; set; }
|
||||
public long ID { get; set; }
|
||||
|
||||
public bool Equals(IGraphXVertex other)
|
||||
{
|
||||
|
|
|
@ -998,15 +998,15 @@ namespace GraphX.PCL.Logic.Algorithms.EdgeRouting
|
|||
|
||||
struct KeyPair
|
||||
{
|
||||
public KeyPair(int n1, int n2)
|
||||
public KeyPair(long n1, long n2)
|
||||
{
|
||||
K1 = n1;
|
||||
K2 = n2;
|
||||
}
|
||||
|
||||
public readonly int K1;
|
||||
public readonly long K1;
|
||||
|
||||
public readonly int K2;
|
||||
public readonly long K2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using GraphX.PCL.Common.Interfaces;
|
||||
using QuickGraph;
|
||||
using QuickGraph.Algorithms.ShortestPath;
|
||||
|
||||
|
@ -40,9 +41,11 @@ namespace GraphX.PCL.Logic.Algorithms
|
|||
/// <param name="g">The graph.</param>
|
||||
/// <param name="set1"></param>
|
||||
/// <param name="set2"></param>
|
||||
/// <param name="undirected">Assume undirected graph - get both in and out edges</param>
|
||||
/// <returns>Return the list of the selected edges.</returns>
|
||||
public static IEnumerable<TEdge> GetEdgesBetween<TVertex, TEdge>(this IVertexAndEdgeListGraph<TVertex, TEdge> g, List<TVertex> set1, List<TVertex> set2)
|
||||
public static IEnumerable<TEdge> GetEdgesBetween<TVertex, TEdge>(this IVertexAndEdgeListGraph<TVertex, TEdge> g, List<TVertex> set1, List<TVertex> set2, bool undirected = false)
|
||||
where TEdge : IEdge<TVertex>
|
||||
where TVertex: class
|
||||
{
|
||||
var edgesBetween = new List<TEdge>();
|
||||
|
||||
|
@ -50,6 +53,8 @@ namespace GraphX.PCL.Logic.Algorithms
|
|||
foreach (var v in set1)
|
||||
{
|
||||
edgesBetween.AddRange(g.OutEdges(v).Where(edge => set2.Contains(edge.Target)));
|
||||
if(undirected)
|
||||
edgesBetween.AddRange(g.Edges.Where(a=> a.Target == v).Where(edge => set2.Contains(edge.Source)));
|
||||
}
|
||||
|
||||
return edgesBetween;
|
||||
|
|
Загрузка…
Ссылка в новой задаче