首页 > 解决方案 > 将重绘功能从 D3.js v3 迁移到 D3.js v4

问题描述

我有一个大数据要绘制,这样做浏览器会挂起,所以我在 V3 中找到了一个解决方案来避免这种影响,问题是,我在 D3V4 中需要它,或者我需要在 V3 中刷和放大。

我正在尝试在 D3 V4 中重写以下代码,似乎它被 updateSelection 破解了。我错过了什么?

我的代码:

<html>
    <head>
        <script src="https://d3js.org/d3.v3.min.js"></script>
        <script>
            var height = 500;
            var width = 960;
            var timer, startTime;
            var startTime;
            var BATCH_SIZE = 1000;

            function showTimeSince(startTime) {
                var currentTime = new Date().getTime();
                var runtime = currentTime - startTime;
                document.getElementById('timeRendering').innerHTML = runtime + 'ms';
            }

            function startTimer() {
                stopTimer();

                startTime = new Date().getTime();

                timer = setInterval(function() {
                    showTimeSince(startTime);
                }, 10);

                showTimeSince(startTime);
            }

            function stopTimer() {
                if (timer) {
                    clearInterval(timer);
                }

                showTimeSince(startTime);
            }

            function drawCircles(svg, data, batchSize) {
                startTimer();
                var circles = svg.selectAll('circle').data(data);

                function drawBatch(batchNumber) {
                    return function() {
                        
                        var startIndex = batchNumber * batchSize;
                        var stopIndex = Math.min(data.length, startIndex + batchSize);
                        var updateSelection = d3.selectAll(circles[0].slice(startIndex, stopIndex));
                        var enterSelection = d3.selectAll(circles.enter()[0].slice(startIndex, stopIndex));
                        var exitSelection = d3.selectAll(circles.exit()[0].slice(startIndex, stopIndex));

                        enterSelection.each(function(d, i) {
                            var newElement = svg.append('circle')[0][0];
                            enterSelection[0][i] = newElement;
                            updateSelection[0][i] = newElement;
                            newElement.__data__ = this.__data__;
                        }).attr('r', 3);

                        exitSelection.remove();

                        updateSelection
                            .attr('cx', function(d) { return d.x })
                            .attr('cy', function(d) { return d.y });

                        if (stopIndex >= data.length) {
                            stopTimer();
                        } else {
                            setTimeout(drawBatch(batchNumber + 1), 0);
                        }
                    };
                }

                setTimeout(drawBatch(0), 0);
            }

            function renderChart() {
                var numPoints = parseInt(document.getElementsByName('numPoints')[0].value, 10);
                if (isNaN(numPoints)) {
                    return;
                }

                startTimer();
                var data = [];
                for (var i = 0; i < numPoints; i++) {
                    data.push({
                        x: Math.random() * width,
                        y: Math.random() * height
                    });
                }

                var svg = d3.selectAll('svg').data([0]);
                svg.enter().append('svg')
                    .attr("height", height)
                    .attr("width", width);


                drawCircles(svg, data, BATCH_SIZE);
            }
        </script>
    </head>
    <body>
        <form action="">
            <input name="numPoints" type="text" value="10000">
            <button type="button" id="render" onClick="renderChart()">Render</button>
        </form>
        Time Rendering: <span id="timeRendering"></span>
    </body>
</html>

标签: htmld3.jsscatter-plotlarge-data

解决方案


推荐阅读