Ni55aN
@Ni55aN

Ускорить обновление данных в D3.js?

Пример кода:

var rects = this.view
            .selectAll('rect.node')
            .data(this.nodes, function (d) { return d.id; });

        rects.enter()
            .append('rect')
            .attr('class', 'node')
            .on('click', function (d) {
                self.selectNode(d);
            })
            .call(d3.drag().on('drag', function (d) {
                d3.select(this)
                    .attr('cx', d.position[0] += self.x.invert(d3.event.dx))
                    .attr('cy', d.position[1] += self.y.invert(d3.event.dy));
                self.update();
            }).on('end', function (d) {
                self.groups.forEach(group => {
                    var contain = group.containNode(d);
                    var cover = group.isCoverNode(d);
                    
                    if (contain && !cover)
                        group.removeNode(d);
                    else if (!contain && cover)
                        group.addNode(d);
                });
            }))
            .attr('rx', 8)
            .attr('ry', 8);

        rects.exit().remove();

        this.view.selectAll('rect.node')
            .attr('x', function (d) {
                return self.x(d.position[0]);
            })
            .attr('y', function (d) {
                return self.y(d.position[1]);
            })
            .attr('width', function (d) {
                return self.x(d.width);
            })
            .attr('height', function (d) {
                return self.y(d.height);
            })
            .attr('class', function (d) {
                return self.active === d ? 'node active' : 'node';
            });

        var titles = this.view
            .selectAll('text.title')
            .data(this.nodes, function (d) { return d.id; });

        titles.enter()
            .append('text')
            .classed('title', true);

        titles.exit().remove();

        this.view.selectAll('text.title')
            .attr('x', function (d) {
                return self.x(d.position[0] + d.margin);
            })
            .attr('y', function (d) {
                return self.y(d.position[1] + d.margin + d.title.size);
            })
            .text(function (d) {
                return d.title.text;
            })
            .attr('font-size', function (d) {
                return self.x(d.title.size) + 'px';
            });


По определенному событию вызываю некий update, который обновляет все данные (как в примере), но при увеличении их количества начинает подтормаживать.
Важно, чтобы меньше приходилось вручную обновлять данные по частям, но и не трогать каждый раз querySelectorAll (см. скриншот), чем и занимается D3.js.
a946bd88dae84a14b1ca8d34ff5f7ed1.png
Бывают и случаи с группами
var groups = this.view
            .selectAll('g.gg')
            .data(this.nodes, function (d) { return d.id; });

        var newGroups = groups.enter()
            .append('g')
            .classed('gg', true)

        groups.exit().remove();

        groups = newGroups.merge(groups);
        
        var outputs = groups.selectAll('circle.output')
            .data(function (d) {
                return d.outputs;
            });

        outputs.exit().remove();
        var newOutputs = outputs.enter()
            .append('circle');

        outputs = newOutputs.merge(outputs);

        outputs.attr('class', function (d) {
            return 'socket output ' + d.socket.id;
        });

        outputs
            .on('mousedown', function (d) {
                self.pickedOutput = d;
            })
            .attr('cx', function (d) {
                return self.x(d.positionX());
            })
            .attr('cy', function (d) {
                return self.y(d.positionY());
            })
            .attr('r', function (d) {
                return self.x(d.socket.radius);
            })
            .append('title').text(function (d) {
                return d.socket.name+'\n'+d.socket.hint
            });

Как можно оптимизировать?

UPD: набросал простой пример
https://codepen.io/Ni55aN/pen/RgjEBV
  • Вопрос задан
  • 348 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы