private void DrawDendrogram(Graphics graphics, DendrogramFormat format) { var locations = format.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); var end = CoordinatesToPoint(line.Item3, (offset + line.Item4) / denominator); 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 = format.LeafLocations[iLeaf].Key; var right = format.LeafLocations[iLeaf].Value; var bottom = colorLevel * colorFraction / format.ColorLevelCount; var top = (colorLevel + 1) * colorFraction / format.ColorLevelCount; var topLeft = CoordinatesToPoint(left, top); var bottomRight = CoordinatesToPoint(right, bottom); 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); } } } }
private double GetFractionForColors(DendrogramFormat dendrogramFormat) { if (dendrogramFormat.Colors == null || dendrogramFormat.Colors.Count == 0) { return(0); } var totalSpace = GetTotalSpace(); var spaceForColors = Math.Max(totalSpace / 10, dendrogramFormat.ColorLevelCount * 5); if (spaceForColors >= totalSpace) { return(1); } return(spaceForColors / totalSpace); }