public override void Draw(Graphics graphics, GraphPane pane, float scaleFactor, float shiftPos) { if (_formats == null) { return; } // Scale the coordinates of the DendrogramFormat using the Axis on the other side of the GraphPane Scale transformScale; if (_dendrogramLocation == DockStyle.Right) { transformScale = pane.YAxis.Scale; Height = pane.CalcChartRect(graphics).Height; Width = 100; } else { transformScale = pane.XAxis.Scale; Width = pane.CalcChartRect(graphics).Width; Height = 100; } var yAxisWidth = pane.YAxis.CalcSpace(graphics, pane, scaleFactor, out float _); var xAxisHeight = pane.XAxis.CalcSpace(graphics, pane, scaleFactor, out float _); foreach (var format in _formats) { var leafLocations = format.LeafLocations.Select(kvp => new KeyValuePair <double, double>( transformScale.Transform(kvp.Key), transformScale.Transform(kvp.Value))).ToList(); var locations = leafLocations.Select(kvp => (kvp.Key + kvp.Value) / 2).ToList(); var lines = format.Data.GetLines(locations, _rectilinearLines).ToList(); var pen = new Pen(Color.Black, 1); var maxHeight = lines.Max(line => line.Item4); if (maxHeight == 0) { // TODO: Draw a degenerate tree where all nodes connect at the same point return; } var colorFraction = GetFractionForColors(format); var treeFraction = 1 - colorFraction; if (treeFraction > 0) { var denominator = maxHeight / treeFraction; var offset = denominator - maxHeight; foreach (var line in lines) { var start = CoordinatesToPoint(line.Item1, (offset + line.Item2) / denominator, pane, xAxisHeight, yAxisWidth); var end = CoordinatesToPoint(line.Item3, (offset + line.Item4) / denominator, pane, xAxisHeight, yAxisWidth); DrawLine(graphics, pen, start, end); } } if (colorFraction > 0) { for (int colorLevel = 0; colorLevel < format.ColorLevelCount; colorLevel++) { for (int iLeaf = 0; iLeaf < format.Colors.Count; iLeaf++) { var color = format.Colors[iLeaf][colorLevel]; var left = leafLocations[iLeaf].Key; var right = leafLocations[iLeaf].Value; var bottom = colorLevel * colorFraction / format.ColorLevelCount; var top = (colorLevel + 1) * colorFraction / format.ColorLevelCount; var topLeft = CoordinatesToPoint(left, top, pane, xAxisHeight, yAxisWidth); var bottomRight = CoordinatesToPoint(right, bottom, pane, xAxisHeight, yAxisWidth); var rectangle = new RectangleF( Math.Min(topLeft.X, bottomRight.X), Math.Min(topLeft.Y, bottomRight.Y), Math.Abs(topLeft.X - bottomRight.X), Math.Abs(topLeft.Y - bottomRight.Y)); graphics.FillRectangle(new SolidBrush(color), rectangle); } } } var x2AxisHeight = pane.X2Axis.CalcSpace(graphics, pane, scaleFactor, out float _); var y2AxisWidth = pane.Y2Axis.CalcSpace(graphics, pane, scaleFactor, out float _); if (_dendrogramLocation == DockStyle.Top) { var leftRectangle = new RectangleF( pane.Rect.Width - yAxisWidth - y2AxisWidth, 0, yAxisWidth * (float)1.1, x2AxisHeight); graphics.FillRectangle(new SolidBrush(Color.White), leftRectangle); var cornerRectangle = new RectangleF( -y2AxisWidth, 0, y2AxisWidth, x2AxisHeight); graphics.FillRectangle(new SolidBrush(Color.White), cornerRectangle); } if (_dendrogramLocation == DockStyle.Right) { var cornerRectangle = new RectangleF( pane.Rect.Height - xAxisHeight - x2AxisHeight, 0, x2AxisHeight * (float)1.2, y2AxisWidth); graphics.FillRectangle(new SolidBrush(Color.White), cornerRectangle); var bottomRectangle = new RectangleF( -xAxisHeight, 0, xAxisHeight, y2AxisWidth); graphics.FillRectangle(new SolidBrush(Color.White), bottomRectangle); } } }