入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
Install-Package HZH_Controls
https://www.cnblogs.com/bfyx/p/11364884.html
调用示例
1 this.ucBarChart1.SetDataSource(new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) });
2 this.ucBarChart2.SetDataSource(new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) }, new string[] { "张三", "李四", "王五", "赵六", "田七" });
3 this.ucBarChart3.SetDataSource(new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) }, new string[] { "张三", "李四", "王五", "赵六", "田七" });
4
5 this.ucBarChart4.SetDataSource(new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) }, new string[] { "张三", "李四", "王五", "赵六", "田七" });
6 this.ucBarChart4.AddAuxiliaryLine(60, Color.Red, "及格线超长占位符");
7
8 this.ucBarChart5.SetDataSource(new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) }, new string[] { "张三", "李四", "王五", "赵六", "田七" });
9 this.ucBarChart5.AddAuxiliaryLine(50, Color.Black, "及格线");
10
11
12 var ds = new double[5][];
13 for (int i = 0; i < ds.Length; i++)
14 {
15 ds[i] = new double[] { random.Next(50, 100), random.Next(50, 100), random.Next(50, 100) };
16 }
17 this.ucBarChart6.BarChartItems = new HZH_Controls.Controls.BarChartItem[] { new HZH_Controls.Controls.BarChartItem(Color.Red, "语文"), new HZH_Controls.Controls.BarChartItem(Color.Blue, "英语"), new HZH_Controls.Controls.BarChartItem(Color.Orange, "数学") };
18 this.ucBarChart6.SetDataSource(ds, new string[] { "张三", "李四", "王五", "赵六", "田七" });
19 this.ucBarChart6.AddAuxiliaryLine(60, Color.Black);
20
21 var ds2 = new List<double[]>();
22 for (int i = 0; i < 20; i++)
23 {
24 ds2.Add(new double[] { random.Next(800, 2000), random.Next(100, 200) });
25 }
26 var titles = new List<string>();
27 double dblSum = ds2.Sum(p=>p[0]);
28 for (int i = 0; i < ds2.Count; i++)
29 {
30 titles.Add("员工" + (i + 1) + "\n" + (ds2[i][0] / dblSum).ToString("0.0%"));
31 }
32 this.ucBarChart7.BarChartItems = new HZH_Controls.Controls.BarChartItem[] { new HZH_Controls.Controls.BarChartItem(Color.Green, "合格"), new HZH_Controls.Controls.BarChartItem(Color.Red, "次品") };
33 this.ucBarChart7.SetDataSource(ds2.ToArray(), titles.ToArray());
34 this.ucBarChart7.AddAuxiliaryLine(1000, Color.Black, "标准线");
GDI画图,不懂可以先百度一下
另外用到了(一)c#Winform自定义控件-基类控件 不知道的可以先前往看一下
我们先理一下思路,
我们需要值,x轴,y轴,辅助线,项列表,标题,以及一些颜色等
添加一个类UCBarChart ,继承UCControlBase
添加一些控制属性
1 /// <summary>
2 /// The auxiliary lines
3 /// </summary>
4 private List<AuxiliaryLine> auxiliary_lines;
5
6 /// <summary>
7 /// The value maximum left
8 /// </summary>
9 private int value_max_left = -1;
10
11 /// <summary>
12 /// The value minimum left
13 /// </summary>
14 private int value_min_left = 0;
15
16 /// <summary>
17 /// The value segment
18 /// </summary>
19 private int value_Segment = 5;
20
21 /// <summary>
22 /// The data values
23 /// </summary>
24 private double[][] data_values = null;
25
26 /// <summary>
27 /// The data texts
28 /// </summary>
29 private string[] data_texts = null;
30
31 ///// <summary>
32 ///// The data colors
33 ///// </summary>
34 //private Color[] data_colors = null;
35
36 /// <summary>
37 /// The brush deep
38 /// </summary>
39 private Brush brush_deep = null;
40
41 /// <summary>
42 /// The pen normal
43 /// </summary>
44 private Pen pen_normal = null;
45
46 /// <summary>
47 /// The pen dash
48 /// </summary>
49 private Pen pen_dash = null;
50
51 /// <summary>
52 /// The bar back color
53 /// </summary>
54 //private Color barBackColor = Color.FromArgb(255, 77, 59);
55
56 /// <summary>
57 /// The use gradient
58 /// </summary>
59 private bool useGradient = false;
60
61 /// <summary>
62 /// The color deep
63 /// </summary>
64 private Color color_deep = Color.FromArgb(150, 255, 77, 59);
65
66 /// <summary>
67 /// The color dash
68 /// </summary>
69 private Color color_dash = Color.FromArgb(50, 255, 77, 59);
70
71 /// <summary>
72 /// The format left
73 /// </summary>
74 private StringFormat format_left = null;
75
76 /// <summary>
77 /// The format right
78 /// </summary>
79 private StringFormat format_right = null;
80
81 /// <summary>
82 /// The format center
83 /// </summary>
84 private StringFormat format_center = null;
85
86 /// <summary>
87 /// The value is render dash line
88 /// </summary>
89 private bool value_IsRenderDashLine = true;
90
91 /// <summary>
92 /// The is show bar value
93 /// </summary>
94 private bool isShowBarValue = true;
95
96 /// <summary>
97 /// The show bar value format
98 /// </summary>
99 private string showBarValueFormat = "{0}";
100
101 /// <summary>
102 /// The value title
103 /// </summary>
104 private string value_title = "";
105
106 /// <summary>
107 /// The bar percent width
108 /// </summary>
109 private float barPercentWidth = 0.9f;
110
111 /// <summary>
112 /// The components
113 /// </summary>
114 private IContainer components = null;
115
116 /// <summary>
117 /// 获取或设置控件的背景色。
118 /// </summary>
119 /// <value>The color of the back.</value>
120 /// <PermissionSet>
121 /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
122 /// </PermissionSet>
123 [Browsable(true)]
124 [Description("获取或设置控件的背景色")]
125 [Category("自定义")]
126 [DefaultValue(typeof(Color), "Transparent")]
127 [EditorBrowsable(EditorBrowsableState.Always)]
128 public override Color BackColor
129 {
130 get
131 {
132 return base.BackColor;
133 }
134 set
135 {
136 base.BackColor = value;
137 }
138 }
139
140 /// <summary>
141 /// Gets or sets the text.
142 /// </summary>
143 /// <value>The text.</value>
144 [Browsable(true)]
145 [Description("获取或设置当前控件的文本")]
146 [Category("自定义")]
147 [EditorBrowsable(EditorBrowsableState.Always)]
148 [Bindable(true)]
149 [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
150 public override string Text
151 {
152 get
153 {
154 return base.Text;
155 }
156 set
157 {
158 base.Text = value;
159 Invalidate();
160 }
161 }
162
163 /// <summary>
164 /// 获取或设置控件的前景色。
165 /// </summary>
166 /// <value>The color of the fore.</value>
167 /// <PermissionSet>
168 /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
169 /// </PermissionSet>
170 [Browsable(true)]
171 [Description("获取或设置控件的前景色")]
172 [Category("自定义")]
173 [EditorBrowsable(EditorBrowsableState.Always)]
174 public override Color ForeColor
175 {
176 get
177 {
178 return base.ForeColor;
179 }
180 set
181 {
182 base.ForeColor = value;
183 }
184 }
185
186 /// <summary>
187 /// Gets or sets the color lines and text.
188 /// </summary>
189 /// <value>The color lines and text.</value>
190 [Category("自定义")]
191 [Description("获取或设置坐标轴及相关信息文本的颜色")]
192 [Browsable(true)]
193 [DefaultValue(typeof(Color), "DimGray")]
194 public Color ColorLinesAndText
195 {
196 get
197 {
198 return color_deep;
199 }
200 set
201 {
202 color_deep = value;
203 InitializationColor();
204 Invalidate();
205 }
206 }
207
208 /// <summary>
209 /// Gets or sets a value indicating whether [use gradient].
210 /// </summary>
211 /// <value><c>true</c> if [use gradient]; otherwise, <c>false</c>.</value>
212 [Category("自定义")]
213 [Description("获取或设置本条形图控件是否使用渐进色")]
214 [Browsable(true)]
215 [DefaultValue(false)]
216 public bool UseGradient
217 {
218 get
219 {
220 return useGradient;
221 }
222 set
223 {
224 useGradient = value;
225 Invalidate();
226 }
227 }
228
229 /// <summary>
230 /// Gets or sets the color dash lines.
231 /// </summary>
232 /// <value>The color dash lines.</value>
233 [Category("自定义")]
234 [Description("获取或设置虚线的颜色")]
235 [Browsable(true)]
236 [DefaultValue(typeof(Color), "LightGray")]
237 public Color ColorDashLines
238 {
239 get
240 {
241 return color_dash;
242 }
243 set
244 {
245 color_dash = value;
246 if (pen_dash != null)
247 pen_dash.Dispose();
248 pen_dash = new Pen(color_dash);
249 Invalidate();
250 }
251 }
252
253 /// <summary>
254 /// Gets or sets a value indicating whether this instance is render dash line.
255 /// </summary>
256 /// <value><c>true</c> if this instance is render dash line; otherwise, <c>false</c>.</value>
257 [Category("自定义")]
258 [Description("获取或设置虚线是否进行显示")]
259 [Browsable(true)]
260 [DefaultValue(true)]
261 public bool IsRenderDashLine
262 {
263 get
264 {
265 return value_IsRenderDashLine;
266 }
267 set
268 {
269 value_IsRenderDashLine = value;
270 Invalidate();
271 }
272 }
273
274 /// <summary>
275 /// Gets or sets the value segment.
276 /// </summary>
277 /// <value>The value segment.</value>
278 [Category("自定义")]
279 [Description("获取或设置图形的纵轴分段数")]
280 [Browsable(true)]
281 [DefaultValue(5)]
282 public int ValueSegment
283 {
284 get
285 {
286 return value_Segment;
287 }
288 set
289 {
290 value_Segment = value;
291 Invalidate();
292 }
293 }
294
295 /// <summary>
296 /// Gets or sets the value maximum left.
297 /// </summary>
298 /// <value>The value maximum left.</value>
299 [Category("自定义")]
300 [Description("获取或设置图形的左纵坐标的最大值,该值必须大于最小值,该值为负数,最大值即为自动适配。")]
301 [Browsable(true)]
302 [DefaultValue(-1)]
303 public int ValueMaxLeft
304 {
305 get
306 {
307 return value_max_left;
308 }
309 set
310 {
311 value_max_left = value;
312 Invalidate();
313 }
314 }
315
316 /// <summary>
317 /// Gets or sets the value minimum left.
318 /// </summary>
319 /// <value>The value minimum left.</value>
320 [Category("自定义")]
321 [Description("获取或设置图形的左纵坐标的最小值,该值必须小于最大值")]
322 [Browsable(true)]
323 [DefaultValue(0)]
324 public int ValueMinLeft
325 {
326 get
327 {
328 return value_min_left;
329 }
330 set
331 {
332 if (value < value_max_left)
333 {
334 value_min_left = value;
335 Invalidate();
336 }
337 }
338 }
339
340 /// <summary>
341 /// Gets or sets the title.
342 /// </summary>
343 /// <value>The title.</value>
344 [Category("自定义")]
345 [Description("获取或设置图标的标题信息")]
346 [Browsable(true)]
347 [DefaultValue("")]
348 public string Title
349 {
350 get
351 {
352 return value_title;
353 }
354 set
355 {
356 value_title = value;
357 Invalidate();
358 }
359 }
360
361 /// <summary>
362 /// Gets or sets a value indicating whether this instance is show bar value.
363 /// </summary>
364 /// <value><c>true</c> if this instance is show bar value; otherwise, <c>false</c>.</value>
365 [Category("自定义")]
366 [Description("获取或设置是否显示柱状图的值文本")]
367 [Browsable(true)]
368 [DefaultValue(true)]
369 public bool IsShowBarValue
370 {
371 get
372 {
373 return isShowBarValue;
374 }
375 set
376 {
377 isShowBarValue = value;
378 Invalidate();
379 }
380 }
381
382 /// <summary>
383 /// Gets or sets the show bar value format.
384 /// </summary>
385 /// <value>The show bar value format.</value>
386 [Category("自定义")]
387 [Description("获取或设置柱状图显示值的格式化信息,可以带单位")]
388 [Browsable(true)]
389 [DefaultValue("")]
390 public string ShowBarValueFormat
391 {
392 get
393 {
394 return showBarValueFormat;
395 }
396 set
397 {
398 showBarValueFormat = value;
399 Invalidate();
400 }
401 }
402
403 private BarChartItem[] barChartItems = new BarChartItem[] { new BarChartItem() };
404 [Category("自定义")]
405 [Description("获取或设置柱状图的项目")]
406 [Browsable(true)]
407 public BarChartItem[] BarChartItems
408 {
409 get { return barChartItems; }
410 set { barChartItems = value; }
411 }
412 [Category("自定义")]
413 [Description("获取或设置是否显示柱状图的项目名称")]
414 [Browsable(true)]
415 public bool ShowChartItemName { get; set; }
做一些初始化数据
1 public UCBarChart()
2 {
3 InitializeComponent();
4 ConerRadius = 10;
5 ForeColor = Color.FromArgb(150, 255, 77, 59);
6 FillColor = Color.FromArgb(243, 220, 219);
7 format_left = new StringFormat
8 {
9 LineAlignment = StringAlignment.Center,
10 Alignment = StringAlignment.Near
11 };
12 format_right = new StringFormat
13 {
14 LineAlignment = StringAlignment.Center,
15 Alignment = StringAlignment.Far
16 };
17 format_center = new StringFormat
18 {
19 LineAlignment = StringAlignment.Center,
20 Alignment = StringAlignment.Center
21 };
22 auxiliary_lines = new List<AuxiliaryLine>();
23 pen_dash = new Pen(color_dash);
24 pen_dash.DashStyle = DashStyle.Custom;
25 pen_dash.DashPattern = new float[2]
26 {
27 5f,
28 5f
29 };
30 InitializationColor();
31 SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
32 SetStyle(ControlStyles.ResizeRedraw, true);
33 SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
34 SetStyle(ControlStyles.AllPaintingInWmPaint, true);
35
36 if (DesignMode)
37 {
38 barChartItems = new BarChartItem[] { new BarChartItem() };
39
40 data_values = new double[5][];
41 for (int i = 0; i < data_values.Length; i++)
42 {
43 data_values[i] = new double[] { i + 1 };
44 }
45 }
46
47 }
设置数据源的函数
1 /// <summary>
2 /// Sets the data source.
3 /// </summary>
4 /// <param name="data">The data.</param>
5 public void SetDataSource(double[] data)
6 {
7 SetDataSource(data, null);
8 }
9
10 public void SetDataSource(double[][] data)
11 {
12 SetDataSource(data, null);
13 }
14 /// <summary>
15 /// Sets the data source.
16 /// </summary>
17 /// <param name="data">The data.</param>
18 /// <param name="texts">X texts</param>
19 public void SetDataSource(double[] data, string[] texts)
20 {
21 data_values = new double[data.Length][];
22 for (int i = 0; i < data.Length; i++)
23 {
24 data_values[i] = new double[] { data[i] };
25 }
26 if (barChartItems == null || barChartItems.Length <= 0)
27 barChartItems = new BarChartItem[] { new BarChartItem() };
28 data_texts = texts;
29 Invalidate();
30 }
31 public void SetDataSource(double[][] data, string[] texts)
32 {
33 data_values = data;
34 if (barChartItems == null || barChartItems.Length <= 0)
35 barChartItems = new BarChartItem[] { new BarChartItem() };
36 data_texts = texts;
37 Invalidate();
38 }
重绘
1 protected override void OnPaint(PaintEventArgs e)
2 {
3 base.OnPaint(e);
4 Graphics graphics = e.Graphics;
5 graphics.SmoothingMode = SmoothingMode.HighQuality;
6 graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
7 PaintMain(graphics, base.Width, base.Height);
8 }
9
10 /// <summary>
11 /// Paints the main.
12 /// </summary>
13 /// <param name="g">The g.</param>
14 /// <param name="width">The width.</param>
15 /// <param name="height">The height.</param>
16 private void PaintMain(Graphics g, int width, int height)
17 {
18 if (barChartItems == null || barChartItems.Length <= 0)
19 {
20 if (DesignMode)
21 {
22 barChartItems = new BarChartItem[] { new BarChartItem() };
23 }
24 else
25 {
26 return;
27 }
28 }
29 if (data_values == null && DesignMode)
30 {
31 data_values = new double[5][];
32 for (int i = 0; i < data_values.Length; i++)
33 {
34 data_values[i] = new double[] { i + 1 };
35 }
36 }
37
38 double num = (data_values != null && data_values.Length != 0) ? ChartsHelper.CalculateMaxSectionFrom(data_values) : 5;
39 if (value_max_left > 0)
40 {
41 num = value_max_left;
42 }
43 int intLeftX = (int)g.MeasureString(num.ToString(), Font).Width + 3;
44 if (intLeftX < 50)
45 {
46 intLeftX = 50;
47 }
48 //处理辅助线左侧间距
49 if (auxiliary_lines != null && auxiliary_lines.Count > 0)
50 {
51 var maxAuxiliaryWidth = auxiliary_lines.Max(p => g.MeasureString((p.Tip + "" + p.Value), Font).Width);
52 if (intLeftX < maxAuxiliaryWidth)
53 {
54 intLeftX = (int)maxAuxiliaryWidth + 5;
55 }
56 }
57 int intRightX = 20;
58 //顶部距离
59 int intTopY = 25;
60 if (!string.IsNullOrEmpty(value_title))
61 {
62 intTopY += 20;
63 }
64 //写标题
65 if (!string.IsNullOrEmpty(value_title))
66 {
67 g.DrawString(value_title, Font, brush_deep, new Rectangle(0, 0, width - 1, intTopY - 10), format_center);
68 }
69 //画项目名称颜色
70 if (ShowChartItemName && !(barChartItems.Length == 1 && string.IsNullOrEmpty(barChartItems[0].ItemName)))
71 {
72 int intItemNameRowCount = 0;
73 int intItemNameWidth = 0;
74 int intItemNameComCount = 0;
75
76 intItemNameWidth = (int)barChartItems.Max(p => g.MeasureString(p.ItemName, Font).Width) + 40;
77 intItemNameComCount = this.Width / intItemNameWidth;
78 intItemNameRowCount = barChartItems.Length / intItemNameComCount + (barChartItems.Length % intItemNameComCount != 0 ? 1 : 0);
79 int intItemNameHeight = (int)g.MeasureString("A", Font).Height;
80
81 for (int i = 0; i < intItemNameRowCount; i++)
82 {
83 int intLeft = (this.Width - (intItemNameWidth * ((i == intItemNameRowCount - 1) ? (barChartItems.Length % intItemNameComCount) : intItemNameComCount))) / 2;
84 int intTop = intTopY - 15 + intItemNameHeight * i + 10;
85 for (int j = i * intItemNameComCount; j < barChartItems.Length && j < (i + 1) * intItemNameComCount; j++)
86 {
87 Rectangle rectColor = new Rectangle(intLeft + (j % intItemNameComCount) * intItemNameWidth, intTop, 20, intItemNameHeight);
88 g.FillRectangle(new SolidBrush(barChartItems[j].BarBackColor), rectColor);
89 g.DrawString(barChartItems[j].ItemName, Font, new SolidBrush(ForeColor), new Point(rectColor.Right + 2, rectColor.Top));
90 }
91 }
92 intTopY += intItemNameRowCount * (intItemNameHeight + 20);
93 }
94
95 int intBottomY = 25;
96 //处理x坐标文字高度
97 if (data_texts != null && data_texts.Length > 0)
98 {
99 var maxTextsHeight = data_texts.Max(p => g.MeasureString(p, Font).Height);
100 if (intBottomY < maxTextsHeight)
101 intBottomY = (int)maxTextsHeight + 5;
102 }
103 //画xy轴
104 Point[] array2 = new Point[3]
105 {
106 new Point(intLeftX, intTopY - 8),
107 new Point(intLeftX, height - intBottomY),
108 new Point(width - intRightX+5, height - intBottomY)
109 };
110 g.DrawLine(pen_normal, array2[0], array2[1]);
111 g.DrawLine(pen_normal, array2[1], array2[2]);
112 ChartsHelper.PaintTriangle(g, brush_deep, new Point(intLeftX, intTopY - 8), 4, GraphDirection.Upward);
113 ChartsHelper.PaintTriangle(g, brush_deep, new Point(width - intRightX + 5, height - intBottomY), 4, GraphDirection.Rightward);
114
115
116 //画横向分割线
117 for (int j = 0; j <= value_Segment; j++)
118 {
119 float value = (float)((double)j * (double)(num - value_min_left) / (double)value_Segment + (double)value_min_left);
120 float num6 = ChartsHelper.ComputePaintLocationY((float)num, value_min_left, height - intTopY - intBottomY, value) + (float)intTopY;
121 if (IsNeedPaintDash(num6))
122 {
123 g.DrawLine(pen_normal, intLeftX - 4, num6, intLeftX - 1, num6);
124 g.DrawString(layoutRectangle: new RectangleF(0f, num6 - 19f, intLeftX - 4, 40f), s: value.ToString(), font: Font, brush: brush_deep, format: format_right);
125 if (j > 0 && value_IsRenderDashLine)
126 {
127 g.DrawLine(pen_dash, intLeftX, num6, width - intRightX, num6);
128 }
129 }
130 }
131 //计算辅助线y坐标
132 for (int i = 0; i < auxiliary_lines.Count; i++)
133 {
134 auxiliary_lines[i].PaintValue = ChartsHelper.ComputePaintLocationY((float)num, value_min_left, height - intTopY - intBottomY, auxiliary_lines[i].Value) + (float)intTopY;
135 }
136
137 //画辅助线
138 for (int k = 0; k < auxiliary_lines.Count; k++)
139 {
140 g.DrawLine(auxiliary_lines[k].GetPen(), intLeftX - 4, auxiliary_lines[k].PaintValue, intLeftX - 1, auxiliary_lines[k].PaintValue);
141 g.DrawString(layoutRectangle: new RectangleF(0f, auxiliary_lines[k].PaintValue - 9f, intLeftX - 4, 20f), s: auxiliary_lines[k].Tip + "" + auxiliary_lines[k].Value.ToString(), font: Font, brush: auxiliary_lines[k].LineTextBrush, format: format_right);
142 g.DrawLine(auxiliary_lines[k].GetPen(), intLeftX, auxiliary_lines[k].PaintValue, width - intRightX, auxiliary_lines[k].PaintValue);
143 }
144 if (data_values == null || data_values.Length == 0 || data_values.Max(p => p.Length) <= 0)
145 {
146 return;
147 }
148
149 //x轴分隔宽度
150 float fltSplitWidth = (float)(width - intLeftX - 1 - intRightX) * 1f / (float)data_values.Length;
151 for (int i = 0; i < data_values.Length; i++)
152 {
153 int intItemSplitCount = barChartItems.Length;
154 float _fltSplitWidth = fltSplitWidth * barPercentWidth / intItemSplitCount;
155 float _fltLeft = (float)i * fltSplitWidth + (1f - barPercentWidth) / 2f * fltSplitWidth + (float)intLeftX;
156 for (int j = 0; j < data_values[i].Length; j++)
157 {
158 if (j >= intItemSplitCount)
159 {
160 break;
161 }
162 float fltValueY = ChartsHelper.ComputePaintLocationY((float)num, value_min_left, height - intTopY - intBottomY, (float)data_values[i][j]) + (float)intTopY;
163
164
165 RectangleF rect = new RectangleF(_fltLeft + _fltSplitWidth * j + (1F - barChartItems[j].BarPercentWidth) * _fltSplitWidth / 2f, fltValueY,
166 _fltSplitWidth * barChartItems[j].BarPercentWidth, (float)(height - intBottomY) - fltValueY);
167
168 Color color = barChartItems[j].BarBackColor;
169
170 //画柱状
171 if (useGradient)
172 {
173 if (rect.Height > 0f)
174 {
175 using (LinearGradientBrush brush = new LinearGradientBrush(new PointF(rect.X, rect.Y + rect.Height), new PointF(rect.X, rect.Y), ChartsHelper.GetColorLight(color), color))
176 {
177 g.FillRectangle(brush, rect);
178 }
179 }
180 }
181 else
182 {
183 using (Brush brush2 = new SolidBrush(color))
184 {
185 g.FillRectangle(brush2, rect);
186 }
187 }
188 //写值文字
189 if (isShowBarValue)
190 {
191 using (Brush brush3 = new SolidBrush(ForeColor))
192 {
193 g.DrawString(layoutRectangle: new RectangleF(rect.Left - 50f, fltValueY - (float)Font.Height - 2f, _fltSplitWidth + 100f, Font.Height + 2), s: string.Format(showBarValueFormat, data_values[i][j]), font: Font, brush: brush3, format: format_center);
194 }
195 }
196 }
197
198 //写x轴文字
199 if (data_texts != null && i < data_texts.Length)
200 {
201 g.DrawString(layoutRectangle: new RectangleF((float)i * fltSplitWidth + (float)intLeftX - 50f, height - intBottomY - 1, fltSplitWidth + 100f, intBottomY + 1), s: data_texts[i], font: Font, brush: brush_deep, format: format_center);
202 }
203 }
204 }
辅助线相关函数
1 #region 辅助线 English:Guide
2 /// <summary>
3 /// Adds the left auxiliary.
4 /// </summary>
5 /// <param name="value">The value.</param>
6 public void AddAuxiliaryLine(float value, string strTip = "")
7 {
8 AddAuxiliaryLine(value, ColorLinesAndText, strTip);
9 }
10
11 /// <summary>
12 /// Adds the left auxiliary.
13 /// </summary>
14 /// <param name="value">The value.</param>
15 /// <param name="lineColor">Color of the line.</param>
16 public void AddAuxiliaryLine(float value, Color lineColor, string strTip = "")
17 {
18 AddAuxiliaryLine(value, lineColor, 1f, true, strTip);
19 }
20
21 /// <summary>
22 /// Adds the left auxiliary.
23 /// </summary>
24 /// <param name="value">The value.</param>
25 /// <param name="lineColor">Color of the line.</param>
26 /// <param name="lineThickness">The line thickness.</param>
27 /// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
28 public void AddAuxiliaryLine(float value, Color lineColor, float lineThickness, bool isDashLine, string strTip = "")
29 {
30 AddAuxiliary(value, lineColor, lineThickness, isDashLine, strTip);
31 }
32
33 /// <summary>
34 /// Adds the auxiliary.
35 /// </summary>
36 /// <param name="value">The value.</param>
37 /// <param name="lineColor">Color of the line.</param>
38 /// <param name="lineThickness">The line thickness.</param>
39 /// <param name="isDashLine">if set to <c>true</c> [is dash line].</param>
40 /// <param name="isLeft">if set to <c>true</c> [is left].</param>
41 private void AddAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine, string strTip = "")
42 {
43 auxiliary_lines.Add(new AuxiliaryLine
44 {
45 Value = value,
46 LineColor = lineColor,
47 PenDash = new Pen(lineColor)
48 {
49 DashStyle = DashStyle.Custom,
50 DashPattern = new float[2]
51 {
52 5f,
53 5f
54 }
55 },
56 PenSolid = new Pen(lineColor),
57 IsDashStyle = isDashLine,
58 LineThickness = lineThickness,
59 LineTextBrush = new SolidBrush(lineColor),
60 Tip = strTip
61 });
62 Invalidate();
63 }
64
65 /// <summary>
66 /// Removes the auxiliary.
67 /// </summary>
68 /// <param name="value">The value.</param>
69 public void RemoveAuxiliary(float value)
70 {
71 int num = 0;
72 for (int num2 = auxiliary_lines.Count - 1; num2 >= 0; num2--)
73 {
74 if (auxiliary_lines[num2].Value == value)
75 {
76 auxiliary_lines[num2].Dispose();
77 auxiliary_lines.RemoveAt(num2);
78 num++;
79 }
80 }
81 if (num > 0)
82 {
83 Invalidate();
84 }
85 }
86
87 /// <summary>
88 /// Removes all auxiliary.
89 /// </summary>
90 public void RemoveAllAuxiliary()
91 {
92 int count = auxiliary_lines.Count;
93 auxiliary_lines.Clear();
94 if (count > 0)
95 {
96 Invalidate();
97 }
98 }
99 #endregion
完整代码,请前往开源地址查看吧。