Bill
Bill

Reputation: 25565

Efficiently drawing text using Raphael.js

I'm drawing a chart using Raphael.js and am running into a performance issue concerning text. I'm currently using the following pattern to draw text:

var labels = paper.set();    

for (var i = 0; i < 6; i++ ) {
  labels.push(paper.text(0, i * 10, 'my text'));
}

labels.attr({'font-size',10});

However, using this method seems to be very slow. I can draw 400 rectangles (using a single path string) twice as fast as I can add 6 labels to the chart. Is there any way to batch up text drawing or a different way to do this that is faster? At the moment, almost 80% of my drawing time is spent adding labels.

Upvotes: 3

Views: 3799

Answers (2)

zcrar70
zcrar70

Reputation: 3194

Not sure if this is any use, but I've found it fairly quick to use normal divs for text labels (rather than vectors.)

Upvotes: 1

iRedMedia
iRedMedia

Reputation: 138

As in your example, I've tested the following using console.time(). It appears that your push adds about 10% to the time, where as your attr call almost doubles the process. For example:

for (var i = 0; i < 4200; i++ ) {
  labels.push(paper.text(0, i * 10, 'my text'));
}

Resulted in:

labels: 3452ms
attr: 2455ms

Where as, when we removed the attr calls:

for (var i = 0; i < 4200; i++ ) {
  paper.text(0, i * 10, 'my text');
}

Resulted in:

labels: 3011ms
attr: 0ms

Doing this by chaining has little effect on performance.

for (var i = 0; i < 4200; i++ ) {
  labels.push(paper.text(0, i * 10, 'my text').attr({'font-size':10}));
}

Resulted in:

draw: 5759ms

Next we analyzed the amount of characters in a string to determine if there is any direct correlation between number of characters drawn, and time elapsed.

paper.text(5, i * 10, '0'); resulted in a time of draw: 2974ms

paper.text(5, i * 10, 'texttexttexttexttexttexttexttexttexttexttexttext'); resulted in a time of draw: 3122ms which is negligable.

Now lets try that case you spoke of, with the rectangles. Lets draw the same amount, using the same positioning, and only change a few attributes that will not affect render times (width and height)

for (var i = 0; i < 4200; i++ ) {
  paper.rect(5, i * 10, 50, 50);
}

Resulted in:

draw: 333ms

As the numbers show, I believe this is because we are drawing vectors with incredibly more complex curves. A squares vector formula is going to be exponentially shorter, and easier to calculate then a series of letters and their curves.

Upvotes: 4

Related Questions