求一个关于关系图绘制的方法及算法【100分奉上】

mrtxc 2012-12-03 09:17:30
在数据库中表中有两个字段保存了两个对象的关系,暂且分别叫source和target,假定有如下数据记录:
source,target
a,b
a,f
a,e
b,c
b,f
b,g
c,e
c,f
d,a

现在的需求是根据这个值列表绘制出以下关系图,不知有什么方法或现成的第三方组件可以实现?
(要求链接线要能用箭头表示出方向,结点形状无要求,一个实心圆点就行,要在结点处显示值,现实中数据记录数会很大,可能成千上万条):
...全文
183 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
gnimgnot 2012-12-03
  • 打赏
  • 举报
回复
引用 4 楼 mrtxc 的回复:
引用 3 楼 cuit 的回复:你绘制也要绘制成可拖动的。 如果能自动整理最好,不然成千上万条,要人工整理会很累
那你可以考虑绘制的时候检测不要落到现有项的关键区域上。但这样就更考究效率了。
mrtxc 2012-12-03
  • 打赏
  • 举报
回复
引用 3 楼 cuit 的回复:
你绘制也要绘制成可拖动的。
如果能自动整理最好,不然成千上万条,要人工整理会很累
gnimgnot 2012-12-03
  • 打赏
  • 举报
回复
你绘制也要绘制成可拖动的。
mrtxc 2012-12-03
  • 打赏
  • 举报
回复
引用 1 楼 cuit 的回复:
自定义控件然后自绘吧,绘制看起来不难,关键是效率。 如果只是上万条,只要你的代码不是太搓,WPF或者GDI+的问题都不大。
按数据一条一条绘制倒不难,关键还要考虑结果的可读性,比如我上面的例图,如果是按从a到g顺序显示,可能是一团糟,我是用Visor画好还手工调整了各个结点的位置,这样才可能结构清晰
gnimgnot 2012-12-03
  • 打赏
  • 举报
回复
自定义控件然后自绘吧,绘制看起来不难,关键是效率。 如果只是上万条,只要你的代码不是太搓,WPF或者GDI+的问题都不大。
PART1 引入 因为刚刚沐浴完入学的洗礼晋级到新的级别不久,杂事挺多的,所以也没怎么逛论坛,距离上一篇 低多边形运动(LowPolyMotion)算法 的帖子发布至今也有挺长一段时间了没露面了。今天就再奉上一帖,和大家交流切磋。 刚正式接触线性代数这门学科不到两个月,觉得课堂上的线代实在枯燥。好在有幸遇见国外3Blue1Brown大神的线代解析,使得对线性变换的几何意义初有体会。在对这种美妙变换的感慨之余也不忘用自己动手,尝试独创算法实现这种变换的形化渲染。 我将整个程序写成了可交互式的即时演算动画。 其实是个半半成品,嗯...主要原因是交互性还比较单一。 目前完成了基向量添加、自定义向量添加、矩阵×矩阵动画演算、矩阵×向量动画演算、两种副本网格模式、两种动画预览模式,上演示的就是基向量和自定义向量的添加。其实单动画本身而言,除了好看和能够帮助更形象地理解线性变换以及明白低阶矩阵运算的几何本质之外也没啥别的意义了,但是这种交互式的编程动画还是挺有意思的,也有一定的学习价值,特此开源。 PART2 演示 ↑ 添加基向量与自定义向量 ↑ ↑ 观察基向量变换 ↑ PART3 简析 这一部分简单分析一下这个算法的内容,或者说解析一下源码吧,因为之前也有发一些这类的帖子,但是反应大多是看不太懂,因此我也打算在以后的帖子中都对源码做一下大致的剖析。要实现这种动画主要分成四大部分 来看,有兴趣的话就让我们就一起来看看吧。 一、坐标系部分 在这个项目中坐标系可以说是整个动画最有看点的部分了。所有变换的美感都在坐标系网格的拉伸中体现得淋漓尽致。 1 .1搭建一个可变换的坐标系,即要搭建一个可变换的网格,网格由许多条横纵线条组成,为了绘制这些线条,我们只需要确定每一根线条的左右端点的坐标 即可。此外我们还需要确定坐标轴的单位长度,以及坐标原点的位置,为此,程序中定义了两个数据类型,用于存放坐标系的基本参数,分别是CoordinateSystemParam和CoordinateGroup。 通过画板的宽高和单位长度,不难确定Line_X和Line_Y的值,再设定一下颜色,通过循环调用画板的画直线命令很容易画出动中的坐标系。 二、缓动函数部分 2 .1为了让我们的坐标系动起来只需要让端点动起来即可,计算出运动的始末位置后利用循环的方法来达到缓动的目的。例如做一个循环n次使得点P0从(x1,y1)位置运动到(x2,y2)位置的动画,只需要在第i次循环的时候将点P0从x1位置移动到x1+(x2-x1)×k位置即可,其中k=i/n。 2 .2为了使得动画更加平滑,我们借助正弦函数对线性数据进行“软化”。 考虑到实际需,我们仅截取正弦函数的[-π/2,π/2]区间。通过f(i)=π×i/n-π/2即可将i∈[0,1]映射到f(i)∈[-π/2,π/2],这样一来我们就可以得到sin(f(i))∈[-1,1],为了使得比例值k依旧从0开始到1结束,不难发现只需令k=[sin(f(i))+1]/2,即k=[sin(π×i/n-π/2)+1]/2 。这一技法贯穿整个程序动画,如果要实现更加复杂的缓动效果,可以参阅网上的其他资料,或调用现成的缓动函数。 三、向量箭头部分 3 .1两点确定一条直线,那么如何画出向量的矢量箭头?本程序中使用在原直线两侧再画两根短线段的方法来实现,为了达到目的,只需要确定直线倾斜角α、箭头开角β以及线段长度L即可。L在中没有标出,L=|P0P1|或|P0P2|。 以计算点P1的坐标为例,首先α=arctan(y0/x0), 由几何关系不难发现∠EP0D=π/2-α-β,进而易得P1到直线DP0的距离d=Lcos(α-β),代入x1=x0-d得到P1的横坐标为x1=x0-Lcos[arctan(y0/x0)-β],同理y1=y0-Lsin[arctan(y0/x0)-β],考虑到L与β都是我们自定义的已知量,当P0确定后,P1与P2的坐标也就确定了。值得注意的是x=x0±d的正负号具体由箭头所处的象限来指定 ,具体规则见源码的CoordinateSystemDraw函数。 确定了箭头三点的坐标后(P0,1,2),结合第二节缓动部分即可完成向量箭头的生成和移动动画。 四、运算表达式部分 4 .1运算表达式部分即矩阵乘法算式的动态显示部分。略,详见源码。 ↑ 观察自定义向量的变换(Vector的坐标跟随箭头所在处渐显)↑ ↑ 伸缩变换及张成空间的"降维" ↑

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