source: trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualizationView.cs @ 2819

Last change on this file since 2819 was 2819, checked in by mkommend, 11 years ago

new version of graph visualization with menuitems (ticket #867)

File size: 8.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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.ComponentModel;
25using System.Drawing;
26using System.Data;
27using System.Linq;
28using System.Text;
29using System.Windows.Forms;
30using HeuristicLab.MainForm;
31using HeuristicLab.Core;
32using HeuristicLab.Core.Views;
33using Netron.Diagramming.Core;
34using HeuristicLab.Parameters;
35
36namespace HeuristicLab.Operators.Views.GraphVisualization {
37  [Content(typeof(IOperator), false)]
38  public partial class OperatorGraphVisualizationView : ItemView {
39    private Dictionary<IOperator, IShape> operatorShapeMapping;
40    private Dictionary<KeyValuePair<IOperator, IValueParameter<IOperator>>, IConnection> connectionMapping;
41    private HashSet<IValueParameter<IOperator>> parameters;
42    /// <summary>
43    /// Initializes a new instance of <see cref="OperatorGraphVisualizationView"/> with caption "Operator Graph".
44    /// </summary>
45    public OperatorGraphVisualizationView() {
46      InitializeComponent();
47      Caption = "Operator Graph";
48      this.operatorShapeMapping = new Dictionary<IOperator, IShape>();
49      this.connectionMapping = new Dictionary<KeyValuePair<IOperator, IValueParameter<IOperator>>, IConnection>();
50      this.parameters = new HashSet<IValueParameter<IOperator>>();
51
52      this.graphVisualization.Controller.Model.OnEntityRemoved += new EventHandler<EntityEventArgs>(Model_OnEntityRemoved);
53    }
54
55    /// <summary>
56    /// Initializes a new instance of <see cref="OperatorGraphVisualizationView"/>
57    /// with the given <paramref name="operatorGraph"/>.
58    /// </summary>
59    /// <remarks>Calls <see cref="OperatorGraphView()"/>.</remarks>
60    /// <param name="operatorGraph">The operator graph to represent visually.</param>
61    public OperatorGraphVisualizationView(IOperator content)
62      : this() {
63      this.Content = content;
64    }
65
66    /// <summary>
67    /// Gets or sets the operator graph to represent visually.
68    /// </summary>
69    /// <remarks>Uses property <see cref="ViewBase.Item"/> of base class <see cref="ViewBase"/>.
70    /// No own data storage present.</remarks>
71    public new IOperator Content {
72      get { return (IOperator)base.Content; }
73      set { base.Content = value; }
74    }
75
76    private IModel GraphModel {
77      get { return this.graphVisualization.Controller.Model; }
78    }
79
80
81    protected override void OnContentChanged() {
82      base.OnContentChanged();
83      this.ClearGraph();
84
85      this.CreateGraph(null, new OperatorParameter(string.Empty, this.Content));
86      foreach (IShape shape in this.operatorShapeMapping.Values)
87        this.GraphModel.AddShape(shape);
88
89      foreach (IConnection connection in this.connectionMapping.Values)
90        this.GraphModel.AddConnection(connection);
91
92      if (this.Content == null)
93        this.graphVisualization.Controller.Model.LayoutRoot = null;
94      else
95        this.graphVisualization.Controller.Model.LayoutRoot = this.operatorShapeMapping[this.Content];
96      this.RelayoutOperatorGraph();
97    }
98
99    private void opParam_ValueChanged(object sender, EventArgs e) {
100      if (InvokeRequired)
101        Invoke(new EventHandler(opParam_ValueChanged), sender, e);
102      else {
103        this.OnContentChanged();
104      }
105    }
106
107    private void ClearGraph() {
108      this.GraphModel.Clear();
109      foreach (IValueParameter<IOperator> opParam in this.parameters)
110        opParam.ValueChanged -= opParam_ValueChanged;
111
112      this.operatorShapeMapping.Clear();
113      this.parameters.Clear();
114      this.connectionMapping.Clear();
115    }
116
117
118
119    private void CreateGraph(IOperator parent, IValueParameter<IOperator> op) {
120      if (op == null || op.Value == null)
121        return;
122
123      IShape shape;
124      if (!this.operatorShapeMapping.ContainsKey(op.Value)) {
125        shape = CreateOperatorShape(op.Value);
126        this.operatorShapeMapping[op.Value] = shape;
127
128        foreach (IParameter param in op.Value.Parameters) {
129          IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
130          if (opParam != null) {
131            HandleOperatorParameter(opParam);
132            this.CreateGraph(op.Value, opParam);
133          }
134        }
135      }
136
137      if (parent != null)
138        ConnectShapes(parent, op);
139    }
140
141    private void HandleOperatorParameter(IValueParameter<IOperator> opParam) {
142      if (opParam == null)
143        return;
144      opParam.ValueChanged += new EventHandler(opParam_ValueChanged);
145      parameters.Add(opParam);
146    }
147
148    private IConnection ConnectShapes(IOperator parent, IValueParameter<IOperator> opParam) {
149      IShape operatorShape = this.operatorShapeMapping[opParam.Value];
150      IShape parentShape = this.operatorShapeMapping[parent];
151      IConnector operatorConnector = parentShape.Connectors.Where(c => c.Name == "Bottom connector").First();
152      IConnector parentConnector = operatorShape.Connectors.Where(c => c.Name == "Top connector").First();
153
154      IConnection connection = new Connection(parentConnector.Point, operatorConnector.Point);
155      parentConnector.AttachConnector(connection.From);
156      operatorConnector.AttachConnector(connection.To);
157
158      this.connectionMapping[new KeyValuePair<IOperator, IValueParameter<IOperator>>(parent, opParam)] = connection;
159      return connection;
160    }
161
162    private IShape CreateOperatorShape(IOperator op) {
163      ClassShape shape = new ClassShape();
164      shape.Name = op.Name;
165      shape.Text = op.Name;
166      shape.Title = op.Name;
167      shape.SubTitle = op.GetType().ToString();
168
169      return shape;
170    }
171
172    private void Model_OnEntityRemoved(object sender, EntityEventArgs e) {
173      IShape shape = e.Entity as IShape;
174      if (shape != null) {
175        IOperator op = operatorShapeMapping.Where(os => os.Value == shape).First().Key;
176        if (op == this.Content)
177          this.Content = null;
178        else {
179          //clear all connections to the removed operator
180          IEnumerable<IValueParameter<IOperator>> parentOperator = this.connectionMapping.Where(cs => cs.Key.Value.Value == op).Select(x => x.Key.Value);
181          foreach(IValueParameter<IOperator> opParam in parentOperator.ToArray())
182            opParam.Value = null;
183
184          //remove connections from graph view
185          IEnumerable<IConnection> connections = this.connectionMapping.Where(cs => cs.Key.Value.Value == op).Select(x => x.Value);
186          foreach (IConnection connection in connections)
187            this.GraphModel.Remove(connection);
188
189          this.graphVisualization.Invalidate();
190        }
191
192
193      }
194    }
195
196    #region methods for toolbar items
197
198    internal void RelayoutOperatorGraph() {
199      if (this.operatorShapeMapping.Count > 0 && this.connectionMapping.Count > 0) { //otherwise the layout does not work
200        this.graphVisualization.Invalidate();
201        this.graphVisualization.Controller.RunActivity("Standard TreeLayout");
202      }
203    }
204
205    internal void ActivateZoomAreaTool() {
206      this.graphVisualization.Controller.ActivateTool(ControllerBase.ZoomAreaToolName);
207    }
208
209    internal void ActivateZoomInTool() {
210      this.graphVisualization.Controller.ActivateTool(ControllerBase.ZoomInToolName);
211    }
212
213    internal void ActivateZoomOutTool() {
214      this.graphVisualization.Controller.ActivateTool(ControllerBase.ZoomOutToolName);
215    }
216
217    internal void ActivatePanTool() {
218      this.graphVisualization.Controller.ActivateTool(ControllerBase.PanToolName);
219    }
220
221    internal void ActivateSelectTool() {
222      this.graphVisualization.Controller.ActivateTool(ControllerBase.SelectionToolName);
223    }
224
225    #endregion
226  }
227}
Note: See TracBrowser for help on using the repository browser.