/// <summary>Calculate / create a directed graph from model</summary> public void CalculateDirectedGraph() { if (directedGraphInfo == null) { directedGraphInfo = new DirectedGraph(); } directedGraphInfo.Begin(); bool needAtmosphereNode = false; foreach (NutrientPool pool in Apsim.Children(this, typeof(NutrientPool))) { directedGraphInfo.AddNode(pool.Name, ColourUtilities.ChooseColour(3), Color.Black); foreach (CarbonFlow cFlow in Apsim.Children(pool, typeof(CarbonFlow))) { foreach (string destinationName in cFlow.destinationNames) { string destName = destinationName; if (destName == null) { destName = "Atmosphere"; needAtmosphereNode = true; } directedGraphInfo.AddArc(null, pool.Name, destName, Color.Black); } } } foreach (Solute solute in Apsim.Children(this, typeof(Solute))) { directedGraphInfo.AddNode(solute.Name, ColourUtilities.ChooseColour(2), Color.Black); foreach (NFlow nitrogenFlow in Apsim.Children(solute, typeof(NFlow))) { string destName = nitrogenFlow.destinationName; if (destName == null) { destName = "Atmosphere"; needAtmosphereNode = true; } directedGraphInfo.AddArc(null, nitrogenFlow.sourceName, destName, Color.Black); } } if (needAtmosphereNode) { directedGraphInfo.AddTransparentNode("Atmosphere"); } directedGraphInfo.End(); }
/// <summary> /// Set the graph in the view. /// </summary> /// <param name="nodes">Nodes of the graph.</param> /// <param name="arcs">Arcs of the graph.</param> public void SetGraph(List <StateNode> nodes, List <RuleAction> arcs) { rules.Clear(); actions.Clear(); nodeDescriptions.Clear(); comboModel.Clear(); var graph = new DirectedGraph(); nodes.ForEach(node => { graph.AddNode(node); //NodeNames[node.Name] = node.NodeName; comboModel.AppendValues(node.Name); nodeDescriptions[node.Name] = node.Description; }); arcs.ForEach(arc => { rules[arc.Name] = arc.Conditions; actions[arc.Name] = arc.Actions; graph.AddArc(arc); }); graphView.DirectedGraph = graph; graphView.MainWidget.QueueDraw(); }
/// <summary>Calculate / create a directed graph from model</summary> public void CalculateDirectedGraph() { DirectedGraph oldGraph = directedGraphInfo; if (directedGraphInfo == null) { directedGraphInfo = new DirectedGraph(); } directedGraphInfo.Begin(); bool needAtmosphereNode = false; foreach (NutrientPool pool in this.FindAllChildren <NutrientPool>()) { Point location = default(Point); Node oldNode; if (oldGraph != null && pool.Name != null && (oldNode = oldGraph.Nodes.Find(f => f.Name == pool.Name)) != null) { location = oldNode.Location; } directedGraphInfo.AddNode(pool.Name, ColourUtilities.ChooseColour(3), Color.Black, location); foreach (CarbonFlow cFlow in pool.FindAllChildren <CarbonFlow>()) { foreach (string destinationName in cFlow.destinationNames) { string destName = destinationName; if (destName == null) { destName = "Atmosphere"; needAtmosphereNode = true; } location = default(Point); Arc oldArc; if (oldGraph != null && pool.Name != null && (oldArc = oldGraph.Arcs.Find(f => f.SourceName == pool.Name && f.DestinationName == destName)) != null) { location = oldArc.Location; } directedGraphInfo.AddArc(null, pool.Name, destName, Color.Black, location); } } } foreach (Solute solute in this.FindAllChildren <Solute>()) { directedGraphInfo.AddNode(solute.Name, ColourUtilities.ChooseColour(2), Color.Black); foreach (NFlow nitrogenFlow in solute.FindAllChildren <NFlow>()) { string destName = nitrogenFlow.destinationName; if (destName == null) { destName = "Atmosphere"; needAtmosphereNode = true; } directedGraphInfo.AddArc(null, nitrogenFlow.sourceName, destName, Color.Black); } } if (needAtmosphereNode) { directedGraphInfo.AddTransparentNode("Atmosphere"); } directedGraphInfo.End(); }
/// <summary> /// Callback for the 'duplicate node' context menu option. /// </summary> /// <remarks> /// Does this belong in the presenter? /// </remarks> /// <param name="sender">Sending object.</param> /// <param name="args">Event data.</param> private void OnDuplicateNode(object sender, EventArgs args) { try { if (graphView.SelectedObject is DGNode node) { List <StateNode> nodes = Nodes; List <RuleAction> arcs = Arcs; // Create a copy of the existing node. StateNode newNode = new StateNode(node.ToNode()); newNode.Location = new System.Drawing.Point(newNode.Location.X + node.Width / 2, newNode.Location.Y); newNode.Name = graphView.DirectedGraph.NextNodeID(); if (nodeDescriptions.ContainsKey(node.Name)) { newNode.Description = nodeDescriptions[node.Name]; } nodes.Add(newNode); // Copy all arcs moving to/from the existing node. DirectedGraph graph = graphView.DirectedGraph; foreach (var arc in graphView.DirectedGraph.Arcs.FindAll(arc => arc.SourceName == node.Name)) { RuleAction newArc = new RuleAction(arc); newArc.Name = graph.NextArcID(); newArc.SourceName = newNode.Name; if (rules.ContainsKey(arc.Name)) { newArc.Conditions = rules[arc.Name]; } if (actions.ContainsKey(arc.Name)) { newArc.Actions = actions[arc.Name]; } arcs.Add(newArc); // Add the arc to the local copy of the directed graph. // Need to do this to ensure that NextArcID() doesn't // generate the same name when we call it multiple times. graph.AddArc(newArc); } foreach (var arc in graphView.DirectedGraph.Arcs.FindAll(arc => arc.DestinationName == graphView.SelectedObject.Name)) { RuleAction newArc = new RuleAction(arc); newArc.Name = graph.NextArcID(); newArc.DestinationName = newNode.Name; if (rules.ContainsKey(arc.Name)) { newArc.Conditions = rules[arc.Name]; } if (actions.ContainsKey(arc.Name)) { newArc.Actions = actions[arc.Name]; } arcs.Add(newArc); // Add the arc to the local copy of the directed graph. // Need to do this to ensure that NextArcID() doesn't // generate the same name when we call it multiple times. graph.AddArc(newArc); } OnGraphChanged?.Invoke(this, new GraphChangedEventArgs(arcs, nodes)); } } catch (Exception err) { ShowError(err); } }