]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Optimize legend drawing 2723/head
authorEvert Timberg <evert.timberg+github@gmail.com>
Tue, 7 Jun 2016 02:14:42 +0000 (22:14 -0400)
committerEvert Timberg <evert.timberg+github@gmail.com>
Tue, 7 Jun 2016 02:14:42 +0000 (22:14 -0400)
src/core/core.legend.js

index 546085510a455e7b111e913bc2827a992d322473..b3d392c05fc49e1b770294993a631e0d565359e9 100644 (file)
@@ -290,145 +290,106 @@ module.exports = function(Chart) {
                                        fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),
                                        labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
 
-                               // Horizontal
-                               if (me.isHorizontal()) {
-                                       cursor = {
-                                               x: me.left + ((legendWidth - lineWidths[0]) / 2),
-                                               y: me.top + labelOpts.padding,
-                                               line: 0
-                                       };
-
-                                       // Labels
-                                       ctx.textAlign = "left";
-                                       ctx.textBaseline = 'top';
-                                       ctx.lineWidth = 0.5;
-                                       ctx.strokeStyle = fontColor; // for strikethrough effect
-                                       ctx.fillStyle = fontColor; // render in correct colour
-                                       ctx.font = labelFont;
-
-                                       var boxWidth = labelOpts.boxWidth,
-                                               hitboxes = me.legendHitBoxes;
-
-                                       helpers.each(me.legendItems, function(legendItem, i) {
-                                               var textWidth = ctx.measureText(legendItem.text).width,
-                                                       width = boxWidth + (fontSize / 2) + textWidth,
-                                                       x = cursor.x,
-                                                       y = cursor.y;
-
-                                               if (x + width >= legendWidth) {
-                                                       y = cursor.y += fontSize + (labelOpts.padding);
-                                                       cursor.line++;
-                                                       x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
-                                               }
-
-                                               // Set the ctx for the box
-                                               ctx.save();
-
-                                               ctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);
-                                               ctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);
-                                               ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);
-                                               ctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);
-                                               ctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
-                                               ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);
-
-                                               if (ctx.setLineDash) {
-                                                       // IE 9 and 10 do not support line dash
-                                                       ctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));
-                                               }
+                               // Canvas setup
+                               ctx.textAlign = "left";
+                               ctx.textBaseline = 'top';
+                               ctx.lineWidth = 0.5;
+                               ctx.strokeStyle = fontColor; // for strikethrough effect
+                               ctx.fillStyle = fontColor; // render in correct colour
+                               ctx.font = labelFont;
 
-                                               // Draw the box
-                                               ctx.strokeRect(x, y, boxWidth, fontSize);
-                                               ctx.fillRect(x, y, boxWidth, fontSize);
+                               var boxWidth = labelOpts.boxWidth,
+                                       hitboxes = me.legendHitBoxes;
 
-                                               ctx.restore();
+                               // current position
+                               var drawLegendBox = function(x, y, legendItem) {
+                                       // Set the ctx for the box
+                                       ctx.save();
 
-                                               hitboxes[i].left = x;
-                                               hitboxes[i].top = y;
+                                       ctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);
+                                       ctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);
+                                       ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);
+                                       ctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);
+                                       ctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
+                                       ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);
 
-                                               // Fill the actual label
-                                               ctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);
+                                       if (ctx.setLineDash) {
+                                               // IE 9 and 10 do not support line dash
+                                               ctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));
+                                       }
 
-                                               if (legendItem.hidden) {
-                                                       // Strikethrough the text if hidden
-                                                       ctx.beginPath();
-                                                       ctx.lineWidth = 2;
-                                                       ctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));
-                                                       ctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));
-                                                       ctx.stroke();
-                                               }
+                                       // Draw the box
+                                       ctx.strokeRect(x, y, boxWidth, fontSize);
+                                       ctx.fillRect(x, y, boxWidth, fontSize);
+
+                                       ctx.restore();
+                               };
+                               var fillText = function(x, y, legendItem, textWidth) {
+                                       ctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);
+
+                                       if (legendItem.hidden) {
+                                               // Strikethrough the text if hidden
+                                               ctx.beginPath();
+                                               ctx.lineWidth = 2;
+                                               ctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));
+                                               ctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));
+                                               ctx.stroke();
+                                       }
+                               };
 
