模仿Word中组织结构图的特点生成流程图

系统 1489 0
        
          //
        
        
          基本原理:   

 

 
        
        
          //
        
        
           1. 从下往上计算位置   

  

 
        
        
          //
        
        
           2. 模仿Word中组织结构图的特点   

  


        
        
          //
        
        
          调用代码:   
        
        
            

Tree
        
        <
        
          string
        
        > tree = 
        
          new
        
         Tree<
        
          string
        
        >(
        
          null
        
        , 
        
          "
        
        
          董事会
        
        
          "
        
        
          );   

                tree.Add(
        
        
          "
        
        
          北京公司
        
        
          "
        
        
          );   

                tree.Add(
        
        
          "
        
        
          董事秘书室特殊机构
        
        
          "
        
        
          );   

                tree.Add(
        
        
          "
        
        
          上海公司
        
        
          "
        
        
          );   

  

                tree.Childs[
        
        
          0
        
        ].Add(
        
          "
        
        
          总经理办公室
        
        
          "
        
        
          );   

                tree.Childs[
        
        
          0
        
        ].Add(
        
          "
        
        
          财务部
        
        
          "
        
        
          );   

                tree.Childs[
        
        
          0
        
        ].Add(
        
          "
        
        
          销售部
        
        
          "
        
        
          );   

  

                tree.Childs[
        
        
          2
        
        ].Add(
        
          "
        
        
          上海销售部
        
        
          "
        
        
          );   

  

               Bitmap bmp 
        
        =
        
           tree.DrawAsImage();   

  


        
        
          //
        
        
          实现代码:   
        
        
          using
        
        
           System;   


        
        
          using
        
        
           System.Collections.Generic;   


        
        
          using
        
        
           System.Text;   


        
        
          using
        
        
           System.Drawing;   




        
        
          namespace
        
        
           Test   

  

