资讯专栏INFORMATION COLUMN

clay教程二之布局的使用

Forest10 / 2722人阅读

摘要:上图是布局的计算模型。删除方法删除的只是布局保存的数据,然后重绘画面,如果你需要画面平滑改变,修改绘图实现方法即可,这里不再赘述。

作者:心叶
时间:2018-11-06 14:47

clay项目Github地址:https://github.com/yelloxing/...

喜欢本项目的可以在github上给给star。

在绘制一些常见图形的时候,比如关系图,单个结点或连线并不难,麻烦的是位置的计算等,和图形模块不同,布局就是专门计算一些特殊图形位置的模块,用一句通俗的话说就是:决定什么元素绘制在哪里。因此,布局应该和具体的绘图方法无关,她只关心位置的计算。

下面,我们将通过介绍一个最简单的树图的绘制过程来说明布局的设计理念,让我们开始吧!

绘制图形

$$("" +
    // 绘制连线
    "" +
    // 绘制结点
    "" +
    // 绘制文字
    "" +
    "").appendTo("body")
    .attr("width", "400")
    .attr("height", "400");

上图是最终运行结果,上面我们准备好了画布,需要绘图的原始数据如下:

var nodes = [
    // 结点名称、父节点名称
    ["手绘", null],
    ["水粉", "手绘"],
    ["油画", "手绘"],
    ["素描", "手绘"],
    ["中国画", "手绘"],
    ["空间透视", "素描"],
    ["色彩五大调", "素描"],
];

使用布局绘图的第一步是创建布局对象,这里是创建tree布局对象:

// 创建布局对象
var tree = clay.treeLayout();

理论上来说,原始数据可以是任意格式,只要保证整体是一个数组即可。这主要是考虑到实际开发复杂的环境,因此,提供了数据格式配置接口,对于上面的数据,进行如下配置:

tree
// 获取根结点
.root(function (initTree) {
    return initTree[0];
})

// 获取孩子结点
.child(function (parentTree, initTree) {
    var children = [], i;
    for (i = 0; i < nodes.length; i++) {
        if (initTree[i][2] == parentTree[0])
            children.push(initTree[i]);
    }
    return children;
})

// 获取结点标志id
.id(function (treedata) {
    return treedata[0];
})

不同布局需要配置的项不一样,对于tree布局而言,关于数据结构的部分,只需要告诉她如何根据父结点获取子结点,一个结点的唯一标识怎么确定,根节点是谁。

开头就说明的很清楚了,布局应该是和具体绘图方式无关的存在,因此,这里我们选择了svg绘图,就需要再配置一下具体的绘图方法。

tree.drawer(function (nodes, rootid, size) {
    var i, node;
    for (i in nodes) {
        node = nodes[i];

        // 绘制结点
        $$("")
            .appendTo(".node")
            .attr("cx", node.left * 100)
            .attr("cy", node.top * 100);

        // 绘制文字
        $$("" + node.data[0] + "")
            .appendTo(".text")
            .attr("x", node.left * 100)
            .attr("y", (node.top * 100 - 14));

        // 绘制连线
        if (node.pid)
            $$("")
                .appendTo(".line")
                .attr("d",
                    "M" + nodes[node.pid].left * 100 + " " + nodes[node.pid].top * 100 + "C" +
                    (nodes[node.pid].left * 100 + 50) + "," + nodes[node.pid].top * 100 + " " +
                    (node.left * 100 - 50) + "," + node.top * 100 + " " +
                    node.left * 100 + "," + node.top * 100 + " ");
    }
});

到这里,所有必须的配置都写好了,添加下面这行代码,启动绘图:

tree(nodes);

至此,运行代码就可以看见一棵记录着结点关系的树图了,绘图结束!

计算模型

因为布局不会知道最终绘制的图形具体是什么样子,比如这里的树布局,也许你想绘制的是旋转的树或倒树,也可能你就是想要和这里一样的简单树。为了防止问题复杂化,布局在计算位置的时候,都会统一选择一种最朴素的场景作为计算模型,从该模型出发,任何别的模型借助clay提供的一些计算方法实现起来就很容易了。

