组织架构图 orgchart

来源:互联网 发布:照片十字绣软件 编辑:程序博客网 时间:2024/04/30 01:53

原理是利用字典获得坐标位置,一二三层是横向显示,关键控制好X坐标,第四层竖向显示,关键控制好Y坐标

数据方面:员工之间是通过manager=id来做关联的.

1.绘制单元格,图片等信息

2.绘制线条

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.Data;using System.Drawing;using System.Drawing.Drawing2D;using System.IO;namespace Orgchart{    public partial class Orgchart : System.Web.UI.Page    {            Dictionary<int, ImageUnit> NodeDic = new Dictionary<int, ImageUnit>();  //绘制单元集合字典            List<Staff> list1 = null, list2 = null, list3 = null, list4 = null;            int unitWidth = 150;            int startX = 250;            protected void Page_Load(object sender, EventArgs e)            {                if (!IsPostBack)                {                    list1 = new List<Staff>();                    list1.Add(new Staff(1, 0, "董事会", "总裁", "keller1", "77391929@qq.com", DateTime.Now, DateTime.Now, DateTime.Now, "xi.jpg"));                    list2 = new List<Staff>();                    list2.Add(new Staff(11, 1, "人事部", "人事部主管", "keller11", "77391929@qq.com", DateTime.Now, DateTime.Now, DateTime.Now, "xi.jpg"));                    list2.Add(new Staff(12, 1, "开发部", "开发部主管", "keller12", "77391929@qq.com", DateTime.Now, DateTime.Now, DateTime.Now, "xi.jpg"));                    list2.Add(new Staff(13, 1, "市场部", "市场部主管", "keller13", "77391929@qq.com", DateTime.Now, DateTime.Now, DateTime.Now, "xi.jpg"));                    list3 = new List<Staff>();                    list3.Add(new Staff(121, 12, "开发部", "开发经理1", "keller121", "77391929@qq.com", DateTime.Now, DateTime.Now, DateTime.Now, "xi.jpg"));                    list3.Add(new Staff(122, 12, "开发部", "开发经理2", "keller122", "77391929@qq.com", DateTime.Now, DateTime.Now, DateTime.Now, "xi.jpg"));                    list3.Add(new Staff(123, 12, "开发部", "开发经理3", "keller123", "77391929@qq.com", DateTime.Now, DateTime.Now, DateTime.Now, "xi.jpg"));                                      list4 = new List<Staff>();                    list4.Add(new Staff(1211, 121, "开发部", " 程序员1题目要长字体会变小试试 ", "keller1211", "77391929@qq.com", DateTime.Now, DateTime.Now, DateTime.Now, "xi.jpg"));                    list4.Add(new Staff(1212, 121, "开发部", "程序员2", "keller1212", "77391929@qq.com", DateTime.Now, DateTime.Now, DateTime.Now, "xi.jpg"));                                        Graphics g = null;                    Bitmap img = null;                    InitStaff();                    int Mapheight = GetMaxYFromDic() + 150; //画布高度                    int MapWidth = GetMaxXFromDic() + 180; //画布宽度                    img = new Bitmap(MapWidth, Mapheight);//生成图像的实例                    g = Graphics.FromImage(img);//从Img对象生成新的Graphics对象                    g.Clear(Color.White);//填充背景色:白色                    if (list1 != null)                    {                        DrawLineTag(g, 0);                        DrawLayer(g, list1, true);                    }                    if (list2 != null)                    {                        DrawLineTag(g, 1);                        DrawLayer(g, list2, false);                    }                    if (list3 != null)                    {                        DrawLineTag(g, 2);                        DrawLayer3(g, list3, false);                    }                    if (list4 != null)                    {                        DrawLineTag(g, 3);                        DrawLayer4(g, list4, false);                    }                    MemoryStream ms = null;                    ms = new MemoryStream();//生成内存流对象                    System.Drawing.Imaging.EncoderParameters ps = new System.Drawing.Imaging.EncoderParameters(1);                    System.Drawing.Imaging.EncoderParameter p1 = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);                    ps.Param[0] = p1;                    img.Save(ms, GetEncoder(System.Drawing.Imaging.ImageFormat.Jpeg), ps);                    Response.ClearContent();//更改http ContentType                    Response.ContentType = "image/Gif";                    Response.BinaryWrite(ms.ToArray());//将整个二进制流的内容写入字节数组  */                    //回收资源                    g.Dispose();                    img.Dispose();                    Response.End();                }            }            public void InitStaff()            {                ImageUnit iu = null;                int count = 0;                int leftBrotherMaxX = 0;                int leftBrotherCount = 0;                if (list1 != null)                {                    count = 0;                    iu = new ImageUnit();                    for (int i = 0; i < list1.Count; i++)                    {                        Staff obj = list1[i];                        iu.staff = obj;                        iu.x = startX + count * 200;                        iu.y = 5;                        NodeDic.Add(obj.id, iu);                        iu = new ImageUnit();                        count++;                    }                }                if (list2 != null)                {                    count = 0;                    iu = new ImageUnit();                    foreach (Staff item in list2)                    {                        iu.staff = item;                        iu.x = NodeDic[item.manager].x + 180;//父节点X                        iu.y = 185;                        leftBrotherCount = FindBrotherLeft(item.manager, list2, out leftBrotherMaxX);                        if (leftBrotherCount > 0)                        {                            iu.x = leftBrotherMaxX + (unitWidth + 30);                            MoveRightNodes(item.manager, list1);                            MoveRightNodes2(iu.x, list2);                        }                        else                        {                            if (iu.staff.manager == item.manager)//第二层对齐方式                            {                                iu.x = iu.x - 180;                            }                        }                        NodeDic.Add(item.id, iu);                        iu = new ImageUnit();                        count++;                    }                }                if (list3 != null)                {                    count = 0;                    iu = new ImageUnit();                    foreach (Staff item in list3)                    {                        iu.staff = item;                        iu.y = 365;                        iu.x = NodeDic[item.manager].x;  //父节点X                        leftBrotherCount = FindBrotherLeft(item.manager, list3, out leftBrotherMaxX);                        if (leftBrotherCount > 0)                        {                            iu.x = leftBrotherMaxX + (unitWidth + 30);                            MoveRightNodes(NodeDic[item.manager].staff.manager, list1);                            MoveRightNodes(item.manager, list2);                            MoveRightNodes2(iu.x, list3);                        }                        NodeDic.Add(item.id, iu);                        iu = new ImageUnit();                        count++;                    }                }                if (list4 != null)                {                    count = 0;                    iu = new ImageUnit();                    foreach (Staff item in list4)                    {                        iu.staff = item;                        iu.y = 545;                        iu.x = NodeDic[item.manager].x - 15;  //父节点X                        leftBrotherCount = FindBrotherLeft(item.manager, list4);                        if (leftBrotherCount > 0)                        {                            leftBrotherCount = leftBrotherCount + 1;                            iu.y = 545 + (leftBrotherCount - 1) * 180;                        }                        NodeDic.Add(item.id, iu);                        iu = new ImageUnit();                        count++;                    }                }            }            #region left right            //寻找左边兄弟            public int FindBrotherLeft(int parentId, List<Staff> list, out int leftBrotherMaxX)            {                int count = 0;                leftBrotherMaxX = 0;                foreach (Staff obj in list)                {                    //ContainsKey是否包含指定的键                    if (obj.manager == parentId && NodeDic.ContainsKey(obj.id))                    {                        count++;                        if (NodeDic[obj.id].x > leftBrotherMaxX)                        {                            leftBrotherMaxX = NodeDic[obj.id].x;                        }                    }                }                return count;            }            //寻找己赋坐标兄弟            public int FindBrotherLeft(int parentId, List<Staff> list)            {                int count = 0;                foreach (Staff obj in list)                {                    //ContainsKey是否包含指定的键                    if (obj.manager == parentId && NodeDic.ContainsKey(obj.id))                    {                        count++;                    }                }                return count;            }            //移动指定x 右边的节点 半个unit宽度            public void MoveRightNodes(int parentId, List<Staff> list)            {                foreach (Staff obj in list)                {                    if (obj.id == parentId)                    {                        NodeDic[obj.id].x += (unitWidth + 30) / 2;                    }                    else                    {                        if (NodeDic[obj.id].x > NodeDic[parentId].x)                        {                            NodeDic[obj.id].x += (unitWidth + 30);                        }                    }                }            }            //移动指定x 右边的节点 半个unit宽度            public void MoveRightNodes(int parentId, List<Staff> listParent, List<Staff> listCurrent)            {                foreach (Staff obj in listParent)                {                    if (obj.id == parentId)                        NodeDic[obj.id].x += (unitWidth + 30) / 2;                    else if (NodeDic[obj.id].x > NodeDic[parentId].x)                    {                        NodeDic[obj.id].x += (unitWidth + 30);                        foreach (Staff _obj in listCurrent)                        {                            if (_obj.manager == obj.id)                            {                                if (NodeDic.ContainsKey(obj.id))                                    NodeDic[obj.id].x += (unitWidth + 30);                            }                        }                    }                }            }            //移动指定x 右边的节点 半个unit宽度            public void MoveRightNodes2(int x, List<Staff> list)            {                foreach (Staff obj in list)                {                    if (NodeDic.ContainsKey(obj.id) && NodeDic[obj.id].x >= x)                        NodeDic[obj.id].x += (unitWidth + 30);                }            }            #endregion            #region 绘制线条            public void DrawLayer(Graphics g, List<Staff> list, bool isFirst)            {                int MinChildX = 0, MaxChildX = 0;                SolidBrush sb = new SolidBrush(Color.Black);                Pen p = new Pen(sb);                foreach (Staff obj in list)                {                    if (GetChildCount(obj.id) > 0)                    {                        MinChildX = GetMinXFromDicByParentID(obj.id, NodeDic);  //获取子结点中最小x                        MaxChildX = GetMaxXFromDicByParentID(obj.id, NodeDic);//获取子结点中最大x                        g.DrawLine(p, MinChildX + unitWidth / 2, NodeDic[obj.id].y + 180 - 15, MaxChildX + 75, NodeDic[obj.id].y + 180 - 15);  //画子横线                             g.DrawLine(p, NodeDic[obj.id].x + unitWidth / 2, NodeDic[obj.id].y + 150, NodeDic[obj.id].x + unitWidth / 2, NodeDic[obj.id].y + 165);   //画子竖线                      }                    DrawUnit123(g, obj, isFirst);    //画结点                }            }            public void DrawLayer3(Graphics g, List<Staff> list, bool isFirst)            {                int MaxChildY = 0;                SolidBrush sb = new SolidBrush(Color.Black);                Pen p = new Pen(sb);                p.Width = 1;                p.Color = Color.Black;                foreach (Staff obj in list)                {                    if (GetChildCount(obj.id) > 0)                    {                        MaxChildY = GetMaxYFromDicByParentID(obj.id);                        g.DrawLine(p, NodeDic[obj.id].x + unitWidth - 3, NodeDic[obj.id].y + 60, NodeDic[obj.id].x + unitWidth - 3, MaxChildY + 20); //NodeDic[obj.ID].y + 165);   //画子竖线                      }                    DrawUnit123(g, obj, isFirst);    //画结点                }            }            public void DrawLayer4(Graphics g, List<Staff> list, bool isFirst)            {                int MaxChildY = 0;                SolidBrush sb = new SolidBrush(Color.Black);                Pen p = new Pen(sb);                p.Width = 1;                foreach (Staff obj in list)                {                    if (GetChildCount(obj.id) > 0)                    {                        MaxChildY = GetMaxYFromDicByParentID(obj.id);                   }                    DrawUnit4(g, obj, isFirst);    //画结点                }            }            #endregion            #region 绘图处理            private static System.Drawing.Imaging.ImageCodecInfo GetEncoder(System.Drawing.Imaging.ImageFormat format)            {                System.Drawing.Imaging.ImageCodecInfo[] codecs = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders();                foreach (System.Drawing.Imaging.ImageCodecInfo codec in codecs)                {                    if (codec.FormatID == format.Guid)                    {                        return codec;                    }                }                return null;            }            //图片缩放--变窄            public System.Drawing.Image NarrowImage(System.Drawing.Image img, int x, int y)            {                return new Bitmap(img, x, y);            }            //获取子结点个数            public int GetChildCount(int parentId)            {                int Count = 0;                foreach (int ID in NodeDic.Keys)                {                    if (NodeDic[ID].staff.manager == parentId)                        Count++;                }                return Count;            }            //获取字典指定父级的子结点的最小横坐标            public int GetMinXFromDicByParentID(int parentId, Dictionary<int, ImageUnit> Dic)            {                int MinValue = 1000000;                foreach (int ID in Dic.Keys)                {                    if (Dic[ID].staff.manager == parentId)                    {                        if (Dic[ID].x < MinValue)                            MinValue = Dic[ID].x;                    }                }                if (MinValue == 1000000)                    MinValue = 0;                return MinValue;            }            //获取字典指定父级的子结点的最大横坐标            public int GetMaxXFromDicByParentID(int parentId, Dictionary<int, ImageUnit> Dic)            {                int MaxValue = 0;                foreach (int ID in Dic.Keys)                {                    if (Dic[ID].staff.manager == parentId)                    {                        if (Dic[ID].x > MaxValue)                            MaxValue = Dic[ID].x;                    }                }                return MaxValue;            }            //获取字典指定父级的子结点的最大横坐标            public int GetMaxXFromDic()            {                int MaxValue = 0;                foreach (int ID in NodeDic.Keys)                {                    if (NodeDic[ID].x > MaxValue)                        MaxValue = NodeDic[ID].x;                }                return MaxValue;            }            //获取字典指定父级的子结点的最大纵坐标            public int GetMaxYFromDicByParentID(int parentId)            {                int MaxValue = 0;                foreach (int ID in NodeDic.Keys)                {                    if (NodeDic[ID].staff.manager == parentId)                    {                        if (NodeDic[ID].y > MaxValue)                            MaxValue = NodeDic[ID].y;                    }                }                return MaxValue;            }            //获得字典指定父级的子结点的最大纵坐标            public int GetMaxYFromDic()            {                int MaxValue = 0;                foreach (int ID in NodeDic.Keys)                {                    if (NodeDic[ID].y > MaxValue)                        MaxValue = NodeDic[ID].y;                }                return MaxValue;            }            #endregion            #region 绘制单元            // 绘制员工单元 1 2 3             public void DrawUnit123(Graphics g, Staff obj, bool isFirst)            {                int x, y;                x = NodeDic[obj.id].x;                y = NodeDic[obj.id].y;                SolidBrush sb = new SolidBrush(Color.FromArgb(39, 57, 153));                Font f = new Font("", 9, FontStyle.Regular); //定义字体                Rectangle r = new Rectangle(x, y, unitWidth, 70); //绘制矩形                g.FillRectangle(sb, r);//填充矩形                sb.Color = Color.White;//笔刷颜色                              //部门                int StringStartX = (unitWidth - Convert.ToInt32(g.MeasureString(obj.department, f).Width)) / 2;                g.DrawString(obj.department, f, sb, x + StringStartX, y + 3, StringFormat.GenericTypographic);                //部门                //处理职位过长的状况                if (obj.position == null)                {                    obj.position = "";                }                else                {                    if (g.MeasureString(obj.position, f).Width > unitWidth)                    {                        float FontSize = 9;                        while (g.MeasureString(obj.position, f).Width > unitWidth)                        {                            FontSize--;                            f = new Font("", FontSize, FontStyle.Regular);                            y++;                        }                        f = new Font("", FontSize + 1, FontStyle.Regular);                    }                    StringStartX = (unitWidth - Convert.ToInt32(g.MeasureString(obj.position, f).Width)) / 2;                    //g.DrawString(currentPositionName.ToUpper(), f, sb, x + StringStartX, y + 18);                    g.DrawString(obj.position, f, sb, x + StringStartX, y + 18);                }                //处理职位过长的状况                //姓名                f = new Font("", 9, FontStyle.Regular);                StringStartX = (unitWidth - Convert.ToInt32(g.MeasureString(obj.name, f).Width)) / 2;                g.DrawString(obj.name, f, sb, x + StringStartX, y + 33);                //姓名                //邮箱                if (obj.email.Contains("@"))                {                    obj.email = obj.email.Substring(0, obj.email.IndexOf('@'));                }                else                    obj.email = obj.email;                                StringStartX = (unitWidth - Convert.ToInt32(g.MeasureString(obj.email, f).Width)) / 2;                g.DrawString(obj.email, f, sb, x + StringStartX, y + 48);                //邮箱                sb.Color = Color.Black;                g.DrawString(FormatDate(obj.joinCompany), f, sb, x + 5, y + 75);                g.DrawString(FormatDate(obj.joinMarketing), f, sb, x + 5, y + 95);                g.DrawString(FormatDate(obj.joinCurrentPosition), f, sb, x + 5, y + 115);                if (!isFirst)                {                    Pen p = new Pen(sb);                    g.DrawLine(p, x + unitWidth / 2, y, x + unitWidth / 2, y - 15);                }                if (obj.imgPath != null)                {                    string path = Server.MapPath(obj.imgPath);                    System.Drawing.Image img = System.Drawing.Image.FromFile(path);                    img = NarrowImage(img, 45, 50);                    g.DrawImage(img, x + 53, y + 75);                }            }            // 绘制第四层员工单元            public void DrawUnit4(Graphics g, Staff obj, bool isFirst)            {                int x, y;                x = NodeDic[obj.id].x;                y = NodeDic[obj.id].y;                SolidBrush sb = new SolidBrush(Color.FromArgb(39, 57, 153));                Font f = new Font("", 9, FontStyle.Regular); //定义字体                Rectangle r = new Rectangle(x, y, unitWidth, 70); //绘制矩形                g.FillRectangle(sb, r);//填充矩形                sb.Color = Color.White;//笔刷颜色                //部门                int StringStartX = (unitWidth - Convert.ToInt32(g.MeasureString(obj.department, f).Width)) / 2;                g.DrawString(obj.department, f, sb, x + StringStartX, y + 3, StringFormat.GenericTypographic);                //部门                //处理职位过长的状况                if (obj.position == null)                {                    obj.position = "";                }                else                {                    if (g.MeasureString(obj.position, f).Width > unitWidth)                    {                        float FontSize = 9;                        while (g.MeasureString(obj.position, f).Width > unitWidth)                        {                            FontSize--;                            f = new Font("", FontSize, FontStyle.Regular);                            y++;                        }                        f = new Font("", FontSize + 1, FontStyle.Regular);                    }                    StringStartX = (unitWidth - Convert.ToInt32(g.MeasureString(obj.position, f).Width)) / 2;                    //g.DrawString(currentPositionName.ToUpper(), f, sb, x + StringStartX, y + 18);                    g.DrawString(obj.position, f, sb, x + StringStartX, y + 18);                }                //处理职位过长的状况                //姓名                f = new Font("", 9, FontStyle.Regular);                StringStartX = (unitWidth - Convert.ToInt32(g.MeasureString(obj.name, f).Width)) / 2;                g.DrawString(obj.name, f, sb, x + StringStartX, y + 33);                //姓名                //邮箱                if (obj.email.Contains("@"))                {                    obj.email = obj.email.Substring(0, obj.email.IndexOf('@'));                }                else                    obj.email = obj.email;                StringStartX = (unitWidth - Convert.ToInt32(g.MeasureString(obj.email, f).Width)) / 2;                g.DrawString(obj.email, f, sb, x + StringStartX, y + 48);                //邮箱                sb.Color = Color.Black;                g.DrawString(FormatDate(obj.joinCompany), f, sb, x + 5, y + 75);                g.DrawString(FormatDate(obj.joinMarketing), f, sb, x + 5, y + 95);                g.DrawString(FormatDate(obj.joinCurrentPosition), f, sb, x + 5, y + 115);                if (!isFirst)                {                    Pen p = new Pen(sb);                    p.Width = 1;                    p.Color = Color.Black;                    if (NodeDic[obj.id].toRight == true)                        g.DrawLine(p, x + unitWidth, y + 20, x + unitWidth + 13, y + 20);                    else                        g.DrawLine(p, x, y + 20, x - 15, y + 20);                }                if (obj.imgPath != null)                {                    string path = Server.MapPath(obj.imgPath);                    System.Drawing.Image img = System.Drawing.Image.FromFile(path);                    img = NarrowImage(img, 45, 50);                    g.DrawImage(img, x + 53, y + 75);                }            }            #endregion            //时间转换            public string FormatDate(DateTime? dt)            {                if (dt == null)                    return "000-00";                else                {                    string MM = "";                    if (dt.Value.Month == 1)                        MM = "Jan";                    else if (dt.Value.Month == 2)                        MM = "Feb";                    else if (dt.Value.Month == 3)                        MM = "Mar";                    else if (dt.Value.Month == 4)                        MM = "Apr";                    else if (dt.Value.Month == 5)                        MM = "May";                    else if (dt.Value.Month == 6)                        MM = "Jun";                    else if (dt.Value.Month == 7)                        MM = "Jul";                    else if (dt.Value.Month == 8)                        MM = "Aug";                    else if (dt.Value.Month == 9)                        MM = "Sep";                    else if (dt.Value.Month == 10)                        MM = "Oct";                    else if (dt.Value.Month == 11)                        MM = "Nov";                    else if (dt.Value.Month == 12)                        MM = "Dec";                    return MM + "-" + dt.Value.Year.ToString().Substring(2, 2);                }            }            //业务相关的:记录员工的加入公司时间,市场部的时间,当前职位时间            public void DrawLineTag(Graphics g, int layth)            {                SolidBrush sb = new SolidBrush(Color.Black);//生成笔刷类的实例                Font f = new Font("", 10, FontStyle.Regular);                g.DrawString("joinCompany:", f, sb, 5, 75 + layth * 180);                g.DrawString("joinMarketing:", f, sb, 5, 95 + layth * 180);                g.DrawString("joinCurrentPosition:", f, sb, 5, 115 + layth * 180);            }        }    public class ImageUnit    {        // x,y坐标        public int x;        public int y;        public bool toRight = true;        public Staff staff;        public ImageUnit() { }        public ImageUnit(int x, int y, Staff staff)        {            this.x = x;            this.y = y;            this.staff = staff;        }    }    public class Staff    {        public int id{ get; set; }//员工编号            public int manager { get; set; }//经理--对应员工编号        public string department { get; set; }//部门        public string position { get; set; }//职位        public string name { get; set; }//员工姓名        public string email { get; set; }//员工邮箱        public DateTime joinCompany { get; set; }//加入公司时间        public DateTime joinMarketing { get; set; }//加入市场部时间        public DateTime joinCurrentPosition { get; set; }//加入当前职位时间        public string imgPath { get; set; }//图片URL        public Staff() { }        public Staff(int _id, int _manager, string _department, string _position, string _name, string _email, DateTime _joinCompany, DateTime _joinMarketing, DateTime _joinCurrentPosition, string _imgPath)        {            id = _id;            manager = _manager;            department = _department;            position = _position;            name = _name;            email = _email;            joinCompany = _joinCompany;            joinMarketing = _joinMarketing;            joinCurrentPosition = _joinCurrentPosition;            imgPath = _imgPath;        }    }}
原创粉丝点击