C#简单的绘图处理

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;
    }
}

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月巴月巴白勺合鸟月半

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值