-                                               cursor.x += width + (labelOpts.padding);
-                                       }, me);
+                               // Horizontal
+                               var isHorizontal = me.isHorizontal();
+                               if (isHorizontal) {
+                                       cursor = {
+                                               x: me.left + ((legendWidth - lineWidths[0]) / 2),
+                                               y: me.top + labelOpts.padding,
+                                               line: 0
+                                       };
                                } else {
                                        cursor = {
                                                x: me.left + labelOpts.padding,
                                                y: me.top,
                                                line: 0
                                        };
+                               }
 
-                                       // Labels
-                                       ctx.textAlign = "left";
-                                       ctx.textBaseline = 'top';
-                                       ctx.lineWidth = 0.5;
-                                       ctx.strokeStyle = fontColor; // for strikethrough effect
-                                       ctx.fillStyle = fontColor; // render in correct colour
-                                       ctx.font = labelFont;
-
-                                       var boxWidth = labelOpts.boxWidth,
-                                               hitboxes = me.legendHitBoxes;
-
-                                       helpers.each(me.legendItems, function(legendItem, i) {
-                                               var textWidth = ctx.measureText(legendItem.text).width,
-                                                       width = boxWidth + (fontSize / 2) + textWidth,
-                                                       height = fontSize + labelOpts.padding,
-                                                       x = cursor.x,
-                                                       y = cursor.y;
+                               var itemHeight = fontSize + labelOpts.padding;
+                               helpers.each(me.legendItems, function(legendItem, i) {
+                                       var textWidth = ctx.measureText(legendItem.text).width,
+                                               width = boxWidth + (fontSize / 2) + textWidth,
+                                               x = cursor.x,
+                                               y = cursor.y;
 
-                                               if (y + height > me.bottom) {
+                                       if (isHorizontal) {
+                                               if (x + width >= legendWidth) {
+                                                       y = cursor.y += fontSize + (labelOpts.padding);
+                                                       cursor.line++;
+                                                       x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
+                                               }
+                                       } else {
+                                               if (y + itemHeight > me.bottom) {
                                                        x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;
                                                        y = cursor.y = me.top;
                                                        cursor.line++;
                                                }
+                                       }
+                                       
 
-                                               // Set the ctx for the box
-                                               ctx.save();
-
-                                               ctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);
-                                               ctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);
-                                               ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);
-                                               ctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);
-                                               ctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
-                                               ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);
-
-                                               if (ctx.setLineDash) {
-                                                       // IE 9 and 10 do not support line dash
-                                                       ctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));
-                                               }
-
-                                               // Draw the box
-                                               ctx.strokeRect(x, y, boxWidth, fontSize);
-                                               ctx.fillRect(x, y, boxWidth, fontSize);
-
-                                               ctx.restore();
-
-                                               hitboxes[i].left = x;
-                                               hitboxes[i].top = y;
+                                       drawLegendBox(x, y, legendItem);
 
-                                               // Fill the actual label
-                                               ctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);
+                                       hitboxes[i].left = x;
+                                       hitboxes[i].top = y;
 
-                                               if (legendItem.hidden) {
-                                                       // Strikethrough the text if hidden
-                                                       ctx.beginPath();
-                                                       ctx.lineWidth = 2;
-                                                       ctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));
-                                                       ctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));
-                                                       ctx.stroke();
-                                               }
+                                       // Fill the actual label
+                                       fillText(x, y, legendItem, textWidth);
 
-                                               cursor.y += height;
-                                       });
-                               }
+                                       if (isHorizontal) {
+                                               cursor.x += width + (labelOpts.padding);
+                                       } else {
+                                               cursor.y += itemHeight;
+                                       }
+                                       
+                               });
                        }
                },