/// <summary> /// Initializes a new instance of the <see cref="UCFunnelChart"/> class. /// </summary> public UCFunnelChart() { this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.Selectable, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.SetStyle(ControlStyles.UserPaint, true); this.FontChanged += UCFunnelChart_FontChanged; Font = new Font("微软雅黑", 8); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; this.SizeChanged += UCFunnelChart_SizeChanged; Size = new System.Drawing.Size(150, 150); items = new FunelChartItem[0]; if (ControlHelper.IsDesignMode()) { items = new FunelChartItem[5]; for (int i = 0; i < 5; i++) { items[i] = new FunelChartItem() { Text = "item" + i, Value = 10 * (i + 1) }; } } }
/// <summary> /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。 /// </summary> /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); var g = e.Graphics; g.SetGDIHigh(); if (!string.IsNullOrEmpty(title)) { g.DrawString(title, titleFont, new SolidBrush(titleForeColor), new RectangleF(0, 0, this.Width, m_titleSize.Height), new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }); } if (items == null || items.Length <= 0) { g.DrawString("没有数据", Font, new SolidBrush(Color.Black), this.m_rectWorking, new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }); return; } List <FunelChartItem> lstItems; if (direction == FunelChartDirection.UP) { lstItems = items.OrderBy(p => p.Value).ToList(); } else { lstItems = items.OrderByDescending(p => p.Value).ToList(); } List <RectangleF> lstRects = new List <RectangleF>(); List <GraphicsPath> lstPaths = new List <GraphicsPath>(); float maxValue = lstItems.Max(p => p.Value); float dblSplitHeight = m_rectWorking.Height / lstItems.Count; for (int i = 0; i < lstItems.Count; i++) { FunelChartItem item = lstItems[i]; if (item.ValueColor == null || item.ValueColor == Color.Empty || item.ValueColor == Color.Transparent) { item.ValueColor = ControlHelper.Colors[i]; } switch (alignment) { case FunelChartAlignment.Left: lstRects.Add(new RectangleF(m_rectWorking.Left, m_rectWorking.Top + dblSplitHeight * i, item.Value / maxValue * m_rectWorking.Width, dblSplitHeight)); break; case FunelChartAlignment.Center: lstRects.Add(new RectangleF(m_rectWorking.Left + (m_rectWorking.Width - (item.Value / maxValue * m_rectWorking.Width)) / 2, m_rectWorking.Top + dblSplitHeight * i, item.Value / maxValue * m_rectWorking.Width, dblSplitHeight)); break; case FunelChartAlignment.Right: lstRects.Add(new RectangleF(m_rectWorking.Right - (item.Value / maxValue * m_rectWorking.Width), m_rectWorking.Top + dblSplitHeight * i, item.Value / maxValue * m_rectWorking.Width, dblSplitHeight)); break; } } for (int i = 0; i < lstRects.Count; i++) { var rect = lstRects[i]; GraphicsPath path = new GraphicsPath(); List <PointF> lstPoints = new List <PointF>(); if (direction == FunelChartDirection.UP) { switch (alignment) { case FunelChartAlignment.Left: lstPoints.Add(new PointF(rect.Left, rect.Top)); if (i != 0) { lstPoints.Add(new PointF(lstRects[i - 1].Right, rect.Top)); } break; case FunelChartAlignment.Center: if (i == 0) { lstPoints.Add(new PointF(rect.Left + rect.Width / 2, rect.Top)); } else { lstPoints.Add(new PointF(lstRects[i - 1].Left, rect.Top)); lstPoints.Add(new PointF(lstRects[i - 1].Right, rect.Top)); } break; case FunelChartAlignment.Right: if (i == 0) { lstPoints.Add(new PointF(rect.Right, rect.Top)); } else { lstPoints.Add(new PointF(rect.Right - lstRects[i - 1].Width, rect.Top)); lstPoints.Add(new PointF(rect.Right, rect.Top)); } break; } lstPoints.Add(new PointF(rect.Right, rect.Bottom - intSplitWidth)); lstPoints.Add(new PointF(rect.Left, rect.Bottom - intSplitWidth)); } else { lstPoints.Add(new PointF(rect.Left, rect.Top + intSplitWidth)); lstPoints.Add(new PointF(rect.Right, rect.Top + intSplitWidth)); switch (alignment) { case FunelChartAlignment.Left: if (i == lstRects.Count - 1) { lstPoints.Add(new PointF(rect.Left, rect.Bottom)); } else { lstPoints.Add(new PointF(lstRects[i + 1].Right, rect.Bottom)); lstPoints.Add(new PointF(rect.Left, rect.Bottom)); } break; case FunelChartAlignment.Center: if (i == lstRects.Count - 1) { lstPoints.Add(new PointF(rect.Left + rect.Width / 2, rect.Bottom)); } else { lstPoints.Add(new PointF(lstRects[i + 1].Right, rect.Bottom)); lstPoints.Add(new PointF(lstRects[i + 1].Left, rect.Bottom)); } break; case FunelChartAlignment.Right: if (i == lstRects.Count - 1) { lstPoints.Add(new PointF(rect.Right, rect.Bottom)); } else { lstPoints.Add(new PointF(rect.Right, rect.Bottom)); lstPoints.Add(new PointF(lstRects[i + 1].Left, rect.Bottom)); } break; } } path.AddLines(lstPoints.ToArray()); path.CloseAllFigures(); // g.DrawPath(new Pen(new SolidBrush(lstItems[i].ValueColor.Value)), path); g.FillPath(new SolidBrush(lstItems[i].ValueColor.Value), path); //写字 if (itemTextAlign == FunelChartAlignment.Center) { g.DrawString(lstItems[i].Text + (ShowValue ? lstItems[i].Value.ToString("\n" + valueFormat) : ""), Font, new SolidBrush((lstItems[i].TextForeColor == null || lstItems[i].TextForeColor == Color.Empty || lstItems[i].TextForeColor == Color.Transparent) ? Color.White : lstItems[i].TextForeColor.Value), rect, new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }); } else if (itemTextAlign == FunelChartAlignment.Left) { g.DrawString(lstItems[i].Text + (ShowValue ? lstItems[i].Value.ToString("\n" + valueFormat) : ""), Font, new SolidBrush((lstItems[i].TextForeColor == null || lstItems[i].TextForeColor == Color.Empty || lstItems[i].TextForeColor == Color.Transparent) ? lstItems[i].ValueColor.Value : lstItems[i].TextForeColor.Value), new RectangleF(0, rect.Top, rect.Left, rect.Height), new StringFormat() { Alignment = StringAlignment.Far, LineAlignment = StringAlignment.Center }); g.DrawLine(new Pen(new SolidBrush((lstItems[i].TextForeColor == null || lstItems[i].TextForeColor == Color.Empty || lstItems[i].TextForeColor == Color.Transparent) ? lstItems[i].ValueColor.Value : lstItems[i].TextForeColor.Value)), rect.Left, rect.Top + rect.Height / 2, rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); } else { g.DrawString(lstItems[i].Text + (ShowValue ? lstItems[i].Value.ToString("\n" + valueFormat) : ""), Font, new SolidBrush((lstItems[i].TextForeColor == null || lstItems[i].TextForeColor == Color.Empty || lstItems[i].TextForeColor == Color.Transparent) ? lstItems[i].ValueColor.Value : lstItems[i].TextForeColor.Value), new RectangleF(rect.Right, rect.Top, this.Width - rect.Right, rect.Height), new StringFormat() { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center }); g.DrawLine(new Pen(new SolidBrush((lstItems[i].TextForeColor == null || lstItems[i].TextForeColor == Color.Empty || lstItems[i].TextForeColor == Color.Transparent) ? lstItems[i].ValueColor.Value : lstItems[i].TextForeColor.Value)), rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, rect.Right, rect.Top + rect.Height / 2); } } }