Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 繁重的计算和显示数据而不阻塞用户界面_Javascript_User Interface_D3.js_Nonblocking_Web Worker - Fatal编程技术网

Javascript 繁重的计算和显示数据而不阻塞用户界面

Javascript 繁重的计算和显示数据而不阻塞用户界面,javascript,user-interface,d3.js,nonblocking,web-worker,Javascript,User Interface,D3.js,Nonblocking,Web Worker,我正在开发一个应用程序,它将进行统计计算,并在之后使用D3.js显示结果数据 在大多数情况下,我可以通过将实际计算传递给一个应用程序来避免阻塞UI 计算完成后,数据点将进行排序,并用d3.js显示。在WebWorker中使用DOM元素是令人讨厌的(),即使worker本身不能与DOM交互。但我真的想避免这种情况 假设我有大约100万个数据点,它们将用d3进行排序和显示当js执行此任务时,如何避免UI冻结? 在某种程度上有效的想法: d3代码如下所示: d3.select ... .sort ..

我正在开发一个应用程序,它将进行统计计算,并在之后使用D3.js显示结果数据

在大多数情况下,我可以通过将实际计算传递给一个应用程序来避免阻塞UI

计算完成后,数据点将进行排序,并用d3.js显示。在WebWorker中使用DOM元素是令人讨厌的(),即使worker本身不能与DOM交互。但我真的想避免这种情况

假设我有大约100万个数据点,它们将用d3进行排序和显示当js执行此任务时,如何避免UI冻结?

在某种程度上有效的想法

d3代码如下所示:

d3.select ...
.sort ...
.enter ...
.attr ...
.attr ...
.style ...
 let prom = new Promise((re, rj) => {
            setTimeout(function() {
                let val = d3.select ...
                            .sort ...
                            .enter ...
                re(val);            
              }, 0);
        });

prom.then(val => {
    val = val.attr ...
            .attr ...
            .style ...
}); 
这一切都将在一次内执行。要让用户有机会在两件事情之间进行渲染,您可以执行以下操作:

d3.select ...
.sort ...
.enter ...
.attr ...
.attr ...
.style ...
 let prom = new Promise((re, rj) => {
            setTimeout(function() {
                let val = d3.select ...
                            .sort ...
                            .enter ...
                re(val);            
              }, 0);
        });

prom.then(val => {
    val = val.attr ...
            .attr ...
            .style ...
}); 
数据上d3操作的第一部分将推送到回调队列上,呈现队列有机会呈现,然后执行d3代码的下一部分(可能有多个承诺的更复杂模型)。但这仍然不能解决问题。这可能比一次执行所有内容要好一点,但是如果单个部分本身花费太长时间,UI仍然会冻结


有谁知道解决这个问题的好方法吗?

问题在于您使用的是SVG,它必须添加Dom元素来表示所有的条形图。即使您使用web workers进行繁重的处理,添加数千个Dom元素、计算图像和绘制也是锁定主线程的关键


您可以通过使用canvas来解决这个问题,canvas不存在大量Dom元素的问题,并且可以与GPU配合使用。D3V4支持画布,但需要一些重新设计才能使其工作。也可以使其逐渐渲染。棘手的一点是添加您的交互,因为您没有单独的元素来附加侦听器

正如elliot已经指出的那样,问题在于D3将向DOM添加太多元素。为了避免阻塞主线程,可以将数据分块绘制,如建议的那样


不过,我还是需要先进行排序。

你能将结果分为50批(20000批)吗?@Archer已经考虑过了。这通常是个好主意,但情况不允许这样做。在某些情况下,我想对所有(1百万)数据点进行排序,并将它们显示在一个图表中。在返回它们(成批)之前,您不能在WebWorker中对它们进行排序,从而解决该特定问题吗?@Archer yea,我也期待着看到我解决它xD@User12547645忘掉编程、计算机和D3吧。让我们来谈谈dataviz。为什么要向用户显示100万个数据点?非常感谢您的提示。我会试试的