Skip to content
This repository was archived by the owner on Jun 7, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,13 @@
<DependentUpon>EditVerticesDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Visualization\Arrow.cs" />
<Compile Include="Visualization\CirclePositionsVisualizer.cs" />
<Compile Include="Visualization\Edge.cs" />
<Compile Include="Visualization\GraphVisualizer.xaml.cs">
<DependentUpon>GraphVisualizer.xaml</DependentUpon>
</Compile>
<Compile Include="Visualization\IVisualizationAlgorithm.cs" />
<Compile Include="Visualization\RandomPositionVisualizer.cs" />
<Compile Include="Visualization\Vertex.cs" />
<Compile Include="Visualization\VertexClickEventArgs.cs" />
<Compile Include="Visualization\VisualizationAlgorithm.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Linq;

namespace GraphLabs.Graphs.UIComponents.Visualization
{
/// <summary>
/// по кургу
/// </summary>
public class CirclePositionsVisualizer : IVisualizationAlgorithm
{
private GraphVisualizer g_;

/// <summary>
/// constr
/// </summary>
public CirclePositionsVisualizer(GraphVisualizer g)
{
g_ = g;
}

/// <inheritdoc />
public string Name()
{
return "Circle";
}

/// <inheritdoc />
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;
}
}
}
}
100 changes: 30 additions & 70 deletions GraphLabs.Graphs.UIComponents/Visualization/GraphVisualizer.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/// <summary> Алгоритм, используемый для визу </summary>
public IVisualizationAlgorithm IVisualizationAlgorithm
{
get { return _ivisualizationAlgorithm; }
set
{
if (value == _ivisualizationAlgorithm)
{
return;
}
_visualizationAlgorithm = VisualizationAlgorithm.User;
_ivisualizationAlgorithm = value;
Refresh();
}
}
private IVisualizationAlgorithm _ivisualizationAlgorithm;

/// <summary> Полностью обновляет состояние визуализатора, перечитывая отображаемый граф </summary>
public void Refresh()
{
Expand All @@ -359,7 +385,7 @@ public void Refresh()
{
AddEdge(edge);
}
CalculateVertexPositions();
_ivisualizationAlgorithm.Visualize();
_suspendNotifications = false;
}

Expand Down Expand Up @@ -405,60 +431,14 @@ private double GetScaleFactor()
return scaleFactor;
}

/// <summary> Устанавливает начальное рандомное положение вершин </summary>
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;
}
}

/// <summary> Устанавливает начальные положения вершин по окружности </summary>
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;
}

}

/// <summary> Рассотяние между v1 и v2 </summary>
private static double Distance(Vertex v1, Vertex v2)
{
return Math.Sqrt(Math.Pow(v1.ModelX - v2.ModelX, 2) + Math.Pow(v1.ModelY - v2.ModelY, 2));
}

/// <summary> Оперделяет, пересекаются ли вершины </summary>
private static bool AreIntersecting(Vertex v1, Vertex v2)
public static bool AreIntersecting(Vertex v1, Vertex v2)
{
return Distance(v1, v2) <= v1.Radius + v2.Radius;
}
Expand Down Expand Up @@ -572,28 +552,7 @@ private void MoveVertices()
_animationTimer.Start();
}

/// <summary> Считает позиции всех вершин, используя модель с зарядами и пружинками </summary>
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 // Вычисление коориднат вершин
Expand Down Expand Up @@ -833,6 +792,7 @@ protected virtual void MouseMoveVertex(object sender, MouseEventArgs mouseEventA
/// <summary> Конструктор </summary>
public GraphVisualizer()
{
_animationTimer = null;
InitializeComponent();
_vertices = new ObservableCollection<Vertex>();
_edges = new ObservableCollection<Edge>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace GraphLabs.Graphs.UIComponents.Visualization
{
/// <summary>
/// можно сделать свою визуализацию
/// </summary>
public interface IVisualizationAlgorithm
{
/// <summary>
/// имя алгоритма визуализации
/// </summary>
/// <returns></returns>
string Name();

/// <summary>
/// то как мы выпоняем визуализацию
/// </summary>
void Visualize();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Linq;

namespace GraphLabs.Graphs.UIComponents.Visualization
{
/// <summary>
/// случайные позиции
/// </summary>
public class RandomPositionVisualizer : IVisualizationAlgorithm
{
private GraphVisualizer _g;
/// <summary>
/// constructor
/// </summary>
/// <param name="g"></param>
public RandomPositionVisualizer(GraphVisualizer g)
{
_g = g;
}

/// <inheritdoc />
public string Name()
{
return "RandomPositions";
}

/// <inheritdoc />
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;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,10 @@ public enum VisualizationAlgorithm

/// <summary> Случайные позиции </summary>
RandomPositions,

/// <summary>
/// типа кастомный алгоритм
/// </summary>
User
}
}
1 change: 1 addition & 0 deletions GraphLabs.Tests.UI/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
DefaultEdgeStrokeThickness="2.5"
DefaultVertexRadius="15"
DefaultVertexBackground="LightGray"/>

<StackPanel Orientation="Vertical" Grid.Column="1">
<Button Width="100" Height="30" Content="Run" Click="RunClick"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
Expand Down