]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Optimize element.point and controller.line 2578/head
authorSimon Brunel <simonbrunel@users.noreply.github.com>
Tue, 17 May 2016 11:32:40 +0000 (13:32 +0200)
committerSimon Brunel <simonbrunel@users.noreply.github.com>
Tue, 17 May 2016 22:25:45 +0000 (00:25 +0200)
Change some helpers.each() to `for` loops when iterating on a potentially large number of items and use more local variables when appropriate (making the minified build a bit smaller).

src/controllers/controller.line.js
src/elements/element.point.js

index 58349034c9b4e0b698de69e5364a9287c508bdee..0807600688a01e10f9d7a4365927d4104a78e2a3 100644 (file)
@@ -23,50 +23,58 @@ module.exports = function(Chart) {
                }
        };
 
-
        Chart.controllers.line = Chart.DatasetController.extend({
                addElements: function() {
-                       var meta = this.getMeta();
+                       var me = this;
+                       var meta = me.getMeta();
+                       var data = me.getDataset().data || [];
+                       var value, i, ilen;
+
                        meta.dataset = meta.dataset || new Chart.elements.Line({
-                               _chart: this.chart.chart,
-                               _datasetIndex: this.index,
+                               _chart: me.chart.chart,
+                               _datasetIndex: me.index,
                                _points: meta.data
                        });
 
-                       helpers.each(this.getDataset().data, function(value, index) {
-                               meta.data[index] = meta.data[index] || new Chart.elements.Point({
-                                       _chart: this.chart.chart,
-                                       _datasetIndex: this.index,
-                                       _index: index
+                       for (i=0, ilen=data.length; i<ilen; ++i) {
+                               value = data[i];
+                               meta.data[i] = meta.data[i] || new Chart.elements.Point({
+                                       _chart: me.chart.chart,
+                                       _datasetIndex: me.index,
+                                       _index: i
                                });
-                       }, this);
+                       }
                },
 
                addElementAndReset: function(index) {
+                       var me = this;
+                       var options = me.chart.options;
                        var point = new Chart.elements.Point({
-                               _chart: this.chart.chart,
-                               _datasetIndex: this.index,
+                               _chart: me.chart.chart,
+                               _datasetIndex: me.index,
                                _index: index
                        });
 
                        // Add to the points array and reset it
-                       this.getMeta().data.splice(index, 0, point);
-                       this.updateElement(point, index, true);
+                       me.getMeta().data.splice(index, 0, point);
+                       me.updateElement(point, index, true);
 
                        // Make sure bezier control points are updated
-                       if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0)
-                               this.updateBezierControlPoints();
+                       if (options.showLines && options.elements.line.tension !== 0) {
+                               me.updateBezierControlPoints();
+                       }
                },
 
                update: function update(reset) {
-                       var meta = this.getMeta();
+                       var me = this;
+                       var meta = me.getMeta();
                        var line = meta.dataset;
-                       var lineElementOptions = this.chart.options.elements.line;
-                       var points = meta.data;
-
-                       var yScale = this.getScaleForId(meta.yAxisID);
-                       var xScale = this.getScaleForId(meta.xAxisID);
-                       var scaleBase;
+                       var points = meta.data || [];
+                       var options = me.chart.options;
+                       var lineElementOptions = options.elements.line;
+                       var yScale = me.getScaleForId(meta.yAxisID);
+                       var xScale = me.getScaleForId(meta.xAxisID);
+                       var scaleBase, i, ilen, dataset, custom;
 
                        if (yScale.min < 0 && yScale.max < 0) {
                                scaleBase = yScale.getPixelForValue(yScale.max);
@@ -77,21 +85,21 @@ module.exports = function(Chart) {
                        }
 
                        // Update Line
-                       if (this.chart.options.showLines) {
-                               // Utility
-                               line._scale = yScale;
-                               line._datasetIndex = this.index;
-                               // Data
-                               line._children = points;
-                               // Model
+                       if (options.showLines) {
+                               dataset = me.getDataset();
+                               custom = line.custom || {};
 
-                               var dataset = this.getDataset();
-                               var custom = line.custom || {};
                                // Compatibility: If the properties are defined with only the old name, use those values
                                if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
                                        dataset.lineTension = dataset.tension;
                                }
 
+                               // Utility
+                               line._scale = yScale;
+                               line._datasetIndex = me.index;
+                               // Data
+                               line._children = points;
+                               // Model
                                line._model = {
                                        // Appearance
                                        tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),
@@ -108,16 +116,17 @@ module.exports = function(Chart) {
                                        scaleBottom: yScale.bottom,
                                        scaleZero: scaleBase
                                };
+
                                line.pivot();
                        }
 
                        // Update Points
-                       helpers.each(points, function(point, index) {
-                               this.updateElement(point, index, reset);
-                       }, this);
+                       for (i=0, ilen=points.length; i<ilen; ++i) {
+                               me.updateElement(points[i], i, reset);
+                       }
 
-                       if (this.chart.options.showLines && lineElementOptions.tension !== 0) {
-                               this.updateBezierControlPoints();
+                       if (options.showLines && lineElementOptions.tension !== 0) {
+                               me.updateBezierControlPoints();
                        }
                },
 
@@ -136,6 +145,7 @@ module.exports = function(Chart) {
 
                        return backgroundColor;
                },
+
                getPointBorderColor: function(point, index) {
                        var borderColor = this.chart.options.elements.point.borderColor;
                        var dataset = this.getDataset();
@@ -151,6 +161,7 @@ module.exports = function(Chart) {
 
                        return borderColor;
                },
+
                getPointBorderWidth: function(point, index) {
                        var borderWidth = this.chart.options.elements.point.borderWidth;
                        var dataset = this.getDataset();
@@ -168,12 +179,16 @@ module.exports = function(Chart) {
                },
 
                updateElement: function(point, index, reset) {
-                       var meta = this.getMeta();
+                       var me = this;
+                       var meta = me.getMeta();
                        var custom = point.custom || {};
-                       var dataset = this.getDataset();
-                       var yScale = this.getScaleForId(meta.yAxisID);
-                       var xScale = this.getScaleForId(meta.xAxisID);
-                       var scaleBase;
+                       var dataset = me.getDataset();
+                       var datasetIndex = me.index;
+                       var value = dataset.data[index];
+                       var yScale = me.getScaleForId(meta.yAxisID);
+                       var xScale = me.getScaleForId(meta.xAxisID);
+                       var pointOptions = me.chart.options.elements.point;
+                       var scaleBase, x, y;
 
                        if (yScale.min < 0 && yScale.max < 0) {
                                scaleBase = yScale.getPixelForValue(yScale.max);
@@ -183,56 +198,56 @@ module.exports = function(Chart) {
                                scaleBase = yScale.getPixelForValue(0);
                        }
 
-                       // Utility
-                       point._chart = this.chart.chart;
-                       point._xScale = xScale;
-                       point._yScale = yScale;
-                       point._datasetIndex = this.index;
-                       point._index = index;
-
-                       // Desired view properties
-
                        // Compatibility: If the properties are defined with only the old name, use those values
-                       if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined))
-                       {
+                       if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
                                dataset.pointRadius = dataset.radius;
                        }
-                       if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined))
-                       {
+                       if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
                                dataset.pointHitRadius = dataset.hitRadius;
                        }
 
+                       x = xScale.getPixelForValue(value, index, datasetIndex, me.chart.isCombo);
+                       y = reset ? scaleBase : me.calculatePointY(value, index, datasetIndex, me.chart.isCombo);
+
+                       // Utility
+                       point._chart = me.chart.chart;
+                       point._xScale = xScale;
+                       point._yScale = yScale;
+                       point._datasetIndex = datasetIndex;
+                       point._index = index;
+
+                       // Desired view properties
                        point._model = {
-                               x: xScale.getPixelForValue(dataset.data[index], index, this.index, this.chart.isCombo),
-                               y: reset ? scaleBase : this.calculatePointY(dataset.data[index], index, this.index, this.chart.isCombo),
+                               x: x,
+                               y: y,
+                               skip: custom.skip || isNaN(x) || isNaN(y),
                                // Appearance
-                               radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, this.chart.options.elements.point.radius),
-                               pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, this.chart.options.elements.point.pointStyle),
-                               backgroundColor: this.getPointBackgroundColor(point, index),
-                               borderColor: this.getPointBorderColor(point, index),
-                               borderWidth: this.getPointBorderWidth(point, index),
+                               radius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),
+                               pointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),
+                               backgroundColor: me.getPointBackgroundColor(point, index),
+                               borderColor: me.getPointBorderColor(point, index),
+                               borderWidth: me.getPointBorderWidth(point, index),
                                tension: meta.dataset._model ? meta.dataset._model.tension : 0,
                                // Tooltip
-                               hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, this.chart.options.elements.point.hitRadius)
+                               hitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)
                        };
