d3突然变得缓慢

时间:2016-04-29 19:57:40

标签: performance d3.js mouseclick-event

不幸的是,突然间',我的意思是版本3.1.1.10和3.2.0之间。我有一个散点图,其中有大约3000个点,我们正在尝试基于鼠标点击工具提示工作,因为基于鼠标悬停事件的工具提示并不适用于我们。

因此,在测试我们的初始尝试时,我们发现在发生任何事情之前需要整整2或3秒。我觉得这有点奇怪。我的意思是,我们正在进行最近邻计算,但它只有3000点,所以给出了什么?我对它进行了分析并发现一旦我们得到事件触发器,我们的计算只需要大约22毫秒,所以这很好。那么是什么导致d3花了这么多时间让我们积极地点击鼠标呢?我开始使用不同版本的d3来查看它是否是罪魁祸首,果然,在我回到3.1.0之前,事情进展缓慢。那个让我们立刻得到了鼠标事件,我们的工具提示弹出窗口现在运行良好。

唯一的问题是我无法使用3.1.10,因为我需要最近添加的zoom()。center()功能。

那么任何想法?有谁知道为什么那里发生减速?可以打补丁吗?有人可以建议一个聪明的解决方法吗?我不能成为唯一一个看过这个问题的人。 我在d3论坛,主题编号qfz11UYgMC8

中提出了它

我理解为什么我不能在没有代码的情况下在这里发布codepen演示,但我已经通过不同的d3包含在其中的两个版本来证明我的观点。如果人们真的想看到它,我会在这里包含代码,但它是非常标准的d3.js,我从json对象创建散点图,并且它有数千行代码。

问题肯定是基于散点图的大小。一个小点的十几个点会立即弹出工具提示,而3000点的那个点很慢(在所有d3.js库3.2及更高版本上)。

编辑:添加代码段和codepen链接 代码本身长达数千行,因为数据本身嵌入在html中。以下是我希望的相关代码...

<html>
<head>
    <title>Rolling D3 speed test</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.2.0/d3.min.js"></script>
    <!-- <script src="file://C:/d3.v3.5.16.min.js"></script> -->
    <script type="text/javascript" charset="utf8" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script type="text/javascript" language="javascript" class="init">

// variable init left out for brevity
...
var svg = d3.select("body").append("svg")
            .attr("width",viewportWidth)
            .attr("height",viewportHeight)
            .call(zoom)
            .append("g")
    .attr("class", "main")
            .attr("transform","translate("+(left_shift)+","+(top_shift)+")");
...
//mouse click on svg (to display tooltip on nearest point)
d3.select('svg').on("click",  function() {
  var startTime = new Date();
  var coords = [0, 0];
  coords = d3.mouse(this);
  var isClicked = isPointClicked(point_clicked);
  if(!isClicked) clicked(coords[0], coords[1]);
  point_clicked = false;

  var finalEndTime = new Date();
  var finalTimeDiff = finalEndTime - startTime;
  console.log('all click actions completed in '+finalTimeDiff+' milliseconds.');
});
 //mouse-right click event to remove tooltip
  d3.select('body').on("contextmenu", function() {
  d3.event.preventDefault();
  var ele = d3.select('div.tooltip');
  //if(ele!=="undefined" && ele!==null)
ele.style("opacity",0);
});

...
// x and y axis rendering removed for brevity
...

//draw all data
//var radius = 2.5; // 2.5 normally, 8 is good for testing small sets
var side = 2;     // takes place of radius
// shiftrect needs to be half the square size to center square on data point
var shiftrect = 1;
for(var k=0;k<plot_data.series.length;++k) {
    if(plot_data.series[k].visible === true) {
        var y_list = plot_data.series[k].ydata;
        var x_list = plot_data.series[k].xdata;
        svg.selectAll("dot")
           .data(x_list)
           .enter().append("rect")
       .attr("id", function(d, i) { return "rect"+k+i;})
           .attr("x", function(d) {return x(parseFloat(d))-shiftrect;})
           .attr("y", function(d,i) {return y(parseFloat(y_list[i]))-shiftrect;})
           .attr("height", side)
           .attr("width", side)
           .attr("fill",function() { return color(k);})
           .attr("clip-path", "url(#plot-clip)");
    }
}

Codepen很慢 http://codepen.io/pkrouse/details/ONwQmz/

Codepen很快。只有diff是使用的D3版本 http://codepen.io/pkrouse/details/JXBpKo/

0 个答案:

没有答案