/// <summary> /// 根据搜索好的路线绘制分支线 /// </summary> /// <param name="listBranch"></param> /// <param name="mp"></param> /// <param name="md"></param> private MDocument WriteBranchWithMD(List <string> listBranch) { //当前行 int lineIndex = 0; //先绘制出一条线 List <string> branchList = listBranch[0].Split(',').ToList(); var molList = branchList[0].Split(';').ToList(); MoleCulePostion mp = new MoleCulePostion(molList[0]); MDocument md = new MDocument(mp.Mol); //写mol层次号 string txt = molList[1]; _ListTextPosition.Add(txt + "," + mp.Center_x + "," + (mp.Bottom_y - TxtspaceWithMolInY)); WriteSimpleBranch(mp, branchList, 1, mp.Mol, md, true); lineIndex += branchList.Count / BranchOneLineNum + (branchList.Count % BranchOneLineNum > 0 ? 1 : 0); //再绘制出其他的线 for (int i = 1; i < listBranch.Count; i++) { List <string> branchList1 = listBranch[i].Split(',').ToList(); var molList1 = branchList1[0].Split(';').ToList(); MoleCulePostion mp1 = new MoleCulePostion(molList1[0]); SetMolPosition(mp1, 0, mp.Center_y - SpanceY * BranchSPFWithY * lineIndex); //写mol层次号 txt = molList1[1]; _ListTextPosition.Add(txt + "," + mp1.Center_x + "," + (mp1.Bottom_y - TxtspaceWithMolInY)); lineIndex += branchList1.Count / BranchOneLineNum + (branchList1.Count % BranchOneLineNum > 0 ? 1 : 0); //划分支 WriteSimpleBranch(mp1, branchList1, 1, mp.Mol, md, false); //合并分支显示 mp.Mol.fuse(mp1.Mol); } //返回绘图 return(md); }
/// <summary> /// 设置每个原子距离原点的X距离,Y距离 /// </summary> /// <param name="mol2"></param> /// <param name="spaceX"></param> /// <param name="spaceY"></param> private void SetMolPosition(MoleCulePostion mp, double spaceX, double spaceY) { foreach (var item in mp.Mol.getAtomArray()) { double x = item.getX(); double y = item.getY(); item.setX(x + spaceX); item.setY(y + spaceY); } //调用位置类计算位置函数重新赋值 mp.AddSpace(spaceX, spaceY); }
/// <summary> /// 绘图 /// </summary> /// <param name="rootTree"></param> /// <returns></returns> private MDocument WriteTree(TreeNodes rootTree) { MoleCulePostion mp = new MoleCulePostion(rootTree.Smiles); MDocument md = new MDocument(mp.Mol); //初始化树的叶子节点数量 InitTreeLeapNum(rootTree); //开始遍历子节点 _DicListTextPosition = new Dictionary <int, List <string> >(); _DicListTextPosition.Add(0, new List <string>()); //上 _DicListTextPosition.Add(1, new List <string>()); //中 _DicListTextPosition.Add(2, new List <string>()); //下 SearchChildNode(rootTree, md, mp, mp.Mol, 1); return(md); }
/// <summary> /// 不包括根点的树单分支递归绘制 /// </summary> /// <param name="previousMp">前一个mol类</param> /// <param name="branchList">分支smiles记录</param> /// <param name="index">当前次序</param> /// <param name="rootMol">根mol</param> /// <param name="md">文档对象</param> /// <param name="isRoot">是否是最长分支路线</param> private void WriteSimpleBranch(MoleCulePostion previousMp, List <string> branchList, int index, Molecule rootMol, MDocument md, bool isRoot) { double molLeftSpace = 0; if (branchList.Count <= index) { //WriteText(md); return; } double curY = previousMp.Center_y; double curX = previousMp.Right_x; if (index % BranchOneLineNum == 0) { curY -= SpanceY * BranchSPFWithY; curX = 0 - SpanceX * BranchSPFWithX; //WriteText(md); } //写反应的其他物质,仅限最长路线 int anotherMolNum = 0; double maxLength = 0; if (!string.IsNullOrEmpty(DicBranchSmiles[index]) && isRoot) { List <string> listSmiles = DicBranchSmiles[index].Split(',').ToList(); anotherMolNum = listSmiles.Count; if (listSmiles.Count == 1) { var molList = listSmiles[0].Split(';').ToList(); MoleCulePostion mp1 = new MoleCulePostion(molList[0]); double leftDistance = mp1.Center_x - mp1.Left_x; double bottomDistance = mp1.Center_y - mp1.Bottom_y; maxLength = mp1.Right_x - mp1.Left_x + BranchAnotherMolDistanceX * 2; SetMolPosition(mp1, previousMp.Right_x + leftDistance + BranchAnotherMolDistanceX, previousMp.Center_y + bottomDistance + BranchAnotherMolDistanceY + 1.5); //写箭头上mol层次号 md.addObject(CreateMTextBox(molList[1], new MPoint(previousMp.Right_x + leftDistance + BranchAnotherMolDistanceX, previousMp.Center_y + 1.5))); rootMol.fuse(mp1.Mol); } else if (listSmiles.Count == 2) { foreach (var smiles in listSmiles) { var molList = smiles.Split(';').ToList(); MoleCulePostion mp1 = new MoleCulePostion(molList[0]); double leftDistance = mp1.Center_x - mp1.Left_x; double bottomDistance = mp1.Center_y - mp1.Bottom_y; SetMolPosition(mp1, maxLength + previousMp.Right_x + leftDistance + BranchAnotherMolDistanceX, previousMp.Center_y + bottomDistance + BranchAnotherMolDistanceY + 1.5); //写箭头上mol层次号 md.addObject(CreateMTextBox(molList[1], new MPoint(maxLength + previousMp.Right_x + leftDistance + BranchAnotherMolDistanceX, previousMp.Center_y + 1.5))); rootMol.fuse(mp1.Mol); maxLength += mp1.Right_x - mp1.Left_x + BranchAnotherMolDistanceX * 2; } } } //箭头绘制; MPoint p1 = new MPoint(previousMp.Right_x + SpanceX * BranchSPFWithX * 0.15, previousMp.Center_y); MPoint p2 = new MPoint(previousMp.Right_x + SpanceX * BranchSPFWithX * 0.85, previousMp.Center_y); if (anotherMolNum == 2) { p1 = new MPoint(previousMp.Right_x + maxLength * 0.15, previousMp.Center_y); p2 = new MPoint(previousMp.Right_x + maxLength * 0.85, previousMp.Center_y); } if (anotherMolNum == 1) { p1 = new MPoint(previousMp.Right_x + maxLength * 0.15, previousMp.Center_y); p2 = new MPoint(previousMp.Right_x + maxLength * 0.85, previousMp.Center_y); } MPolyline arrow = new MPolyline(p1, p2); arrow.setArrow(true); arrow.setArrowLength(1, chemaxon.struc.graphics.MPolyline.DEFAULT_ARROW_HEAD_LENGTH / 2); arrow.setArrowWidth(1, chemaxon.struc.graphics.MPolyline.DEFAULT_ARROW_HEAD_WIDTH); arrow.setArrowFlags(1, chemaxon.struc.graphics.MPolyline.ARROW_DASHED_FLAG); md.addObject(arrow); //分子绘制 var molList1 = branchList[index].Split(';').ToList(); MoleCulePostion tempMp = new MoleCulePostion(molList1[0]); molLeftSpace = tempMp.Center_x - tempMp.Left_x; if (curX == -SpanceX * BranchSPFWithX) { molLeftSpace = 0; maxLength = SpanceX * BranchSPFWithX; } if (anotherMolNum == 2) { SetMolPosition(tempMp, curX + maxLength + molLeftSpace, curY); } else if (anotherMolNum == 1) { SetMolPosition(tempMp, curX + maxLength + molLeftSpace, curY); } else if (anotherMolNum == 0) { SetMolPosition(tempMp, curX + SpanceX * BranchSPFWithX + molLeftSpace, curY); } rootMol.fuse(tempMp.Mol); //写mol层次号 string txt = molList1[1]; if (txt != "0a") { _ListTextPosition.Add(txt + "," + tempMp.Center_x + "," + (tempMp.Bottom_y - TxtspaceWithMolInY)); } //下一级 WriteSimpleBranch(tempMp, branchList, index + 1, rootMol, md, isRoot); }
/// <summary> /// 遍历子节点加入画图中 /// </summary> /// <param name="node">当前节点</param> /// <param name="md">画图对象</param> /// <param name="previousMp">前一个节点的位置坐标对象</param> /// <param name="RootMol">根mol</param> /// <param name="level">层级</param> private void SearchChildNode(TreeNodes node, MDocument md, MoleCulePostion previousMp, Molecule RootMol, int bracnchIndex) { double molLeftSpace = 0; int num = node.Children.Count; if (num == 1) { TreeNodes childNode = node.Children[0]; //绘制 MoleCulePostion mp = new MoleCulePostion(childNode.Smiles); molLeftSpace = mp.Center_x - mp.Left_x; SetMolPosition(mp, previousMp.Right_x + SpanceX + molLeftSpace, previousMp.Center_y); RootMol.fuse(mp.Mol); //写mol层次号 string txt = ReactionSteps.ToString() + "a"; _DicListTextPosition[bracnchIndex].Add(txt + "," + mp.Center_x + "," + (mp.Bottom_y - TxtspaceWithMolInY)); //划水平线 MPoint p1 = new MPoint(previousMp.Right_x + SpanceX * (0.5 - SpaceLineScale / 2), previousMp.Center_y); MPoint p2 = new MPoint(previousMp.Right_x + SpanceX * (0.5 + SpaceLineScale / 2), previousMp.Center_y); MRectangle arrow = new MRectangle(p1, p2); md.addObject(arrow); //写反应步次 md.addObject(CreateMTextBox((ReactionSteps++).ToString(), new MPoint(previousMp.Right_x + SpanceX * 0.5, previousMp.Center_y + ReactionIndexSpaceWithLine))); //遍历子集 SearchChildNode(childNode, md, mp, RootMol, bracnchIndex); } else if (num > 1) { WriteText(md, bracnchIndex); if (num % 2 == 0) { //对称式绘出节点位置 double topY = previousMp.Center_y; double bottomY = previousMp.Center_y; List <double> listHigh = new List <double>(); List <char> listChar = new List <char>(); for (int i = 0; i < num; i++) { listChar.Add((char)('a' + i)); } var list = node.Children; for (int i = 0; i < list.Count; i += 2) { //记录当前反应的步数 int curStep = ReactionSteps++; double tempY1 = list[i].ChildLeapNum * SpanceY; double tempY2 = list[i + 1].ChildLeapNum * SpanceY; topY += tempY1 > tempY2 ? tempY1 : tempY2; bottomY -= tempY1 > tempY2 ? tempY1 : tempY2; listHigh.Add(topY); listHigh.Add(bottomY); //上半部分 MoleCulePostion mp1 = new MoleCulePostion(list[i].Smiles); molLeftSpace = mp1.Center_x - mp1.Left_x; SetMolPosition(mp1, previousMp.Right_x + SpanceX + molLeftSpace, topY); RootMol.fuse(mp1.Mol); //写mol层次号 string txt1 = curStep.ToString() + listChar[num - (num / 2 + i / 2) - 1]; _DicListTextPosition[0].Add(txt1 + "," + mp1.Center_x + "," + (mp1.Bottom_y - TxtspaceWithMolInY)); //找子集 SearchChildNode(list[i], md, mp1, RootMol, 0); //下半部分 MoleCulePostion mp2 = new MoleCulePostion(list[i + 1].Smiles); molLeftSpace = mp2.Center_x - mp2.Left_x; SetMolPosition(mp2, previousMp.Right_x + SpanceX + molLeftSpace, bottomY); RootMol.fuse(mp2.Mol); //写mol层次号 string txt2 = curStep.ToString() + listChar[num / 2 + i / 2]; _DicListTextPosition[2].Add(txt2 + "," + mp2.Center_x + "," + (mp2.Bottom_y - TxtspaceWithMolInY)); //写反应步次 double startWithText = 0.5 - SpaceLineScale / 4; md.addObject(CreateMTextBox((curStep).ToString(), new MPoint(previousMp.Right_x + SpanceX * startWithText, previousMp.Center_y + ReactionIndexSpaceWithLine))); WriteBranchLine(previousMp.Right_x, previousMp.Center_y, listHigh, md); //找子集 SearchChildNode(list[i + 1], md, mp2, RootMol, 2); } } else { //记录当前反应的步数 int curStep = ReactionSteps++; double topY = previousMp.Center_y; double bottomY = previousMp.Center_y; List <double> listHigh = new List <double>(); List <char> listChar = new List <char>(); for (int i = 0; i < num; i++) { listChar.Add((char)('a' + i)); } var list = node.Children; //先绘画水平节点 MoleCulePostion mp = new MoleCulePostion(list[0].Smiles); molLeftSpace = mp.Center_x - mp.Left_x; SetMolPosition(mp, previousMp.Right_x + SpanceX + molLeftSpace, previousMp.Center_y); RootMol.fuse(mp.Mol); //写mol层次号 string txt = curStep.ToString() + listChar[num / 2]; _DicListTextPosition[1].Add(txt + "," + mp.Center_x + "," + (mp.Bottom_y - TxtspaceWithMolInY)); //找子集 SearchChildNode(list[0], md, mp, RootMol, 1); //分隔两侧间距 double high_mp = list[0].ChildLeapNum * SpanceY; topY += high_mp; bottomY -= high_mp; listHigh.Add(previousMp.Center_y); //两端节点 for (int i = 1; i < list.Count; i += 2) { double tempY1 = list[i].ChildLeapNum * SpanceY; double tempY2 = list[i + 1].ChildLeapNum * SpanceY; topY += tempY1 > tempY2 ? tempY1 : tempY2; bottomY -= tempY1 > tempY2 ? tempY1 : tempY2; listHigh.Add(topY); listHigh.Add(bottomY); //上半部分 MoleCulePostion mp1 = new MoleCulePostion(list[i].Smiles); molLeftSpace = mp1.Center_x - mp1.Left_x; SetMolPosition(mp1, previousMp.Right_x + SpanceX + molLeftSpace, topY); RootMol.fuse(mp1.Mol); //写mol层次号 string txt1 = curStep.ToString() + listChar[num / 2 - 1 - i / 2]; _DicListTextPosition[0].Add(txt1 + "," + mp1.Center_x + "," + (mp1.Bottom_y - TxtspaceWithMolInY)); //找子集 SearchChildNode(list[i], md, mp1, RootMol, 0); //下半部分 MoleCulePostion mp2 = new MoleCulePostion(list[i + 1].Smiles); molLeftSpace = mp2.Center_x - mp2.Left_x; SetMolPosition(mp2, previousMp.Right_x + SpanceX + molLeftSpace, bottomY); RootMol.fuse(mp2.Mol); //写mol层次号 string txt2 = curStep.ToString() + listChar[num / 2 + 1 + i / 2]; _DicListTextPosition[2].Add(txt2 + "," + mp2.Center_x + "," + (mp2.Bottom_y - TxtspaceWithMolInY)); //写反应步次 double startWithText = 0.5 - SpaceLineScale / 4; md.addObject(CreateMTextBox((curStep).ToString(), new MPoint(previousMp.Right_x + SpanceX * startWithText, previousMp.Center_y + ReactionIndexSpaceWithLine))); WriteBranchLine(previousMp.Right_x, previousMp.Center_y, listHigh, md); //找子集 SearchChildNode(list[i + 1], md, mp2, RootMol, 2); } } } else { WriteText(md, bracnchIndex); } }