上图是tree布局的计算模型。右边的每个红色矩形都是一个1x1的正方形,坐标原心位于左上角绿色顶点。

配置具体绘图方式的时候,其中第一个参数nodes就记录了每个结点经过布局计算后的位置信息,让我们打印一下其中的一条数据看看:

"油画":{
    children: [];
    data: (2) ["油画", "手绘"];
    id: "油画";
    left: 1.5;
    pid: "手绘";
    show: true;
    top: 1.5
}

其中data记录着结点的原始数据,我们主要看看left和top,这显示该结点应该绘制的坐标为(1.5,1.5),对照上图,是不是就很清晰了。别的布局的设计思想也是如此,请耐心体会一下!

添加交互
// 添加交互用例
$$("circle").bind("click", function () {
    // 删除结点
    tree.delete($$(this).attr("target"));
});

其实交互和布局应该是没有关系的,始终强调,布局只负责计算绘图的位置,比如上面的结点删除例子,绑定点击事件,调用结点的删除结点方法即可。删除方法删除的只是布局保存的数据,然后重绘画面,如果你需要画面平滑改变,修改绘图实现方法即可,这里不再赘述。

例子完整代码:https://yelloxing.github.io/c...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99028.html

相关文章

  • 零基础如何学爬虫技术

    摘要:楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,。本文来源知乎作者路人甲链接楚江数据提供网站数据采集和爬虫软件定制开发服务,服务范围涵盖社交网络电子商务分类信息学术研究等。 楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,http://www.chujiangdata.com。 第一:Python爬虫学习系列教程(来源于某博主:htt...

    KunMinX 评论0 收藏0
  • 使用clay.js绘制一棵圆形树

    摘要:需要说明目前,开发环境已经准备好了,因为绘制树图,我们需要模拟数据,你可以在这里下载数据我们要绘制一棵圆形树,一点点显示,你可以最终代码,查看效果然后在浏览器中打开即可查看效果。余下的就是绘制图形了。 作者:心叶时间:2019-01-23 17:55 温馨提示:clay.js已经停止维护,项目迁移到https://github.com/yelloxing/... 准备环境 我们需要用...

    FingerLiu 评论0 收藏0
  • 数据可视化之clay:设计思想和建立初衷

    摘要:然而,的设计思想和他们不同,是包容而非竞争。建立目的首先,本项目是为了端数据可视化而建立的,如果用更通俗的话说,就是为了方便使用绘制各种和图形来反映统计的数据,并且绘制的图形是可交互的。 作者:心叶时间:2018-05-01 19:28 clay项目Github地址:https://github.com/yelloxing/... showImg(https://segmentfaul...

    XFLY 评论0 收藏0
  • PHP新特性之闭包、匿名函数

    摘要:闭包闭包是什么闭包和匿名函数在中被引入。可以将匿名函数和闭包视作相同的概念。闭包和字符串或整数一样,是一等值类型。何时使用我们通常把闭包当做函数和方法的回调使用。 闭包 闭包是什么? 1).闭包和匿名函数在PHP5.3中被引入。2).闭包是指在创建时封装函数周围状态的函数,即使闭包所在的环境不存在了,闭包封装的状态依然存在,这一点和Javascript的闭包特性很相似。3).匿名函数就...

    luzhuqun 评论0 收藏0
  • python综合学习二之多进程

    摘要:本节讲学习的多进程。和之前的的不同点是丢向的函数有返回值,而的没有返回值。所以接下来让我们来看下这两个进程是否会出现冲突。 本节讲学习Python的多进程。 一、多进程和多线程比较 多进程 Multiprocessing 和多线程 threading 类似, 他们都是在 python 中用来并行运算的. 不过既然有了 threading, 为什么 Python 还要出一个 multip...

    gityuan 评论0 收藏0

发表评论

0条评论

Forest10

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<