/// <summary> /// Draw node on the graph based on the mouse pointer location /// </summary> /// <param name="p"></param> private void DrawNode(Point p) { CanvasNode node = new CanvasNode() { X = p.X, Y = p.Y, IsSelected = true }; graph.Call(graph => graph.Add(node.Impl)); graph[node.Impl] = node; MainCanvas.Children.Add(node); MainCanvas.SelectedNode = node; // As the component is actually a Grid, calculation is needed to obtain the center of the Component in the background MainCanvas.Dispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(Object state) { double widthOffset = node.ActualWidth / 2; double heightOffset = node.ActualHeight / 2; double actualX = p.X - widthOffset; double actualY = p.Y - heightOffset; node.DisplayWidth = node.ActualWidth; node.DisplayHeight = node.ActualHeight; Canvas.SetLeft(node, actualX); Canvas.SetTop(node, actualY); NodePanel.DataContext = node; return(null); }), null); }
/// <summary> /// Draw the edge on the graph that connects 2 nodes passed, if edge param is null, create a new edge /// </summary> /// <param name="startNode"></param> /// <param name="endNode"></param> /// <param name="edge"></param> private void DrawEdge(CanvasNode startNode, CanvasNode endNode, CanvasEdge edge = null) { Point startPoint, endPoint; startPoint = new Point(startNode.X, startNode.Y); endPoint = new Point(endNode.X, endNode.Y); if (edge == null) { edge = new CanvasEdge() { Stroke = Brushes.DarkGray, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, StrokeThickness = 3, X1 = startNode.X, Y1 = startNode.Y, X2 = endNode.X, Y2 = endNode.Y, IsDirected = ArcType.SelectedItem == DirectedArc }; // Add attributes to the edge foreach (KeyValuePair <string, double> attr in graph.CommonAttributes) { if (!edge.Impl.HasNumericAttribute(attr.Key)) { edge.Impl.NumericAttributes.Add(attr.Key, attr.Value); } } graph.Call(graph => { graph.ConnectNodeToWith(startNode.Impl, endNode.Impl, edge.Impl); }); graph[edge.Impl] = edge; } else { edge.Stroke = Brushes.DarkGray; edge.HorizontalAlignment = HorizontalAlignment.Center; edge.VerticalAlignment = VerticalAlignment.Center; edge.StrokeThickness = 3; } MainCanvas.Children.Add(edge); Canvas.SetZIndex(edge, -1); startNode.OutLines.Add(edge); endNode.InLines.Add(edge); MainCanvas.UpdateLines(startNode); MainCanvas.UpdateLines(endNode); }
/// <summary> /// Add edge to the graph, avoid duplicates /// </summary> /// <param name="cgraph"></param> /// <param name="cnode"></param> private void AddIfNotContain(CanvasGraph cgraph, CanvasNode cnode) { INode resultNode = cnode.Impl; //if (resultNode.GetType() != typeof(ResultNode)) // throw new Exception("AddIfNotContain Error!"); if (cgraph.Call(graph => !graph.Contains(resultNode))) { cgraph.Call(graph => graph.Add(resultNode)); } }
public CanvasNode(CanvasNode canvasNode) : base() { OutLines = new List <CanvasEdge>(); InLines = new List <CanvasEdge>(); X = canvasNode.X; Y = canvasNode.Y; DisplayHeight = canvasNode.DisplayHeight; DisplayWidth = canvasNode.DisplayWidth; //Impl = canvasNode.Impl; Impl = new ResultNode(canvasNode.Impl); InitializeComponent(); }
/// <summary> /// Draw result edge onto the result graph /// </summary> /// <param name="resultGraph"></param> /// <param name="canvasEdge"></param> private void DrawOutputEdge(ResultGraph resultGraph, CanvasEdge canvasEdge) { resultGraph.ResultCanvas.Children.Add(canvasEdge); Canvas.SetZIndex(canvasEdge, -1); CanvasNode tempSrcNode = resultGraph.CGraph[canvasEdge.Impl.From]; CanvasNode tempDestNode = resultGraph.CGraph[canvasEdge.Impl.To]; tempSrcNode.OutLines.Add(canvasEdge); tempDestNode.InLines.Add(canvasEdge); resultGraph.ResultCanvas.UpdateLines(tempSrcNode); resultGraph.ResultCanvas.UpdateLines(tempDestNode); }
/// <summary> /// Handles the Click event of both menu items in the context menu. /// </summary> void OnMenuItemClick(object sender, RoutedEventArgs e) { if (this.elementForContextMenu == null || this.elementForContextMenu is CanvasEdge) { return; } if (e.Source == this.menuItemBringToFront || e.Source == this.menuItemSendToBack) { bool bringToFront = e.Source == this.menuItemBringToFront; if (bringToFront) { this.MainCanvas.BringToFront(this.elementForContextMenu); } else { this.MainCanvas.SendToBack(this.elementForContextMenu); } } if (e.Source == this.menuStartArc || e.Source == this.menuEndArc) { CanvasNode selectedNode = this.elementForContextMenu as CanvasNode; bool startDrawing = e.Source == this.menuStartArc; if (startDrawing) { startNode = selectedNode; this.menuStartArc.Visibility = Visibility.Collapsed; this.menuEndArc.Visibility = Visibility.Visible; } else { if (selectedNode == startNode) { MessageBox.Show("Can't connect to the same node", "Error"); return; } endNode = selectedNode; this.menuStartArc.Visibility = Visibility.Visible; this.menuEndArc.Visibility = Visibility.Collapsed; DrawEdge(startNode, endNode); } } }
protected override XElement CreateXElement(INode node) { XElement xelement = base.CreateXElement(node); CanvasNode cnode = cgraph[node]; var position = new XElement("Position", new XElement("X", cnode.X), new XElement("Y", cnode.Y)); var width = new XElement("Width", cnode.DisplayWidth); var height = new XElement("Height", cnode.DisplayHeight); xelement.Add(position); xelement.Add(width); xelement.Add(height); return(xelement); }
protected override INode LoadNode(XElement xnode) { INode node = base.LoadNode(xnode); var position = xnode.Element("Position"); CanvasNode cnode = new CanvasNode(node); cnode.X = Convert.ToDouble(position.Element("X").Value); cnode.Y = Convert.ToDouble(position.Element("Y").Value); cnode.DisplayWidth = Convert.ToDouble(xnode.Element("Width").Value); cnode.DisplayHeight = Convert.ToDouble(xnode.Element("Height").Value); cgraph[node] = cnode; return(node); }
public void UpdateLines(CanvasNode node) { double left = Canvas.GetLeft(node); double top = Canvas.GetTop(node); for (int i = 0; i < node.OutLines.Count; i++) { node.OutLines[i].X1 = left + node.DisplayWidth / 2; node.OutLines[i].Y1 = top + node.DisplayHeight / 2; } for (int i = 0; i < node.InLines.Count; i++) { node.InLines[i].X2 = left + node.DisplayWidth / 2; node.InLines[i].Y2 = top + node.DisplayHeight / 2; } }
/// <summary> /// Draw node on the graph based on the given node (for xml loading) /// </summary> /// <param name="node"></param> private void DrawNode(CanvasNode node, Canvas canvas = null) { double widthOffset = node.DisplayWidth / 2;; double heightOffset = node.DisplayHeight / 2; double actualX = node.X - widthOffset; double actualY = node.Y - heightOffset; if (canvas != null) { canvas.Children.Add(node); } else { MainCanvas.Children.Add(node); } Canvas.SetLeft(node, node.X); Canvas.SetTop(node, node.Y); }
private void SetMainWindowSidePanel(UIElement elementBeingDragged) { if (elementBeingDragged is CanvasNode) { if (this.edge != null) { this.edge.IsSelected = false; this.edge = null; } this.node.IsSelected = true; NetworkObservability.MainWindow.AppWindow.NodePanel.DataContext = this.node; NetworkObservability.MainWindow.AppWindow.SidePanel.SelectedIndex = 0; } else if (elementBeingDragged is CanvasEdge) { if (this.node != null) { this.node.IsSelected = false; this.node = null; } this.edge.IsSelected = true; Dictionary <string, double> tempNumAttr = new Dictionary <string, double>(); Dictionary <string, string> tempDescAttr = new Dictionary <string, string>(); foreach (var a in this.edge.Impl.NumericAttributes) { tempNumAttr[a.Key] = a.Value; } foreach (var a in this.edge.Impl.DescriptiveAttributes) { tempDescAttr[a.Key] = a.Value; } NetworkObservability.MainWindow.AppWindow.NumericAttrList.ItemsSource = tempNumAttr; NetworkObservability.MainWindow.AppWindow.DescAttrList.ItemsSource = tempDescAttr; NetworkObservability.MainWindow.AppWindow.SidePanel.SelectedIndex = 1; } }
/// <summary> /// Add result edge onto the result graph /// </summary> /// <param name="resultGraph"></param> /// <param name="srcNode"></param> /// <param name="destNode"></param> /// <param name="fullyObserved"></param> private void AddOutputEdge(ResultGraph resultGraph, CanvasNode srcNode, CanvasNode destNode, bool fullyObserved) { CanvasEdge edge = new CanvasEdge(isResult: true) { Stroke = fullyObserved ? Brushes.Green : Brushes.DarkOrange, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, StrokeThickness = 3, X1 = srcNode.X, Y1 = srcNode.Y, X2 = destNode.X, Y2 = destNode.Y, IsDirected = ArcType.SelectedItem == DirectedArc, }; resultGraph.CGraph.Call(g => { g.ConnectNodeToWith(srcNode.Impl, destNode.Impl, edge.Impl); }); resultGraph.CGraph[edge.Impl] = edge; }
/// <summary> /// Open and load graph from xml /// </summary> private void OpenFromFile() { OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.Multiselect = false; fileDialog.Filter = "XML Files(*.xml)|*.xml|Textfiles(*.txt)|*.txt|All Files(*.*)|*.*"; fileDialog.DefaultExt = ".xml"; Nullable <bool> getFile = fileDialog.ShowDialog(); if (getFile == true) { CanvasGraphXML reader = new CanvasGraphXML(); //CanvasGraph cGraph = new CanvasGraph(); try { MainCanvas.Children.Clear(); graph = reader.Load((fileDialog.FileName).ToString()); foreach (var node in graph.Impl.AllNodes.Values) { DrawNode(graph[node]); } foreach (var edge in graph.Impl.AllEdges.Values) { CanvasNode fromNode = graph[edge.From]; CanvasNode toNode = graph[edge.To]; DrawEdge(fromNode, toNode, graph[edge]); } } catch (ArgumentNullException) { MessageBox.Show("Failed to load the invalid XML file.\nPlease use a valid one"); } catch (Exception err) { MessageBox.Show(err.Message); } } }
/// <summary> /// Display constraint window /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Start_Click(object sender, RoutedEventArgs e) { // Create a resultGraph instance StartWindow startWindow = new StartWindow(graph.CommonAttributes); if (startWindow.ShowDialog() != true) { MessageBox.Show("Task imcompleted.\nAborted.", "Algorithm not running."); } else { logTab.IsSelected = true; logger.Content = ""; logger.Content += "\nStart Checking observability....\n"; var observers = graph.Call(graph => graph.AllNodes.Values.Where(node => node.IsObserver)).ToArray(); AllPaths algorithm = new AllPaths(); var result = new ConnectivityObserver().Observe(graph.Impl, observers, startWindow.returnValue, algorithm); logger.Content += "Observation Completed.\n"; ResultGraph resultGraph = new ResultGraph(); foreach (var pair in result) { INode from = pair.Key.From, to = pair.Key.To; IEnumerable <Route> observedRoutes = pair.Value.Item1; IEnumerable <Route> unobservedRoutes = pair.Value.Item2; if (observedRoutes.Count() > 0) { Route shortestObRoute = observedRoutes.OrderBy(p => p.PathCost).First(); CanvasNode tempSrcNode = new CanvasNode(graph[from]); CanvasNode tempDestNode = new CanvasNode(graph[to]); if (resultGraph.CGraph.Call(graph => !graph.Contains(from))) { resultGraph.CGraph.Call(graph => graph.Add(from)); resultGraph.CGraph[from] = tempSrcNode; } else { tempSrcNode = resultGraph.CGraph[from]; } if (resultGraph.CGraph.Call(graph => !graph.Contains(to))) { resultGraph.CGraph.Call(graph => graph.Add(to)); resultGraph.CGraph[to] = tempDestNode; } else { tempDestNode = resultGraph.CGraph[to]; } double shortestDistance = Double.MaxValue; if (unobservedRoutes.Count() > 0) { Route shortestUnobRoute = unobservedRoutes.OrderBy(p => p.PathCost).First(); shortestDistance = shortestUnobRoute.PathCost; } if ((from.IsVisible && to.IsVisible) && shortestObRoute.PathCost < shortestDistance) { //resultGraph.logger.Content += String.Format("\nNode {0} to Node {1} : observed\n", from.Id, to.Id); //logger.Content += String.Format("The path from Node {0} to Node {1} is : {2}\n", from.Id, to.Id, shortestObRoute); resultGraph.observedLog.Content += String.Format("{0} (This is the shortest path)\n", shortestObRoute); AddOutputEdge(resultGraph, tempSrcNode, tempDestNode, unobservedRoutes.Count() == 0); } else { resultGraph.observedLog.Content += String.Format("{0}\n", shortestObRoute); } } // foreach (Route through in observedRoutes) //{ // logger.Content += String.Format("Node {0} to Node {1} : observed\n", from.Id, to.Id); // logger.Content += String.Format("The path from Node {0} to Node {1} is : {2}\n", from.Id, to.Id, through); //CanvasNode tempSrcNode = new CanvasNode(graph[from]); //CanvasNode tempDestNode = new CanvasNode(graph[to]); //DrawNode(tempSrcNode, resultGraph.ResultCanvas); //DrawNode(tempDestNode, resultGraph.ResultCanvas); // if (from.IsVisible && to.IsVisible) // { // DrawOutputEdge(resultGraph, tempSrcNode, tempDestNode); // } //} foreach (Route through in unobservedRoutes) { // logger.Content += String.Format("\nNode {0} to Node {1} : not observed\n", from.Id, to.Id); resultGraph.unobservedLog.Content += String.Format("{0}\n", through); } } foreach (var node in resultGraph.CGraph.Call(graph => graph.AllNodes.Values)) { var cnode = resultGraph.CGraph[node]; DrawNode(cnode, resultGraph.ResultCanvas); } foreach (var edge in resultGraph.CGraph.Call(graph => graph.AllEdges.Values)) { var cedge = resultGraph.CGraph[edge]; DrawOutputEdge(resultGraph, cedge); } logger.Content += "Task Finished."; // Display the resultGraph window resultGraph.Show(); } }
public void Remove(CanvasNode node) { nodeToCNode.Remove(node.Impl); Impl.Remove(node.Impl); }