jtopo的项目实战(二)

 

话接上回,继续实现jtopo本身不具有的一些功能,有讲的不对的地方,欢迎大家留言提出,我们一起进步,奥利给,还有,码字不易,如果觉得博主写的不错的欢迎打赏哈!

2.美化节点之间连线的文字标识

        jtopo自带的连线只允许添加一个文字标识,如果想要在一根连线上添加多个描述,要怎么实现呢?首先,需要修改连线(link)的构造函数,增加想要的文字字段属性,方便文字的设置和读取。因为我们项目中需要显示三段文字,所以我新增了两个文字属性,分别是textA和textZ:

 

这样就可以在json文件中定义这个字段,并通过json文件来赋值,当然这只是实现了数据源,有了数据源还要让文字显示到拓扑图中来,这就需要改动连线绘制部分的代码,需要注意的是,我们画的是一个有向的箭头,出发点都是nodeA,结束点永远是nodeZ,不管nodeZ处于nodeA的哪一个方位,最终的箭头始终指向nodeZ,而HTML5画图时通常先把上下文旋转一个角度,使上下文和我们要绘制的对象水平,源代码中使用的是Math.atan来计算反正切来旋转的,如果我们忽略掉这个细节,而直接去绘制textA、textZ,那么最终的效果是,在拓扑图上拖动节点旋转时,随着角度的变化,textA、textZ的位置会周期性的互换,这是因为Math.atan的取值区间是-π/2~π/2,也就是说,当nodeZ旋转到绝对坐标系第一(nodeZ 的坐标x、y都是正数)、四象限(nodeZ的坐标x是正数,y是负数)时,绘制的textA、textZ是正确的,其余象限绘制的textA、textZ有可能位置颠倒,具体什么意思呢?比如说textA本来应该在靠近nodeA的地方绘制,结果绘制到了nodeZ 的旁边,说的更形象一点吧,就是箭羽长到了箭头的位置,那么如何解决呢?其实还有另外一个函数Math.atan2,它的取值范围是-π~π之间,通过测试后发现Math.atan2的值在大于π/2和小于-π/2时textA、textZ的位置是反的,既然有规律可循就有解决问题的办法,既然在这两种情况下是反的,那么我刻意在这两种情形下让它再反一次,负负得正不就ok了,事实证明是对的:

 

 

有人肯定好奇了,textA、textZ的位置是怎么确定的,这还不简单么,源代码只显示一个text,它是这样确定绘制位置的:

var e = (d.x + c.x) / 2 + this.textOffsetX,

    f = (d.y + c.y) / 2 + this.textOffsetY;

a.fillText(this.text, e, f)

 

很简单,他是在连线的最中间绘制的文字,我们需要绘制三段,其他两个点分别是1/4和3/4处,再减去对应文字长度的一半,就能精确定位,对应上图应该很好理解了。好了文字绘制完了,但不美观,需要绘制有一个底色,上图中函数fillRoundRect就是绘制矩形框(底色)的,矩形框的位置确定参考文字的位置,这里不再累述,fillRoundRect函数具体实现如下:

        /**该方法用来绘制一个有填充色的圆角矩形 

         *@param cxt:canvas的上下文环境 

        *@param x:左上角x轴坐标 

        *@param y:左上角y轴坐标 

        *@param width:矩形的宽度 

        *@param height:矩形的高度 

        *@param radius:圆的半径 

        *@param fillColor:填充颜色 

        **/

        function fillRoundRect(cxt, x, y, width, height, radius, /*optional*/ fillColor) {

            //圆的直径必然要小于矩形的宽高          

            if (2 * radius > width || 2 * radius > height) { return false; }

    

            cxt.save();

            cxt.translate(x, y);

            //绘制圆角矩形的各个边  

            drawRoundRectPath(cxt, width, height, radius);

            cxt.fillStyle = fillColor || "#000"; //若是给定了值就用给定的值否则给予默认值  

            cxt.fill();

            cxt.restore();

        }

 

最终的效果如下:

 

最终在生产环境中的效果如下;

 

最后,博主有一个小小的心愿,就是希望大家点一下下方的点赞、分享和收藏,博主希望大家都支持下,后期有好的东西我会继续分享给大家。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不脱发的牧码人

你的鼓励将是我前进的最大动力。

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

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

打赏作者

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

抵扣说明:

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

余额充值