-
-                       point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
                },
 
                calculatePointY: function(value, index, datasetIndex, isCombo) {
-                       var meta = this.getMeta();
-                       var xScale = this.getScaleForId(meta.xAxisID);
-                       var yScale = this.getScaleForId(meta.yAxisID);
+                       var me = this;
+                       var chart = me.chart;
+                       var meta = me.getMeta();
+                       var xScale = me.getScaleForId(meta.xAxisID);
+                       var yScale = me.getScaleForId(meta.yAxisID);
+                       var sumPos = 0;
+                       var sumNeg = 0;
+                       var i, ds, dsMeta;
 
                        if (yScale.options.stacked) {
-
-                               var sumPos = 0,
-                                       sumNeg = 0;
-
-                               for (var i = 0; i < datasetIndex; i++) {
-                                       var ds = this.chart.data.datasets[i];
-                                       var dsMeta = this.chart.getDatasetMeta(i);
-                                       if (dsMeta.type === 'line' && this.chart.isDatasetVisible(i)) {
+                               for (i = 0; i < datasetIndex; i++) {
+                                       ds = chart.data.datasets[i];
+                                       dsMeta = chart.getDatasetMeta(i);
+                                       if (dsMeta.type === 'line' && chart.isDatasetVisible(i)) {
                                                if (ds.data[index] < 0) {
                                                        sumNeg += ds.data[index] || 0;
                                                } else {
@@ -252,45 +267,52 @@ module.exports = function(Chart) {
                },
 
                updateBezierControlPoints: function() {
-                       // Update bezier control points
                        var meta = this.getMeta();
-                       helpers.each(meta.data, function(point, index) {
-                               var controlPoints = helpers.splineCurve(
-                                       helpers.previousItem(meta.data, index)._model,
-                                       point._model,
-                                       helpers.nextItem(meta.data, index)._model,
+                       var area = this.chart.chartArea;
+                       var points = meta.data || [];
+                       var i, ilen, point, model, controlPoints;
+
+                       for (i=0, ilen=points.length; i<ilen; ++i) {
+                               point = points[i];
+                               model = point._model;
+                               controlPoints = helpers.splineCurve(
+                                       helpers.previousItem(points, i)._model,
+                                       model,
+                                       helpers.nextItem(points, i)._model,
                                        meta.dataset._model.tension
                                );
 
                                // Prevent the bezier going outside of the bounds of the graph
-                               point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left);
-                               point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top);
-
-                               point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left);
-                               point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top);
+                               model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, area.right), area.left);
+                               model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, area.bottom), area.top);
+                               model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, area.right), area.left);
+                               model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, area.bottom), area.top);
 
                                // Now pivot the point for animation
                                point.pivot();
