不幸的是,突然间',我的意思是版本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/