{   

   
        
        
          ///
        
        
          <summary>
        
        
          ///
        
        
           用来输出组织结构图的类   

  
        
        
          ///
        
        
          </summary>
        
        
          ///
        
        
          <typeparam name="T"></typeparam>
        
        
          public
        
        
          class
        
         Tree<T>
        
             

   {   

        Tree
        
        <T> _Parent = 
        
          null
        
        
          ;   

      T _Content;   

       List
        
        <Tree<T>> _Childs = 
        
          new
        
         List<Tree<T>>
        
          ();   

        SizeF _Size;   

        Rectangle _Rec;   

 

       
        
        
          public
        
         Tree(Tree<T>
        
           parent, T content)   

       {   

           _Parent 
        
        =
        
           parent;   

            _Content 
        
        =
        
           content;   

      }   

  

       
        
        
          public
        
         Tree<T>
        
           Add(T content)   

        {   

           Tree
        
        <T> tree = 
        
          new
        
         Tree<T>(
        
          this
        
        
          , content);   

          _Childs.Add(tree);   

          
        
        
          return
        
        
           tree;   

       }   

 

       
        
        
          public
        
         Tree<T> Parent { 
        
          get
        
         { 
        
          return
        
        
           _Parent; } }   

  

      
        
        
          public
        
         T Content { 
        
          get
        
         { 
        
          return
        
        
           _Content; } }   



       
        
        
          public
        
         List<Tree<T>> Childs { 
        
          get
        
         { 
        
          return
        
        
           _Childs; } }   



        
        
        
          public
        
         SizeF Size { 
        
          get
        
         { 
        
          return
        
         _Size; } 
        
          set
        
         { _Size =
        
           value; } }   



       
        
        
          public
        
         Rectangle Rec { 
        
          get
        
         { 
        
          return
        
         _Rec; } 
        
          set
        
         { _Rec =
        
           value; } }   



       
        
        
          void
        
         MeatureAllSize(Graphics g, Font font, 
        
          int
        
        
           addWidth)   

       {   

           _Size 
        
        =
        
           g.MeasureString(_Content.ToString(), font);   

            _Size.Width 
        
        +=
        
           addWidth;   

          
        
        
          foreach
        
         (Tree<T> tree 
        
          in
        
        
           Childs)   

               tree.MeatureAllSize(g, font, addWidth);   

      }   

 

       List
        
        <List<Tree<T>>>
        
           GetTreeLayers()   

      {   

            List
        
        <List<Tree<T>>> layers = 
        
          new
        
         List<List<Tree<T>>>
        
          ();   

          GetTreeLayers(layers, 
        
        
          new
        
         List<Tree<T>>(
        
          new
        
         Tree<T>[] { 
        
          this
        
         }), 
        
          0
        
        
          );   

  

          
        
        
          return
        
        
           layers;   

       }   

 

       
        
        
          void
        
         GetTreeLayers(List<List<Tree<T>>> layers, List<Tree<T>> childs, 
        
          int
        
        
           level)   

       {   

           
        
        
          if
        
         (childs.Count == 
        
          0
        
        ) 
        
          return
        
        
          ;   

           
        
        
          if
        
         (layers.Count <= level) layers.Add(
        
          new
        
         List<Tree<T>>
        
          ());   

 

          
        
        
          for
        
         (
        
          int
        
         i = 
        
          0
        
        ; i < childs.Count; i++
        
          )   

           {   

               layers[level].Add(childs[i]);   

               GetTreeLayers(layers, childs[i].Childs, level 
        
        + 
        
          1
        
        
          );   

           }   

       }   



        
        
        
          ///
        
        
          <summary>
        
        
          ///
        
        
           设置显示区域(从最后一层最左开始)   

       
        
        
          ///
        
        
          </summary>
        
        
          ///
        
        
          <param name="level"></param>
        
        
          ///
        
        
          <param name="height"></param>
        
        
          ///
        
        
          <param name="interval"></param>
        
        
          ///
        
        
          <param name="left"></param>
        
        
          void
        
         SetRectangle(
        
          int
        
         level, 
        
          int
        
         height, 
        
          int
        
         hInterval, 
        
          int
        
         vInterval, 
        
          int
        
        
           left)   

      {   

           
        
        
          int
        
         index = 
        
          0
        
        
          ;   

           
        
        
          if
        
         (Parent != 
        
          null
        
        ) index = Parent.Childs.IndexOf(
        
          this
        
        
          );   

 

          
        
        
          if
        
         (Childs.Count == 
        
          0
        
        
          )   

           {   

               
        
        
          //
        
        
           没有儿子,就向前靠   
        
        
          if
        
         (left > 
        
          0
        
        ) left +=
        
           hInterval;   

            }   

         
        
        
          else
        
        
            

           {   

               
        
        
          //
        
        
           有儿子,就在儿子中间   
        
        
          int
        
         centerX = (Childs[
        
          0
        
        ].Rec.Left + Childs[Childs.Count - 
        
          1
        
        ].Rec.Right) / 
        
          2
        
        
          ;   

               left 
        
        = centerX - (
        
          int
        
        )_Size.Width / 
        
          2
        
        
          ;   

 

              
        
        
          //
        
        
           并且不能和前面的重复,如果重复,联同子孙和子孙的右边节点右移   
        
        
          if
        
         (Parent != 
        
          null
        
         && index > 
        
          0
        
        
          )   

               {   

                   
        
        
          int
        
         ex = (Parent.Childs[index - 
        
          1
        
        ].Rec.Right + hInterval) -
        
           left;   

                  
        
        
          if
        
         (index > 
        
          0
        
         && ex > 
        
          0
        
        
          )   

                  {   

                      
        
        
          for
        
         (
        
          int
        
         i = index; i < Parent.Childs.Count; i++
        
          )   

                           Parent.Childs[i].RightChilds(ex);   

                       left 
        
        +=
        
           ex;   

                  }   

               }   

           }   

           _Rec 
        
        = 
        
          new
        
         Rectangle(left, (height + vInterval) * level, (
        
          int
        
        
          )_Size.Width, height);   

       }   



       
        
        
          ///
        
        
          <summary>
        
        
          ///
        
        
           所有子孙向右平移   

       
        
        
          ///
        
        
          </summary>
        
        
          ///
        
        
          <param name="ex"></param>
        
        
          void
        
         RightChilds(
        
          int
        
        
           ex)   

       {   

            Rectangle rec;   

            
        
        
          for
        
         (
        
          int
        
         i = 
        
          0
        
        ; i < _Childs.Count; i++
        
          )   

          {   

              rec 
        
        =
        
           _Childs[i].Rec;   

               rec.Offset(ex, 
        
        
          0
        
        
          );   

              _Childs[i].Rec 
        
        =
        
           rec;   

               _Childs[i].RightChilds(ex);   

           }   

     }   



      
        
        
          void
        
         Offset(
        
          int
        
         x, 
        
          int
        
        
           y)   

        {   

            _Rec.Offset(x, y);   

           
        
        
          for
        
         (
        
          int
        
         i = 
        
          0
        
        ; i < _Childs.Count; i++
        
          )   

               _Childs[i].Offset(x, y);   

        }   

 

       
        
        
          public
        
        
           Bitmap DrawAsImage()   

        {   

           
        
        
          return
        
         DrawAsImage(Pens.Black, 
        
          new
        
         Font(
        
          "
        
        
          宋体
        
        
          "
        
        , 
        
          10.5f
        
        ), 
        
          26
        
        , 
        
          20
        
        , 
        
          5
        
        , 
        
          20
        
        , 
        
          26
        
        
          );   

       }   



       
        
        
          public
        
         Bitmap DrawAsImage(Pen pen, Font font, 
        
          int
        
         h, 
        
          int
        
        
           horPadding,   

           
        
        
          int
        
         horInterval, 
        
          int
        
         verInterval, 
        
          int
        
        
           borderWidth)   

       {   

           Bitmap bmp 
        
        = 
        
          new
        
         Bitmap(
        
          1
        
        , 
        
          1
        
        
          );   

            Graphics g 
        
        =
        
           Graphics.FromImage(bmp);   

            
        
        
          //
        
        
           把树扁平化   
        
        

           List<List<Tree<T>>> layers =
        
           GetTreeLayers();   

 

         
        
        
          //
        
        
           算出每个单元的大小   
        
        
                     MeatureAllSize(g, font, horPadding);   

            g.Dispose();   

           bmp.Dispose();   

 

           
        
        
          //
        
        
           从最后一层开始排列   
        
        
          int
        
         left = 
        
          0
        
        
          ;   

          
        
        
          for
        
         (
        
          int
        
         i = layers.Count - 
        
          1
        
        ; i >= 
        
          0
        
        ; i--
        
          )   

          {   

               
        
        
          for
        
         (
        
          int
        
         j = 
        
          0
        
        ; j < layers[i].Count; j++
        
          )   

               {   

                   layers[i][j].SetRectangle(i, h, horInterval, verInterval, left);   

                    left 
        
        =
        
           layers[i][j].Rec.Right;   

               }   

           }   

  

          Offset(borderWidth, borderWidth);   



           
        
        
          //
        
        
           获取画布需要的大小   
        
        
          int
        
         maxHeight = (h + verInterval) * layers.Count - verInterval + borderWidth * 
        
          2
        
        
          ;   

           
        
        
          int
        
         maxWidth = 
        
          0
        
        
          ;   

            
        
        
          for
        
         (
        
          int
        
         i = layers.Count - 
        
          1
        
        ; i >= 
        
          0
        
        ; i--
        
          )   

          {   

               
        
        
          for
        
         (
        
          int
        
         j = 
        
          0
        
        ; j < layers[i].Count; j++
        
          )   

                {   

                  
        
        
          if
        
         (layers[i][j].Rec.Right >
        
           maxWidth)   

                       maxWidth 
        
        =
        
           layers[i][j].Rec.Right;   

              }   

           }   

          maxWidth 
        
        += borderWidth; 
        
          //
        
        
           边宽   

 

          
        
        
          //
        
        
        

           bmp = 
        
          new
        
        
           Bitmap(maxWidth, maxHeight);   

            g 
        
        =
        
           Graphics.FromImage(bmp);   

           g.Clear(Color.White);   

           StringFormat format 
        
        =
        
           (StringFormat)StringFormat.GenericDefault.Clone();   

            format.Alignment 
        
        =
        
           StringAlignment.Center;   

           format.LineAlignment 
        
        =
        
           StringAlignment.Center;   

 

           Rectangle rec, recParent;   

            
        
        
          for
        
         (
        
          int
        
         i = 
        
          0
        
        ; i < layers.Count; i++
        
          )   

          {   

               
        
        
          for
        
         (
        
          int
        
         j = 
        
          0
        
        ; j < layers[i].Count; j++
        
          )   

                {   

                   
        
        
          //
        
        
           画字   
        
        

                  rec =
        
           (Rectangle)layers[i][j].Rec;   

                   g.DrawRectangle(pen, rec);   

                   g.DrawString(layers[i][j].Content.ToString(), font, 
        
        
          new
        
        
           SolidBrush(pen.Color),   

                       rec, format);   

                   
        
        
          //
        
        
           画到父亲的线   
        
        
          if
        
         (layers[i][j].Parent != 
        
          null
        
        
          )   

                  {   

                        recParent 
        
        =
        
           layers[i][j].Parent.Rec;   

                       g.DrawLine(pen, rec.Left 
        
        + rec.Width / 
        
          2
        
        
          , rec.Top,   

                          rec.Left 
        
        + rec.Width / 
        
          2
        
        , rec.Top - verInterval / 
        
          2
        
        
          );   

                       g.DrawLine(pen, recParent.Left 
        
        + recParent.Width / 
        
          2
        
        
          , recParent.Bottom,   

                          recParent.Left 
        
        + recParent.Width / 
        
          2
        
        , rec.Top - verInterval / 
        
          2
        
        
          );   

                       g.DrawLine(pen, rec.Left 
        
        + rec.Width / 
        
          2
        
        , rec.Top - verInterval / 
        
          2
        
        
          ,   

                           recParent.Left 
        
        + recParent.Width / 
        
          2
        
        , rec.Top - verInterval / 
        
          2
        
        
          );   

                  }   

              }   

          }   



          g.Flush();   

          g.Dispose();   

 

          
        
        
          return
        
        
           bmp;   

       }   

   }   

}   
        
      
View Code

 

模仿Word中组织结构图的特点生成流程图


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论