source: branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/NetworkVisualizationView.cs @ 13833

Last change on this file since 13833 was 13833, checked in by jkarder, 3 years ago

#2205: worked on optimization networks

  • added layout algorithm prototype
  • fixed bug in LoadVisualProperties methods
File size: 8.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Collections;
26using HeuristicLab.Core;
27using HeuristicLab.Core.Networks;
28using HeuristicLab.Core.Networks.Views;
29using HeuristicLab.MainForm;
30using HeuristicLab.Networks.Views.NetworkVisualization.Views.ChartModes;
31using HeuristicLab.Visualization;
32using HeuristicLab.Visualization.ChartModes;
33
34namespace HeuristicLab.Networks.Views.NetworkVisualization.Views {
35  [View("Network Visualization View")]
36  [Content(typeof(Network), false)]
37  [Content(typeof(INetwork), false)]
38  public partial class NetworkVisualizationView : NetworkItemView {
39    private Dictionary<string, IPrimitive> primitiveDict = new Dictionary<string, IPrimitive>();
40
41    public new INetwork Content {
42      get { return (INetwork)base.Content; }
43      set { base.Content = value; }
44    }
45
46    public NetworkVisualizationView() {
47      InitializeComponent();
48
49      var selectMode = new SelectChartMode(chartControl);
50      selectMode.SelectedPrimitivesChanged += SelectMode_SelectedPrimitivesChanged;
51      chartControl.AddChartModes(
52        selectMode,
53        new PanChartMode(chartControl),
54        new RulerChartMode(chartControl),
55        new ZoomInChartMode(chartControl),
56        new ZoomOutChartMode(chartControl),
57        new AddNodesChartMode(chartControl),
58        new AddPortsChartMode(chartControl),
59        new ConnectPortsChartMode(chartControl)
60      );
61      chartControl.Mode = selectMode;
62    }
63
64    protected override void OnContentChanged() {
65      base.OnContentChanged();
66      UpdateContent();
67      if (Content != null)
68        LayoutNodes(Content.Nodes);
69      chartControl.Tag = Content;
70    }
71
72    protected override void RegisterContentEvents() {
73      base.RegisterContentEvents();
74      Content.Nodes.ItemsAdded += Nodes_ItemsAdded;
75      Content.Nodes.ItemsRemoved += Nodes_ItemsRemoved;
76      Content.Nodes.ItemsReplaced += Nodes_ItemsReplaced;
77      Content.Ports.ItemsAdded += Ports_ItemsAdded;
78      Content.Ports.ItemsRemoved += Ports_ItemsRemoved;
79      Content.Ports.ItemsReplaced += Ports_ItemsReplaced;
80    }
81
82    protected override void DeregisterContentEvents() {
83      Content.Nodes.ItemsAdded -= Nodes_ItemsAdded;
84      Content.Nodes.ItemsRemoved -= Nodes_ItemsRemoved;
85      Content.Nodes.ItemsReplaced -= Nodes_ItemsReplaced;
86      Content.Ports.ItemsAdded -= Ports_ItemsAdded;
87      Content.Ports.ItemsRemoved -= Ports_ItemsRemoved;
88      Content.Ports.ItemsReplaced -= Ports_ItemsReplaced;
89      base.DeregisterContentEvents();
90    }
91
92    #region Event Handlers
93    private void SelectMode_SelectedPrimitivesChanged(object sender, EventArgs e) {
94      var selectedPrimitives = chartControl.Chart.Group.SelectedPrimitives;
95      var nodePrimitive = selectedPrimitives.OfType<NodeRectangle>().SingleOrDefault();
96      viewHost.Content = nodePrimitive != null ? nodePrimitive.NetworkItem : null;
97    }
98
99    #region Nodes Event Handlers
100    private void Nodes_ItemsAdded(object sender, CollectionItemsChangedEventArgs<INode> e) {
101      // TODO: don't update everything
102      UpdateContent();
103    }
104
105    private void Nodes_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<INode> e) {
106      // TODO: don't update everything
107      UpdateContent();
108    }
109
110    private void Nodes_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<INode> e) {
111      // TODO: don't update everything
112      UpdateContent();
113    }
114    #endregion
115
116    #region Ports Event Handlers
117    private void Ports_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IPort> e) { }
118
119    private void Ports_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IPort> e) { }
120
121    private void Ports_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IPort> e) { }
122    #endregion
123
124    private void detailsToggleButton_Click(object sender, EventArgs e) {
125      splitContainer.Panel2Collapsed = !splitContainer.Panel2Collapsed;
126      detailsToggleButton.Text = splitContainer.Panel2Collapsed ? "<" : ">";
127    }
128    #endregion
129
130    #region Helpers
131    private void UpdateContent() {
132      if (Content == null) return;
133
134      chartControl.SuspendRendering();
135      try {
136        foreach (var r in primitiveDict.Values.OfType<NodeRectangle>())
137          r.NetworkItem = null;
138        primitiveDict.Clear();
139        chartControl.Chart.Group.Clear();
140        DrawNodes(Content.Nodes);
141        ConnectNodes(Content.Nodes);
142      } finally {
143        chartControl.ResumeRendering();
144      }
145    }
146
147    private void DrawNodes(IKeyedItemCollection<string, INode> nodes) {
148      foreach (var node in nodes) {
149        var defaultPrimitive = PrimitiveAttribute.CreateDefaultPrimitive(node.GetType(), chartControl.Chart, node);
150        if (defaultPrimitive == null) continue;
151        chartControl.Chart.Group.Add(defaultPrimitive);
152        primitiveDict[node.Name] = defaultPrimitive;
153      }
154    }
155
156    private void ConnectNodes(IKeyedItemCollection<string, INode> nodes) {
157      var chart = chartControl.Chart;
158      foreach (var node in nodes) {
159        var nodeRectangle = primitiveDict[node.Name] as NodeRectangle;
160        if (nodeRectangle == null) continue;
161
162        foreach (var port in node.Ports.OfType<IConnectablePort>()) {
163          var connectedPort = port.ConnectedPort as IConnectablePort;
164          if (connectedPort == null) continue;
165
166          var connectedNode = connectedPort.Parent;
167          if (connectedNode == null) continue;
168
169          var connectedRectangle = primitiveDict[connectedNode.Name] as NodeRectangle;
170          if (connectedRectangle == null) continue;
171
172          var leftPortRectangle = (PortRectangle)nodeRectangle.GetPortPrimitive(port);
173          var rightPortRectangle = (PortRectangle)connectedRectangle.GetPortPrimitive(connectedPort);
174
175          var connectionShape = new ConnectionLine(chart, leftPortRectangle, rightPortRectangle);
176
177          chart.Group.Add(connectionShape);
178        }
179      }
180    }
181
182    private void LayoutNodes(IKeyedItemCollection<string, INode> nodes) {
183      var layout = new Layout();
184      var layoutNodes = new Dictionary<string, Layout.LayoutNode>();
185
186      foreach (var node in nodes) {
187        var nodeRectangle = primitiveDict[node.Name] as NodeRectangle;
188        if (nodeRectangle == null) continue;
189
190        var nodeSize = chartControl.Chart.TransformWorldToPixel(nodeRectangle.Size);
191        Layout.LayoutNode layoutNode;
192        if (!layoutNodes.TryGetValue(node.Name, out layoutNode)) {
193          layoutNodes.Add(node.Name, layoutNode = new Layout.LayoutNode(nodeSize));
194          layout.AddNode(layoutNode);
195        }
196
197        foreach (var port in node.Ports.OfType<IConnectablePort>()) {
198          var connectedPort = port.ConnectedPort as IConnectablePort;
199          if (connectedPort == null) continue;
200
201          var connectedNode = connectedPort.Parent;
202          if (connectedNode == null) continue;
203
204          var connectedRectangle = primitiveDict[connectedNode.Name] as NodeRectangle;
205          if (connectedRectangle == null) continue;
206
207          nodeSize = chartControl.Chart.TransformWorldToPixel(connectedRectangle.Size);
208          if (!layoutNodes.ContainsKey(connectedNode.Name)) {
209            layoutNodes.Add(connectedNode.Name, new Layout.LayoutNode(nodeSize));
210            layout.AddNode(layoutNodes[connectedNode.Name]);
211          }
212
213          layoutNode.AddNode(layoutNodes[connectedNode.Name]);
214        }
215      }
216
217      var bounds = chartControl.GetPictureBounds();
218      bounds.Offset((int)chartControl.Chart.LowerLeft.X, -(int)chartControl.Chart.UpperRight.Y);
219
220      layout.Arrange(bounds);
221
222      foreach (var entry in layoutNodes) {
223        var nodeRectangle = primitiveDict[entry.Key] as NodeRectangle;
224        if (nodeRectangle == null) continue;
225        var rectangleNode = entry.Value;
226        nodeRectangle.Move(rectangleNode.Location - nodeRectangle.Center());
227      }
228    }
229    #endregion
230  }
231}
Note: See TracBrowser for help on using the repository browser.