-                       }, this);
+                       }
                },
 
                draw: function(ease) {
                        var meta = this.getMeta();
+                       var points = meta.data || [];
                        var easingDecimal = ease || 1;
+                       var i, ilen;
 
                        // Transition Point Locations
-                       helpers.each(meta.data, function(point) {
-                               point.transition(easingDecimal);
-                       });
+                       for (i=0, ilen=points.length; i<ilen; ++i) {
+                               points[i].transition(easingDecimal);
+                       }
 
                        // Transition and Draw the line
-                       if (this.chart.options.showLines)
+                       if (this.chart.options.showLines) {
                                meta.dataset.transition(easingDecimal).draw();
+                       }
 
                        // Draw the points
-                       helpers.each(meta.data, function(point) {
-                               point.draw();
-                       });
+                       for (i=0, ilen=points.length; i<ilen; ++i) {
+                               points[i].draw();
+                       }
                },
 
                setHoverStyle: function(point) {
@@ -300,28 +322,28 @@ module.exports = function(Chart) {
                        var custom = point.custom || {};
                        var model = point._model;
 
-                       model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
-                       model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
-                       model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
-                       model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
+                       model.radius = custom.hoverRadius || helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
+                       model.backgroundColor = custom.hoverBackgroundColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
+                       model.borderColor = custom.hoverBorderColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
+                       model.borderWidth = custom.hoverBorderWidth || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
                },
 
                removeHoverStyle: function(point) {
-                       var dataset = this.chart.data.datasets[point._datasetIndex];
+                       var me = this;
+                       var dataset = me.chart.data.datasets[point._datasetIndex];
                        var index = point._index;
                        var custom = point.custom || {};
                        var model = point._model;
 
                        // Compatibility: If the properties are defined with only the old name, use those values
-                       if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined))
-                       {
+                       if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
                                dataset.pointRadius = dataset.radius;
                        }
 
