public void Draw(GenealogyAllViz cgv, Node srcNode, Node destNode, XmlElement evoXml) { Point p1 = new Point(srcNode.center.X + (int)(0.5 * Node.width) + 1, srcNode.center.Y); Point p2 = new Point(destNode.center.X - (int)(0.5 * Node.width) - 1, destNode.center.Y); string pattern = ((XmlElement)evoXml.SelectSingleNode("CGMapInfo")).GetAttribute("pattern"); if (pattern.Contains("STATIC")) { cgv.Gra.DrawLine(GenealogyAllViz.pen2, p1, p2); } else { cgv.Gra.DrawLine(GenealogyAllViz.pen3, p1, p2); } }
public void adjustxy(GenealogyAllViz v) { List <Node> cglist = new List <Node>(); for (int i = 0; i < v.nodeList.Count; i++) { cglist.Add(v.NodeList[i]); } StreamWriter sw = new StreamWriter(@"E:\\4", false); for (int i = 0; i < cglist.Count; i++) { sw.Write(cglist[i].center.X); sw.Write(","); sw.Write(cglist[i].center.Y); sw.Write("\n"); } sw.Close(); }
public void DrawGenealogy() { //首先显示克隆家系整体简单视图 GenealogyAllViz gav = new GenealogyAllViz(); gav.Gra = this.g; Node.SetBase(); gav.nodeList = new List <Node>(); gav.Init(); gav.SetGenealogyXml(GenealogyXml); Node.NodeCenterDis = 60; int y = gav.DrawGenGraphics(80, 25, GenealogyXml.Name);//80为首节点横坐标,25为首节点纵坐标,获取已绘图纵坐标 //描绘该克隆家系详细视图 int genealogyNo = Int32.Parse(((XmlElement)(GenealogyXml.DocumentElement.SelectSingleNode("GenealogyInfo"))).GetAttribute("id")); List <XmlElement> evoList = new List <XmlElement>(); //存放所有元素的列表 foreach (XmlElement evoNode in GenealogyXml.DocumentElement.SelectNodes("Evolution")) { evoList.Add(evoNode); } List <XmlElement> leftEvoList = new List <XmlElement>(evoList); //存放未处理元素的列表 int roundNum = 0; //记录处理到第一轮 //定义用到的对象 XmlElement curNode; XmlElement srcInfoEle; //Evolution的子元素srcInfo XmlElement destInfoEle; XmlElement evoInfoEle; //Evolution的子元素CGMapInfo CGNode srcCGNode = new CGNode(); //src元素在家系图中对应的节点 CGNode preNode = new CGNode(); //定义前驱节点 CGNode baseNode = new CGNode(); //CGNode destCGNode = new CGNode(); EvolutionLine evoLine = new EvolutionLine(); //CGMap对应的连接线 //初始化nodeList this.nodeList = new List <CGNode>(); //用于保存所有克隆群中的克隆代码的标签集(每个克隆代码用A,B,C,等表示) List <string> tagList = new List <string>(); string preTags = ""; string baseTags = ""; string curTags; int tagSetIndex = 0; int rowHeightMax = 0; //保存每一行CGNode高度的最大值,用于确定下一行的rowY int rowheight = 0; int flag = 0; List <int> visit = new List <int>();//深度优先遍历,采用栈,标记访问 Stack <CGNode> s = new Stack <CGNode>(); Stack <string> stag = new Stack <string>(); for (int i = 0; i <= evoList.Count; i++) { visit.Add(0); } //处理每个Evolution元素,绘制CGNode while (leftEvoList.Count != 0) { roundNum++; curNode = leftEvoList[0]; srcInfoEle = (XmlElement)curNode.SelectSingleNode("srcInfo"); if (roundNum == 1)//基节点 { CGNode.rowY = y + 20; int cgsize = Int32.Parse(srcInfoEle.GetAttribute("size")); curTags = ""; while (tagSetIndex < cgsize) { curTags += tagSet[tagSetIndex].ToString(); //构造第一个CGNode的标签集 tagSetIndex++; } //只有第一个Evo需要画src srcCGNode.Set(curNode, srcInfoEle, null, 1, curTags); srcCGNode.Draw1(this, curTags); srcCGNode.patternflag = false; this.nodeList.Add(srcCGNode); baseNode = new CGNode(srcCGNode); //初始化前驱节点,不能直接用"="赋值!! tagList.Add(curTags); baseTags = curTags; } else { if (roundNum == 2) { CGNode.rowY = y + 20; } //判断节点是否为克隆直系的首节点 if (curNode.GetAttribute("parentID") == "null") { #region 根据克隆群映射确定curTags //获取当前Evolution元素对应的克隆群映射 string srcVersion = ((XmlElement)curNode.SelectSingleNode("srcInfo")).GetAttribute("filename"); string destVersion = ((XmlElement)curNode.SelectSingleNode("destInfo")).GetAttribute("filename"); Global.mainForm.GetMAPDirFromTreeView1(); string mapFileName = AdjacentVersionMapping.MapFileDir + @"\blocks\" + srcVersion + "_" + destVersion + "-MapOnBlocks.xml"; XmlDocument mapXml = new XmlDocument(); mapXml.Load(mapFileName); //加载MAP文件 int cgMapID = Int32.Parse(((XmlElement)curNode.SelectSingleNode("CGMapInfo")).GetAttribute("id")); XmlElement mapEle = (XmlElement)mapXml.DocumentElement.ChildNodes[cgMapID + 1]; //此赋值没有实际意义(不初始化会出错) foreach (XmlElement ele in mapXml.DocumentElement.SelectNodes("CGMap")) { if (ele.GetAttribute("cgMapid") == cgMapID.ToString()) { mapEle = ele; break; } } int destcgsize = Int32.Parse(mapEle.GetAttribute("destCGsize")); char[] tempTags = new char[destcgsize]; //为destCG的标签分配空间 bool[] tagFlag = new bool[destcgsize]; //标记destCG中每个CF的标签是否由源继承而来 foreach (XmlElement cfMap in mapEle.SelectNodes("CFMap")) { int srccfid = Int32.Parse(cfMap.GetAttribute("srcCFid")); int destcfid = Int32.Parse(cfMap.GetAttribute("destCFid")); tempTags[destcfid - 1] = baseTags[srccfid - 1]; tagFlag[destcfid - 1] = true; } for (int i = 0; i < destcgsize; i++) { if (!tagFlag[i]) { if (tagSetIndex == 52) { tagSetIndex = 0; } tempTags[i] = tagSet[tagSetIndex++]; //按字母顺序使用下一个字母 } } //tempTags每个tag确定后,保存到curTags中 curTags = ""; for (int i = 0; i < destcgsize; i++) { curTags += tempTags[i].ToString(); } #endregion destInfoEle = (XmlElement)curNode.SelectSingleNode("destInfo"); CGNode destCGNode = new CGNode(); destCGNode.Set(curNode, destInfoEle, baseNode, roundNum, curTags); string pattern = ((XmlElement)curNode.SelectSingleNode("CGMapInfo")).GetAttribute("pattern"); if (pattern.Contains("INCONSISTENTCHANGE")) { destCGNode.Draw2(this, curTags); destCGNode.patternflag = true; } else { destCGNode.Draw1(this, curTags); destCGNode.patternflag = false; } this.nodeList.Add(destCGNode); tagList.Add(curTags); //画进化连接线 evoInfoEle = (XmlElement)curNode.SelectSingleNode("CGMapInfo"); evoLine.Set(baseNode, destCGNode, mapEle); evoLine.Draw(this, mapEle); preNode = new CGNode(destCGNode); //更新前驱节点(上一元素的dest) leftEvoList.Remove(curNode); //处理完毕,从未处理列表中删除 preTags = curTags; s.Push(preNode); stag.Push(preTags); visit[Int32.Parse(curNode.GetAttribute("id"))] = 1; #region 深度优先遍历绘图 while (s.Count != 0) { curNode = evoList[s.Peek().ID() - 1];//取栈顶元素节点 preNode = new CGNode(s.Peek()); preTags = stag.Peek(); do { flag = 0; rowheight = 0; List <int> leftChild = new List <int>(); if (curNode.GetAttribute("childID") != "null") { string childID = curNode.GetAttribute("childID"); while (childID.Contains("+")) { int indexofadd = childID.IndexOf("+"); int cid = Int32.Parse(childID.Substring(0, indexofadd)); leftChild.Add(cid); childID = childID.Substring(indexofadd + 1); } leftChild.Add(Int32.Parse(childID)); //判断孩子节点是否都被访问过,存在没访问过的节点则flag=1,否则flag为0 while (leftChild.Count != 0) { if (visit[leftChild[0]] != 1) { curNode = evoList[leftChild[0] - 1]; flag = 1; break; } rowheight = 1; leftChild.Remove(leftChild[0]); } if (flag == 1)//描绘未被访问的节点 { #region 根据克隆群映射确定destCG标签 //获取当前Evolution元素对应的克隆群映射 string SrcVersion = ((XmlElement)curNode.SelectSingleNode("srcInfo")).GetAttribute("filename"); string DestVersion = ((XmlElement)curNode.SelectSingleNode("destInfo")).GetAttribute("filename"); Global.mainForm.GetMAPDirFromTreeView1(); string MapFileName = AdjacentVersionMapping.MapFileDir + @"\blocks\" + SrcVersion + "_" + DestVersion + "-MapOnBlocks.xml"; XmlDocument MapXml = new XmlDocument(); MapXml.Load(MapFileName); //加载MAP文件 int CgMapID = Int32.Parse(((XmlElement)curNode.SelectSingleNode("CGMapInfo")).GetAttribute("id")); XmlElement MapEle = (XmlElement)MapXml.DocumentElement.ChildNodes[CgMapID + 1]; //此赋值没有实际意义(不初始化会出错) foreach (XmlElement ele in MapXml.DocumentElement.SelectNodes("CGMap")) { if (ele.GetAttribute("cgMapid") == CgMapID.ToString()) { MapEle = ele; break; } } int Destcgsize = Int32.Parse(MapEle.GetAttribute("destCGsize")); char[] TempTags = new char[Destcgsize]; //为destCG的标签分配空间 bool[] TagFlag = new bool[Destcgsize]; //标记destCG中每个CF的标签是否由源继承而来 foreach (XmlElement cfMap in MapEle.SelectNodes("CFMap")) { int srccfid = Int32.Parse(cfMap.GetAttribute("srcCFid")); int destcfid = Int32.Parse(cfMap.GetAttribute("destCFid")); TempTags[destcfid - 1] = preTags[srccfid - 1]; TagFlag[destcfid - 1] = true; } for (int i = 0; i < Destcgsize; i++) { if (!TagFlag[i]) { if (tagSetIndex == 52) { tagSetIndex = 0; } TempTags[i] = tagSet[tagSetIndex++]; //按字母顺序使用下一个字母 } } //tempTags每个tag确定后,保存到curTags中 curTags = ""; for (int i = 0; i < Destcgsize; i++) { curTags += TempTags[i].ToString(); } #endregion destInfoEle = (XmlElement)curNode.SelectSingleNode("destInfo"); CGNode newdestCGNode = new CGNode(); // CGNode.rowY = CGNode.rowY + rowheight * CGNode.rowDis; newdestCGNode.Set(curNode, destInfoEle, preNode, roundNum, curTags); pattern = ((XmlElement)curNode.SelectSingleNode("CGMapInfo")).GetAttribute("pattern"); if (pattern.Contains("INCONSISTENTCHANGE")) { newdestCGNode.Draw2(this, curTags); newdestCGNode.patternflag = true; } else { newdestCGNode.Draw1(this, curTags); newdestCGNode.patternflag = false; } this.nodeList.Add(newdestCGNode); tagList.Add(curTags); //画连接线 evoInfoEle = (XmlElement)curNode.SelectSingleNode("CGMapInfo"); evoLine.Set(preNode, newdestCGNode, MapEle); evoLine.Draw(this, MapEle); preTags = curTags; preNode = new CGNode(newdestCGNode); //更新前驱节点(上一元素的dest) leftEvoList.Remove(curNode); if (rowHeightMax < newdestCGNode.height) { rowHeightMax = newdestCGNode.height; } //this.nodeList.Add(preNode); visit[Int32.Parse(curNode.GetAttribute("id"))] = 1; s.Push(preNode); stag.Push(preTags); } } else { CGNode.rowY = CGNode.rowY + CGNode.rowDis + rowHeightMax;//遍历一层过后更新当前绘图深度 rowHeightMax = 0; } if (flag == 0) { s.Pop(); stag.Pop(); rowheight = 0; rowHeightMax = 0; } } while (flag == 1); } #endregion } } } }
public void Draw2(GenealogyAllViz cgv)//不一致变化时 { cgv.Gra.DrawRectangle(GenealogyAllViz.pen5, this.rect); cgv.Gra.FillRectangle(GenealogyAllViz.brush1, this.rect); }