请教关于绘制目录框图的问题,分数多多!
本人正在做一个把系统类别绘制成框图的样子,就像组织结构图一样,用的是GDI绘图。但:
1、现在客户希望能在图片的每个类别上做链接;
2、现在的绘制有问题,会出现重叠现象,这是在同级类别第一个类别没子类别而其他类别有子类别的情况下出现的。
我贴上具体代码吧。解决再加分,分数不是问题。
1、public partial class view : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
OrgTree<string> orgtree = new OrgTree<string>(null, "图");
BindTree(orgtree, "0001");
Bitmap bmp = orgtree.DrawAsImage();
bmp.Save(Response.OutputStream, ImageFormat.Jpeg);
bmp.Dispose();
}
}
private void BindTree(OrgTree<string> orgtree, string parentclassno)
{
DataSet ds = Standard.GetDstStandClass(parentclassno);
for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
orgtree.Add(ds.Tables[0].Rows[i]["classname"].ToString());
BindTree(orgtree.Childs[i], ds.Tables[0].Rows[i]["classno"].ToString());
}
}
}
--------------------编程问答-------------------- 2、OrgTree
/// <summary>
/// 用来输出组织结构图的类
/// </summary>
/// <typeparam name="T"></typeparam>
public class OrgTree<T>
{
OrgTree<T> _Parent = null;
T _Content;
List<OrgTree<T>> _Childs = new List<OrgTree<T>>();
SizeF _Size;
Rectangle _Rec;
public OrgTree(OrgTree<T> parent, T content)
{
_Parent = parent;
_Content = content;
}
public OrgTree<T> Add(T content)
{
OrgTree<T> OrgTree = new OrgTree<T>(this, content);
_Childs.Add(OrgTree);
return OrgTree;
}
public OrgTree<T> Parent { get { return _Parent; } }
public T Content { get { return _Content; } }
public List<OrgTree<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 (OrgTree<T> OrgTree in Childs)
OrgTree.MeatureAllSize(g, font, addWidth);
}
List<List<OrgTree<T>>> GetOrgTreeLayers()
{
List<List<OrgTree<T>>> layers = new List<List<OrgTree<T>>>();
GetOrgTreeLayers(layers, new List<OrgTree<T>>(new OrgTree<T>[] { this }), 0);
return layers;
}
void GetOrgTreeLayers(List<List<OrgTree<T>>> layers, List<OrgTree<T>> childs, int level)
{
if (childs.Count == 0) return;
if (layers.Count <= level) layers.Add(new List<OrgTree<T>>());
for (int i = 0; i < childs.Count; i++)
{
layers[level].Add(childs[i]);
GetOrgTreeLayers(layers, childs[i].Childs, level + 1);
}
}
/// <summary>
/// 设置显示区域(从最后一层最左开始)
/// </summary>
/// /// <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, FontStyle.Bold), 120, -36, 10, 28, 16);
}
//h:高度
//horPadding:影响矩形宽度
//horInterval:左右矩形之间的宽度
//verInterval:上下矩形之间的高度
//borderWidth:距离页面边距
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<OrgTree<T>>> layers = GetOrgTreeLayers();
// 算出每个单元的大小
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.FormatFlags = StringFormatFlags.DirectionVertical;
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;
}
} --------------------编程问答-------------------- 不会啊,帮你顶,希望有人来解答。 --------------------编程问答-------------------- 学习下
--------------------编程问答-------------------- 就没谁会的? --------------------编程问答-------------------- 看来csdn已日渐没落了,没有高手来了饿 --------------------编程问答-------------------- 帮你顶 --------------------编程问答-------------------- 高手来讲讲 --------------------编程问答-------------------- 高手来讲讲 --------------------编程问答-------------------- 失望啊 --------------------编程问答-------------------- 明天研究下!up --------------------编程问答-------------------- 已经实现http://topic.csdn.net/u/20081021/13/90a28682-b6b4-4b02-beac-25adf3df6f96.html
9楼的效果图, --------------------编程问答-------------------- 这样的需求还是客户端绘制好一些,因为你要用链接。 --------------------编程问答-------------------- 路过,顶一下 --------------------编程问答-------------------- 等待高手进入 --------------------编程问答-------------------- up一下 --------------------编程问答-------------------- ........................................... --------------------编程问答-------------------- 没人回答,还非要结贴,分数还没了? --------------------编程问答-------------------- up --------------------编程问答-------------------- 不懂,帮顶 --------------------编程问答-------------------- 谢谢 --------------------编程问答-------------------- .................. --------------------编程问答-------------------- 。。。。。。。。。。。。。。。。。。。。。。。。 --------------------编程问答-------------------- 这么高难度的问题,为什么不考虑树形目录呢? --------------------编程问答-------------------- 主要是第二个,不要重叠就好 --------------------编程问答-------------------- 期待高手 --------------------编程问答-------------------- 一楼的兄弟wadsunglow,真是感谢你了,您的代码真是解决了我的燃眉之急!我顶!
补充:.NET技术 , ASP.NET