public DrawCouplesGraphEdges(PedigreeModel model) { step = delegate(Graphics g) { if (model.parameters.drawCouplesGraph) { int n = model.coupleEdges.Count; crossedEdges.Clear(); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { PedigreeCoupleEdge edgeA = model.coupleEdges[i]; PedigreeCoupleEdge edgeB = model.coupleEdges[j]; if (DetectPlanarity.EdgesCross(edgeA, edgeB, model.parameters.hideNonBloodRelatives)) { crossedEdges.Add(edgeA); crossedEdges.Add(edgeB); } } } foreach (PedigreeCoupleEdge edge in model.coupleEdges) { int x1 = (int)edge.u.point.x; int y1 = (int)edge.u.point.y; int x2 = (int)edge.v.point.x; int y2 = (int)edge.v.point.y; // Pen pen = model.couplesGraphIsPlanar ? couplesEdgePen : crossedEdgePen; if (edge.intergenerational) { g.DrawLine(couplesEdgePen, x1, y1, x2, y2); } else { //if (x1 != x2 && y1 != y2) // g.DrawArc(couplesEdgePen, x1, y1,x2-x1, 50, 0, (float)Math.PI); int height = model.parameters.halfSibsArcHeight; int y = (int)((y1 + y2) / 2) - height; if (x2 > x1) { g.DrawArc(couplesEdgePen, x1, y, x2 - x1, height * 2, 0, -180); } else if (x1 > x2) { g.DrawArc(couplesEdgePen, x2, y, x1 - x2, height * 2, 0, -180); } } } } }; }
internal DrawLasso(PedigreeModel model) { step = delegate(Graphics g) { //turn on anti-aliasing (smooth lines) g.SmoothingMode = SmoothingMode.AntiAlias; LassoPen.DashPattern = new float[] { 2, 3 }; if (model.SelectionLasso.Count > 2) g.DrawPolygon(LassoPen, model.SelectionLasso.ToArray()); }; }
public DrawZoom(PedigreeModel model) { step = delegate(Graphics g) { g.ScaleTransform(model.parameters.scale, model.parameters.scale); g.TranslateTransform(model.parameters.hOffset, model.parameters.vOffset); //g.FillEllipse(Brushes.Thistle, new Rectangle(new Point((int)(model.displayXMax / 2)-10, (int)(model.displayYMax / 2)-10), new Size(20, 20))); //g.DrawRectangle(Pens.Black, new Rectangle( // (int)model.displayXMin, // (int)model.displayYMin, // (int)(model.displayXMax - model.displayXMin), // (int)(model.displayYMax - model.displayYMin))); }; }
internal DrawLasso(PedigreeModel model) { step = delegate(Graphics g) { //turn on anti-aliasing (smooth lines) g.SmoothingMode = SmoothingMode.AntiAlias; LassoPen.DashPattern = new float[] { 2, 3 }; if (model.SelectionLasso.Count > 2) { g.DrawPolygon(LassoPen, model.SelectionLasso.ToArray()); } }; }
public DrawCouplesGraphEdges(PedigreeModel model) { step = delegate(Graphics g) { if (model.parameters.drawCouplesGraph) { int n = model.coupleEdges.Count; crossedEdges.Clear(); for (int i = 0; i < n; i++) for (int j = i + 1; j < n; j++) { PedigreeCoupleEdge edgeA = model.coupleEdges[i]; PedigreeCoupleEdge edgeB = model.coupleEdges[j]; if (DetectPlanarity.EdgesCross(edgeA, edgeB, model.parameters.hideNonBloodRelatives)) { crossedEdges.Add(edgeA); crossedEdges.Add(edgeB); } } foreach (PedigreeCoupleEdge edge in model.coupleEdges) { int x1 = (int)edge.u.point.x; int y1 = (int)edge.u.point.y; int x2 = (int)edge.v.point.x; int y2 = (int)edge.v.point.y; // Pen pen = model.couplesGraphIsPlanar ? couplesEdgePen : crossedEdgePen; if (edge.intergenerational) g.DrawLine(couplesEdgePen, x1, y1, x2, y2); else { //if (x1 != x2 && y1 != y2) // g.DrawArc(couplesEdgePen, x1, y1,x2-x1, 50, 0, (float)Math.PI); int height = model.parameters.halfSibsArcHeight; int y = (int)((y1 + y2) / 2) - height; if (x2 > x1) g.DrawArc(couplesEdgePen, x1, y, x2 - x1, height * 2, 0, -180); else if (x1 > x2) g.DrawArc(couplesEdgePen, x2, y, x1 - x2, height * 2, 0, -180); } } } }; }
public DrawCouplesGraphNodes(PedigreeModel model) { step = delegate(Graphics g) { if (model.parameters.drawCouplesGraph) { tempRect.Width = tempRect.Height = model.parameters.coupleNodeRadius * 2; foreach (PedigreeCouple couple in model.couples) { tempRect.X = (int)couple.point.x - model.parameters.coupleNodeRadius; tempRect.Y = (int)couple.point.y - model.parameters.coupleNodeRadius; g.FillEllipse(b, tempRect); } } }; }
internal ClearBackground(PedigreeModel model) { step = delegate(Graphics g) { //draw the background g.FillRectangle(model.parameters.BackgroundBrush, (int)model.displayXMin, (int)model.displayYMin, (int)(model.displayXMax - model.displayXMin), (int)(model.displayYMax - model.displayYMin) ); //legendText = ""; //if (model.parameters.ShowUnitnum) // legendText += ", " + model.familyHistory.proband.unitnum; //if (model.parameters.ShowName) // legendText += ", " + model.familyHistory.proband.name; //if (model.parameters.ShowDob) // legendText += ", " + model.familyHistory.proband.dob; //g.DrawString(legendText.Trim(trimChars), idLabelFont, Brushes.Black, labelorigin); if (model.RelativesToLink.Count > 0) { linkingOrigin.X = (int)(model.controlWidth / 2); g.DrawString("Please select the parent", idLabelFont, Brushes.Red, linkingOrigin); } if (model.converged == false && model.parameters.ControllerMode == PedigreeController.SELF_ORGANIZING) { linkingOrigin.X = (int)(model.controlWidth / 2); linkingOrigin.Y += 20; g.DrawString("Working...", idLabelFont, Brushes.Gray, linkingOrigin); linkingOrigin.Y -= 20; } //if ( }; }
public DrawLoading(PedigreeModel model) { step = delegate(Graphics g) { //moved to clear background //if (model.parameters.allRelativesAccountedFor == false) //{ // float x = (float)(model.displayXMax / 2) - 100; // float y = (float)(model.displayYMax / 2); // g.FillRectangle(new SolidBrush(Color.FromArgb(64, Color.Gray)), new Rectangle(0, 0, (int)model.displayXMax, (int)model.displayYMax)); // g.DrawString("Loading...", theFont, Brushes.WhiteSmoke, new PointF(x, y)); //} //if (model.parameters.ControllerMode == PedigreeController.SELF_ORGANIZING) //{ // float x = (float)(model.displayXMax / 2) - 100; // float y = 30; // g.DrawString("Organizing...", theOrganizingFont, Brushes.Red, new PointF(x, y)); //} }; }
public DrawIndividuals(PedigreeModel model) { step = delegate(Graphics g) { try { Font individualFont = new Font("Tahoma", model.parameters.annotationFontSize); //individualsPen = model.couplesGraphEdgesCross() ? new Pen(Brushes.Red) : new Pen(Brushes.Black); int halfIndividualSize = model.parameters.individualSize/2; foreach (PedigreeIndividual individual in model.individuals) { if (individual.HraPerson.relativeID <= 0) break; if (!model.parameters.hideNonBloodRelatives || individual.bloodRelative) { if (individual.HraPerson.relationship == "Self") { PointF[] arrow = new PointF[3]; float centerX = (float) (individual.point.x); float centerY = (float) (individual.point.y); int glyphSize = model.parameters.individualSize; int arrowSize = 12; arrow[0] = new PointF(centerX - glyphSize/2 - arrowSize, centerY + glyphSize/2); arrow[1] = new PointF(centerX - glyphSize/2, centerY + glyphSize/2); arrow[2] = new PointF(centerX - glyphSize/2, centerY + glyphSize/2 + arrowSize); g.FillPolygon(new SolidBrush(Color.Black), arrow); g.DrawLine(new Pen(Color.Black, 5), centerX - glyphSize/2 - arrowSize, centerY + glyphSize/2 + arrowSize, centerX - glyphSize/2 - arrowSize/2, centerY + glyphSize/2 + arrowSize/2); } //////////////////////////////////////////////////////////////////////////////////////// tempRect.X = (int) individual.point.x - halfIndividualSize; tempRect.Y = (int) individual.point.y - halfIndividualSize; tempRect.Width = tempRect.Height = model.parameters.individualSize; if (individual.HraPerson.gender == PedigreeIndividual.GENDER_FEMALE) g.FillEllipse(model.parameters.BackgroundBrush, tempRect); else g.FillRectangle(model.parameters.BackgroundBrush, tempRect); ///////////////////////////////////////////////////////////////////////////////////////// foreach (ClincalObservation co in individual.HraPerson.PMH.Observations) { if (co.ClinicalObservation_diseaseIconType == "Fill") { Brush b; if (co.ClinicalObservation_diseaseIconColor != null) { b = new SolidBrush( Color.FromName(co.ClinicalObservation_diseaseIconColor)); } else { b = new SolidBrush(Color.Transparent); } Rectangle fillArea = tempRect; switch (co.ClinicalObservation_diseaseIconArea) { case "All": if (individual.HraPerson.gender == PedigreeIndividual.GENDER_FEMALE) g.FillEllipse(b, fillArea); else g.FillRectangle(b, fillArea); break; default: break; } } } foreach (ClincalObservation co in individual.HraPerson.PMH.Observations) { if (co.ClinicalObservation_diseaseIconType == "Fill") { Brush b; if (co.ClinicalObservation_diseaseIconColor != null) { b = new SolidBrush( Color.FromName(co.ClinicalObservation_diseaseIconColor)); } else { b = new SolidBrush(Color.Transparent); } Rectangle fillArea = tempRect; switch (co.ClinicalObservation_diseaseIconArea) { case "UL": fillArea.Height = halfIndividualSize; fillArea.Width = halfIndividualSize; if (individual.HraPerson.gender == PedigreeIndividual.GENDER_FEMALE) g.FillPie(b, tempRect, 180, 90); else g.FillRectangle(b, fillArea); break; case "UR": fillArea.X += halfIndividualSize; fillArea.Height = halfIndividualSize; fillArea.Width = halfIndividualSize; if (individual.HraPerson.gender == PedigreeIndividual.GENDER_FEMALE) g.FillPie(b, tempRect, 270, 90); else g.FillRectangle(b, fillArea); break; case "LL": fillArea.Y += halfIndividualSize; fillArea.Height = halfIndividualSize; fillArea.Width = halfIndividualSize; if (individual.HraPerson.gender == PedigreeIndividual.GENDER_FEMALE) g.FillPie(b, tempRect, 90, 90); else g.FillRectangle(b, fillArea); break; case "LR": fillArea.Y += halfIndividualSize; fillArea.X += halfIndividualSize; fillArea.Height = halfIndividualSize; fillArea.Width = halfIndividualSize; if (individual.HraPerson.gender == PedigreeIndividual.GENDER_FEMALE) g.FillPie(b, tempRect, 0, 90); else g.FillRectangle(b, fillArea); break; default: break; } } } foreach (ClincalObservation co in individual.HraPerson.PMH.Observations) { if (co.ClinicalObservation_diseaseIconType == "Dot") { Brush b; if (co.ClinicalObservation_diseaseIconColor != null) { b = new SolidBrush( Color.FromName(co.ClinicalObservation_diseaseIconColor)); } else { b = new SolidBrush(Color.Transparent); } Rectangle fillArea = tempRect; fillArea.Width = tempRect.Width/2; fillArea.Height = tempRect.Height/2; switch (co.ClinicalObservation_diseaseIconArea) { case "All": break; case "UL": break; case "UR": fillArea.X += tempRect.Width/2; break; case "LL": fillArea.Y += tempRect.Height/2; break; case "LR": fillArea.X += tempRect.Width/2; fillArea.Y += tempRect.Height/2; break; default: break; } g.FillEllipse(b, fillArea); } } ///////////////////////////////////////////////////////////////////////////////////// if (model.parameters.annotation_areas != null) foreach (AnnotationContainer area in model.parameters.annotation_areas) { if (area.active) { Point areaOrigin = tempRect.Location; int areaMargin = 3; int verticalFudge = 8; int horizontalFudge = 6; int midLevelYOffset = 7; switch ((int) area.Position) { case ((int) AnnotationContainer.IconRelation.LOWER_CENTER): areaOrigin = new Point((int) individual.point.x, (int) individual.point.y + halfIndividualSize + areaMargin); break; case ((int) AnnotationContainer.IconRelation.MID_LEFT_UPPER): areaOrigin = new Point( (int) individual.point.x - halfIndividualSize - horizontalFudge, (int) individual.point.y - verticalFudge - midLevelYOffset); break; case ((int) AnnotationContainer.IconRelation.MID_LEFT_LOWER): areaOrigin = new Point( (int) individual.point.x - halfIndividualSize - horizontalFudge, (int) individual.point.y + verticalFudge - midLevelYOffset); break; case ((int) AnnotationContainer.IconRelation.UPPER_LEFT): areaOrigin = new Point( (int) individual.point.x - areaMargin - horizontalFudge, (int) individual.point.y - halfIndividualSize - areaMargin - (2*verticalFudge)); break; case ((int) AnnotationContainer.IconRelation.UPPER_RIGHT): areaOrigin = new Point( (int) individual.point.x + areaMargin + horizontalFudge, (int) individual.point.y - halfIndividualSize - areaMargin - (2*verticalFudge)); break; case ((int) AnnotationContainer.IconRelation.MID_RIGHT_UPPER): areaOrigin = new Point( (int) individual.point.x + halfIndividualSize + areaMargin + horizontalFudge, (int) individual.point.y - verticalFudge - midLevelYOffset); break; case ((int) AnnotationContainer.IconRelation.MID_RIGHT_LOWER): areaOrigin = new Point( (int) individual.point.x + halfIndividualSize + areaMargin + horizontalFudge, (int) individual.point.y + verticalFudge - midLevelYOffset); break; case ((int) AnnotationContainer.IconRelation.CENTER_TOP): //if (individual.simpleIndividual.motherID > 0 && individual.simpleIndividual.fatherID > 0) // areaOrigin = new Point((int)individual.point.x, (int)individual.point.y - (4* halfIndividualSize)); //else areaOrigin = new Point((int) individual.point.x, (int) individual.point.y - (2*halfIndividualSize)); break; } foreach (AnnotationContainerSlot slot in area.slots) { if (slot.resident != null) { switch (slot.resident.label) { case "Name": string renderedText = individual.HraPerson.name; //.Substring(0, model.parameters.nameWidth); ; if (string.IsNullOrEmpty(renderedText) == false) { if (model.parameters.nameWidth > 0 && renderedText.Length > model.parameters.nameWidth) { renderedText = renderedText.Substring(0, model .parameters .nameWidth); } g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } break; case "Name and Age": string name_part = individual.HraPerson.name; if (string.IsNullOrEmpty(name_part) == false) { if (model.parameters.nameWidth > 0 && name_part.Length > model.parameters.nameWidth) { name_part = name_part.Substring(0, model.parameters.nameWidth); } } string age_part = individual.HraPerson.age; int i_age = -1; if (int.TryParse(age_part, out i_age)) { if (i_age == 0) { DateTime dt_age; if (DateTime.TryParse(individual.HraPerson.dob, out dt_age)) { TimeSpan ts = individual.HraPerson.owningFHx.proband.apptdatetime - dt_age; age_part = "~ " + Math.Round((ts.TotalDays / 30)).ToString() + " Mos"; } } } renderedText = name_part + " " + age_part; if (string.IsNullOrEmpty(renderedText) == false) { g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } break; case "Age": renderedText = individual.HraPerson.age; i_age = -1; if (int.TryParse(renderedText, out i_age)) { if (i_age == 0) { DateTime dt_age; if ( DateTime.TryParse( individual.HraPerson.dob, out dt_age)) { TimeSpan ts = individual.HraPerson.owningFHx .proband.apptdatetime - dt_age; renderedText = "~ " + Math.Round((ts.TotalDays/ 30)) .ToString() + " Mos"; } } } if (string.IsNullOrEmpty(renderedText) == false) { g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } break; case "Date Of Birth": renderedText = individual.HraPerson.dob; if (string.IsNullOrEmpty(renderedText) == false) { g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } break; case "First Name": renderedText = individual.HraPerson.firstName; if (string.IsNullOrEmpty(renderedText) == false) { g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } break; case "Last Name": renderedText = individual.HraPerson.lastName; if (string.IsNullOrEmpty(renderedText) == false) { g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } break; case "Comment": renderedText = individual.HraPerson.comment; if (string.IsNullOrEmpty(renderedText) == false) { g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } break; case "Ethnicity": renderedText = individual.HraPerson.Ethnicity.GetSummary(); if (string.IsNullOrEmpty(renderedText) == false) { if (model.parameters.limitedEthnicity == false || (individual.Mother == null && individual.Father == null)) { g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } } break; case "Nationality": renderedText = individual.HraPerson.Nationality.GetSummary(); if ( string.IsNullOrEmpty( individual.HraPerson.isAshkenazi) == false) { if ( string.Compare( individual.HraPerson.isAshkenazi, "Yes", true) == 0) renderedText += ", Ashkenazi"; } if ( string.IsNullOrEmpty( individual.HraPerson.isHispanic) == false) { if ( string.Compare( individual.HraPerson.isHispanic, "Yes", true) == 0) renderedText += ", Hispanic"; } if (string.IsNullOrEmpty(renderedText) == false) { renderedText = renderedText.Trim(trimChars); if (model.parameters.limitedNationality == false || (individual.Mother == null && individual.Father == null)) { g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } } break; case "Accession #": renderedText = ""; if (model.FamilialVariants != null) { lock (model.FamilialVariants) { foreach ( GeneticTest gt in individual.HraPerson.PMH.GeneticTests ) { if (string.IsNullOrEmpty(gt.accession) == false) { if (renderedText.Length > 0) { renderedText += ", "; } renderedText += gt.accession; } g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area .justification, renderedText)); areaOrigin.Y += 12; } } } break; case "Panel Name": //foreach (PanelData pd in individual.Panels) //{ // renderedText = pd.panelShortName; // if (string.IsNullOrEmpty(renderedText) == false) // { // g.DrawString(renderedText, // individualFont, // Brushes.Black, // GetLabelPoint(areaOrigin, area.justification, renderedText)); // areaOrigin.Y += 12; // } //} break; case "Test Code": //foreach (PanelData pd in individual.Panels) //{ // renderedText = pd.TEST_CODE; // if (string.IsNullOrEmpty(renderedText) == false) // { // g.DrawString(renderedText, // individualFont, // Brushes.Black, // GetLabelPoint(areaOrigin, area.justification, renderedText)); // areaOrigin.Y += 12; // } //} break; case "Test Result": if (model.FamilialVariants != null) { lock (model.FamilialVariants) { foreach ( GeneticTest gt in individual.HraPerson.PMH.GeneticTests .Where( t => (((GeneticTest) t) .GeneticTest_status != "Pending") && ((GeneticTest) t) .GeneticTest_status != "Cancelled" && (((GeneticTest) t) .GeneticTest_panelID != 26))) { bool allNegative = true; foreach ( GeneticTestResult gtr in gt.GeneticTestResults) { if ( string.IsNullOrEmpty( gtr.resultSignificance) == false) { if ( !string.IsNullOrEmpty( gtr.mutationName) || !((gtr.resultSignificance == "Negative") || (gtr.resultSignificance == "NEG") || (gtr.resultSignificance == "Benign"))) { allNegative = false; } } } if (allNegative) { if ( string.IsNullOrEmpty( gt.panelShortName)) { renderedText = gt.panelName + " -"; } else { renderedText = gt.panelShortName + " -"; } if ( string.IsNullOrEmpty(renderedText) == false) { g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint( areaOrigin, area .justification, renderedText)); areaOrigin.Y += 12; } } } } } break; case "Variant": if (model.FamilialVariants != null) { lock (model.FamilialVariants) { if (individual.HraPerson.PMH.GeneticTests.Count > 0) { foreach (GeneticTestResult familialVariant in model.FamilialVariants.Keys) { if (string.Compare(familialVariant.resultSignificance, "Negative", true) == 0 || string.Compare(familialVariant.resultSignificance, "Neg", true) == 0) { continue; } renderedText = ""; foreach (GeneticTest gt in individual.HraPerson.PMH.GeneticTests.Where (t =>((GeneticTest) t).GeneticTest_status != "Pending" && ((GeneticTest) t).GeneticTest_status != "Cancelled")) { foreach (GeneticTestResult individualResult in gt.GeneticTestResults) { //if (model.FamilialVariants[familialVariant].Any(person => person.relativeID == individual.HraPerson.relativeID)) { if (familialVariant.geneName == individualResult.geneName) { if (familialVariant.mutationName == individualResult.ASOMutationName) { if (individualResult.ASOResult == "Found") { renderedText = model.parameters.VariantFoundText; } else if (individualResult.ASOResult == "Not Found") { renderedText = model.parameters.VariantNotFoundText; } else if (individualResult.ASOResult == "Not Tested") { renderedText = model.parameters.VariantNotTestedText; } else if (individualResult.ASOResult == "Unknown") { renderedText = model.parameters.VariantUnknownText; } } else if (familialVariant.mutationName == individualResult.mutationName) { renderedText = model.parameters.VariantFoundText; } if (renderedText == model.parameters.VariantFoundText) { if (string.IsNullOrEmpty(familialVariant.GeneticTestResult_allelicState) == false) { if (string.Compare(familialVariant.GeneticTestResult_allelicState, "Hemizygous", true) == 0 || string.Compare(familialVariant.GeneticTestResult_allelicState, "Heterozygous", true) == 0) { renderedText = model.parameters.VariantHeteroText; } } string meaning = individualResult.getMeaning(); if (meaning == "VUS") { renderedText = model.parameters.VariantFoundVusText; } else if (meaning == "Unknown") { renderedText = model.parameters.VariantUnknownText; } else if ( meaning == "Favor Polymorphism" || meaning == "Negative") { renderedText = model .parameters .VariantNotFoundText; } } } } //else //{ // if (!string.IsNullOrEmpty(individualResult.mutationName)) // { // renderedText = model.parameters.VariantNotTestedText; // } //} } } if (string.IsNullOrEmpty(renderedText) == false) { g.DrawString(renderedText,individualFont,Brushes.Black,GetLabelPoint(areaOrigin, area.justification, renderedText)); areaOrigin.Y += 12; } } } } } break; case "Disease List": foreach ( ClincalObservation co in individual.HraPerson.PMH.Observations) { string shortString = co.ClinicalObservation_diseaseShortName; if (string.IsNullOrEmpty(shortString)) shortString = co.disease; if (string.IsNullOrEmpty(shortString)) shortString = co.ClinicalObservation_Problem; if (string.IsNullOrEmpty(co.ageDiagnosis) == false) shortString += (" " + co.ageDiagnosis); if (string.IsNullOrEmpty(shortString) == false) { g.DrawString(shortString, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, shortString)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } } break; case "Dx + Comment": foreach ( ClincalObservation co in individual.HraPerson.PMH.Observations) { string shortString = co.ClinicalObservation_diseaseShortName; if (string.IsNullOrEmpty(shortString)) shortString = co.disease; if (string.IsNullOrEmpty(shortString)) shortString = co.ClinicalObservation_Problem; if (string.IsNullOrEmpty(co.ageDiagnosis) == false) shortString += (" " + co.ageDiagnosis); if (string.IsNullOrEmpty(co.comments) == false) shortString += (" " + co.comments); if (string.IsNullOrEmpty(shortString) == false) { g.DrawString(shortString, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area.justification, shortString)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } } break; case "Brca Score": double score = Math.Round( individual.HraPerson.RP .RiskProfile_BrcaPro_1_2_Mut_Prob ?? -1, 0); renderedText = (score >= 1) ? String.Format("{0:0}", score) + "%" : ""; if (string.IsNullOrEmpty(renderedText) == false) { g.DrawString(renderedText, new Font(individualFont, FontStyle.Bold), (score >= 10) ? Brushes.Red : Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText, FontStyle.Bold, true, g)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } break; case "MMR Score": double mmrscore = Math.Round( individual.HraPerson.RP .RiskProfile_MmrPro_1_2_6_Mut_Prob ?? -1, 0); renderedText = (mmrscore >= 1) ? String.Format("{0:0}", mmrscore) + "%" : ""; if (string.IsNullOrEmpty(renderedText) == false) { g.DrawString(renderedText, new Font(individualFont, FontStyle.Bold), (mmrscore >= 10) ? Brushes.Red : Brushes.Black, GetLabelPoint(areaOrigin, area.justification, renderedText, FontStyle.Bold, true, g)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } break; case "Relationship": //only show relationship for unlinked relatives if (individual != null && individual.HraPerson != null) { renderedText = individual.HraPerson.GetShortRelationship(); if (string.IsNullOrEmpty(renderedText) == false) { renderedText = renderedText.Trim(trimChars); if (individual.hasChildren() == false && individual.hasParent() == false) { g.DrawString(renderedText, individualFont, Brushes.Black, GetLabelPoint(areaOrigin, area .justification, renderedText)); areaOrigin.Y += (model.parameters.annotationFontSize + 4); } } } break; default: break; } //Size sz = TextRenderer.MeasureText(renderedText, individualFont); //g.FillRectangle(new SolidBrush(Color.FromArgb(128, 255, 255, 255)), areaOrigin.X, areaOrigin.Y, sz.Width, sz.Height); } } } } //////////////////////////////////////////////////////////////////////////////// if (individual.Selected) { Rectangle r = new Rectangle(tempRect.X - 5, tempRect.Y - 5, tempRect.Width + 10, tempRect.Height + 10); //g.DrawEllipse(selectionPen, tempRect.X - 5, tempRect.Y - 5, tempRect.Width + 10, tempRect.Height + 10); if (model.Selected.Count > 1) { DrawIndividualGlyph(g, multiSelectionPen, r, individual.HraPerson.gender); } else { DrawIndividualGlyph(g, selectionPen, r, individual.HraPerson.gender); } } //else { DrawIndividualGlyph(g, individualsPen, tempRect, individual.HraPerson.gender); } if (individual.HraPerson.adopted == "Yes") { adoptedLeftPoints[0] = new Point(tempRect.X + tempRect.Width/5, tempRect.Y - 8); adoptedLeftPoints[1] = new Point(tempRect.X - 8, tempRect.Y - 8); adoptedLeftPoints[2] = new Point(tempRect.X - 8, tempRect.Y + tempRect.Height + 8); adoptedLeftPoints[3] = new Point(tempRect.X + tempRect.Width/5, tempRect.Y + tempRect.Height + 8); g.DrawLines(Pens.Black, adoptedLeftPoints); adoptedRightPoints[0] = new Point(tempRect.X + tempRect.Width - tempRect.Width/5, tempRect.Y - 8); adoptedRightPoints[1] = new Point(tempRect.X + tempRect.Width + 8, tempRect.Y - 8); adoptedRightPoints[2] = new Point(tempRect.X + tempRect.Width + 8, tempRect.Y + tempRect.Height + 8); adoptedRightPoints[3] = new Point(tempRect.X + tempRect.Width - tempRect.Width/5, tempRect.Y + tempRect.Height + 8); g.DrawLines(Pens.Black, adoptedRightPoints); } //////////////////////////////////////////////////////////////////////////////// if (individual.Group != null) { string num = individual.Group.Count.ToString(); Size sz = TextRenderer.MeasureText(num, individualFont); g.DrawString(num, individualFont, Brushes.Black, (float) (individual.point.x - (sz.Width/2)), (float) (individual.point.y - (sz.Height/2))); } //////////////////////////////////////////////////////////////////////////////// if (individual.HraPerson.vitalStatus == "Dead") { g.DrawLine(individualsPen, new Point(tempRect.X - 5, tempRect.Y - 5), new Point(tempRect.X + tempRect.Width + 5, tempRect.Y + tempRect.Height + 5)); } //////////////////////////////////////////////////////////////////////////////// //int count = model.getIndividualCountUnderContact(individual); //if (count > 1) //{ // g.DrawString(count.ToString(), individualFont, Brushes.Black, new PointF((int)individual.point.x - 5, (int)individual.point.y - 5)); //} int x = (int) (individual.point.x - 7); int y = (int) (individual.point.y - 9); if (model.parameters.drawIdLabels) g.DrawString(individual.HraPerson.relativeID.ToString(), idLabelFont, Brushes.Black, x, y); } /**/ } } catch (Exception ex) { Logger.Instance.WriteToLog(ex.ToString()); g.DrawString(ex.ToString(), idLabelFont, Brushes.Black, 10, 10); } }; }
public void AddDrawingStep(DrawingStep drawingStep) { steps.Add(drawingStep); }
public DrawLayoutSteps(PedigreeModel model) { step = delegate(Graphics g) { if (model.parameters.drawVisualDebugging && model.couplesGraphIsPlanar) { //draw the center line //double idealCenterX = (model.displayXMin + model.displayYMax) / 2; int avgVerticalOffset = (int)( (model.parameters.verticalSpacing - model.parameters.individualSize) / 4); foreach (PedigreeCouple couple in model.couples) { //draw lines showing the averages between couples int motherX = (int)couple.mother.point.x; int motherY = (int)couple.mother.point.y + model.parameters.individualSize / 2; int fatherX = (int)couple.father.point.x; int fatherY = (int)couple.father.point.y + model.parameters.individualSize / 2; int coupleCenterX = (motherX + fatherX) / 2; int coupleCenterY = (motherY + fatherY) / 2 + avgVerticalOffset; Pen pen = Pens.Green; g.DrawLine(pen, motherX, motherY, motherX, coupleCenterY); g.DrawLine(pen, motherX, coupleCenterY, coupleCenterX, coupleCenterY); g.DrawLine(pen, fatherX, fatherY, fatherX, coupleCenterY); g.DrawLine(pen, fatherX, coupleCenterY, coupleCenterX, coupleCenterY); //draw lines showing the averages between sibships if (couple.children.Count > 0) { int sibshipMinX = int.MaxValue; int sibshipMaxX = -int.MaxValue; foreach (PedigreeIndividual child in couple.children) { if (child.point.x < sibshipMinX) { sibshipMinX = (int)child.point.x; } if (child.point.x > sibshipMaxX) { sibshipMaxX = (int)child.point.x; } } int sibshipY = (int)couple.point.y + model.parameters.verticalSpacing - model.parameters.individualSize / 2; int sibshipCenterX = (sibshipMinX + sibshipMaxX) / 2; int sibshipCenterY = sibshipY - avgVerticalOffset; g.DrawLine(pen, sibshipMinX, sibshipY, sibshipMinX, sibshipCenterY); g.DrawLine(pen, sibshipMinX, sibshipCenterY, sibshipCenterX, sibshipCenterY); g.DrawLine(pen, sibshipMaxX, sibshipY, sibshipMaxX, sibshipCenterY); g.DrawLine(pen, sibshipMaxX, sibshipCenterY, sibshipCenterX, sibshipCenterY); //draw the line showing the average of the two centers g.DrawLine(pen, sibshipCenterX, sibshipCenterY, coupleCenterX, coupleCenterY); int middleX = (sibshipCenterX + coupleCenterX) / 2; int middleY = (sibshipCenterY + coupleCenterY) / 2; int midRadius = 5; int side = midRadius * 2; g.FillEllipse(Brushes.Green, middleX - midRadius, middleY - midRadius, side, side); //draw the ideal positions of the couple bool fatherToTheLeft = fatherX < motherX; int f = fatherToTheLeft ? 1 : -1; int idealFatherX = middleX - f * model.parameters.horizontalSpacing / 2; int idealMotherX = middleX + f * model.parameters.horizontalSpacing / 2; pen = Pens.Red; g.DrawLine(pen, idealFatherX, fatherY, middleX, middleY); g.DrawLine(pen, idealMotherX, motherY, middleX, middleY); DrawIndividual(idealFatherX, couple.father.point.y, couple.father.HraPerson.gender, model, g, pen); DrawIndividual(idealMotherX, couple.mother.point.y, couple.mother.HraPerson.gender, model, g, pen); //draw the ideal sibship positions //Step 2 of 2: Pull sibship members toward their ideal positions, //spaced ideally and centered around thir parent couple, leaving //open spaces for spouses (as they will be positioned by the //layout step addressing couples). { double spacing = model.parameters.horizontalSpacing; //Compute the offset from the couple center for positioning individuals double offset = 0; { int numIndividualsInSibshipSpan = 0; // foreach (PedigreeIndividual child in couple.children) for (int j = 0; j < couple.children.Count; j++) { PedigreeIndividual child = couple.children[j]; //count the child numIndividualsInSibshipSpan++; //count the spouse ... sometimes //if (child.spouseCouples.Count == 1) //{ // bool thisSpouseCounts = true; // bool spouseIsToRight = child.Spouse.point.x > child.point.x; // //don't count the spouse to the right of // //the sibship's rightmost child // if (j == couple.children.Count - 1 && spouseIsToRight) // thisSpouseCounts = false; // //don't count the spouse to the left of // //the sibship's leftmost child // if (j == 0 && !spouseIsToRight) // thisSpouseCounts = false; // if (thisSpouseCounts) // numIndividualsInSibshipSpan++; //} //else if (couple.children[j].spouseCouples.Count == 2) // throw new Exception("Half siblings not yet supported"); } double sibshipSpanSize = (numIndividualsInSibshipSpan - 1) * spacing; offset = middleX - sibshipSpanSize / 2; } //position individuals ideally by applying a force to them int i = 0; foreach (PedigreeIndividual child in couple.children) { //position the individuals horizontally based on //computation of their ideal horizontal positions { double goalX = offset; //if the child has no spouse if (child.spouseCouples.Count == 0) { //compute the position directly //without incrementing i goalX += i * spacing; } //if the child has a spouse, insert appropriate spacing else if (child.spouseCouples.Count == 1) { //where the space goes depends on whether the spouse is //to the left or right of the child, so find out //if the spouse is to the right or left of the child: // bool spouseIsToRight = child.Spouse.point.x > child.point.x; // //if the spouse is to the right... // if (spouseIsToRight) // //...but not for the rightmost child // if (i != couple.children.Count - 1) // //leave a space to the right. // goalX = offset + (i++) * spacing; // else // goalX = offset + i * spacing; // else//if the spouse is to the left... // //...but not for the leftmost child // if (i != 0) // //leave a space to the left. // goalX = offset + (++i) * spacing; //} //else if (child.spouseCouples.Count == 2) // throw new Exception("Half siblings not yet supported"); } g.DrawLine(pen, (float)middleX, (float)middleY, (float)goalX, (float)sibshipY); DrawIndividual(goalX, child.point.y, child.HraPerson.gender, model, g, pen); //increment i to account for enumeration this child i++; } } } } } } }; }
public DrawAncestralConnectionLines(PedigreeModel model) { step = delegate(Graphics g) { //g.FillEllipse(Brushes.Plum, new Rectangle((int)(model.displayXMax / 2) - 50, (int)(model.displayYMax / 2) - 50, 100, 100)); //g.DrawRectangle(Pens.Black, new Rectangle(0, 0, (int)model.displayXMax, (int)model.displayYMax)); int halfIndividualSize = model.parameters.individualSize / 2; Pen pen = Pens.Black; //if (model.parameters.ControllerMode == PedigreeController.SELF_ORGANIZING) //{ // //pen = model.layoutIsValid ? Pens.Black : Pens.Red; // pen = model.couplesGraphIsPlanar ? Pens.Black : Pens.Red; //} foreach (PedigreeCouple parents in model.couples) { // draw line between parents if (parents.mother != null && parents.father != null) { if (!model.parameters.hideNonBloodRelatives || (parents.father.bloodRelative && parents.mother.bloodRelative)) { if (parents.mother.HraPerson.consanguineousSpouseID == parents.father.HraPerson.relativeID) { g.DrawLine(pen, (int)parents.mother.point.x, (int)parents.mother.point.y + 2, (int)parents.father.point.x, (int)parents.father.point.y + 2 ); g.DrawLine(pen, (int)parents.mother.point.x, (int)parents.mother.point.y - 2, (int)parents.father.point.x, (int)parents.father.point.y - 2 ); } else { g.DrawLine(pen, (int)parents.mother.point.x, (int)parents.mother.point.y, (int)parents.father.point.x, (int)parents.father.point.y ); } } } try { //draw lines to children List <PedigreeIndividual> children = new List <PedigreeIndividual>(); //= parents.children; foreach (PedigreeIndividual pi in parents.children) { if (!model.parameters.hideNonBloodRelatives || pi.bloodRelative) { children.Add(pi); } } if (children.Count > 1) { if (parents.mother != null && parents.father != null) { // draw horizontal line connecting parents with multiple children double minX = (parents.father.point.x + parents.mother.point.x) / 2; double maxX = minX; Dictionary <int, List <PedigreeIndividual> > twins = new Dictionary <int, List <PedigreeIndividual> >(); foreach (PedigreeIndividual child in children) { if (child.HraPerson.twinID < 1) { minX = child.point.x < minX ? child.point.x : minX; maxX = child.point.x > maxX ? child.point.x : maxX; } else { if (twins.ContainsKey(child.HraPerson.twinID)) { twins[child.HraPerson.twinID].Add(child); } else { twins.Add(child.HraPerson.twinID, new List <PedigreeIndividual>()); twins[child.HraPerson.twinID].Add(child); } } } int midY = (int)(parents.mother.point.y + model.parameters.verticalSpacing / 2); g.DrawLine(pen, (int)minX, midY, (int)maxX, midY); // draw line from parents down int x = (int)((parents.father.point.x + parents.mother.point.x) / 2); int topY = (int)((parents.father.point.y + parents.mother.point.y) / 2); g.DrawLine(pen, x, topY, x, midY); // draw lines from children up foreach (PedigreeIndividual child in children) { if (child.HraPerson.twinID < 1) { if (child.HraPerson.motherID > 0 || child.HraPerson.fatherID > 0) { g.DrawLine(pen, (int)child.point.x, (int)child.point.y - model.parameters.individualSize / 2, (int)child.point.x, midY ); } } } foreach (List <PedigreeIndividual> twinKids in twins.Values) { double twinMin = double.MaxValue; double twinMax = double.MinValue; double twinCenter = 0; foreach (PedigreeIndividual t in twinKids) { twinCenter += t.point.x; if (t.point.x > twinMax) { twinMax = t.point.x; } if (t.point.x < twinMin) { twinMin = t.point.x; } } twinCenter /= twinKids.Count; foreach (PedigreeIndividual t in twinKids) { double x1 = t.point.x; double y1 = t.point.y - model.parameters.individualSize / 2; double x2 = twinCenter; double y2 = midY; g.DrawLine(pen, (int)x1, (int)y1, (int)x2, (int)y2); if (t.HraPerson.twinType == "Identical") { double alpha = Math.Atan((y2 - y1) / (x2 - x1)); double deltaY = (y2 - y1) / 2.0; double dx = deltaY * Math.Tan((Math.PI / 2) - alpha); //g.DrawLine(pen, (int)(t.point.x + dx), (int)(t.point.y + deltaY), (int)(twinCenter), (int)(t.point.y + deltaY)); g.DrawLine(pen, (int)(t.point.x + dx), (int)(y2 - deltaY), (int)(twinCenter), (int)(midY - deltaY)); } } g.DrawLine(pen, (int)(parents.father.point.x + parents.mother.point.x) / 2, midY, (int)twinCenter, midY); } } } else if (children.Count == 1) { if (parents.mother != null && parents.father != null) { double motherX = parents.mother.point.x; double motherY = parents.mother.point.y; double fatherX = parents.father.point.x; double fatherY = parents.father.point.y; double childX = children[0].point.x; double childY = children[0].point.y; double parentsSpan = motherX - fatherX; double p = parentsSpan == 0 ? 0.5 : (childX - fatherX) / parentsSpan; p = p > 1 ? 1 : p < 0 ? 0 : p; int topX = (int)((fatherX * (1 - p) + motherX * p)); int topY = (int)((fatherY * (1 - p) + motherY * p)); g.DrawLine(pen, topX, topY, (int)childX, (int)childY); } } } catch (Exception e) { Logger.Instance.WriteToLog(e.ToString()); } } }; }
public DrawAncestralConnectionLines(PedigreeModel model) { step = delegate(Graphics g) { //g.FillEllipse(Brushes.Plum, new Rectangle((int)(model.displayXMax / 2) - 50, (int)(model.displayYMax / 2) - 50, 100, 100)); //g.DrawRectangle(Pens.Black, new Rectangle(0, 0, (int)model.displayXMax, (int)model.displayYMax)); int halfIndividualSize = model.parameters.individualSize / 2; Pen pen = Pens.Black; //if (model.parameters.ControllerMode == PedigreeController.SELF_ORGANIZING) //{ // //pen = model.layoutIsValid ? Pens.Black : Pens.Red; // pen = model.couplesGraphIsPlanar ? Pens.Black : Pens.Red; //} foreach (PedigreeCouple parents in model.couples) { // draw line between parents if (parents.mother != null && parents.father != null) if (!model.parameters.hideNonBloodRelatives || (parents.father.bloodRelative && parents.mother.bloodRelative)) { if (parents.mother.HraPerson.consanguineousSpouseID == parents.father.HraPerson.relativeID) { g.DrawLine(pen, (int)parents.mother.point.x, (int)parents.mother.point.y + 2, (int)parents.father.point.x, (int)parents.father.point.y + 2 ); g.DrawLine(pen, (int)parents.mother.point.x, (int)parents.mother.point.y - 2, (int)parents.father.point.x, (int)parents.father.point.y - 2 ); } else { g.DrawLine(pen, (int)parents.mother.point.x, (int)parents.mother.point.y, (int)parents.father.point.x, (int)parents.father.point.y ); } } try { //draw lines to children List<PedigreeIndividual> children = new List<PedigreeIndividual>(); //= parents.children; foreach (PedigreeIndividual pi in parents.children) { if (!model.parameters.hideNonBloodRelatives || pi.bloodRelative) { children.Add(pi); } } if (children.Count > 1) { if (parents.mother != null && parents.father != null) { // draw horizontal line connecting parents with multiple children double minX = (parents.father.point.x + parents.mother.point.x) / 2; double maxX = minX; Dictionary<int, List<PedigreeIndividual>> twins = new Dictionary<int, List<PedigreeIndividual>>(); foreach (PedigreeIndividual child in children) { if (child.HraPerson.twinID < 1) { minX = child.point.x < minX ? child.point.x : minX; maxX = child.point.x > maxX ? child.point.x : maxX; } else { if (twins.ContainsKey(child.HraPerson.twinID)) { twins[child.HraPerson.twinID].Add(child); } else { twins.Add(child.HraPerson.twinID, new List<PedigreeIndividual>()); twins[child.HraPerson.twinID].Add(child); } } } int midY = (int)(parents.mother.point.y + model.parameters.verticalSpacing / 2); g.DrawLine(pen, (int)minX, midY, (int)maxX, midY); // draw line from parents down int x = (int)((parents.father.point.x + parents.mother.point.x) / 2); int topY = (int)((parents.father.point.y + parents.mother.point.y) / 2); g.DrawLine(pen, x, topY, x, midY); // draw lines from children up foreach (PedigreeIndividual child in children) { if (child.HraPerson.twinID < 1) { if (child.HraPerson.motherID > 0 || child.HraPerson.fatherID > 0) { g.DrawLine(pen, (int)child.point.x, (int)child.point.y - model.parameters.individualSize / 2, (int)child.point.x, midY ); } } } foreach (List<PedigreeIndividual> twinKids in twins.Values) { double twinMin = double.MaxValue; double twinMax = double.MinValue; double twinCenter = 0; foreach (PedigreeIndividual t in twinKids) { twinCenter += t.point.x; if (t.point.x > twinMax) twinMax = t.point.x; if (t.point.x < twinMin) twinMin = t.point.x; } twinCenter /= twinKids.Count; foreach (PedigreeIndividual t in twinKids) { double x1 = t.point.x; double y1 = t.point.y - model.parameters.individualSize / 2; double x2 = twinCenter; double y2 = midY; g.DrawLine(pen, (int)x1, (int)y1, (int)x2, (int)y2); if (t.HraPerson.twinType == "Identical") { double alpha = Math.Atan((y2 - y1) / (x2 - x1)); double deltaY = (y2 - y1) / 2.0; double dx = deltaY * Math.Tan((Math.PI / 2) - alpha); //g.DrawLine(pen, (int)(t.point.x + dx), (int)(t.point.y + deltaY), (int)(twinCenter), (int)(t.point.y + deltaY)); g.DrawLine(pen, (int)(t.point.x + dx), (int)(y2 - deltaY), (int)(twinCenter), (int)(midY - deltaY)); } } g.DrawLine(pen, (int)(parents.father.point.x + parents.mother.point.x) / 2, midY, (int)twinCenter, midY); } } } else if (children.Count == 1) { if (parents.mother != null && parents.father != null) { double motherX = parents.mother.point.x; double motherY = parents.mother.point.y; double fatherX = parents.father.point.x; double fatherY = parents.father.point.y; double childX = children[0].point.x; double childY = children[0].point.y; double parentsSpan = motherX - fatherX; double p = parentsSpan == 0 ? 0.5 : (childX - fatherX) / parentsSpan; p = p > 1 ? 1 : p < 0 ? 0 : p; int topX = (int)((fatherX * (1 - p) + motherX * p)); int topY = (int)((fatherY * (1 - p) + motherY * p)); g.DrawLine(pen, topX, topY, (int)childX, (int)childY); } } } catch (Exception e) { Logger.Instance.WriteToLog(e.ToString()); } } }; }