Tôi đã thử mô phỏng biểu đồ thời gian thực với dữ liệu động bằng cách sử dụng d3.js
. Tôi đang chạy điều này bằng trình duyệt IE-10.Bộ nhớ tăng dần khi sử dụng d3 cho biểu đồ thời gian thực?
tôi đi qua cho một vấn đề mà bộ nhớ của trình duyệt IE của tôi sẽ được tăng dần nếu rời khỏi ứng dụng web chạy trong một khoảng thời gian.
Tôi Google đã tìm kiếm nguyên nhân có thể gây ra sự cố này.
Hai điều đi vào tâm trí của tôi để thảo luận:
Các bộ đếm thời gian ngăn cản việc thu gom rác thải của IE
Biểu đồ d3 không giải phóng bộ nhớ sau khi
data.shift()
Câu hỏi của tôi:
Làm cách nào để chẩn đoán xem sự cố của tôi có thực sự bắt nguồn từ cuộc thảo luận 1 hoặc 2 hay không?
Làm cách nào để giải quyết vấn đề về bộ nhớ?
Bạn có thể cần tải xuống mã và chạy mã đó một lúc và theo dõi iexplorer.exe
bằng màn hình tài nguyên để xác định sự cố.
Cảm ơn bạn.
Mã Nguồn:
<html>
<head>
<title>Animated Sparkline using SVG Path and d3.js</title>
<script src="http://mbostock.github.com/d3/d3.v2.js"></script>
<style>
/* tell the SVG path to be a thin blue line without any area fill */
path {
stroke: steelblue;
stroke-width: 1;
fill: none;
}
</style>
</head>
<body>
<span>
<b>Size:</b> 300x30 <b>Interpolation:</b> basis <b>Animation:</b> true <b>Transition:</b> 1000ms <b>Update Frequency:</b> 1000ms
<div id="graph1" class="aGraph" style="width:300px; height:30px;"></div>
</span>
<script>
var myTimer;
function FeedDataToChart(id, width, height, interpolation, animate, updateDelay, transitionDelay, data, startIndex) {
// create an SVG element inside the #graph div that fills 100% of the div
var graph = d3.select(id).append("svg:svg").attr("width", "80%").attr("height", "80%");
// X scale will fit values from 0-10 within pixels 0-100
var x = d3.scale.linear().domain([0, 48]).range([10, width-10]); // starting point is -5 so the first value doesn't show and slides off the edge as part of the transition
// Y scale will fit values from 0-10 within pixels 0-100
var y = d3.scale.linear().domain([0, 20]).range([height-10, 10]);
// create a line object that represents the SVN line we're creating
var line = d3.svg.line()
// assign the X function to plot our line as we wish
.x(function(d,i) {
// verbose logging to show what's actually being done
//console.log('Plotting X value for data point: ' + d + ' using index: ' + i + ' to be at: ' + x(i) + ' using our xScale.');
// return the X coordinate where we want to plot this datapoint
return x(i);
})
.y(function(d) {
// verbose logging to show what's actually being done
//console.log('Plotting Y value for data point: ' + d + ' to be at: ' + y(d) + " using our yScale.");
// return the Y coordinate where we want to plot this datapoint
return y(d);
})
.interpolate(interpolation)
var counter = startIndex;
//var myData = data.slice();
// display the line by appending an svg:path element with the data line we created above
graph.append("svg:path").attr("d", line(data));
// or it can be done like this
function redrawWithAnimation() {
// update with animation
graph.selectAll("path")
.data([data]) // set the new data
.attr("transform", "translate(" + x(1) + ")") // set the transform to the right by x(1) pixels (6 for the scale we've set) to hide the new value
.attr("d", line) // apply the new data values ... but the new value is hidden at this point off the right of the canvas
.transition() // start a transition to bring the new value into view
.ease("linear")
.duration(transitionDelay) // for this demo we want a continual slide so set this to the same as the setInterval amount below
.attr("transform", "translate(" + x(0) + ")"); // animate a slide to the left back to x(0) pixels to reveal the new value
}
function redrawWithoutAnimation() {
// static update without animation
graph.selectAll("path")
.data([data]) // set the new data
.attr("d", line); // apply the new data values
}
function stopTimer()
{
clearInterval(myTimer);
myTimer = null;
graph.selectAll("path").data([data]).remove().append("svg:path").attr("d", line);
buffer = null;
signalGenerator();
}
function startTimer()
{
if (myTimer == null)
{
myTimer = setInterval(function() {
if (counter < data.length - 1)
{
var v = data.shift(); // remove the first element of the array
data.push(v); // add a new element to the array (we're just taking the number we just shifted off the front and appending to the end)
if(animate)
{
redrawWithAnimation();
}
else
{
redrawWithoutAnimation();
}
counter++;
}
else
{
//alert("no more data in buffer");
stopTimer();
counter = startIndex;
}
}, updateDelay);
}
}
startTimer();
}
var buffer;
function signalGenerator()
{
if (buffer == null)
{
buffer = new Array(100);
var i;
for (i = 0; i < buffer.length; i++)
{
buffer[i] = Math.random() * 10;
}
FeedDataToChart("#graph1", 300, 300, "basis", true, 100, 100, buffer, 0);
}
}
function startGenerator()
{
signalGenerator();
}
startGenerator();
</script>
</body>
</html>
Tôi không biết một cách trung thực nếu lượng dữ liệu có thể như vậy, nhưng bạn có thể thử xóa dữ liệu cũ/không sử dụng khỏi tập dữ liệu và xem dữ liệu đó như thế nào. (Ngoài ra tôi không thể thử chạy nó trên máy tính của tôi kể từ khi tôi đang ở trên OSX) – tomtomtom
Tôi nghĩ rằng nguồn của tôi có thể chạy ở chrome cũng như – jhyap
tôi để nó chạy trong 5 phút hoặc lâu hơn (thanh bao phủ toàn bộ trục x và một số dữ liệu đi ra khỏi màn hình), không thấy bất kỳ mức sử dụng bộ nhớ tăng nào trong màn hình hoạt động của tôi khi sử dụng Safari – tomtomtom