如何使用d3js画分帧画一棵树

本文介绍了如何解决使用d3js在树节点过多时导致的加载卡顿问题,通过分帧加载技术改善用户体验。作者分享了在尝试现有方案失败后,如何深入理解d3js的enter()方法,将数据拆分成单个元素的数组,进而实现分步执行绘制过程,从而达到分帧加载的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近用d3js写了一个把树可视化的工具,但是遇到一个问题,当树的结点非常多的时候,加载整棵树会卡一段时间,体验不是很好,所以想是不是能用分帧加载的方法,不要一次加载整棵树,而是隔一段时间加载一部分。
这是老套路了,本来觉得应该挺简单的,但是网上查了半天也找到符合需求的文章,又去查API,发现也没有可用的。期间也发现了一个看起来可以用的,先贴一下链接:http://jsfiddle.net/cyril123/sef9udod/ 。但是当我用过才发现,这是个花架子,中看不中用,它的缺点是每次都要重新生成数据,数据量小的时候当然怎样都好,但是对于我当前要解决的问题并没有什么帮助。
看了一下源码,没看懂……有些关键代码不知道隐藏到什么地方去了,而且我只是想做个工具,不想研究太深。没办法,只能看看有没有什么黑科技了,一搬生成树的数据的时候,会有这样一个代码:

var tree = d3.layout.tree().size([width - 50,height - 50])
                .separation(function(a,b){
    return (a.parent == b.parent ? 1 : 2); });
var diagonal = d3.svg.diagonal()
                .projection(function(d){
   return [d.x, d.y]});
var svg = d3.select('#display').append('svg')
                .attr('width',width)
                .attr('height', height)
                .append('g')
                .attr('transform', 'translate(0,10)');
var nodes = tree.nodes(target);
var node = svg.selectAll('.node')
            .data(nodes)
            .enter()
            .append('g')
            .attr('class','node')
            .attr('transform', function(d) {
   return 'translate(' + d.x + ',' + d.y + ')';})

其实我的目的呢,就是分步去执行代码中append(‘g’)以及后面一系列操作,但是这个操作d3js是不支持的,所以我把执行到enter()的结果打印出来,发现这是一个数组+一些其他额外的属性,之前尝试把数组中的数拆开,未果,最后想了个招,把这个数组中的每个元素,也就是每个结点都拿出来,用形成一堆数组,只不过这些数组中只有一个元素罢了,这样我虽然不知道这个源码怎么实现,但是我只要每次去调对应的函数就好了,因为我把这些属性都copy下来,形成一个新的对象了。也得亏是js这种原型模式,其他语言不一定会出现什么奇怪的bug……

最后贴一下代码:

var NODE_NUM = 10000;
var MAX_CHILD = 50;
var updateTimeout = null;
var Node = function() {
   
    this.index = 0;
    this.parent = {};
    this.children = [];
    this.history = "";
}

//随机生成一棵树
function generalRandomTreeObject(total_number, max_child, idx) {
   
    var tree = {name:idx + 1};
    if (total_number == 1) {
        return tree;
    }
    tree.children = [];
    total_number -= 1;
    idx &#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值