/// <summary> /// Draw an node using Microsoft Automatic Graph Layout. /// </summary> /// <param name="node">Node to draw.</param> /// <param name="graphics">Graphics context; we know it's a Graphics object from GViewer.</param> /// <returns>False, to invoke the default drawing as well.</returns> private bool ShadePlanNode(Msagl.Drawing.Node node, object graphics) { DryadJobStaticPlan.Stage stage = (DryadJobStaticPlan.Stage)node.UserData; DryadLinqJobStage jobStage = this.Job.GetStage(stage.Name); Graphics g = (Graphics)graphics; if (jobStage != null) { List<Tuple<double, Color>> colors; if (this.colorByStagestatusToolStripMenuItem.Checked) { colors = StageStatusAsColors(jobStage, this.HideCancelledVertices, stage.Replication).ToList(); } else { colors = new List<Tuple<double, Color>> { new Tuple<double, Color>(1, this.stageColorMap[jobStage.Name]) }; } if (colors.Count > 0) { using (System.Drawing.Drawing2D.Matrix m = g.Transform) { using (System.Drawing.Drawing2D.Matrix saveM = m.Clone()) { System.Drawing.Drawing2D.GraphicsPath boundary = CreateGraphicsPath(node.Attr.GeometryNode.BoundaryCurve); g.SetClip(boundary); using (var m2 = new System.Drawing.Drawing2D.Matrix(1, 0, 0, -1, 0, 2 * (float)node.Attr.GeometryNode.Center.Y)) m.Multiply(m2); g.Transform = m; float totalFraction = 0; double top = node.Attr.GeometryNode.Center.Y - node.Attr.GeometryNode.Height / 2; double left = node.Attr.GeometryNode.Center.X - node.Attr.GeometryNode.Width / 2; double width = node.Attr.Width; foreach (var colorInfo in colors) { float fraction = (float)colorInfo.Item1; Brush brush = new SolidBrush(colorInfo.Item2); RectangleF rect = new RectangleF( new PointF((float)(left + width * totalFraction), (float)(top)), new SizeF((float)(width * fraction), (float)node.Attr.Height)); totalFraction += fraction; g.FillRectangle(brush, rect); } g.ResetClip(); g.Transform = saveM; } } } } return false; // still invoke the default drawing. }
// this code is pilfered from MSAGL private static PointF PointF(Msagl.Point p) { return new PointF((float)p.X, (float)p.Y); }