static int ChooseSeeds(IList <RectangleNode <T, P> > nodes, ref IRectangle <P> b0, ref int seed0) { double area = b0.Add(nodes[seed0].Rectangle).Area; for (int i = 2; i < nodes.Count; i++) { double area0 = b0.Add(nodes[i].Rectangle).Area; if (area0 > area) { seed0 = i; area = area0; } } //Got the first seed seed0 //Now looking for a seed for the second group int seed1 = 0; //the compiler forces me to init it //init seed1 for (int i = 0; i < nodes.Count; i++) { if (i != seed0) { seed1 = i; break; } } area = nodes[seed0].Rectangle.Add(nodes[seed1].Rectangle).Area; //Now try to improve the second seed for (int i = 0; i < nodes.Count; i++) { if (i == seed0) { continue; } double area1 = nodes[seed0].Rectangle.Add(nodes[i].Rectangle).Area; if (area1 > area) { seed1 = i; area = area1; } } return(seed1); }
static void DivideNodes(IList <RectangleNode <T, P> > nodes, int seed0, int seed1, List <RectangleNode <T, P> > gr0, List <RectangleNode <T, P> > gr1, ref IRectangle <P> box0, ref IRectangle <P> box1, int groupSplitThreshold) { for (int i = 0; i < nodes.Count; i++) { if (i == seed0 || i == seed1) { continue; } // ReSharper disable InconsistentNaming var box0_ = box0.Add(nodes[i].Rectangle); double delta0 = box0_.Area - box0.Area; var box1_ = box1.Add(nodes[i].Rectangle); double delta1 = box1_.Area - box1.Area; // ReSharper restore InconsistentNaming //keep the tree roughly balanced if (gr0.Count * groupSplitThreshold < gr1.Count) { gr0.Add(nodes[i]); box0 = box0_; } else if (gr1.Count * groupSplitThreshold < gr0.Count) { gr1.Add(nodes[i]); box1 = box1_; } else if (delta0 < delta1) { gr0.Add(nodes[i]); box0 = box0_; } else if (delta1 < delta0) { gr1.Add(nodes[i]); box1 = box1_; } else if (box0.Area < box1.Area) { gr0.Add(nodes[i]); box0 = box0_; } else { gr1.Add(nodes[i]); box1 = box1_; } } }
private void UpdateIcon() { //special treatment for root if (FBackground.Parent is IDot && !FViewer.ShowRoot) { return; } FIcon.Clear(); FIcon.Brush = null; FIcon.Position = new PointF(3, 3); FIcon.Visible = false; if (FDecoratable != null) { if (FDecoratable.Icon > NodeIcon.None) { FIcon.Visible = true; if (FDecoratable.Icon == NodeIcon.GUI || FDecoratable.Icon == NodeIcon.GUICode || FDecoratable.Icon == NodeIcon.GUIPatch) { FIcon.Pen = FTextColor; FIcon.Size = new SizeF(16, 12); } if (FDecoratable.Icon == NodeIcon.Patch || FDecoratable.Icon == NodeIcon.GUIPatch) { var n = FCanvas.CreateRectangle(null); n.Pen = FTextColor; n.Size = new SizeF(8, 2); n.Position = new PointF(3, 2); FIcon.Add(n); n = FCanvas.CreateRectangle(null); n.Pen = FTextColor; n.Size = new SizeF(8, 2); n.Position = new PointF(6, 5); FIcon.Add(n); n = FCanvas.CreateRectangle(null); n.Pen = FTextColor; n.Size = new SizeF(8, 2); n.Position = new PointF(3, 8); FIcon.Add(n); } if (FDecoratable.Icon == NodeIcon.Code || FDecoratable.Icon == NodeIcon.GUICode) { IPolygon line; var y = 3; for (int i = 0; i < 4; i++) { line = FCanvas.CreatePoly(null); line.IsClosed = false; line.Pen = FTextColor; line.Brush = null; line.Points.Add(new PointF(3, y)); if (i == 0) { line.Points.Add(new PointF(7, y)); } else { line.Points.Add(new PointF(13, y)); } FIcon.Add(line); y += 2; } } if (FDecoratable.Icon == NodeIcon.Comment) { IPolygon line; line = FCanvas.CreatePoly(null); line.IsClosed = false; line.Pen = FTextColor; line.Brush = null; line.Points.Add(new PointF(5, 12)); line.Points.Add(new PointF(7, 0)); FIcon.Add(line); line = FCanvas.CreatePoly(null); line.IsClosed = false; line.Pen = FTextColor; line.Brush = null; line.Points.Add(new PointF(7, 12)); line.Points.Add(new PointF(9, 0)); FIcon.Add(line); } if (FDecoratable.Icon == NodeIcon.IONode) { IPolygon line; line = FCanvas.CreatePoly(null); line.IsClosed = false; line.Pen = FTextColor; line.Brush = null; line.Points.Add(new PointF(2, 2)); line.Points.Add(new PointF(2, 10)); FIcon.Add(line); ICircle circle; circle = FCanvas.CreateCircle(null); circle.PositionMode = PositionMode.Center; circle.Pen = FTextColor; circle.Brush = null; circle.Position = new PointF(8, 6); circle.Radius = 4; FIcon.Add(circle); } } } }
public MapperHierarchyNode(ModelMapper mapper, ICanvas canvas, IGraphElement parent, HierarchyViewer viewer) : base() { Mapper = mapper; FCanvas = canvas; FViewer = viewer; MouseClick += FViewer.MouseClickHandler; MouseDoubleClick += FViewer.MouseDoubleClickHandler; Tag = mapper.Model; //graphelements FBackground = canvas.CreateRectangle(this); FPoly = canvas.CreatePoly(this); FText = canvas.CreateText(null, ""); FIcon = FCanvas.CreateRectangle(null); parent.Add(FBackground); FBackground.Add(FPoly); FBackground.Add(FText); FBackground.Add(FIcon); //compute level of depth IGraphElement p = FBackground; while (p.Parent != null) { FDepth++; p = p.Parent; } FDepth -= 1; //init static properties via Mapper if (Mapper.CanMap <ISelectable>()) { FSelectable = Mapper.Map <ISelectable>(); FSelectable.SelectionChanged += selectable_SelectionChanged; Selected = FSelectable.Selected; } if (Mapper.CanMap <IDecoratable>()) { FDecoratable = Mapper.Map <IDecoratable>(); FDecoratable.DecorationChanged += decorated_DecorationChanged; } if (Mapper.CanMap <ILinkSource>()) { FLinkSource = Mapper.Map <ILinkSource>(); FLinkSourceRectangle = FCanvas.CreateRectangle(null); FBackground.Add(FLinkSourceRectangle); FLinkOffset = FTextOffset; } if (Mapper.CanMap <ILinkSink>()) { FLinkSink = Mapper.Map <ILinkSink>(); FLinkSinkRectangle = FCanvas.CreateRectangle(null); FBackground.Add(FLinkSinkRectangle); } if (Mapper.CanMap <INamed>()) { FNamed = Mapper.Map <INamed>(); FNamed.Renamed += named_Renamed; SetCaption(FNamed.Name); } if (Mapper.CanMap <IParent>()) { var node = Mapper.Map <IParent>(); if (node.Childs != null) { // Keep Nodes and items in sync FSynchronizer = FSubTree.SyncWith(node.Childs, CreateChildNode); FSynchronizer.Synced += synchronizer_Synced; } } //init dynamic properties via Mapper UpdateColors(); UpdateIcon(); UpdateLinkSink(); UpdateLinkSource(); }