diff --git a/GraphLabs.Graphs.UIComponents/GraphLabs.Graphs.UIComponents.csproj b/GraphLabs.Graphs.UIComponents/GraphLabs.Graphs.UIComponents.csproj
index a170ef8..0ab2064 100644
--- a/GraphLabs.Graphs.UIComponents/GraphLabs.Graphs.UIComponents.csproj
+++ b/GraphLabs.Graphs.UIComponents/GraphLabs.Graphs.UIComponents.csproj
@@ -177,10 +177,13 @@
EditVerticesDialog.xaml
+
GraphVisualizer.xaml
+
+
diff --git a/GraphLabs.Graphs.UIComponents/Visualization/CirclePositionsVisualizer.cs b/GraphLabs.Graphs.UIComponents/Visualization/CirclePositionsVisualizer.cs
new file mode 100644
index 0000000..b418634
--- /dev/null
+++ b/GraphLabs.Graphs.UIComponents/Visualization/CirclePositionsVisualizer.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Linq;
+
+namespace GraphLabs.Graphs.UIComponents.Visualization
+{
+ ///
+ /// по кургу
+ ///
+ public class CirclePositionsVisualizer : IVisualizationAlgorithm
+ {
+ private GraphVisualizer g_;
+
+ ///
+ /// constr
+ ///
+ public CirclePositionsVisualizer(GraphVisualizer g)
+ {
+ g_ = g;
+ }
+
+ ///
+ public string Name()
+ {
+ return "Circle";
+ }
+
+ ///
+ public void Visualize()
+ {
+ var vertices = g_.Vertices;
+ if (!vertices.Any())
+ return;
+
+ var r = Math.Min(g_.ActualHeight, g_.ActualWidth) / 2;
+ var phi = 0.0;
+ var deltaPhi = 2 * Math.PI / vertices.Count;
+ foreach (var vertex in vertices)
+ {
+ vertex.ModelX = (r - 2 * g_.DefaultVertexRadius) * Math.Cos(phi) + r;
+ vertex.ModelY = (r - 2 * g_.DefaultVertexRadius) * Math.Sin(phi) + r;
+ vertex.ScaleFactor = 1;
+
+ phi += deltaPhi;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/GraphLabs.Graphs.UIComponents/Visualization/GraphVisualizer.xaml.cs b/GraphLabs.Graphs.UIComponents/Visualization/GraphVisualizer.xaml.cs
index 761e4a8..805ab7d 100644
--- a/GraphLabs.Graphs.UIComponents/Visualization/GraphVisualizer.xaml.cs
+++ b/GraphLabs.Graphs.UIComponents/Visualization/GraphVisualizer.xaml.cs
@@ -332,11 +332,37 @@ public VisualizationAlgorithm VisualizationAlgorithm
return;
}
_visualizationAlgorithm = value;
+ switch (_visualizationAlgorithm)
+ {
+ case VisualizationAlgorithm.Circle:
+ _ivisualizationAlgorithm = new CirclePositionsVisualizer(this); break;
+ case VisualizationAlgorithm.RandomPositions:
+ _ivisualizationAlgorithm = new RandomPositionVisualizer(this); break;
+ default:
+ throw new Exception("I cant or dont want do it");
+ }
Refresh();
}
}
private VisualizationAlgorithm _visualizationAlgorithm;
+ /// Алгоритм, используемый для визу
+ public IVisualizationAlgorithm IVisualizationAlgorithm
+ {
+ get { return _ivisualizationAlgorithm; }
+ set
+ {
+ if (value == _ivisualizationAlgorithm)
+ {
+ return;
+ }
+ _visualizationAlgorithm = VisualizationAlgorithm.User;
+ _ivisualizationAlgorithm = value;
+ Refresh();
+ }
+ }
+ private IVisualizationAlgorithm _ivisualizationAlgorithm;
+
/// Полностью обновляет состояние визуализатора, перечитывая отображаемый граф
public void Refresh()
{
@@ -359,7 +385,7 @@ public void Refresh()
{
AddEdge(edge);
}
- CalculateVertexPositions();
+ _ivisualizationAlgorithm.Visualize();
_suspendNotifications = false;
}
@@ -405,52 +431,6 @@ private double GetScaleFactor()
return scaleFactor;
}
- /// Устанавливает начальное рандомное положение вершин
- private void SetRandomStartLocations()
- {
- if (!_vertices.Any())
- return;
-
- var rnd = new Random();
-
- for (var i = 0; i < _vertices.Count; ++i)
- {
- var vertex = _vertices[i];
- vertex.ModelX = rnd.NextDouble() * (ActualWidth - 2 * DefaultVertexRadius) + DefaultVertexRadius;
- vertex.ModelY = rnd.NextDouble() * (ActualHeight - 2 * DefaultVertexRadius) + DefaultVertexRadius;
- vertex.ScaleFactor = 1;
-
- var j = 0;
- for (; j < i; j++)
- {
- if (AreIntersecting(vertex, (Vertex)_vertices[j]))
- break;
- }
- if (j < i)
- --i;
- }
- }
-
- /// Устанавливает начальные положения вершин по окружности
- private void SetCircleLocations()
- {
- if (!_vertices.Any())
- return;
-
- var r = Math.Min(ActualHeight, ActualWidth) / 2;
- var phi = 0.0;
- var deltaPhi = 2*Math.PI/_vertices.Count;
- foreach (var vertex in _vertices)
- {
- vertex.ModelX = (r - 2 * DefaultVertexRadius) * Math.Cos(phi) + r;
- vertex.ModelY = (r - 2 * DefaultVertexRadius) * Math.Sin(phi) + r;
- vertex.ScaleFactor = 1;
-
- phi += deltaPhi;
- }
-
- }
-
/// Рассотяние между v1 и v2
private static double Distance(Vertex v1, Vertex v2)
{
@@ -458,7 +438,7 @@ private static double Distance(Vertex v1, Vertex v2)
}
/// Оперделяет, пересекаются ли вершины
- private static bool AreIntersecting(Vertex v1, Vertex v2)
+ public static bool AreIntersecting(Vertex v1, Vertex v2)
{
return Distance(v1, v2) <= v1.Radius + v2.Radius;
}
@@ -572,28 +552,7 @@ private void MoveVertices()
_animationTimer.Start();
}
- /// Считает позиции всех вершин, используя модель с зарядами и пружинками
- private void CalculateVertexPositions()
- {
- switch (_visualizationAlgorithm)
- {
- case VisualizationAlgorithm.ChargesAndSprings:
- SetRandomStartLocations();
- _animationTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(ANIMATION_INTERVAL) };
- _animationTimer.Tick += (s, e) => MoveVertices();
- _animationTimer.Start();
- break;
- case VisualizationAlgorithm.RandomPositions:
- SetRandomStartLocations();
- break;
- case VisualizationAlgorithm.Circle:
- SetCircleLocations();
- break;
- default:
- throw new NotSupportedException(
- string.Format("Указан неизвестный алгоритм визуализации {0}", _visualizationAlgorithm));
- }
- }
+
#endregion // Вычисление коориднат вершин
@@ -833,6 +792,7 @@ protected virtual void MouseMoveVertex(object sender, MouseEventArgs mouseEventA
/// Конструктор
public GraphVisualizer()
{
+ _animationTimer = null;
InitializeComponent();
_vertices = new ObservableCollection();
_edges = new ObservableCollection();
diff --git a/GraphLabs.Graphs.UIComponents/Visualization/IVisualizationAlgorithm.cs b/GraphLabs.Graphs.UIComponents/Visualization/IVisualizationAlgorithm.cs
new file mode 100644
index 0000000..3ce9b75
--- /dev/null
+++ b/GraphLabs.Graphs.UIComponents/Visualization/IVisualizationAlgorithm.cs
@@ -0,0 +1,19 @@
+namespace GraphLabs.Graphs.UIComponents.Visualization
+{
+ ///
+ /// можно сделать свою визуализацию
+ ///
+ public interface IVisualizationAlgorithm
+ {
+ ///
+ /// имя алгоритма визуализации
+ ///
+ ///
+ string Name();
+
+ ///
+ /// то как мы выпоняем визуализацию
+ ///
+ void Visualize();
+ }
+}
\ No newline at end of file
diff --git a/GraphLabs.Graphs.UIComponents/Visualization/RandomPositionVisualizer.cs b/GraphLabs.Graphs.UIComponents/Visualization/RandomPositionVisualizer.cs
new file mode 100644
index 0000000..87dd414
--- /dev/null
+++ b/GraphLabs.Graphs.UIComponents/Visualization/RandomPositionVisualizer.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Linq;
+
+namespace GraphLabs.Graphs.UIComponents.Visualization
+{
+ ///
+ /// случайные позиции
+ ///
+ public class RandomPositionVisualizer : IVisualizationAlgorithm
+ {
+ private GraphVisualizer _g;
+ ///
+ /// constructor
+ ///
+ ///
+ public RandomPositionVisualizer(GraphVisualizer g)
+ {
+ _g = g;
+ }
+
+ ///
+ public string Name()
+ {
+ return "RandomPositions";
+ }
+
+ ///
+ public void Visualize()
+ {
+ var vertices = _g.Vertices;
+ if (!vertices.Any())
+ return;
+
+ var rnd = new Random();
+
+ for (var i = 0; i < vertices.Count; ++i)
+ {
+ var vertex = vertices[i];
+ vertex.ModelX = rnd.NextDouble() * (_g.ActualWidth - 2 * _g.DefaultVertexRadius) + _g.DefaultVertexRadius;
+ vertex.ModelY = rnd.NextDouble() * (_g.ActualHeight - 2 * _g.DefaultVertexRadius) + _g.DefaultVertexRadius;
+ vertex.ScaleFactor = 1;
+
+ var j = 0;
+ for (; j < i; j++)
+ {
+ if (GraphVisualizer.AreIntersecting(vertex, (Vertex)vertices[j]))
+ break;
+ }
+ if (j < i)
+ --i;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/GraphLabs.Graphs.UIComponents/Visualization/VisualizationAlgorithm.cs b/GraphLabs.Graphs.UIComponents/Visualization/VisualizationAlgorithm.cs
index 72a9935..94d97e7 100644
--- a/GraphLabs.Graphs.UIComponents/Visualization/VisualizationAlgorithm.cs
+++ b/GraphLabs.Graphs.UIComponents/Visualization/VisualizationAlgorithm.cs
@@ -11,5 +11,10 @@ public enum VisualizationAlgorithm
/// Случайные позиции
RandomPositions,
+
+ ///
+ /// типа кастомный алгоритм
+ ///
+ User
}
}
diff --git a/GraphLabs.Tests.UI/MainPage.xaml b/GraphLabs.Tests.UI/MainPage.xaml
index ddf1fa9..3ecf79e 100644
--- a/GraphLabs.Tests.UI/MainPage.xaml
+++ b/GraphLabs.Tests.UI/MainPage.xaml
@@ -97,6 +97,7 @@
DefaultEdgeStrokeThickness="2.5"
DefaultVertexRadius="15"
DefaultVertexBackground="LightGray"/>
+