clay教程一之结点和数据操作

心叶

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

温馨提示:clay.js已经停止维护,项目迁移到https://github.com/yelloxing/...

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

clay本身提供了一些基本的DOM操作,比如结点的CSS字符串查找、事件绑定和属性编辑等快捷方法。不过,她的目的是绘图,因此这些方法只提供了非常小的集合,而更重要的是,由于绘图的话就离不开数据,她提供了数据和结点绑定的操作。

结点操作

$$('<svg>' +
    // 基本背景
    '<g class="background"></g>' +
    // 数据,也就是条形图
    '<g class="data"></g>' +
    // 绘制刻度尺
    '<g class="ruler"></g>'
    + '</svg>')
    .appendTo('body')
    .attr('width', '560')
    .attr('height', '420');
    

比如你想绘制一个条形图,选择的绘图环境是svg,首先你需要初始化绘图环境,就像上面这样。

我们直接传递一个标签字符串给clay($$和clay是完全相同的)方法创建了结点对象,然后把这个字符串追加在body标签后面,并且修改了svg的尺寸。很显然,svg标签作为一个特殊的xml标签,namespaceURI和普通的html标签不一样,因此在操作上也不一样,可是在这里,你不需要关心这些,把它当成普通的html标签即可。

不只是svg标签,包括不同的标签属性等,你都可以和这里一样通过clay操作而无需在意不同浏览器和不同namespaceURI的区别。更具体的请查看接口API。

数据绑定

假如现在有一组数据需要使用条形图来展示,接着上面的代码,为了方便说明,先添加一个g标签,然后通过数据绑定的方法来添加剩余的g标签(一个g标签绘制一个月份的数据)。

// 6到10月份公司在天津、河北和山东的销售情况
var data = [
    ['六月', 280, 310, 205],
    ['七月', 200, 260, 150],
    ['八月', 300, 370, 260],
    ['九月', 340, 420, 320],
    ['十月', 350, 450, 340]
];
$$('<g class="update"></g>').appendTo('.data');
$$('.data').find('g').data(data).enter('<g class="enter"></g>').appendTo('.data');

运行上面的代码,我们就会发现class="data"的g标签中多了5个标签:

<g class="data">
    <g class="update" month="六月"></g>
    <g class="enter" month="七月"></g>
    <g class="enter" month="八月"></g>
    <g class="enter" month="九月"></g>
    <g class="enter" month="十月"></g>
</g>

细心的可以发现,新添加的g标签中除了第一个class='update'外,别的都是class='enter',这是我们在追加结点的时候用来标记是普通追加的还是后面根据数据条目计算出来的不足结点,接下来,就来说明一下第二种追加方法。

数据和结点的桥梁

这部分一共涉及结点对象上的四个核心方法:data、datum、enter和exit,还有一些相关方法(因为结点对象的各个方法之间不完全是独立的)。
图片描述

$$('.data').find('g').data(data).enter('<g class="enter"></g>').appendTo('.data');

以前面使用到的上面这句为例来说明。

$$('.data').find('g')获取了一个结点对象,其中维护着已经存在的一个g标签,接着使用.data(data)方法告诉这个结点对象,需要展示的数据是什么,基本上这是第一步。

因为我们事先知道数据条目个数多于结点数目,调用.enter('<g class="enter"></g>')方法获取维护着由多余数据生成的结点的结点对象,其中参数表示生成的结点是什么,具体查看接口API,这样,就完成了第二步。

最后,执行.appendTo('.data')把获取的不足的g标签追加到页面上去,结束。

对照上图的第一个关系图,本来就存在的结点(不是多余结点)称之为update部分,补足的结点称之为enter部分,每个结点记录着绑定的数据。

如果结点多于数据,类似的采用exit方法获取需要删除的结点,再调用remove方法删除即可,对照右图的第二个关系图,说明结束。

// 绘图
$$('[month]').attr('month', function (data, index, target) {
    // 小条形
    $$('<line class="data-line"' +
        ' x1=' + (120 - -index * 80 - 20) +
        ' x2=' + (120 - -index * 80 - 20) +
        ' y2=' + (360 - data[1] / 500 * 300) +
        '></line>').appendTo(target)
        .css('stroke', 'rgb(73, 130, 203)');
    $$('<line class="data-line"' +
        ' x1=' + (120 - -index * 80) +
        ' x2=' + (120 + index * 80) +
        ' y2=' + (360 - data[2] / 500 * 300) +
        '></line>').appendTo(target)
        .css('stroke', 'rgb(211, 63, 70)');
    $$('<line class="data-line"' +
        ' x1=' + (120 - -index * 80 + 20) +
        ' x2=' + (120 - -index * 80 + 20) +
        ' y2=' + (360 - data[3] / 500 * 300) +
        '></line>').appendTo(target)
    .css('stroke', 'rgb(140, 195, 81)');

    // 返回属性值,月份
    return data[0];
});
$$('.data-line').attr('y1', 360).css("stroke-width","20px");

因为新追加的g标签记录着具体数据,调用attr方法修改标签的month属性,在属性获取方法里面分别追加天津、河北和山东的小条形line标签。

其中data表示当前g标签记录的数据,以10月份为例,数据如下:

["十月", 350, 450, 340]

其中target表示维护着当前g标签的结点对象。

上面的例子主要是想说明数据绑定到结点的过程,这样开发的好处一方面是我们不需要再根据数据条目个数的改变去考虑应该添加或删除哪些结点,而更重要的是,绘图结束后,如果想知道一个图形对应的原始数据是什么的时候,结点本身就可以告诉你。

阅读 1.6k

clay系列文章
clay相关教程和使用总结

我还惊讶地意识到, 在我生命中有很多时刻, 每当我遇到一个遥不可及、令人害怕的情境,并感到惊慌失措...

303 声望
114 粉丝
0 条评论

我还惊讶地意识到, 在我生命中有很多时刻, 每当我遇到一个遥不可及、令人害怕的情境,并感到惊慌失措...

303 声望
114 粉丝
宣传栏