-                       model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, this.chart.options.elements.point.radius);
-                       model.backgroundColor = this.getPointBackgroundColor(point, index);
-                       model.borderColor = this.getPointBorderColor(point, index);
-                       model.borderWidth = this.getPointBorderWidth(point, index);
+                       model.radius = custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);
+                       model.backgroundColor = me.getPointBackgroundColor(point, index);
+                       model.borderColor = me.getPointBorderColor(point, index);
+                       model.borderWidth = me.getPointBorderWidth(point, index);
                }
        });
 };
index 306a643c533ac727211ef281d09e8fcc8e976251..f96207713ea5f45f2ae55f59f855c57c570cb969 100644 (file)
@@ -18,7 +18,6 @@ module.exports = function(Chart) {
                hoverBorderWidth: 1
        };
 
-
        Chart.elements.Point = Chart.Element.extend({
                inRange: function(mouseX, mouseY) {
                        var vm = this._view;
@@ -26,7 +25,7 @@ module.exports = function(Chart) {
                },
                inLabelRange: function(mouseX) {
                        var vm = this._view;
-                       return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false; 
+                       return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
                },
                tooltipPosition: function() {
                        var vm = this._view;
@@ -37,110 +36,112 @@ module.exports = function(Chart) {
                        };
                },
                draw: function() {
-                       var vm = this._view,
-                               x = vm.x,
-                               y = vm.y;
+                       var vm = this._view;
                        var ctx = this._chart.ctx;
+                       var pointStyle = vm.pointStyle;
+                       var radius = vm.radius;
+                       var x = vm.x;
+                       var y = vm.y;
+                       var type, edgeLength, xOffset, yOffset, height, size;
 
                        if (vm.skip) {
                                return;
                        }
 
-                       var pointStyle = vm.pointStyle;
-                       if (typeof pointStyle === 'object' && ((pointStyle.toString() === '[object HTMLImageElement]') || (pointStyle.toString() === '[object HTMLCanvasElement]'))) {
-                               ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2);
-                               return;
+                       if (typeof pointStyle === 'object') {
+                               type = pointStyle.toString();
+                               if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
+                                       ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2);
+                                       return;
+                               }
                        }
 
-                       if (!isNaN(vm.radius) && vm.radius > 0) {
-
-                               ctx.strokeStyle = vm.borderColor || defaultColor;
-                               ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);
-
-                               ctx.fillStyle = vm.backgroundColor || defaultColor;
-
-                               var radius = vm.radius;
-
-                               var xOffset,
-                                       yOffset;
+                       if (isNaN(radius) || radius <= 0) {
+                               return;
+                       }
 
-                               switch (pointStyle) {
-                                       // Default includes circle
-                                       default: 
-                                               ctx.beginPath();
-                                               ctx.arc(x, y, radius, 0, Math.PI * 2);
-                                               ctx.closePath();
-                                               ctx.fill();
-                                               break;
-                                       case 'triangle':
-                                               ctx.beginPath();
-                                               var edgeLength = 3 * radius / Math.sqrt(3);
-                                               var height = edgeLength * Math.sqrt(3) / 2;
-                                               ctx.moveTo(x - edgeLength / 2, y + height / 3);
-                                               ctx.lineTo(x + edgeLength / 2, y + height / 3);
-                                               ctx.lineTo(x, y - 2 * height / 3);
-                                               ctx.closePath();
-                                               ctx.fill();
-                                               break;
-                                       case 'rect':
-                                               ctx.fillRect(x - 1 / Math.SQRT2 * radius, y - 1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius);
-                                               ctx.strokeRect(x - 1 / Math.SQRT2 * radius, y - 1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius);
-                                               break;
-                                       case 'rectRot':
-                                               ctx.translate(x, y);
-                                               ctx.rotate(Math.PI / 4);
-                                               ctx.fillRect(-1 / Math.SQRT2 * radius, -1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius);
-                                               ctx.strokeRect(-1 / Math.SQRT2 * radius, -1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius);
-                                               ctx.setTransform(1, 0, 0, 1, 0, 0);
-                                               break;
-                                       case 'cross':
-                                               ctx.beginPath();
-                                               ctx.moveTo(x, y + radius);
-                                               ctx.lineTo(x, y - radius);
-                                               ctx.moveTo(x - radius, y);
-                                               ctx.lineTo(x + radius, y);
-                                               ctx.closePath();
-                                               break;
-                                       case 'crossRot':
-                                               ctx.beginPath();
-                                               xOffset = Math.cos(Math.PI / 4) * radius;
-                                               yOffset = Math.sin(Math.PI / 4) * radius;
-                                               ctx.moveTo(x - xOffset, y - yOffset);
-                                               ctx.lineTo(x + xOffset, y + yOffset);
-                                               ctx.moveTo(x - xOffset, y + yOffset);
-                                               ctx.lineTo(x + xOffset, y - yOffset);
-                                               ctx.closePath();
-                                               break;
-                                       case 'star':
-                                               ctx.beginPath();
-                                               ctx.moveTo(x, y + radius);
-                                               ctx.lineTo(x, y - radius);
-                                               ctx.moveTo(x - radius, y);
-                                               ctx.lineTo(x + radius, y);
-                                               xOffset = Math.cos(Math.PI / 4) * radius;
-                                               yOffset = Math.sin(Math.PI / 4) * radius;
-                                               ctx.moveTo(x - xOffset, y - yOffset);
-                                               ctx.lineTo(x + xOffset, y + yOffset);
-                                               ctx.moveTo(x - xOffset, y + yOffset);
-                                               ctx.lineTo(x + xOffset, y - yOffset);
-                                               ctx.closePath();
-                                               break;
-                                       case 'line':
-                                               ctx.beginPath();
-                                               ctx.moveTo(x - radius, y);
-                                               ctx.lineTo(x + radius, y);
-                                               ctx.closePath();
-                                               break;
-                                       case 'dash':
-                                               ctx.beginPath();
-                                               ctx.moveTo(x, y);
-                                               ctx.lineTo(x + radius, y);
-                                               ctx.closePath();
-                                               break;
-                               }
+                       ctx.strokeStyle = vm.borderColor || defaultColor;
+                       ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);
+                       ctx.fillStyle = vm.backgroundColor || defaultColor;
 
-                               ctx.stroke();
+                       switch (pointStyle) {
+                       // Default includes circle
+                       default:
+                               ctx.beginPath();
+                               ctx.arc(x, y, radius, 0, Math.PI * 2);
+                               ctx.closePath();
+                               ctx.fill();
+                               break;
+                       case 'triangle':
+                               ctx.beginPath();
+                               edgeLength = 3 * radius / Math.sqrt(3);
+                               height = edgeLength * Math.sqrt(3) / 2;
+                               ctx.moveTo(x - edgeLength / 2, y + height / 3);
+                               ctx.lineTo(x + edgeLength / 2, y + height / 3);
+                               ctx.lineTo(x, y - 2 * height / 3);
+                               ctx.closePath();
+                               ctx.fill();
+                               break;
+                       case 'rect':
+                               size = 1 / Math.SQRT2 * radius;
+                               ctx.fillRect(x - size, y - size, 2 * size,  2 * size);
+                               ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);
+                               break;
+                       case 'rectRot':
+                               ctx.translate(x, y);
+                               ctx.rotate(Math.PI / 4);
+                               size = 1 / Math.SQRT2 * radius;
+                               ctx.fillRect(-size, -size, 2 * size, 2 * size);
+                               ctx.strokeRect(-size, -size, 2 * size, 2 * size);
+                               ctx.setTransform(1, 0, 0, 1, 0, 0);
+                               break;
+                       case 'cross':
+                               ctx.beginPath();
+                               ctx.moveTo(x, y + radius);
+                               ctx.lineTo(x, y - radius);
+                               ctx.moveTo(x - radius, y);
+                               ctx.lineTo(x + radius, y);
+                               ctx.closePath();
+                               break;
+                       case 'crossRot':
+                               ctx.beginPath();
+                               xOffset = Math.cos(Math.PI / 4) * radius;
+                               yOffset = Math.sin(Math.PI / 4) * radius;
+                               ctx.moveTo(x - xOffset, y - yOffset);
+                               ctx.lineTo(x + xOffset, y + yOffset);
+                               ctx.moveTo(x - xOffset, y + yOffset);
+                               ctx.lineTo(x + xOffset, y - yOffset);
+                               ctx.closePath();
+                               break;
+                       case 'star':
+                               ctx.beginPath();
+                               ctx.moveTo(x, y + radius);
+                               ctx.lineTo(x, y - radius);
+                               ctx.moveTo(x - radius, y);
+                               ctx.lineTo(x + radius, y);
+                               xOffset = Math.cos(Math.PI / 4) * radius;
+                               yOffset = Math.sin(Math.PI / 4) * radius;
+                               ctx.moveTo(x - xOffset, y - yOffset);
+                               ctx.lineTo(x + xOffset, y + yOffset);
+                               ctx.moveTo(x - xOffset, y + yOffset);
+                               ctx.lineTo(x + xOffset, y - yOffset);
+                               ctx.closePath();
+                               break;
+                       case 'line':
+                               ctx.beginPath();
+                               ctx.moveTo(x - radius, y);
+                               ctx.lineTo(x + radius, y);
+                               ctx.closePath();
+                               break;
+                       case 'dash':
+                               ctx.beginPath();
+                               ctx.moveTo(x, y);
+                               ctx.lineTo(x + radius, y);
+                               ctx.closePath();
+                               break;
                        }
+
+                       ctx.stroke();
                }
        });
-};
\ No newline at end of file
+};