public static TagBox CreateTagBox(GTagBox g, TreeLayoutEnv env) { TagBox b = (env == null) ? new TagBox(g) : env.New(g); b.FontFamily = StaticCfg.Ins.GFontF; b.FontSize = g.FontSize; b.Height1 = g.InnerBox.Height; b.Width1 = g.InnerBox.Width; b.Margin = new Thickness(g.InnerBox.X - 10, g.InnerBox.Y, 0, 0); b.TextAlignment = TextAlignment.Center; b.GUTag = g.Tag; b.Background1 = g.Distance;//new SolidColorBrush(GetColor(g.Distance,g.Level)); //if (g.Distance >= 5) b.Foreground1 = g.Distance;// new SolidColorBrush(Colors.White); b.Foreground1 = g.Distance; return(b); }
public static GTagBoxTree ExpandNode(GUTag tag, int level, ITagDB db, double x, double y, int direct, Size size, TreeLayoutEnv env, LayoutMode mode) { Logger.IN(tag.Title); Logger.D("Expand " + tag + " " + x + " " + y); //已经展开过,直接返回 //if (env.Get(tag) != null) //{ // Logger.D("FOUND " + tag); // Logger.OUT(); // return env.Get(tag); //} //创建子树的根对象 GTagBoxTree root = new GTagBoxTree(); root.GTagBox = new GTagBox(level, tag, x, y, direct); root.totalRange = root.GTagBox.OutterBox; root.D("计算自身大小(不包括子节点)" + root.GTagBox.Tag); env.Add(tag, root);//这个特别需要注意,在递归展开之前,先要将该节点加入DB,否则可能会出现无限递归 List <GUTag> children = db.QueryTagChildren(tag); List <Size> childrenSize = new List <Size>(); GTagBoxTree pre = null; GTagBoxTree cur = null; double childX = x + direct * root.GTagBox.OutterBox.Width; double childY = y; int MaxLevel = CalcMaxLevel(mode); //double h = 0; //double w = 0; if (level < MaxLevel) { //遍历展开所有子节点 foreach (GUTag ctag in children) { //if (env.Get(ctag) != null) continue; cur = null; //GTreeObj child = ExpandNode(ctag, level + 1, db, x + root.box.InnerBox.Width, y + h); //h += child.OutBox.Height; //w = Math.Max(w, child.OutBox.Width); switch (mode) { case LayoutMode.TREE_COMPACT_MORE: case LayoutMode.LRTREE_COMPACT_MORE: cur = ExpandChildMoreCompact(level, MaxLevel, db, root, pre, ctag, direct, size, env, mode); break; case LayoutMode.TREE_COMPACT: case LayoutMode.LRTREE_COMPACT: cur = ExpandChildCompact(level, MaxLevel, db, root, pre, ctag, direct, size, env, mode); break; case LayoutMode.TREE_NO_COMPACT: case LayoutMode.LRTREE_NO_COMPACT: cur = ExpandChildNoCompact(level, MaxLevel, db, root, pre, ctag, direct, size, env, mode); break; default: break; } //h += cur.OutBox.Height; //w = Math.Max(w, cur.OutBox.Width); root.totalRange.Union(cur.totalRange); root.Children.Add(cur); pre = cur; } } //根据所有子节点所占区域的大小,计算自己的位置 //root.OutBox.Width = w + root.box.InnerBox.Width; //root.OutBox.Height = Math.Max(h, root.box.InnerBox.Height); //root.GTagBox.InnerBox.Y = (root.TotalRange.Top + root.TotalRange.Bottom) / 2; root.GTagBox.CenterRootY(root.totalRange); root.D(null); Logger.OUT(); return(root); }
private static GTagBoxTree ExpandChildNoCompact(int level, int MaxLevel, ITagDB db, GTagBoxTree root, GTagBoxTree pre, GUTag ctag, int direct, Size size, TreeLayoutEnv env, LayoutMode mode) { GTagBoxTree cur; Logger.D("ChoosePos:pre:{0}-{1}-{2} cur:{0}-{1},", pre?.GTagBox.Tag, pre == null ? 0 : db.QueryTagChildren(pre.GTagBox.Tag).Count, pre == null ? 0 : pre.totalRange.Right, ctag, db.QueryTagChildren(ctag).Count); if (pre == null) { Logger.D("Place {0} after {1}:follow", ctag, root.GTagBox.Tag); cur = ExpandNode(ctag, level + 1, db, direct == 1 ? root.GTagBox.OutterBox.Right : root.GTagBox.OutterBox.Left, root.totalRange.Top, direct, size, env, mode); } else { Logger.D("Place {0} after {1}:newline", ctag, root.GTagBox.Tag); cur = ExpandNode(ctag, level + 1, db, direct == 1 ? root.GTagBox.OutterBox.Right : root.GTagBox.OutterBox.Left, root.totalRange.Bottom, direct, size, env, mode); } env.AddLine(root, cur, direct); return(cur); }
private static GTagBoxTree ExpandChildCompact(int rootLevel, int MaxLevel, ITagDB db, GTagBoxTree root, GTagBoxTree pre, GUTag ctag, int direct, Size size, TreeLayoutEnv env, LayoutMode mode) { double estimateWidth = 0; GTagBoxTree cur; Logger.D("ChoosePos:pre:{0}-{1}-{2} cur:{0}-{1},", pre?.GTagBox.Tag, pre == null ? 0 : db.QueryTagChildren(pre.GTagBox.Tag).Count, pre == null ? 0 : pre.totalRange.Right, ctag, db.QueryTagChildren(ctag).Count); bool leftOK = true, rightOK = true; //TagBoxSizeInf sizeinf = new TagBoxSizeInf(ctag, rootLevel + 1, StaticCfg.Ins.GFontName); int OneLineChild = GetTagTreeWidth(ctag, db, rootLevel + 1, MaxLevel, out estimateWidth); //右边是否有足够空间(初步预估,用OneLineChild*本节点的宽度预估) if (pre != null) { if (direct == 1) { rightOK = pre.totalRange.Right + estimateWidth < size.Width; } //左边是否有足够空间 if (direct == -1) { leftOK = estimateWidth < pre.totalRange.Left; } } else //pre == null,前面没有兄弟节点,前面一个节点时父节点 { if (direct == 1) { rightOK = root.GTagBox.OutterBox.Right + estimateWidth < size.Width; } if (direct == -1) { leftOK = estimateWidth < root.GTagBox.OutterBox.Left; } } //只有满足严格条件的情况下,才放在兄弟节点的后面,否则在父节点后展开 if (pre != null && OneLineChild >= 0 && (db.QueryTagChildren(pre.GTagBox.Tag).Count == 0 || rootLevel + 1 == MaxLevel) && rightOK && leftOK) { Logger.D("Place {0} after {1}:follow", ctag, pre.GTagBox.Tag); cur = ExpandNode(ctag, rootLevel + 1, db, direct == 1 ? pre.totalRange.Right : pre.totalRange.Left, //X pre.totalRange.Top, //Y direct, size, env, mode); } //第一个节点,没有兄弟节点,放在父节点后面 ==== > 放在父节点的同一行 //非叶子节点,也直接放在父节点后面 or ==== > 放在父节点的下一行 //前一个兄弟已经把这一行占完了 ==== > 放在父节点的下一行 else { if (pre == null) { Logger.D("Place {0} after {1}:follow", ctag, root.GTagBox.Tag); cur = ExpandNode(ctag, rootLevel + 1, db, direct == 1 ? root.GTagBox.OutterBox.Right : root.GTagBox.OutterBox.Left, root.totalRange.Top, direct, size, env, mode); //放在父节点后面,与父节点同行 } else { Logger.D("Place {0} after {1}:newline", ctag, root.GTagBox.Tag); cur = ExpandNode(ctag, rootLevel + 1, db, direct == 1 ? root.GTagBox.OutterBox.Right : root.GTagBox.OutterBox.Left, root.totalRange.Bottom, direct, size, env, mode); //放在父节点后面,是父节点下一行(严格来说,是前一个兄弟节点的下一行) } env.AddLine(root, cur, direct); } return(cur); }
//public static Line CreateLine(GBoxObj parent, GBoxObj child) //{ // Line l = new Line(); // l.X1 = parent.ColorBox.X + parent.ColorBox.Width / 2; // l.Y1 = parent.ColorBox.Y + parent.ColorBox.Height; // l.X2 = child.ColorBox.X + child.ColorBox.Width / 2; // l.Y2 = child.ColorBox.Y; // l.Tag = parent.Tag.ToString() + StaticCfg.Ins.ParentChildSplit + child.Tag.ToString(); // if (Math.Min(parent.GTagBox.Level, child.GTagBox.Level) == 0) // { // l.Stroke = new SolidColorBrush(GetColor(parent.GTagBox.Distance + 1, parent.GTagBox.Level + 1)); // l.StrokeThickness = StaticCfg.Ins.StrokeThickness * 1.5; // l.StrokeDashArray = StaticCfg.Ins.StrokeDashArray; // } // else // { // l.Stroke = new SolidColorBrush(GetColor(parent.GTagBox.Distance + 1, parent.GTagBox.Level + 1)); // l.StrokeThickness = StaticCfg.Ins.StrokeThickness; // l.StrokeDashArray = StaticCfg.Ins.StrokeDashArray; // } // return l; //} public static Path CreateBezier(Tuple <GTagBoxTree, GTagBoxTree, int> p_c, TreeLayoutEnv env) { GTagBoxTree p = p_c.Item1; GTagBoxTree c = p_c.Item2; int direct = (int)p_c.Item3; System.Windows.Point p1 = new System.Windows.Point(); System.Windows.Point p5 = new System.Windows.Point(); System.Windows.Point p2 = new System.Windows.Point(); System.Windows.Point p4 = new System.Windows.Point(); System.Windows.Point p3 = new System.Windows.Point(); if (direct == 1) { p1.X = p.GTagBox.InnerBox.Right; p5.X = c.GTagBox.InnerBox.Left; } else { p1.X = p.GTagBox.InnerBox.Left; p5.X = c.GTagBox.InnerBox.Right; } p1.Y = (p.GTagBox.InnerBox.Top + p.GTagBox.InnerBox.Bottom) / 2; p5.Y = (c.GTagBox.InnerBox.Top + c.GTagBox.InnerBox.Bottom) / 2; p3.X = (p1.X + p5.X) / 2; p3.Y = (p1.Y + p5.Y) / 2; const int N = 3; p2.X = (p1.X * N + p5.X) / (N + 1); p4.X = (p1.X + p5.X * N) / (N + 1); p2.Y = p1.Y; p4.Y = p5.Y; Path path = env.New(p_c); if (path.Data == null) { PathGeometry pg = new PathGeometry(); PathFigureCollection pfc = new PathFigureCollection(); PathFigure pf = new PathFigure(); BezierSegment seg1 = new BezierSegment(p1, p2, p3, true); seg1.IsSmoothJoin = true; BezierSegment seg2 = new BezierSegment(p3, p4, p5, true); seg2.IsSmoothJoin = true; //Path->PathGeometry->PathFigureCollection->PathFigure->PathSegmentCollection->BezierSegment path.Data = pg; //PathGeometry pg.Figures = pfc; //PathFigureCollection pfc.Add(pf); //PF pf.StartPoint = p1; pf.Segments.Add(seg1); pf.Segments.Add(seg2); pg.Figures.Add(pf); } else { PathGeometry pg = path.Data as PathGeometry; PathFigureCollection pfc = pg.Figures as PathFigureCollection; PathFigure pf = pfc[0] as PathFigure; pf.StartPoint = p1; BezierSegment seg1 = pf.Segments[0] as BezierSegment; BezierSegment seg2 = pf.Segments[1] as BezierSegment; seg1.Point1 = p1; seg1.Point2 = p2; seg1.Point3 = p3; seg2.Point1 = p3; seg2.Point2 = p4; seg2.Point3 = p5; //pg.Figures.Add(pf); } SetBezierStyle(p.GTagBox, c.GTagBox, path); return(path); }