What is the right way to change Raphaël path elements
I try to change Raphaël path elements essentially in the following way (please regard the code includes build up stuff for a complete example):
var n = 100,
i = 0;
var values = [n];
var panel = document.createElement("div");
var paper = null;
var path = null;
panel.id = "panel";
panel.style.top = '0px';
panel.style.left = '0px';
panel.style.width = '300px';
panel.style.height = '300px';
panel.style.background = 'black';
document.getElementsByTagName('body')[0].appendChild(panel);
paper = Raphael(panel, 0, 0);
path = paper.path('m0,0');
path.attr({ stroke: '#fff', 'stroke-width': 1 });
function test () {
i = n;
while (i--)
values[i] = Math.round(Math.random() * 3);
// perform change here!
path.attr({ path: 'm0,0l0,' + values.join('l3,') });
// just a test case!
setTimeout(test, 1);
};
test();
Unfortunately this approach leaks in memory. I've tested it in FF 4 and IE 7+ with Raphaël 1.5.2 and 2.0 beta. The only difference is that Raphaël 1.5.2 leaks much faster tha开发者_如何学运维n 2.0 beta.
What am I doing wrong?
Update
To put this question into context: I want to implement a 'realtime' graph control with Raphaël. Therefore I use an array buffer for each series and render them when the buffer size is reached, so I need only to render a given fix length series.
The only way I saw to do this in Raphaël is a path element per series which gets an update of it's path attribute .attr({path: path.attr('path') + getSvgPath(buffer)})
if necessary, followed by an translation on the x axis depending on the buffer size .animate({translation: (bufferSize*valuesDistance*-1) + ',0'}, 500, '<', callback)
- for a smooth animation of the updates - and at last a shift of the path attribute after the animation to prevent ever expanding path strings: .attr({path: shiftSvgPath(path.attr('path'))})
.
The functions shiftSvgPath()
and getSvgPath()
just returning the appropriate svg path string. So that the result always consits of one moveTo
command at the beginning and a constant number of lineTo
commands, either equal to the number of displayed values or plus the buffer size.
I ran into a similar problem lately. I wouldn't call it a leak, but rather a huge memory consumption from Raphael, when drawing paths. I'm just guessing it uses some caching arrays internally that eat up a lot of memory.
My approach was to ditch Raphael and draw the svg elements with plain old javascript.
精彩评论