01.using
System;
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Text;
05.//
06.using System.Drawing;
07.//
08.namespace DatePrint
09.{
10. /// <summary>
11. /// 根据统计数据,输出各种统计统计图形,包括饼状图、曲线分析图、柱形图、多组数据曲线分析图;
12. /// 统计图形统一大小:600*420;
13. /// 开发人员:###;
14. /// 开发时间:###;
15. /// </summary>
16. public class CountImage
17. {
18. #region // 颜色,画框,
19. /// <summary>
20. /// 生成随机颜色
21. /// </summary>
22. /// <returns></returns>
23. private static Color GetRandomColor(int seed)
24. {
25. Random random = new Random(seed);
26. int r = 0;
27. int g = 0;
28. int b = 0;
29. r = random.Next(0, 230);
30. g = random.Next(0, 230);
31. b = random.Next(0, 235);
32. Color randomcolor = Color.FromArgb(r, g, b);
33. return randomcolor;
34. }
35. /// <summary>
36. /// 绘制区域框,框何其阴影
37. /// </summary>
38. /// <param name="image">图形</param>
39. /// <param name="rect">矩形框对象</param>
40. /// <returns>图形</returns>
41. private static Bitmap DrawRectangle(Bitmap image,Rectangle rect)
42. {
43. Bitmap Image=image;
44. Graphics g = Graphics.FromImage(Image);
45. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
46. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
47. try
48. {
49. Rectangle rn = new Rectangle(rect.X + 3, rect.Y + 3, rect.Width, rect.Height);
50. SolidBrush brush1 = new SolidBrush(Color.FromArgb(233, 234, 249));
51. SolidBrush brush2 = new SolidBrush(Color.FromArgb(221, 213, 215));
52. //
53. g.FillRectangle(brush2, rn);
54. g.FillRectangle(brush1, rect);
55. return Image;
56. }
57. finally
58. {
59. g.Dispose();
60. }
61. }
62. #endregion
63. #region //绘制图例框,绘制扇形
64. /// <summary>
65. /// 绘制图例信息
66. /// </summary>
67. /// <param name="image">图像</param>
68. /// <param name="rect">第一个矩形框</param>
69. /// <param name="c">颜色</param>
70. /// <param name="DesStr">图例说明文字</param>
71. /// <param name="f">文字样式</param>
72. /// <param name="i">图例说明序号</param>
73. /// <returns>图形</returns>
74. private static Bitmap DrawDes(Bitmap image, Rectangle rect,Color c,string DesStr,Font f,int i)
75. {
76. Bitmap Image = image;
77. Graphics g = Graphics.FromImage(Image);
78. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
79. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
80. try
81. {
82. SolidBrush brush = new SolidBrush(c);
83. //
84. Rectangle R = new Rectangle(rect.X, rect.Y + 18 * i, rect.Width, rect.Height);
85. Point p = new Point(rect.X + 12, rect.Y + 18 * i);
86. //?颜色矩形框
87. g.FillRectangle(brush,R);
88. //文字说明
89. g.DrawString(DesStr, f, new SolidBrush(Color.Black), p);
90. return Image;
91. }
92. finally
93. {
94. g.Dispose();
95. }
96. }
97. //绘制扇形
98. private static Bitmap DrawPie(Bitmap image, Rectangle rect, Color c, int Angle1, int Angle2)
99. {
100. Bitmap Image = image;
101. Graphics g = Graphics.FromImage(Image);
102. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
103. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
104. try
105. {
106. SolidBrush brush = new SolidBrush(c);
107. //
108. Rectangle R = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
109. g.FillPie(brush, R, Angle1, Angle2); //Angle1:第一条射线沿X轴顺时针旋转的夹角 Angle2:第二条射线与X轴顺时针旋转的夹角
110. return Image;
111. }
112. finally
113. {
114. g.Dispose();
115. }
116. }
117. #endregion
118. #region//绘制基本图形
119. /// <summary>
120. /// 生成图片,统一设置图片大小、背景色,图片布局,及标题
121. /// </summary>
122. /// <returns>图片</returns>
123. private static Bitmap GenerateImage(string Title)
124. {
125. //图片大小:宽度、高度
126. int width = 600;
127. int height = 420;
128. //标题
129. Point PTitle=new Point(30,20);
130. Font f1 = new Font("宋体", 10, FontStyle.Bold);
131. //线
132. Point PLine1=new Point(20,40);
133. Point PLine2=new Point(390,40);
134. Pen pen = new Pen(new SolidBrush(Color.FromArgb(8,34,231)),1.5f);
135. //主区域,主区域图形
136. Rectangle RMain1=new Rectangle(20,55,410,345);
137. Rectangle RMain2=new Rectangle(25,60,400,335);
138. //图例区域
139. Rectangle RDes1=new Rectangle(440,55,150,345);
140. //图例说明
141. string Des="图例说明:";
142. Font f2 = new Font("新宋体", 9, FontStyle.Bold);
143. Point PDes=new Point(445,65);
144. //图例信息,后面的x坐标上累加20
145. Rectangle RDes2=new Rectangle(445,90,10,10);
146. Bitmap image = new Bitmap(width, height);
147. //
148. Graphics g = Graphics.FromImage(image);
149. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
150. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
151. try
152. {
153. //设置背景色、绘制边框
154. g.Clear(Color.White);
155. g.DrawRectangle(new Pen(Color.Black), 0, 0, width - 1, height - 1);
156. //绘制标题、线
157. g.DrawString(Title, f1, new SolidBrush(Color.Black),PTitle);
158. g.DrawLine(pen, PLine1, PLine2);
159.
160. //主区域
161. image = DrawRectangle(image, RMain1);
162. //图例区域
163. image = DrawRectangle(image, RDes1);
164. //“图例说明”
165. g.DrawString(Des, f2, new SolidBrush(Color.Black), PDes);
166. //return
167. return image;
168. }
169. finally
170. {
171. g.Dispose();
172. }
173. }
174. #endregion
175. #region //绘制饼状图************************
176. /// <summary>
177. /// 计算数值综合
178. /// </summary>
179. /// <param name="Value"></param>
180. /// <returns></returns>
181. private static decimal Sum(decimal[] Value)
182. {
183. decimal t=0;
184. foreach (decimal d in Value)
185. {
186. t += d;
187. }
188. return t;
189. }
190. /// <summary>
191. /// 计算各项比例
192. /// </summary>
193. /// <param name="Value"></param>
194. /// <returns></returns>
195. private static decimal[] GetItemRate(decimal[] Value)
196. {
197. decimal sum = Sum(Value);
198. decimal[] ItemRate = new decimal[Value.Length];
199. for (int i = 0; i < Value.Length; i++)
200. {
201. ItemRate[i] = Value[i] / sum;
202. }
203. return ItemRate;
204. }
205. /// <summary>
206. /// 根据比例,计算各项角度值
207. /// </summary>
208. /// <param name="ItemRate"></param>
209. /// <returns></returns>
210. private static int[] GetItemAngle(decimal[] ItemRate)
211. {
212. int[] ItemAngel = new int[ItemRate.Length];
213. for (int i = 0; i < ItemRate.Length; i++)
214. {
215. decimal t=360*ItemRate[i];
216. ItemAngel[i] = Convert.ToInt32(t);
217. }
218. return ItemAngel;
219. }
220. /// <summary>
221. /// 绘制饼图(主要是分析不同类型的数值所占比例),参数有图的标题,项目名称,项目的数值,名称和数值都是长度对应的
222. /// </summary>
223. /// <param name="Title">图的标题</param>
224. /// <param name="ItemName">项目名称</param>
225. /// <param name="ItemValue">项目的数值</param>
226. /// <returns>Bitmap图形</returns>
227. public static Bitmap GetPieImage(string Title, string[] ItemName, decimal[] ItemValue)
228. {
229. Bitmap image = GenerateImage(Title);
230. //
231. //主区域图形
232. Rectangle RMain = new Rectangle(35, 70, 380, 300);
233. //图例信息
234. Rectangle RDes = new Rectangle(445, 90, 10, 10);
235. Font f = new Font("新宋体", 9, FontStyle.Bold);
236. Graphics g = Graphics.FromImage(image);
237. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
238. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
239. try
240. {
241. //分析数据,绘制饼图和图例说明
242. decimal[] ItemRate = GetItemRate(ItemValue);
243. int[] ItemAngle = GetItemAngle(ItemRate);
244. int Angle1 = 0;
245. int Angle2 = 0;
246. int len = ItemValue.Length;
247. Color c = new Color();
248. //3D
249. g.DrawPie(new Pen(Color.Black), RMain, 0F, 360F);
250. g.DrawPie(new Pen(Color.Black), new Rectangle(RMain.X, RMain.Y + 10, RMain.Width, RMain.Height), 0F, 360F);
251. g.FillPie(new SolidBrush (Color.Black), new Rectangle(RMain.X, RMain.Y + 10, RMain.Width, RMain.Height), 0F, 360F);
252. //绘制
253. for (int i = 0; i < len; i++)
254. {
255. Angle2 = ItemAngle[i];
256. //if (c != GetRandomColor(i))
257. c = GetRandomColor(i);
258. SolidBrush brush=new SolidBrush(c);
259. string DesStr=ItemName[i]+"("+(ItemRate[i]*100).ToString(".00")+"%"+")"+ItemValue[i].ToString(".00");
260. //
261. DrawPie(image, RMain, c, Angle1, Angle2);
262. Angle1 += Angle2;
263. DrawDes(image, RDes, c, DesStr, f, i);
264. }
265. return image;
266. }
267. finally
268. {
269. g.Dispose();
270. }
271. }
272. #endregion
273. #region //获取Y轴坐标数据
274. /*
275. 坐标轴实现算法描述:
276. * X轴坐标根据项目数量把X轴均等分,有效长度350,
277. * Y轴有效长度280,平分为10个等分,即有十个点;
278. * Y轴的数值算法:第一个点位最小值,然后每个等分所对应的值是(最大值-最小值)/9,
279. */
280. /// <summary>
281. /// 获取Y轴坐标的点分布值
282. /// </summary>
283. /// <param name="ItemValue">项目数值</param>
284. /// <param name="YCount">Y轴点的数量</param>
285. /// <returns>图形</returns>
286. private static int[] GetYValue(decimal[] ItemValue,int YCount)
287. {
288. int len = ItemValue.Length;
289. int[] Value = new int[YCount];
290. int Max = Convert.ToInt32(ItemValue.Max());
291. int Min = Convert.ToInt32(ItemValue.Min());
292. int Distance = Convert.ToInt32((Max-Min)/(YCount-1));
293. for (int i = 0; i < YCount; i++)
294. {
295. Value[i] = Min + Distance * i;
296. }
297. //Value[YCount - 1] = Max;
298. return Value;
299. }
300. #endregion
301. #region //建立坐标轴
302. /// <summary>
303. /// 绘制坐标轴,X、Y轴的坐标值
304. /// </summary>
305. /// <param name="image">图像</param>
306. /// <param name="ItemName">项目名称</param>
307. /// <param name="ItemValue">项目数值</param>
308. /// <returns>图像</returns>
309. private static Bitmap DrawCoordinate(Bitmap image,string[] ItemName, decimal[] ItemValue)
310. {
311. //坐标轴
312. Point P0 = new Point(60, 360);
313. Point Px = new Point(420, 360);
314. Point Py = new Point(60, 65);
315. Pen pen=new Pen(Color.Black);
316. //箭头
317. Point Py1=new Point(58,70);
318. Point Py2=new Point(62,70);
319. Point Px1=new Point(415,358);
320. Point Px2=new Point(415,362);
321. //Y,X Value
322. //y 280-10
323. int YCount = 10;//Y轴点的数量
324. int YDistance = Convert.ToInt32(280/YCount) ;//Y轴点击的距离
325. int[] YValue = GetYValue(ItemValue, YCount);
326. int len = 3;//短线的长度
327. int XCount = ItemName.Length;//X轴点的数量
328. int XDistance = Convert.ToInt32(350/XCount);//X轴点间的距离
329. //
330. Font f = new Font("新宋体", 8, FontStyle.Bold);
331. //Image
332. Graphics g = Graphics.FromImage(image);
333. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
334. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
335. try
336. {
337. //绘制坐标轴线
338. g.DrawLine(pen, P0, Px);
339. g.DrawLine(pen, P0, Py);
340. //箭头
341. g.DrawLine(pen, Py, Py1);
342. g.DrawLine(pen, Py, Py2);
343. g.DrawLine(pen, Px, Px1);
344. g.DrawLine(pen, Px, Px2);
345. //X
346. for (int i = 1; i <= XCount; i++)
347. {
348. Point pl1 = new Point(P0.X+i*XDistance,P0.Y);
349. Point pl2 = new Point(P0.X + i * XDistance, P0.Y - len);
350. string str=ItemName[i - 1];
351. Point ps = new Point(pl1.X-(str.Length*8),pl1.Y+5);
352. g.DrawLine(pen, pl1, pl2);
353. g.DrawString(str, f, new SolidBrush(Color.Black), ps);
354. }
355. //Y
356. for (int i = 1; i <= YCount; i++)
357. {
358. Point pl1 = new Point(P0.X, P0.Y-YDistance*i);
359. Point pl2 = new Point(pl1.X+len, pl1.Y);
360. string str=YValue[i-1].ToString();
361. Point ps = new Point(pl1.X - str.Length*8, pl1.Y - 5);
362. g.DrawLine(pen, pl1, pl2);
363. g.DrawString(str, f, new SolidBrush(Color.Black), ps);
364. }
365. //0
366. g.DrawString("0",f,new SolidBrush(Color.Black),new Point(P0.X-10,P0.Y-10));
367. //return
368. return image;
369. }
370. finally
371. {
372. g.Dispose();
373. }
374. }
375. #endregion
376.
377. #region //获取某个数值在坐标系中的位置
378. /// <summary>
379. /// 获取某个数值在坐标系中的位置
380. /// </summary>
381. /// <param name="Value">当前数值</param>
382. /// <param name="ItemValue">所有数值</param>
383. /// <returns>位置</returns>
384. private static int GetCoordinateValue(decimal Value,decimal[] ItemValue)
385. {
386. //y 280-10
387. //get y value
388. int[] YValue=GetYValue(ItemValue,10);
389. int Max = YValue.Max();
390. int Min = YValue.Min();
391. float AvgDis = (Max - Min) / 9;
392. float tt = (Convert.ToSingle(Value) - Min) / AvgDis;
393. int m = Convert.ToInt32(tt*28);
394. m = 360 - 28 - m;
395. //if((Convert.ToInt32(Value)) >= Max)
396. // m=80;
397. //else if (Convert.ToInt32(Value) <= Min)
398. // m=332;
399. return m;
400. }
401. #endregion
402. #region //绘制曲线图****************************
403. /// <summary>
404. /// 绘制曲线图(主要是分析不同类型的数值所占比例,或者同意项目不同状态下的值和趋势),参数有图的标题,项目名称,项目的数值,名称和数值都是长度对应的
405. /// </summary>
406. /// <param name="Title">图的标题</param>
407. /// <param name="ItemName">项目名称</param>
408. /// <param name="ItemValue">项目的数值</param>
409. /// <returns>Bitmap图形</returns>
410. public static Bitmap GetLineImage(string Title, string[] ItemName, decimal[] ItemValue)
411. {
412. Bitmap image = GenerateImage(Title);
413. image = DrawCoordinate(image, ItemName, ItemValue);
414. Graphics g = Graphics.FromImage(image);
415. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
416. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
417. try
418. {
419. int PNum = ItemName.Length;
420. Point[] Pts = new Point[PNum];
421. //坐标轴
422. Point P0 = new Point(60, 360);
423. Point Px = new Point(420, 360);
424. Point Py = new Point(60, 65);
425. Pen pen = new Pen(Color.Black);
426. //
427. int XCount = ItemName.Length;//X轴点的数量
428. int XDistance = Convert.ToInt32(350 / XCount);//X轴点间的距离
429. //图例
430. Rectangle RDes = new Rectangle(445, 90, 10, 10);
431. Font f = new Font("新宋体", 9, FontStyle.Bold);
432. //
433. for (int i = 0; i < PNum; i++)
434. {
435. int x=P0.X + (i+1) * XDistance;
436. int y = GetCoordinateValue(ItemValue[i], ItemValue);
437. Pts[i] = new Point(x, y);
438. }
439. //把点连起来
440. for (int i = 1; i < PNum; i++)
441. {
442. g.DrawLine(pen, Pts[i - 1], Pts[i]);
443. }
444. //画图例说明
445. Color c = GetRandomColor(3);
446. for (int i = 0; i < PNum; i++)
447. {
448. string str = ItemName[i] + ":" + ItemValue[i].ToString();
449. DrawDes(image, RDes, c, str, f, i);
450. }
451. //return
452. return image;
453. }
454. finally
455. {
456. g.Dispose();
457. }
458. }
459. #endregion
460. #region //绘制柱状图*********************
461. /// <summary>
462. /// 绘制柱状图(主要是分析某一个项目在不同状态下的值,获取其发展趋势),参数有图的标题,项目名称,项目的数值,名称和数值都是长度对应的
463. /// </summary>
464. /// <param name="Title">图的标题</param>
465. /// <param name="ItemName">项目名称</param>
466. /// <param name="ItemValue">项目的数值</param>
467. /// <returns>Bitmap图形</returns>
468. public static Bitmap GetColumnImage(string Title, string[] ItemName, decimal[] ItemValue)
469. {
470. Bitmap image = GenerateImage(Title);
471. DrawCoordinate(image,ItemName,ItemValue);
472. Graphics g = Graphics.FromImage(image);
473. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
474. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
475. try
476. {
477. int PNum = ItemName.Length;
478. Point[] Pts = new Point[PNum];
479. //坐标轴
480. Point P0 = new Point(60, 360);
481. Point Px = new Point(420, 360);
482. Point Py = new Point(60, 65);
483. Pen pen = new Pen(Color.Black);
484. //
485. int XCount = ItemName.Length;//X轴点的数量
486. int XDistance = Convert.ToInt32(350 / XCount);//X轴点间的距离
487. //图例
488. Rectangle RDes = new Rectangle(445, 90, 10, 10);
489. Font f = new Font("新宋体", 9, FontStyle.Bold);
490. //获取值所对应的点
491. for (int i = 0; i < PNum; i++)
492. {
493. int x = P0.X + (i + 1) * XDistance;
494. int y = GetCoordinateValue(ItemValue[i], ItemValue);
495. Pts[i] = new Point(x, y);
496. }
497. //绘制条形框图
498. Color c=GetRandomColor(0);
499. for (int i = 0; i < PNum; i++)
500. {
501. Rectangle rect = new Rectangle(Pts[i].X - 5, Pts[i].Y, 10, P0.Y - Pts[i].Y);
502. Font ff = new Font("新宋体", 8, FontStyle.Regular);
503. g.DrawString(ItemValue[i].ToString(".00"), f, new SolidBrush(Color.Black), new Point(Pts[i].X - 15, Pts[i].Y - 12));
504. g.DrawRectangle(new Pen(Color.Black), rect);
505. g.FillRectangle(new SolidBrush(c), rect);
506. }
507. //画图例说明
508. for (int i = 0; i < PNum; i++)
509. {
510. string str = ItemName[i] + ":" + ItemValue[i].ToString();
511. DrawDes(image, RDes, c, str, f, i);
512. }
513. //return
514. return image;
515. }
516. finally
517. {
518. g.Dispose();
519. }
520. }
521. #endregion
522. #region //绘制多组数据曲线图********************
523. /// <summary>
524. /// 获取二维数组中的最大值
525. /// </summary>
526. /// <param name="ItemValues"></param>
527. /// <returns></returns>
528. private static int GetMax(decimal[][] ItemValues)
529. {
530. int Max = 0;
531. for (int i = 0; i < ItemValues.Length; i++)
532. {
533. int t = Convert.ToInt32(ItemValues[i].Max());
534. if (i == 0)
535. Max = t;
536. if (Max <= t)
537. Max = t;
538. }
539. return Max;
540. }
541. /// <summary>
542. /// 获取二维数组中的最小值
543. /// </summary>
544. /// <param name="ItemValues"></param>
545. /// <returns></returns>
546. private static int GetMin(decimal[][] ItemValues)
547. {
548. int Min = 0;
549. for (int i = 0; i < ItemValues.Length; i++)
550. {
551. int t = Convert.ToInt32(ItemValues[i].Min());
552. if (i == 0)
553. Min = t;
554. if (Min >= t)
555. Min = t;
556. }
557. return Min;
558. }
559. /// <summary>
560. /// 获取Y轴上点的数值
561. /// </summary>
562. /// <param name="ItemValues"></param>
563. /// <param name="YCount"></param>
564. /// <returns></returns>
565. private static int[] GetYValue(decimal[][] ItemValues, int YCount)
566. {
567. int[] Value = new int[YCount];
568. int Max = GetMax(ItemValues);
569. int Min = GetMin(ItemValues);
570. int Distance = Convert.ToInt32((Max - Min) / (YCount - 1));
571. for (int i = 0; i < YCount; i++)
572. {
573. Value[i] = Min + Distance * i;
574. }
575. //Value[YCount - 1] = Max;
576. return Value;
577. }
578. /// <summary>
579. /// 获取某个数值在坐标系中的位置
580. /// </summary>
581. /// <param name="Value">当前数值</param>
582. /// <param name="ItemValue">所有数值</param>
583. /// <returns>位置</returns>
584. private static int GetCoordinateValue(decimal Value, decimal[][] ItemValues)
585. {
586. //y 280-10
587. //get y value
588. int[] YValue = GetYValue(ItemValues, 10);
589. int Max = GetMax(ItemValues);
590. int Min = GetMin(ItemValues);
591. float AvgDis = (Max - Min) / 9;
592. float tt = (Convert.ToSingle(Value) - Min) / AvgDis;
593. int m = Convert.ToInt32(tt * 28);
594. m = 360 - 28 - m;
595. return m;
596. }
597. /// <summary>
598. /// 绘制坐标轴,X、Y轴的坐标值
599. /// </summary>
600. /// <param name="image">图像</param>
601. /// <param name="ItemName">项目名称</param>
602. /// <param name="ItemValue">多组项目数值</param>
603. /// <returns>图像</returns>
604. private static Bitmap DrawCoordinate(Bitmap image,string[] ItemName, decimal[][] ItemValues)
605. {
606. //坐标轴
607. Point P0 = new Point(60, 360);
608. Point Px = new Point(420, 360);
609. Point Py = new Point(60, 65);
610. Pen pen=new Pen(Color.Black);
611. //箭头
612. Point Py1=new Point(58,70);
613. Point Py2=new Point(62,70);
614. Point Px1=new Point(415,358);
615. Point Px2=new Point(415,362);
616. //Y,X Value
617. //y 280-10
618. int YCount = 10;//Y轴点的数量
619. int YDistance = Convert.ToInt32(280/YCount) ;//Y轴点击的距离
620. int[] YValue = GetYValue(ItemValues, YCount);
621. int len = 3;//短线的长度
622. int XCount = ItemName.Length;//X轴点的数量
623. int XDistance = Convert.ToInt32(350/XCount);//X轴点间的距离
624. //
625. Font f = new Font("新宋体", 8, FontStyle.Bold);
626. //Image
627. Graphics g = Graphics.FromImage(image);
628. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
629. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
630. try
631. {
632. //绘制坐标轴线
633. g.DrawLine(pen, P0, Px);
634. g.DrawLine(pen, P0, Py);
635. //箭头
636. g.DrawLine(pen, Py, Py1);
637. g.DrawLine(pen, Py, Py2);
638. g.DrawLine(pen, Px, Px1);
639. g.DrawLine(pen, Px, Px2);
640. //X
641. for (int i = 1; i <= XCount; i++)
642. {
643. Point pl1 = new Point(P0.X+i*XDistance,P0.Y);
644. Point pl2 = new Point(P0.X + i * XDistance, P0.Y - len);
645. string str=ItemName[i - 1];
646. Point ps = new Point(pl1.X-(str.Length*8),pl1.Y+5);
647. g.DrawLine(pen, pl1, pl2);
648. g.DrawString(str, f, new SolidBrush(Color.Black), ps);
649. }
650. //Y
651. for (int i = 1; i <= YCount; i++)
652. {
653. Point pl1 = new Point(P0.X, P0.Y-YDistance*i);
654. Point pl2 = new Point(pl1.X+len, pl1.Y);
655. string str=YValue[i-1].ToString();
656. Point ps = new Point(pl1.X - str.Length*8, pl1.Y - 5);
657. g.DrawLine(pen, pl1, pl2);
658. g.DrawString(str, f, new SolidBrush(Color.Black), ps);
659. }
660. //0
661. g.DrawString("0",f,new SolidBrush(Color.Black),new Point(P0.X-10,P0.Y-10));
662. //return
663. return image;
664. }
665. finally
666. {
667. g.Dispose();
668. }
669. }
670. /// <summary>
671. /// 绘制多组数据的曲线图
672. /// </summary>
673. /// <param name="Title">主标题</param>
674. /// <param name="ItemName">数据项名称</param>
675. /// <param name="ItemValues">多组数据集合</param>
676. /// <param name="ItemsName">各组的名称</param>
677. /// <returns></returns>
678. public static Bitmap GetMulLineImage(string Title, string[] ItemName, decimal[][] ItemValues,string[] ItemsName)
679. {
680. Bitmap image = GenerateImage(Title);
681. image = DrawCoordinate(image, ItemName, ItemValues);
682. Graphics g = Graphics.FromImage(image);
683. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
684. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
685. try
686. {
687. //绘制多条线
688. for (int m = 0; m < ItemsName.Length; m++)
689. {
690. int PNum = ItemName.Length;
691. Point[] Pts = new Point[PNum];
692. //坐标轴
693. Point P0 = new Point(60, 360);
694. Point Px = new Point(420, 360);
695. Point Py = new Point(60, 65);
696. //color
697. Color c = GetRandomColor(m);
698. Pen pen = new Pen(c);
699. //
700. int XCount = ItemName.Length;//X轴点的数量
701. int XDistance = Convert.ToInt32(350 / XCount);//X轴点间的距离
702. //图例
703. Rectangle RDes = new Rectangle(445, 90, 10, 10);
704. Font f = new Font("新宋体", 9, FontStyle.Bold);
705. //
706. for (int i = 0; i < PNum; i++)
707. {
708. int x = P0.X + (i + 1) * XDistance;
709. int y = GetCoordinateValue(ItemValues[m][i], ItemValues);
710. Pts[i] = new Point(x, y);
711. }
712. //把点连起来
713. for (int i = 1; i < PNum; i++)
714. {
715. g.DrawLine(pen, Pts[i - 1], Pts[i]);
716. }
717. //画图例说明
718. DrawDes(image, RDes, c, ItemsName[m], f, m);
719. }
720. //return
721. return image;
722. }
723. finally
724. {
725. g.Dispose();
726. }
727. }
728.#endregion
729. //end
730. }
731.}
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Text;
05.//
06.using System.Drawing;
07.//
08.namespace DatePrint
09.{
10. /// <summary>
11. /// 根据统计数据,输出各种统计统计图形,包括饼状图、曲线分析图、柱形图、多组数据曲线分析图;
12. /// 统计图形统一大小:600*420;
13. /// 开发人员:###;
14. /// 开发时间:###;
15. /// </summary>
16. public class CountImage
17. {
18. #region // 颜色,画框,
19. /// <summary>
20. /// 生成随机颜色
21. /// </summary>
22. /// <returns></returns>
23. private static Color GetRandomColor(int seed)
24. {
25. Random random = new Random(seed);
26. int r = 0;
27. int g = 0;
28. int b = 0;
29. r = random.Next(0, 230);
30. g = random.Next(0, 230);
31. b = random.Next(0, 235);
32. Color randomcolor = Color.FromArgb(r, g, b);
33. return randomcolor;
34. }
35. /// <summary>
36. /// 绘制区域框,框何其阴影
37. /// </summary>
38. /// <param name="image">图形</param>
39. /// <param name="rect">矩形框对象</param>
40. /// <returns>图形</returns>
41. private static Bitmap DrawRectangle(Bitmap image,Rectangle rect)
42. {
43. Bitmap Image=image;
44. Graphics g = Graphics.FromImage(Image);
45. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
46. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
47. try
48. {
49. Rectangle rn = new Rectangle(rect.X + 3, rect.Y + 3, rect.Width, rect.Height);
50. SolidBrush brush1 = new SolidBrush(Color.FromArgb(233, 234, 249));
51. SolidBrush brush2 = new SolidBrush(Color.FromArgb(221, 213, 215));
52. //
53. g.FillRectangle(brush2, rn);
54. g.FillRectangle(brush1, rect);
55. return Image;
56. }
57. finally
58. {
59. g.Dispose();
60. }
61. }
62. #endregion
63. #region //绘制图例框,绘制扇形
64. /// <summary>
65. /// 绘制图例信息
66. /// </summary>
67. /// <param name="image">图像</param>
68. /// <param name="rect">第一个矩形框</param>
69. /// <param name="c">颜色</param>
70. /// <param name="DesStr">图例说明文字</param>
71. /// <param name="f">文字样式</param>
72. /// <param name="i">图例说明序号</param>
73. /// <returns>图形</returns>
74. private static Bitmap DrawDes(Bitmap image, Rectangle rect,Color c,string DesStr,Font f,int i)
75. {
76. Bitmap Image = image;
77. Graphics g = Graphics.FromImage(Image);
78. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
79. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
80. try
81. {
82. SolidBrush brush = new SolidBrush(c);
83. //
84. Rectangle R = new Rectangle(rect.X, rect.Y + 18 * i, rect.Width, rect.Height);
85. Point p = new Point(rect.X + 12, rect.Y + 18 * i);
86. //?颜色矩形框
87. g.FillRectangle(brush,R);
88. //文字说明
89. g.DrawString(DesStr, f, new SolidBrush(Color.Black), p);
90. return Image;
91. }
92. finally
93. {
94. g.Dispose();
95. }
96. }
97. //绘制扇形
98. private static Bitmap DrawPie(Bitmap image, Rectangle rect, Color c, int Angle1, int Angle2)
99. {
100. Bitmap Image = image;
101. Graphics g = Graphics.FromImage(Image);
102. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
103. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
104. try
105. {
106. SolidBrush brush = new SolidBrush(c);
107. //
108. Rectangle R = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
109. g.FillPie(brush, R, Angle1, Angle2); //Angle1:第一条射线沿X轴顺时针旋转的夹角 Angle2:第二条射线与X轴顺时针旋转的夹角
110. return Image;
111. }
112. finally
113. {
114. g.Dispose();
115. }
116. }
117. #endregion
118. #region//绘制基本图形
119. /// <summary>
120. /// 生成图片,统一设置图片大小、背景色,图片布局,及标题
121. /// </summary>
122. /// <returns>图片</returns>
123. private static Bitmap GenerateImage(string Title)
124. {
125. //图片大小:宽度、高度
126. int width = 600;
127. int height = 420;
128. //标题
129. Point PTitle=new Point(30,20);
130. Font f1 = new Font("宋体", 10, FontStyle.Bold);
131. //线
132. Point PLine1=new Point(20,40);
133. Point PLine2=new Point(390,40);
134. Pen pen = new Pen(new SolidBrush(Color.FromArgb(8,34,231)),1.5f);
135. //主区域,主区域图形
136. Rectangle RMain1=new Rectangle(20,55,410,345);
137. Rectangle RMain2=new Rectangle(25,60,400,335);
138. //图例区域
139. Rectangle RDes1=new Rectangle(440,55,150,345);
140. //图例说明
141. string Des="图例说明:";
142. Font f2 = new Font("新宋体", 9, FontStyle.Bold);
143. Point PDes=new Point(445,65);
144. //图例信息,后面的x坐标上累加20
145. Rectangle RDes2=new Rectangle(445,90,10,10);
146. Bitmap image = new Bitmap(width, height);
147. //
148. Graphics g = Graphics.FromImage(image);
149. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
150. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
151. try
152. {
153. //设置背景色、绘制边框
154. g.Clear(Color.White);
155. g.DrawRectangle(new Pen(Color.Black), 0, 0, width - 1, height - 1);
156. //绘制标题、线
157. g.DrawString(Title, f1, new SolidBrush(Color.Black),PTitle);
158. g.DrawLine(pen, PLine1, PLine2);
159.
160. //主区域
161. image = DrawRectangle(image, RMain1);
162. //图例区域
163. image = DrawRectangle(image, RDes1);
164. //“图例说明”
165. g.DrawString(Des, f2, new SolidBrush(Color.Black), PDes);
166. //return
167. return image;
168. }
169. finally
170. {
171. g.Dispose();
172. }
173. }
174. #endregion
175. #region //绘制饼状图************************
176. /// <summary>
177. /// 计算数值综合
178. /// </summary>
179. /// <param name="Value"></param>
180. /// <returns></returns>
181. private static decimal Sum(decimal[] Value)
182. {
183. decimal t=0;
184. foreach (decimal d in Value)
185. {
186. t += d;
187. }
188. return t;
189. }
190. /// <summary>
191. /// 计算各项比例
192. /// </summary>
193. /// <param name="Value"></param>
194. /// <returns></returns>
195. private static decimal[] GetItemRate(decimal[] Value)
196. {
197. decimal sum = Sum(Value);
198. decimal[] ItemRate = new decimal[Value.Length];
199. for (int i = 0; i < Value.Length; i++)
200. {
201. ItemRate[i] = Value[i] / sum;
202. }
203. return ItemRate;
204. }
205. /// <summary>
206. /// 根据比例,计算各项角度值
207. /// </summary>
208. /// <param name="ItemRate"></param>
209. /// <returns></returns>
210. private static int[] GetItemAngle(decimal[] ItemRate)
211. {
212. int[] ItemAngel = new int[ItemRate.Length];
213. for (int i = 0; i < ItemRate.Length; i++)
214. {
215. decimal t=360*ItemRate[i];
216. ItemAngel[i] = Convert.ToInt32(t);
217. }
218. return ItemAngel;
219. }
220. /// <summary>
221. /// 绘制饼图(主要是分析不同类型的数值所占比例),参数有图的标题,项目名称,项目的数值,名称和数值都是长度对应的
222. /// </summary>
223. /// <param name="Title">图的标题</param>
224. /// <param name="ItemName">项目名称</param>
225. /// <param name="ItemValue">项目的数值</param>
226. /// <returns>Bitmap图形</returns>
227. public static Bitmap GetPieImage(string Title, string[] ItemName, decimal[] ItemValue)
228. {
229. Bitmap image = GenerateImage(Title);
230. //
231. //主区域图形
232. Rectangle RMain = new Rectangle(35, 70, 380, 300);
233. //图例信息
234. Rectangle RDes = new Rectangle(445, 90, 10, 10);
235. Font f = new Font("新宋体", 9, FontStyle.Bold);
236. Graphics g = Graphics.FromImage(image);
237. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
238. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
239. try
240. {
241. //分析数据,绘制饼图和图例说明
242. decimal[] ItemRate = GetItemRate(ItemValue);
243. int[] ItemAngle = GetItemAngle(ItemRate);
244. int Angle1 = 0;
245. int Angle2 = 0;
246. int len = ItemValue.Length;
247. Color c = new Color();
248. //3D
249. g.DrawPie(new Pen(Color.Black), RMain, 0F, 360F);
250. g.DrawPie(new Pen(Color.Black), new Rectangle(RMain.X, RMain.Y + 10, RMain.Width, RMain.Height), 0F, 360F);
251. g.FillPie(new SolidBrush (Color.Black), new Rectangle(RMain.X, RMain.Y + 10, RMain.Width, RMain.Height), 0F, 360F);
252. //绘制
253. for (int i = 0; i < len; i++)
254. {
255. Angle2 = ItemAngle[i];
256. //if (c != GetRandomColor(i))
257. c = GetRandomColor(i);
258. SolidBrush brush=new SolidBrush(c);
259. string DesStr=ItemName[i]+"("+(ItemRate[i]*100).ToString(".00")+"%"+")"+ItemValue[i].ToString(".00");
260. //
261. DrawPie(image, RMain, c, Angle1, Angle2);
262. Angle1 += Angle2;
263. DrawDes(image, RDes, c, DesStr, f, i);
264. }
265. return image;
266. }
267. finally
268. {
269. g.Dispose();
270. }
271. }
272. #endregion
273. #region //获取Y轴坐标数据
274. /*
275. 坐标轴实现算法描述:
276. * X轴坐标根据项目数量把X轴均等分,有效长度350,
277. * Y轴有效长度280,平分为10个等分,即有十个点;
278. * Y轴的数值算法:第一个点位最小值,然后每个等分所对应的值是(最大值-最小值)/9,
279. */
280. /// <summary>
281. /// 获取Y轴坐标的点分布值
282. /// </summary>
283. /// <param name="ItemValue">项目数值</param>
284. /// <param name="YCount">Y轴点的数量</param>
285. /// <returns>图形</returns>
286. private static int[] GetYValue(decimal[] ItemValue,int YCount)
287. {
288. int len = ItemValue.Length;
289. int[] Value = new int[YCount];
290. int Max = Convert.ToInt32(ItemValue.Max());
291. int Min = Convert.ToInt32(ItemValue.Min());
292. int Distance = Convert.ToInt32((Max-Min)/(YCount-1));
293. for (int i = 0; i < YCount; i++)
294. {
295. Value[i] = Min + Distance * i;
296. }
297. //Value[YCount - 1] = Max;
298. return Value;
299. }
300. #endregion
301. #region //建立坐标轴
302. /// <summary>
303. /// 绘制坐标轴,X、Y轴的坐标值
304. /// </summary>
305. /// <param name="image">图像</param>
306. /// <param name="ItemName">项目名称</param>
307. /// <param name="ItemValue">项目数值</param>
308. /// <returns>图像</returns>
309. private static Bitmap DrawCoordinate(Bitmap image,string[] ItemName, decimal[] ItemValue)
310. {
311. //坐标轴
312. Point P0 = new Point(60, 360);
313. Point Px = new Point(420, 360);
314. Point Py = new Point(60, 65);
315. Pen pen=new Pen(Color.Black);
316. //箭头
317. Point Py1=new Point(58,70);
318. Point Py2=new Point(62,70);
319. Point Px1=new Point(415,358);
320. Point Px2=new Point(415,362);
321. //Y,X Value
322. //y 280-10
323. int YCount = 10;//Y轴点的数量
324. int YDistance = Convert.ToInt32(280/YCount) ;//Y轴点击的距离
325. int[] YValue = GetYValue(ItemValue, YCount);
326. int len = 3;//短线的长度
327. int XCount = ItemName.Length;//X轴点的数量
328. int XDistance = Convert.ToInt32(350/XCount);//X轴点间的距离
329. //
330. Font f = new Font("新宋体", 8, FontStyle.Bold);
331. //Image
332. Graphics g = Graphics.FromImage(image);
333. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
334. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
335. try
336. {
337. //绘制坐标轴线
338. g.DrawLine(pen, P0, Px);
339. g.DrawLine(pen, P0, Py);
340. //箭头
341. g.DrawLine(pen, Py, Py1);
342. g.DrawLine(pen, Py, Py2);
343. g.DrawLine(pen, Px, Px1);
344. g.DrawLine(pen, Px, Px2);
345. //X
346. for (int i = 1; i <= XCount; i++)
347. {
348. Point pl1 = new Point(P0.X+i*XDistance,P0.Y);
349. Point pl2 = new Point(P0.X + i * XDistance, P0.Y - len);
350. string str=ItemName[i - 1];
351. Point ps = new Point(pl1.X-(str.Length*8),pl1.Y+5);
352. g.DrawLine(pen, pl1, pl2);
353. g.DrawString(str, f, new SolidBrush(Color.Black), ps);
354. }
355. //Y
356. for (int i = 1; i <= YCount; i++)
357. {
358. Point pl1 = new Point(P0.X, P0.Y-YDistance*i);
359. Point pl2 = new Point(pl1.X+len, pl1.Y);
360. string str=YValue[i-1].ToString();
361. Point ps = new Point(pl1.X - str.Length*8, pl1.Y - 5);
362. g.DrawLine(pen, pl1, pl2);
363. g.DrawString(str, f, new SolidBrush(Color.Black), ps);
364. }
365. //0
366. g.DrawString("0",f,new SolidBrush(Color.Black),new Point(P0.X-10,P0.Y-10));
367. //return
368. return image;
369. }
370. finally
371. {
372. g.Dispose();
373. }
374. }
375. #endregion
376.
377. #region //获取某个数值在坐标系中的位置
378. /// <summary>
379. /// 获取某个数值在坐标系中的位置
380. /// </summary>
381. /// <param name="Value">当前数值</param>
382. /// <param name="ItemValue">所有数值</param>
383. /// <returns>位置</returns>
384. private static int GetCoordinateValue(decimal Value,decimal[] ItemValue)
385. {
386. //y 280-10
387. //get y value
388. int[] YValue=GetYValue(ItemValue,10);
389. int Max = YValue.Max();
390. int Min = YValue.Min();
391. float AvgDis = (Max - Min) / 9;
392. float tt = (Convert.ToSingle(Value) - Min) / AvgDis;
393. int m = Convert.ToInt32(tt*28);
394. m = 360 - 28 - m;
395. //if((Convert.ToInt32(Value)) >= Max)
396. // m=80;
397. //else if (Convert.ToInt32(Value) <= Min)
398. // m=332;
399. return m;
400. }
401. #endregion
402. #region //绘制曲线图****************************
403. /// <summary>
404. /// 绘制曲线图(主要是分析不同类型的数值所占比例,或者同意项目不同状态下的值和趋势),参数有图的标题,项目名称,项目的数值,名称和数值都是长度对应的
405. /// </summary>
406. /// <param name="Title">图的标题</param>
407. /// <param name="ItemName">项目名称</param>
408. /// <param name="ItemValue">项目的数值</param>
409. /// <returns>Bitmap图形</returns>
410. public static Bitmap GetLineImage(string Title, string[] ItemName, decimal[] ItemValue)
411. {
412. Bitmap image = GenerateImage(Title);
413. image = DrawCoordinate(image, ItemName, ItemValue);
414. Graphics g = Graphics.FromImage(image);
415. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
416. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
417. try
418. {
419. int PNum = ItemName.Length;
420. Point[] Pts = new Point[PNum];
421. //坐标轴
422. Point P0 = new Point(60, 360);
423. Point Px = new Point(420, 360);
424. Point Py = new Point(60, 65);
425. Pen pen = new Pen(Color.Black);
426. //
427. int XCount = ItemName.Length;//X轴点的数量
428. int XDistance = Convert.ToInt32(350 / XCount);//X轴点间的距离
429. //图例
430. Rectangle RDes = new Rectangle(445, 90, 10, 10);
431. Font f = new Font("新宋体", 9, FontStyle.Bold);
432. //
433. for (int i = 0; i < PNum; i++)
434. {
435. int x=P0.X + (i+1) * XDistance;
436. int y = GetCoordinateValue(ItemValue[i], ItemValue);
437. Pts[i] = new Point(x, y);
438. }
439. //把点连起来
440. for (int i = 1; i < PNum; i++)
441. {
442. g.DrawLine(pen, Pts[i - 1], Pts[i]);
443. }
444. //画图例说明
445. Color c = GetRandomColor(3);
446. for (int i = 0; i < PNum; i++)
447. {
448. string str = ItemName[i] + ":" + ItemValue[i].ToString();
449. DrawDes(image, RDes, c, str, f, i);
450. }
451. //return
452. return image;
453. }
454. finally
455. {
456. g.Dispose();
457. }
458. }
459. #endregion
460. #region //绘制柱状图*********************
461. /// <summary>
462. /// 绘制柱状图(主要是分析某一个项目在不同状态下的值,获取其发展趋势),参数有图的标题,项目名称,项目的数值,名称和数值都是长度对应的
463. /// </summary>
464. /// <param name="Title">图的标题</param>
465. /// <param name="ItemName">项目名称</param>
466. /// <param name="ItemValue">项目的数值</param>
467. /// <returns>Bitmap图形</returns>
468. public static Bitmap GetColumnImage(string Title, string[] ItemName, decimal[] ItemValue)
469. {
470. Bitmap image = GenerateImage(Title);
471. DrawCoordinate(image,ItemName,ItemValue);
472. Graphics g = Graphics.FromImage(image);
473. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
474. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
475. try
476. {
477. int PNum = ItemName.Length;
478. Point[] Pts = new Point[PNum];
479. //坐标轴
480. Point P0 = new Point(60, 360);
481. Point Px = new Point(420, 360);
482. Point Py = new Point(60, 65);
483. Pen pen = new Pen(Color.Black);
484. //
485. int XCount = ItemName.Length;//X轴点的数量
486. int XDistance = Convert.ToInt32(350 / XCount);//X轴点间的距离
487. //图例
488. Rectangle RDes = new Rectangle(445, 90, 10, 10);
489. Font f = new Font("新宋体", 9, FontStyle.Bold);
490. //获取值所对应的点
491. for (int i = 0; i < PNum; i++)
492. {
493. int x = P0.X + (i + 1) * XDistance;
494. int y = GetCoordinateValue(ItemValue[i], ItemValue);
495. Pts[i] = new Point(x, y);
496. }
497. //绘制条形框图
498. Color c=GetRandomColor(0);
499. for (int i = 0; i < PNum; i++)
500. {
501. Rectangle rect = new Rectangle(Pts[i].X - 5, Pts[i].Y, 10, P0.Y - Pts[i].Y);
502. Font ff = new Font("新宋体", 8, FontStyle.Regular);
503. g.DrawString(ItemValue[i].ToString(".00"), f, new SolidBrush(Color.Black), new Point(Pts[i].X - 15, Pts[i].Y - 12));
504. g.DrawRectangle(new Pen(Color.Black), rect);
505. g.FillRectangle(new SolidBrush(c), rect);
506. }
507. //画图例说明
508. for (int i = 0; i < PNum; i++)
509. {
510. string str = ItemName[i] + ":" + ItemValue[i].ToString();
511. DrawDes(image, RDes, c, str, f, i);
512. }
513. //return
514. return image;
515. }
516. finally
517. {
518. g.Dispose();
519. }
520. }
521. #endregion
522. #region //绘制多组数据曲线图********************
523. /// <summary>
524. /// 获取二维数组中的最大值
525. /// </summary>
526. /// <param name="ItemValues"></param>
527. /// <returns></returns>
528. private static int GetMax(decimal[][] ItemValues)
529. {
530. int Max = 0;
531. for (int i = 0; i < ItemValues.Length; i++)
532. {
533. int t = Convert.ToInt32(ItemValues[i].Max());
534. if (i == 0)
535. Max = t;
536. if (Max <= t)
537. Max = t;
538. }
539. return Max;
540. }
541. /// <summary>
542. /// 获取二维数组中的最小值
543. /// </summary>
544. /// <param name="ItemValues"></param>
545. /// <returns></returns>
546. private static int GetMin(decimal[][] ItemValues)
547. {
548. int Min = 0;
549. for (int i = 0; i < ItemValues.Length; i++)
550. {
551. int t = Convert.ToInt32(ItemValues[i].Min());
552. if (i == 0)
553. Min = t;
554. if (Min >= t)
555. Min = t;
556. }
557. return Min;
558. }
559. /// <summary>
560. /// 获取Y轴上点的数值
561. /// </summary>
562. /// <param name="ItemValues"></param>
563. /// <param name="YCount"></param>
564. /// <returns></returns>
565. private static int[] GetYValue(decimal[][] ItemValues, int YCount)
566. {
567. int[] Value = new int[YCount];
568. int Max = GetMax(ItemValues);
569. int Min = GetMin(ItemValues);
570. int Distance = Convert.ToInt32((Max - Min) / (YCount - 1));
571. for (int i = 0; i < YCount; i++)
572. {
573. Value[i] = Min + Distance * i;
574. }
575. //Value[YCount - 1] = Max;
576. return Value;
577. }
578. /// <summary>
579. /// 获取某个数值在坐标系中的位置
580. /// </summary>
581. /// <param name="Value">当前数值</param>
582. /// <param name="ItemValue">所有数值</param>
583. /// <returns>位置</returns>
584. private static int GetCoordinateValue(decimal Value, decimal[][] ItemValues)
585. {
586. //y 280-10
587. //get y value
588. int[] YValue = GetYValue(ItemValues, 10);
589. int Max = GetMax(ItemValues);
590. int Min = GetMin(ItemValues);
591. float AvgDis = (Max - Min) / 9;
592. float tt = (Convert.ToSingle(Value) - Min) / AvgDis;
593. int m = Convert.ToInt32(tt * 28);
594. m = 360 - 28 - m;
595. return m;
596. }
597. /// <summary>
598. /// 绘制坐标轴,X、Y轴的坐标值
599. /// </summary>
600. /// <param name="image">图像</param>
601. /// <param name="ItemName">项目名称</param>
602. /// <param name="ItemValue">多组项目数值</param>
603. /// <returns>图像</returns>
604. private static Bitmap DrawCoordinate(Bitmap image,string[] ItemName, decimal[][] ItemValues)
605. {
606. //坐标轴
607. Point P0 = new Point(60, 360);
608. Point Px = new Point(420, 360);
609. Point Py = new Point(60, 65);
610. Pen pen=new Pen(Color.Black);
611. //箭头
612. Point Py1=new Point(58,70);
613. Point Py2=new Point(62,70);
614. Point Px1=new Point(415,358);
615. Point Px2=new Point(415,362);
616. //Y,X Value
617. //y 280-10
618. int YCount = 10;//Y轴点的数量
619. int YDistance = Convert.ToInt32(280/YCount) ;//Y轴点击的距离
620. int[] YValue = GetYValue(ItemValues, YCount);
621. int len = 3;//短线的长度
622. int XCount = ItemName.Length;//X轴点的数量
623. int XDistance = Convert.ToInt32(350/XCount);//X轴点间的距离
624. //
625. Font f = new Font("新宋体", 8, FontStyle.Bold);
626. //Image
627. Graphics g = Graphics.FromImage(image);
628. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
629. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
630. try
631. {
632. //绘制坐标轴线
633. g.DrawLine(pen, P0, Px);
634. g.DrawLine(pen, P0, Py);
635. //箭头
636. g.DrawLine(pen, Py, Py1);
637. g.DrawLine(pen, Py, Py2);
638. g.DrawLine(pen, Px, Px1);
639. g.DrawLine(pen, Px, Px2);
640. //X
641. for (int i = 1; i <= XCount; i++)
642. {
643. Point pl1 = new Point(P0.X+i*XDistance,P0.Y);
644. Point pl2 = new Point(P0.X + i * XDistance, P0.Y - len);
645. string str=ItemName[i - 1];
646. Point ps = new Point(pl1.X-(str.Length*8),pl1.Y+5);
647. g.DrawLine(pen, pl1, pl2);
648. g.DrawString(str, f, new SolidBrush(Color.Black), ps);
649. }
650. //Y
651. for (int i = 1; i <= YCount; i++)
652. {
653. Point pl1 = new Point(P0.X, P0.Y-YDistance*i);
654. Point pl2 = new Point(pl1.X+len, pl1.Y);
655. string str=YValue[i-1].ToString();
656. Point ps = new Point(pl1.X - str.Length*8, pl1.Y - 5);
657. g.DrawLine(pen, pl1, pl2);
658. g.DrawString(str, f, new SolidBrush(Color.Black), ps);
659. }
660. //0
661. g.DrawString("0",f,new SolidBrush(Color.Black),new Point(P0.X-10,P0.Y-10));
662. //return
663. return image;
664. }
665. finally
666. {
667. g.Dispose();
668. }
669. }
670. /// <summary>
671. /// 绘制多组数据的曲线图
672. /// </summary>
673. /// <param name="Title">主标题</param>
674. /// <param name="ItemName">数据项名称</param>
675. /// <param name="ItemValues">多组数据集合</param>
676. /// <param name="ItemsName">各组的名称</param>
677. /// <returns></returns>
678. public static Bitmap GetMulLineImage(string Title, string[] ItemName, decimal[][] ItemValues,string[] ItemsName)
679. {
680. Bitmap image = GenerateImage(Title);
681. image = DrawCoordinate(image, ItemName, ItemValues);
682. Graphics g = Graphics.FromImage(image);
683. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
684. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
685. try
686. {
687. //绘制多条线
688. for (int m = 0; m < ItemsName.Length; m++)
689. {
690. int PNum = ItemName.Length;
691. Point[] Pts = new Point[PNum];
692. //坐标轴
693. Point P0 = new Point(60, 360);
694. Point Px = new Point(420, 360);
695. Point Py = new Point(60, 65);
696. //color
697. Color c = GetRandomColor(m);
698. Pen pen = new Pen(c);
699. //
700. int XCount = ItemName.Length;//X轴点的数量
701. int XDistance = Convert.ToInt32(350 / XCount);//X轴点间的距离
702. //图例
703. Rectangle RDes = new Rectangle(445, 90, 10, 10);
704. Font f = new Font("新宋体", 9, FontStyle.Bold);
705. //
706. for (int i = 0; i < PNum; i++)
707. {
708. int x = P0.X + (i + 1) * XDistance;
709. int y = GetCoordinateValue(ItemValues[m][i], ItemValues);
710. Pts[i] = new Point(x, y);
711. }
712. //把点连起来
713. for (int i = 1; i < PNum; i++)
714. {
715. g.DrawLine(pen, Pts[i - 1], Pts[i]);
716. }
717. //画图例说明
718. DrawDes(image, RDes, c, ItemsName[m], f, m);
719. }
720. //return
721. return image;
722. }
723. finally
724. {
725. g.Dispose();
726. }
727. }
728.#endregion
729. //end
730. }
731.}