C#简单的绘图处理
测试代码
生成5个随机数据,并绘图
private void do_test()
{
String layerFiename = @"D:\\test.jpg";
Draw d = new Draw();
d.option = new DrawOption();
d.option.init();
Random r = new Random();
for (int i = 0; i < 5; i++)
{
ProjectDraw pj = new ProjectDraw();
pj.title = "项目" + (i + 1).ToString() + ":\r\n" + "北京市第" + (i + 1).ToString() + "污水处理厂";
pj.title_time = "工期: 2016年5月1日 - 2016年11月1日\r\n总工期: 180天\r\n剩余工期: 72天";
pj.title_cost = "总成本: " + (300 + (r.Next(200))).ToString() + "万元\r\n已完成: " + (100 + (r.Next(200))).ToString() + "万元";
pj.begin_dt = DateTime.Parse("2016-5-1");
pj.end_dt = DateTime.Parse("2016-11-10");
pj.cost = 1000F;
pj.process_time_v = r.Next(100);
pj.process_time_warning = (r.Next(10) < 3);
pj.process_cost_v = r.Next(100);
pj.process_cost_warning = (r.Next(10) < 3);
make_test(pj);
d.project_list.Add(pj);
}
int height = d.get_img_height();
Bitmap bmp = new Bitmap(panel3.Width - 20, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(bmp);
d.make_drawlist(bmp.Width);
d.paint(g);
g.Dispose();
pictureBox1.Image = bmp;
pictureBox1.Width = bmp.Width;
pictureBox1.Height = bmp.Height;
pictureBox1.Refresh();
}
测试数据的生成
private void make_test(ProjectDraw pj)
{
List<string> t = new List<string>();
t.Add("启动会");
t.Add("施工图设计");
t.Add("三通一平");
t.Add("场地临建");
t.Add("土建主体施工");
t.Add("安装工程");
t.Add("厂平绿化");
t.Add("竣工验收");
DateTime d_begin = pj.begin_dt;
DateTime d_end = pj.end_dt;
TimeSpan ts = d_end - d_begin;
int days = (int)(ts.TotalDays + 0.5F);
List<int> dl = new List<int>();
for (int i = 0; i < t.Count - 1; i++)
{
for (int k = 0; k < 1000; k++)
{
int d = random.Next(days);
if (d > 0)
if (dl.IndexOf(d) < 0)
{
dl.Add(d);
break;
}
}
}
dl.Add(0);
dl.Add(days);
dl.Sort();
for (int i = 1; i < dl.Count - 1; i++)
{
dl[i] = (dl[i - 1] + dl[i + 1]) / 2;
}
int is_curr = random.Next(t.Count-1);
if (is_curr<2)
is_curr=2;
List<int> dl_a = new List<int>();
dl_a.AddRange(dl);
for (int i = 1; i < dl_a.Count - 1; i++)
{
dl_a[i] = (dl_a[i - 1] + dl_a[i + 1]) / 2;
}
float tmp_v = 0;
for (int i = 0; i < t.Count; i++)
{
ProjectItem p = new ProjectItem();
p.title = t[i];
p.plan_begin_dt = d_begin.AddDays(dl[i]);
p.plan_end_dt = d_begin.AddDays(dl[i + 1]);
if (i == is_curr)
p.is_current = true;
if (i == t.Count - 1)
p.plan_cost = 1000 - tmp_v;
else
p.plan_cost = 125 + random.Next(100) - 60;
tmp_v = tmp_v + p.plan_cost;
if (i <= is_curr)
{
p.have_actual = true;
p.actual_begin_dt = d_begin.AddDays(dl_a[i]);
p.actual_end_dt = d_begin.AddDays(dl_a[i + 1]);
p.actual_cost = p.plan_cost + random.Next(100) - 20;
}
pj.item_list.Add(p);
}
pj.cost = 1000;
pj.create_cost_txt_list(pj.get_s_c(pj.cost, pj.item_list.Count));
}
绘图处理
Draw
绘图的处理在Draw类中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace PjDraw
{
public class Draw
{
public DrawOption option = null;
public List<ProjectDraw> project_list = new List<ProjectDraw>();
public List<ProjectDrawData> projectdata_list = new List<ProjectDrawData>();
public int get_project_height(ProjectDraw project)
{
int result = option.line_width + option.header_height + option.line_width;
int ac = project.item_list.Count;
if (ac > 0)
{
result = result + (option.planitem_height + option.line_width) * ac;
result = result - option.line_width;
}
return result + option.line_width;
}
public int get_img_height()
{
int result = option.margin_top;
for (int i = 0; i < project_list.Count; i++)
{
if (i > 0)
result = result + option.split_height;
result = result + get_project_height(project_list[i]);
}
result = result + option.margin_bottom;
return result;
}
private List<DrawObject> _drawlist = new List<DrawObject>();
private int _width = 0;
public void add_frame_draw_line(Pen pen, int left, int top, int right, int boottom)
{
add_line(pen, left, top, right - pen.Width + 1, top);
add_line(pen, right - pen.Width + 1, top, right - pen.Width + 1, boottom - pen.Width + 1);
add_line(pen, left, top, left, boottom - pen.Width + 1);
add_line(pen, left, boottom - pen.Width + 1, right - pen.Width + 1, boottom - pen.Width + 1);
}
public DrawObject add_line(Pen pen, float left, float top, float right, float boottom)
{
DrawObject line = new DrawLine(pen, left, top, right, boottom);
_drawlist.Add(line);
return line;
}
public DrawObject add_line(Pen pen, PointF pt1, PointF pt2)
{
return add_line(pen, pt1.X, pt1.Y, pt2.X, pt2.Y);
}
public void add_fill_rect(Brush brush, int left, int top, int right, int boottom)
{
_drawlist.Add(new DrawFill(brush, left, top, right, boottom));
}
public void add_fill_rect(Brush brush, Rectangle r)
{
_drawlist.Add(new DrawFill(brush, r.Left, r.Top, r.Right, r.Bottom));
}
public void add_txt(Font font,Brush brush, Rectangle r,StringFormat sf,string txt)
{
_drawlist.Add(new DrawText(txt, font, brush, r, sf));
}
public ProjectDrawData make_data_project(ProjectDraw pj, int left, int top, int right, int bottom)
{
ProjectDrawData pd = new ProjectDrawData();
pd.project = pj;
pd.left=left;
pd.top=top;
pd.right=right;
pd.bottom = bottom;
int x0 = left+option.line_width;
int y0 = top + option.line_width; ;
int x2 = right - option.line_width;
int y2 = y0 + option.header_height;
pd.header_rect = new Rectangle(x0, y0, x2-x0+1, y2-y0);
pd.header_line_pt1 = new PointF(x0, y2);
pd.header_line_pt2 = new PointF(x2, y2);
pd.draw_header = true;
int x_info_title = x0 + option.info_title_width;
int y_info_title_1 = y2 + option.line_width;
int y_info_title_2 = bottom - option.line_width;
pd.info_title_line_pt1 = new PointF(x_info_title, y_info_title_1);
pd.info_title_line_pt2 = new PointF(x_info_title, y_info_title_2);
pd.info_title_rect = new Rectangle(x0, y_info_title_1, x_info_title - x0, y_info_title_2 - y_info_title_1+1);
int x_info_detail = x_info_title + option.line_width + option.info_detail_width;
pd.info_detail_line_pt1 = new PointF(x_info_detail,y0);
pd.info_detail_line_pt2 = new PointF(x_info_detail, y_info_title_2);
pd.info_detail_rect = new Rectangle(x_info_title + option.line_width, y_info_title_1, x_info_detail - x_info_title - option.line_width, y_info_title_2 - y_info_title_1+1);
pd.header_title_rect = new Rectangle(x0, y0, x_info_detail - x0, y2 - y0);
int x_process_title = x_info_detail + option.line_width + option.process_title_width;
pd.process_title_line_pt1 = new PointF(x_process_title, y_info_title_1);
pd.process_title_line_pt2 = new PointF(x_process_title, y_info_title_2);
pd.process_title_rect = new Rectangle(x_info_detail + option.line_width, y_info_title_1, x_process_title - x_info_detail - option.line_width, y_info_title_2 - y_info_title_1+1);
pd.header_proess_rect = new Rectangle(x_info_detail, y0, option.header_proess_text_width, y2 - y0);
int x_process_detail = x_process_title + option.line_width + option.process_detail_width;
pd.process_detail_line_pt1 = new PointF(x_process_detail, y0);
pd.process_detail_line_pt2 = new PointF(x_process_detail, y_info_title_2);
pd.process_detail_rect = new Rectangle(x_process_title + option.line_width, y_info_title_1, x_process_detail - x_process_title - option.line_width, y_info_title_2 - y_info_title_1+1);
int x_project_type = x_process_detail + option.line_width + option.project_type_width;
pd.project_type_line_pt1 = new PointF(x_project_type, y0);
pd.project_type_line_pt2 = new PointF(x_project_type, y_info_title_2);
pd.project_type_rect = new Rectangle(x_process_detail + option.line_width, y_info_title_1, x_project_type - x_process_detail - option.line_width, y_info_title_2 - y_info_title_1 + 1);
pd.header_type_rect = new Rectangle(x_process_detail, y0, x_project_type - x_process_detail, y2 - y0);
int cost_x = x2 - option.cost_width-option.line_width;
pd.cost_line_pt1 = new PointF(cost_x, y0);
pd.cost_line_pt2 = new PointF(cost_x, y_info_title_2);
pd.cost_rect = new Rectangle(cost_x + option.line_width, y_info_title_1, option.cost_width, y_info_title_2 - y_info_title_1 + 1);
pd.header_cost_rect = new Rectangle(pd.cost_rect.Left, y0, pd.cost_rect.Width, y2 - y0);
pd.item_title_rect.Clear();
pd.item_title_line1.Clear();
pd.item_title_line2.Clear();
int x_item1 = x_process_detail + option.line_width;
int x_item2 = x_project_type - option.line_width+1;
int y_item1 = y2+1;
int y_item2 = y2 + option.planitem_height+1;
int y_mid = 0;
for (int i = 0; i < pj.item_list.Count; i++)
{
Rectangle rect = new Rectangle(x_item1, y_item1, x_item2 - x_item1, y_item2 - y_item1);
pd.item_title_rect.Add(rect);
if (i > 0)
{
if (i == (pj.item_list.Count / 2))
{
pd.item_title_line1.Add(new PointF(x_info_title, y_item1 - option.line_width));
pd.item_title_line2.Add(new PointF(x_item2, y_item1 - option.line_width));
y_mid = y_item1 - option.line_width;
}
else
{
pd.item_title_line1.Add(new PointF(x_item1, y_item1 - option.line_width));
pd.item_title_line2.Add(new PointF(x_item2, y_item1 - option.line_width));
}
}
y_item1 = y_item1 + option.planitem_height + option.line_width;
y_item2 = y_item2 + option.planitem_height + option.line_width;
}
pd.process_detail_time_v_rect = new Rectangle(pd.process_detail_rect.Left, y2+1, pd.process_detail_rect.Width*pj.process_time_v/100, y_mid - y2-1);
pd.process_detail_cost_v_rect = new Rectangle(pd.process_detail_rect.Left, y_mid + 1, pd.process_detail_rect.Width * pj.process_cost_v / 100, bottom - y_mid - 1);
pd.process_title_time_rect = new Rectangle(pd.process_title_rect.Left, y2, pd.process_title_rect.Width, y_mid - y2);
pd.process_title_cost_rect = new Rectangle(pd.process_title_rect.Left, y_mid, pd.process_title_rect.Width, bottom - y_mid);
pd.info_title_time_rect = new Rectangle(pd.info_detail_rect.Left, y2, pd.info_detail_rect.Width, y_mid - y2);
pd.info_title_cost_rect = new Rectangle(pd.info_detail_rect.Left, y_mid, pd.info_detail_rect.Width, bottom - y_mid);
int y_tmp = (y0 + y2) / 2;
pd.header_month_line_pt1=new PointF(x_project_type,y_tmp);
pd.header_month_line_pt2 = new PointF(cost_x, y_tmp);
pd.set_dt(pj.begin_dt, pj.end_dt);
return pd;
}
public void make_drawlist_project(ProjectDrawData pd)
{
add_frame_draw_line(option.get_line_pen(), pd.left, pd.top, pd.right, pd.bottom);
if (pd.draw_header)
{
add_line(option.get_line_pen(), pd.header_line_pt1, pd.header_line_pt2);
add_fill_rect(option.get_header_brush(), pd.header_rect);
}
add_line(option.get_line_pen(), pd.info_title_line_pt1, pd.info_title_line_pt2);
add_fill_rect(option.get_header_brush(), pd.info_title_rect);
add_line(option.get_line_pen(), pd.info_detail_line_pt1, pd.info_detail_line_pt2);
add_fill_rect(option.get_header_brush(), pd.info_detail_rect);
add_line(option.get_line_pen(), pd.process_title_line_pt1, pd.process_title_line_pt2);
add_fill_rect(option.get_header_brush(), pd.process_title_rect);
add_line(option.get_line_pen(), pd.process_detail_line_pt1, pd.process_detail_line_pt2);
add_fill_rect(option.get_process_detail_brush(), pd.process_detail_rect);
add_line(option.get_line_pen(), pd.project_type_line_pt1, pd.project_type_line_pt2);
add_fill_rect(option.get_header_brush(), pd.project_type_rect);
add_line(option.get_line_pen(), pd.cost_line_pt1, pd.cost_line_pt2);
add_fill_rect(option.get_header_brush(), pd.cost_rect);
//
for (int i = 0; i < pd.item_title_line1.Count; i++)
{
add_line(option.get_line_pen(), pd.item_title_line1[i], pd.item_title_line2[i]);
}
for (int i = 0; i < pd.item_title_rect.Count; i++)
{
ProjectItem pi = pd.project.item_list[pd.project.item_list.Count - i - 1];
if (pi.is_current)
{
add_fill_rect(option.get_item_curr_brush(), pd.item_title_rect[i]);
}
add_txt(option.get_text_font(), option.get_text_brush(), pd.item_title_rect[i], option.get_text_format(), pi.title);
}
Brush b = option.get_process_v_brush();
if (pd.project.process_time_warning)
b = option.get_process_warning_brush();
add_fill_rect(b, pd.process_detail_time_v_rect);
if (pd.project.process_time_v > 5)
add_txt(option.get_text_font(), option.get_text_brush(), pd.process_detail_time_v_rect, option.get_text_format(), pd.project.process_time_v.ToString() + "%");
if (pd.project.process_time_v < 100)
add_line(option.get_line_pen(), pd.process_detail_time_v_rect.Right, pd.process_detail_time_v_rect.Top, pd.process_detail_time_v_rect.Right, pd.process_detail_time_v_rect.Bottom);
b = option.get_process_v_brush();
if (pd.project.process_cost_warning)
b = option.get_process_warning_brush();
add_fill_rect(b, pd.process_detail_cost_v_rect);
if (pd.project.process_cost_v > 5)
add_txt(option.get_text_font(), option.get_text_brush(), pd.process_detail_cost_v_rect, option.get_text_format(), pd.project.process_cost_v.ToString() + "%");
if (pd.project.process_cost_v < 100)
add_line(option.get_line_pen(), pd.process_detail_cost_v_rect.Right, pd.process_detail_cost_v_rect.Top, pd.process_detail_cost_v_rect.Right, pd.process_detail_cost_v_rect.Bottom);
add_txt(option.get_text_font(), option.get_text_brush(), pd.header_title_rect, option.get_text_format(), option.header_title);
add_txt(option.get_text_font(), option.get_text_brush(), pd.header_proess_rect, option.get_text_format(), option.header_process);
add_txt(option.get_text_font(), option.get_text_brush(), pd.header_type_rect, option.get_text_format(), option.header_type);
add_txt(option.get_text_font(), option.get_text_brush(), pd.header_cost_rect, option.get_text_format(), option.header_cost);
add_txt(option.get_text_font(), option.get_text_brush(), pd.info_title_rect, option.get_text_format(), pd.project.title);
add_txt(option.get_text_font(), option.get_text_brush(), pd.process_title_time_rect, option.get_text_format(), option.proess_title_time);
add_txt(option.get_text_font(), option.get_text_brush(), pd.process_title_cost_rect, option.get_text_format(), option.proess_title_cost);
add_txt(option.get_text_font(), option.get_text_brush(), pd.info_title_time_rect, option.get_text_format(), pd.project.title_time);
add_txt(option.get_text_font(), option.get_text_brush(), pd.info_title_cost_rect, option.get_text_format(), pd.project.title_cost);
add_line(option.get_line_pen(), pd.header_month_line_pt1, pd.header_month_line_pt2);
float x_tmp = pd.header_month_line_pt1.X;
for (int i = 0; i < pd.item_title_rect.Count; i++)
{
ProjectItem pi = pd.project.item_list[pd.project.item_list.Count - i - 1];
if (!pi.have_actual)
continue;
float x_a_tmp = pd.get_x_by_date(pi.actual_end_dt);
if (x_a_tmp > x_tmp)
x_tmp = x_a_tmp;
}
if ((x_tmp - pd.header_month_line_pt1.X) > 2)
{
Rectangle r_tmp = new Rectangle(pd.header_type_rect.Right + 1, pd.header_rect.Bottom + 1,
(int)x_tmp - pd.header_type_rect.Right - 1, pd.bottom - pd.header_rect.Bottom - 1
);
add_fill_rect(option.get_actual_ground_brush(), r_tmp);
add_line(option.get_line_pen(), (int)x_tmp, pd.header_rect.Bottom + 1, (int)x_tmp, pd.bottom);
}
for (int i = 0; i < pd.item_title_rect.Count; i++)
{
ProjectItem pi = pd.project.item_list[pd.project.item_list.Count - i - 1];
int x1 = pd.get_x_by_date(pi.plan_begin_dt) + 1;
int x2 = pd.get_x_by_date(pi.plan_end_dt);
Rectangle r = pd.item_title_rect[i];
int y1 = (r.Top + r.Bottom - option.plan_proess_bar_height) / 2;
Rectangle r_p = new Rectangle(x1, y1, x2 - x1, option.plan_proess_bar_height);
add_fill_rect(option.get_plan_proess_bar_brush(), r_p);
add_frame_draw_line(option.get_line_pen(), r_p.Left-1, r_p.Top-1, r_p.Right, r_p.Bottom);
}
Rectangle r_last = new Rectangle(0, 0, 0, 0);
for (int i = pd.item_title_rect.Count - 1; i >= 0; i--)
{
ProjectItem pi = pd.project.item_list[pd.project.item_list.Count - i - 1];
if (!pi.have_actual)
continue;
int x1 = pd.get_x_by_date(pi.actual_begin_dt) + 1;
int x2 = pd.get_x_by_date(pi.actual_end_dt);
Rectangle r = pd.item_title_rect[i];
int y1 = (r.Top + r.Bottom - option.actual_proess_bar_height) / 2;
Rectangle r_p = new Rectangle(x1, y1, x2 - x1, option.actual_proess_bar_height);
add_fill_rect(option.get_actual_proess_bar_brush(), r_p);
add_frame_draw_line(option.get_line_pen(), r_p.Left - 1, r_p.Top - 1, r_p.Right, r_p.Bottom);
if (i < pd.item_title_rect.Count - 1)
if (r_last.Height > 1)
{
float x_0_tmp = r_last.Right;
float y_0_tmp = (r_last.Top + r_last.Bottom) / 2;
float x_2_tmp = r_p.Left - 1;
float y_2_tmp = (r_p.Top + r_p.Bottom) / 2;
float y_1_tmp = (y_0_tmp + y_2_tmp) / 2;
add_line(option.get_line_pen(), x_0_tmp, y_0_tmp, x_0_tmp + option.actual_proess_bar_x_inc, y_0_tmp);
add_line(option.get_line_pen(), x_0_tmp + option.actual_proess_bar_x_inc, y_0_tmp, x_0_tmp + option.actual_proess_bar_x_inc, y_1_tmp);
add_line(option.get_line_pen(), x_0_tmp + option.actual_proess_bar_x_inc, y_1_tmp, x_2_tmp - option.actual_proess_bar_x_inc, y_1_tmp);
add_line(option.get_line_pen(), x_2_tmp - option.actual_proess_bar_x_inc, y_1_tmp, x_2_tmp - option.actual_proess_bar_x_inc, y_2_tmp);
add_line(option.get_line_pen(), x_2_tmp - option.actual_proess_bar_x_inc, y_2_tmp, x_2_tmp, y_2_tmp);
}
r_last = r_p;
}
int mw = (int)(pd.header_month_line_pt2.X - pd.header_month_line_pt1.X);
int x_m_last = (int)pd.header_month_line_pt1.X;
int x_m = 0;
for (int i = 1; i < pd.days; i++)
{
if (pd.date_list[i].Day == 1)
{
x_m = pd.get_x_by_date(pd.date_list[i]);
add_line(option.get_line_pen(), x_m, pd.top, x_m, pd.bottom);
if ((x_m - x_m_last) > 36)
{
Rectangle r = new Rectangle(x_m_last, pd.top + 3, x_m - x_m_last, (int)(pd.header_month_line_pt1.Y - pd.top - 2));
add_txt(option.get_text_font(), option.get_text_brush(), r, option.get_text_format(), (pd.date_list[i].AddDays(-1)).Month.ToString() + "月份");
}
x_m_last = x_m;
}
if (pd.date_list[i].DayOfWeek == DayOfWeek.Monday)
{
x_m = pd.get_x_by_date(pd.date_list[i]);
add_line(option.get_line_pen(), x_m, pd.header_month_line_pt1.Y, x_m, pd.header_rect.Bottom);
}
}
x_m = (int)pd.header_month_line_pt2.X;
if ((x_m - x_m_last) > 36)
{
Rectangle r = new Rectangle(x_m_last, pd.top + 3, x_m - x_m_last, (int)(pd.header_month_line_pt1.Y - pd.top - 2));
add_txt(option.get_text_font(), option.get_text_brush(), r, option.get_text_format(), pd.date_list[pd.days - 1].Month.ToString() + "月份");
}
if (pd.project.cost_txt_list.Count > 0)
{
float h_tmp = (pd.bottom - pd.header_cost_rect.Bottom) / pd.project.cost_txt_list.Count;
for (int i = 0; i < pd.project.cost_txt_list.Count; i++)
{
float y = pd.header_cost_rect.Bottom + h_tmp * i + 2;
Rectangle r = new Rectangle(pd.header_cost_rect.Left, (int)y, pd.header_cost_rect.Width, (int)h_tmp);
add_txt(option.get_text_font(), option.get_text_brush(), r, option.get_text_format(), pd.project.cost_txt_list[pd.project.cost_txt_list.Count - 1 - i]);
}
}
{
float h_tmp = (pd.bottom - pd.header_cost_rect.Bottom) / pd.project.cost_txt_list.Count;
float x_cost_0 = pd.header_month_line_pt1.X;
float y_cost_0 = pd.bottom - h_tmp / 2; ;
float y_cost_max = pd.header_cost_rect.Bottom + h_tmp / 2;
float x_cost_last = x_cost_0;
float y_cost_last = y_cost_0;
float cost_tmp = 0;
for (int i = 0; i < pd.item_title_rect.Count; i++)
{
ProjectItem pi = pd.project.item_list[i];
float x2 = pd.get_x_by_date(pi.plan_end_dt);
float y2 = (y_cost_0 - (y_cost_0 - y_cost_max) *( cost_tmp + pi.plan_cost) / pd.project.cost);
if (i == 0)
{
x_cost_last = pd.get_x_by_date(pi.plan_begin_dt) + 1;
}
add_line(option.get_line_plan_cost_pen(), x_cost_last, y_cost_last, x2, y2).smoothing = true ;
x_cost_last = x2;
y_cost_last = y2;
cost_tmp = cost_tmp + pi.plan_cost;
}
x_cost_last = x_cost_0;
y_cost_last = y_cost_0;
cost_tmp = 0;
for (int i = 0; i < pd.item_title_rect.Count; i++)
{
ProjectItem pi = pd.project.item_list[i];
if (! pi.have_actual )
break;
float x2 = pd.get_x_by_date(pi.actual_end_dt);
float y2 = (y_cost_0 - (y_cost_0 - y_cost_max) * (cost_tmp + pi.actual_cost) / pd.project.cost);
if (i == 0)
{
x_cost_last = pd.get_x_by_date(pi.actual_begin_dt) + 1;
}
add_line(option.get_line_actual_cost_pen(), x_cost_last, y_cost_last, x2, y2).smoothing = true;
x_cost_last = x2;
y_cost_last = y2;
cost_tmp = cost_tmp + pi.actual_cost;
}
}
//Font font,Brush brush, Rectangle r,StringFormat sf,string txt
}
public void make_drawlist(int width)
{
projectdata_list.Clear();
_drawlist.Clear();
_width = width;
int x = option.margin_left;
int y = option.margin_top;
for (int i = 0; i < project_list.Count; i++)
{
if (i > 0)
y = y + option.split_height;
int h = get_project_height(project_list[i]);
ProjectDrawData pd = make_data_project(project_list[i], x, y, width - option.margin_right, y + h - 1);
projectdata_list.Add(pd);
make_drawlist_project(pd);
y = y + h;
}
}
public void paint(Graphics g)
{
g.SmoothingMode = SmoothingMode.None;
g.Clear(option.ground_color);
foreach (DrawObject d in _drawlist)
{
if (d is DrawText)
continue;
if (d.smoothing)
continue;
d.Draw(g);
}
g.SmoothingMode = SmoothingMode.HighQuality;
foreach (DrawObject d in _drawlist)
{
if (d is DrawText)
continue;
if (! d.smoothing)
continue;
d.Draw(g);
}
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
foreach (DrawObject d in _drawlist)
{
if (d is DrawText)
d.Draw(g);
}
}
}
}
DrawObject
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace PjDraw
{
public class DrawObject
{
public int Id { get; set; }
public virtual void Draw(Graphics g)
{
}
public virtual int HitTest(PointF point)
{
return -1;
}
public Boolean smoothing = false;
}
public class DrawLine : DrawObject
{
public Pen pen;
public float x1;
public float y1;
public float x2;
public float y2;
public override void Draw(Graphics g)
{
g.DrawLine(pen, x1, y1, x2, y2);
}
public DrawLine()
{
}
public DrawLine(Pen _pen, float _x1, float _y1, float _x2, float _y2)
{
this.pen = _pen;
this.x1 = _x1;
this.y1 = _y1;
this.x2 = _x2;
this.y2 = _y2;
}
}
public class DrawFill : DrawObject
{
public Brush brush;
public float x1;
public float y1;
public float x2;
public float y2;
public override void Draw(Graphics g)
{
g.FillRectangle(brush, x1, y1, x2-x1, y2-y1);
}
public DrawFill()
{
}
public DrawFill(Brush _brush, float _x1, float _y1, float _x2, float _y2)
{
this.brush = _brush;
this.x1 = _x1;
this.y1 = _y1;
this.x2 = _x2;
this.y2 = _y2;
}
}
public class DrawText : DrawObject
{
public string text;
public Font font;
public Brush brush;
public RectangleF rect;
public StringFormat format;
public override void Draw(Graphics g)
{
g.DrawString(text, font, brush, rect, format);
}
public DrawText()
{
}
public DrawText(string _text, Font _font, Brush _brush, RectangleF _rect, StringFormat _format)
{
this.text = _text;
this.font = _font;
this.brush = _brush;
this.rect = _rect;
this.format = _format;
}
}
}
DrawOption
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Drawing;
namespace PjDraw
{
public class DrawOption
{
public Color ground_color = Color.White;
public Color border_color = Color.Black;
public Color header_ground_color = Color.FromArgb(242,242,242);
public int header_height = 42;
public int margin_top = 15;
public int margin_bottom = 15;
public int margin_left = 15;
public int margin_right = 15;
public int split_height = 10;
public int line_width = 1;
public int planitem_height = 20;
public int info_title_width = 80;
public int info_detail_width = 150;
public int process_title_width = 40;
public int process_detail_width = 120;
public int project_type_width = 100;
public int cost_width = 80;
public Color process_detail_ground_color = Color.FromArgb(52, 117, 205);
public Color process_v_color = Color.FromArgb(146, 208, 80);
public Color process_warning_color = Color.FromArgb(255, 0, 0);
public Color plan_proess_bar_color = Color.FromArgb(0, 0, 255);
public Color actual_proess_bar_color = Color.FromArgb(193, 23, 154);
public Color plan_proess_line_color = Color.FromArgb(60, 60, 255);
public Color actual_proess_line_color = Color.FromArgb(193, 63, 194);
public Color actual_ground_color = Color.FromArgb(202, 218, 169);
public Color item_curr_color = Color.FromArgb(255, 192, 0);
private Pen _line_pen = null;
private Pen _line_plan_cost_pen = null;
private Pen _line_actual_cost_pen = null;
private Brush _header_brush = null;
private Brush _process_detail_brush = null;
public string header_title = "项目简介";
public string header_process = "进度展示条";
public string header_cost = "成本";
public int header_proess_text_width = 95;
public int plan_proess_bar_height = 14;
public int actual_proess_bar_height = 6;
public int actual_proess_bar_x_inc = 5;
public string header_type = "项目类别";
public string proess_title_time = "工期\r\n进度";
public string proess_title_cost = "成本\r\n进度";
private Brush _text_brush = null;
private Font _text_font = null;
private StringFormat _text_format = null;
private Brush _process_v_brush = null;
private Brush _process_warning_brush = null;
private Brush _plan_proess_bar_brush = null;
private Brush _item_curr_brush = null;
private Brush _actual_proess_bar_brush = null;
private Brush _actual_ground_brush = null;
public Brush get_actual_ground_brush()
{
return _actual_ground_brush;
}
public Brush get_actual_proess_bar_brush()
{
return _actual_proess_bar_brush;
}
public Brush get_item_curr_brush()
{
return _item_curr_brush;
}
public Brush get_plan_proess_bar_brush()
{
return _plan_proess_bar_brush;
}
public Brush get_process_v_brush()
{
return _process_v_brush;
}
public Brush get_process_warning_brush()
{
return _process_warning_brush;
}
public Pen get_line_pen()
{
return _line_pen;
}
public Brush get_header_brush()
{
return _header_brush;
}
public Brush get_process_detail_brush()
{
return _process_detail_brush;
}
public Brush get_text_brush()
{
return _text_brush;
}
public Font get_text_font()
{
return _text_font;
}
public StringFormat get_text_format()
{
return _text_format;
}
public Pen get_line_plan_cost_pen()
{
return _line_plan_cost_pen;
}
public Pen get_line_actual_cost_pen()
{
return _line_actual_cost_pen;
}
public void init()
{
_line_pen = new Pen(border_color, line_width);
_line_plan_cost_pen = new Pen(plan_proess_line_color, 2);
_line_actual_cost_pen = new Pen(actual_proess_line_color, 2);
_header_brush = new SolidBrush(header_ground_color);
_process_detail_brush = new SolidBrush(process_detail_ground_color);
_text_brush = new SolidBrush(Color.Black);
_process_v_brush= new SolidBrush(process_v_color);
_process_warning_brush= new SolidBrush(process_warning_color);
_plan_proess_bar_brush = new SolidBrush(plan_proess_bar_color);
_actual_proess_bar_brush = new SolidBrush(actual_proess_bar_color);
_actual_ground_brush = new SolidBrush(actual_ground_color);
_item_curr_brush = new SolidBrush(item_curr_color);
_text_font = new Font(new FontFamily("黑体"), 11);
_text_format = new StringFormat();
_text_format.LineAlignment = StringAlignment.Center;
_text_format.Alignment = StringAlignment.Center;
}
~DrawOption()
{
if (_line_pen != null)
_line_pen.Dispose();
if (_header_brush != null)
_header_brush.Dispose();
if (_process_detail_brush != null)
_process_detail_brush.Dispose();
if (_text_brush != null)
_text_brush.Dispose();
if (_process_v_brush != null)
_process_v_brush.Dispose();
if (_process_warning_brush != null)
_process_warning_brush.Dispose();
if (_plan_proess_bar_brush != null)
_plan_proess_bar_brush.Dispose();
if (_item_curr_brush != null)
_item_curr_brush.Dispose();
if (_actual_proess_bar_brush != null)
_actual_proess_bar_brush.Dispose();
if (_actual_ground_brush != null)
_actual_ground_brush.Dispose();
if (_line_plan_cost_pen != null)
_line_plan_cost_pen.Dispose();
if (_line_actual_cost_pen != null)
_line_actual_cost_pen.Dispose();
}
}
}
ProjectDraw
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Drawing;
namespace PjDraw
{
public class ProjectDraw
{
public List<ProjectItem> item_list = new List<ProjectItem>();
public string title = "";
public string title_time = "";
public string title_cost = "";
public DateTime begin_dt;
public DateTime end_dt;
public float cost = 0;
public List<string> cost_txt_list = new List<string>();
public int process_time_v = 0;
public Boolean process_time_warning = false;
public int process_cost_v = 0;
public Boolean process_cost_warning = false;
public void create_cost_txt_list(int c)
{
make_textlist(cost,c, cost_txt_list);
}
public void make_textlist(float f, int c, List<string> list)
{
list.Clear();
if (c <= 0)
return;
float f_inc = f / c;
list.Add("0");
float v = 0F;
for (int i = 1; i < c; i++)
{
v = v + f_inc;
list.Add(v.ToString());
}
list.Add(f.ToString());
}
public int get_s_c(float f, int c)
{
int int_f = (int)f;
for (int i = c; i >= 2; i--)
{
if ((int_f % i) == 0)
return i;
}
return c;
}
public static ProjectDraw load(string fn)
{
if (!System.IO.File.Exists(fn))
{
return new ProjectDraw();
}
XmlReader xmlreader = XmlReader.Create(fn);
XmlSerializer xmlserilize = new XmlSerializer(typeof(ProjectDraw));
ProjectDraw obj = (ProjectDraw)xmlserilize.Deserialize(xmlreader);
xmlreader.Close();
return obj;
}
public virtual Boolean save(string fn)
{
using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
{
System.IO.TextWriter writer = new System.IO.StreamWriter(stream, Encoding.UTF8);
Type type = this.GetType();
XmlSerializer serializer = new XmlSerializer(type);
serializer.Serialize(writer, this);
stream.Position = 0;
byte[] buf = new byte[stream.Length];
stream.Read(buf, 0, buf.Length);
string serializerString = System.Text.Encoding.UTF8.GetString(buf);
System.IO.File.WriteAllText(fn, serializerString);
}
return true;
}
}
public class ProjectDrawData
{
public ProjectDraw project = null;
public int left;
public int top;
public int right;
public int bottom;
public Boolean draw_header = true;
public Rectangle header_rect;
public PointF header_line_pt1;
public PointF header_line_pt2;
public Rectangle header_title_rect;
public Rectangle header_proess_rect;
public Rectangle header_type_rect;
public Rectangle header_cost_rect;
public Rectangle info_title_rect;
public PointF info_title_line_pt1;
public PointF info_title_line_pt2;
public Rectangle info_detail_rect;
public PointF info_detail_line_pt1;
public PointF info_detail_line_pt2;
public Rectangle process_title_rect;
public PointF process_title_line_pt1;
public PointF process_title_line_pt2;
public Rectangle process_detail_rect;
public PointF process_detail_line_pt1;
public PointF process_detail_line_pt2;
public Rectangle project_type_rect;
public PointF project_type_line_pt1;
public PointF project_type_line_pt2;
public Rectangle cost_rect;
public PointF cost_line_pt1;
public PointF cost_line_pt2;
public PointF info_time_line_pt1;
public PointF info_time_line_pt2;
public List<Rectangle> item_title_rect = new List<Rectangle>();
public List<PointF> item_title_line1 = new List<PointF>();
public List<PointF> item_title_line2 = new List<PointF>();
public Rectangle process_title_time_rect;
public Rectangle process_title_cost_rect;
public Rectangle info_title_time_rect;
public Rectangle info_title_cost_rect;
public Rectangle process_detail_time_v_rect;
public Rectangle process_detail_cost_v_rect;
public PointF header_month_line_pt1;
public PointF header_month_line_pt2;
public DateTime begin_dt;
public DateTime end_dt;
public int days;
public DateTime[] date_list;
public int get_x_by_date(DateTime d)
{
float mw = header_month_line_pt2.X - header_month_line_pt1.X + 0.5F;
TimeSpan ts = d - begin_dt;
int i = (int)(ts.TotalDays + 0.5);
return (int)(header_month_line_pt1.X + mw * i / days);
}
public void set_dt(DateTime v1, DateTime v2)
{
begin_dt = v1;
end_dt = v2;
TimeSpan ts = end_dt - begin_dt;
days = (int)(ts.TotalDays+0.5);
date_list=new DateTime[days];
for (int i = 0; i < days; i++)
{
date_list[i] = begin_dt.AddDays(i);
}
}
}
}
ProjectItem
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PjDraw
{
public class ProjectItem
{
public List<ProjectItem> item_list = new List<ProjectItem>();
public string title = "";
public DateTime plan_begin_dt;
public DateTime plan_end_dt;
public Boolean is_current = false;
public Boolean have_actual = false;
public DateTime actual_begin_dt;
public DateTime actual_end_dt;
public float plan_cost;
public float actual_cost;
}
}