diff --git a/src/chart.js b/src/chart.js index 146cfbaa8d3..56fc8f24cd0 100644 --- a/src/chart.js +++ b/src/chart.js @@ -9,11 +9,12 @@ Chart.helpers = require('./helpers/index'); require('./core/core.helpers')(Chart); Chart.defaults = require('./core/core.defaults'); +Chart.Element = require('./core/core.element'); +Chart.elements = require('./elements/index'); Chart.Interaction = require('./core/core.interaction'); Chart.platform = require('./platforms/platform'); Chart.Ticks = require('./core/core.ticks'); -require('./core/core.element')(Chart); require('./core/core.plugin')(Chart); require('./core/core.animation')(Chart); require('./core/core.controller')(Chart); @@ -23,11 +24,6 @@ require('./core/core.scaleService')(Chart); require('./core/core.scale')(Chart); require('./core/core.tooltip')(Chart); -require('./elements/element.arc')(Chart); -require('./elements/element.line')(Chart); -require('./elements/element.point')(Chart); -require('./elements/element.rectangle')(Chart); - require('./scales/scale.linearbase')(Chart); require('./scales/scale.category')(Chart); require('./scales/scale.linear')(Chart); diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 97a077e66d5..637d589d1ea 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var elements = require('../elements/index'); var helpers = require('../helpers/index'); defaults._set('bar', { @@ -89,7 +90,7 @@ module.exports = function(Chart) { Chart.controllers.bar = Chart.DatasetController.extend({ - dataElementType: Chart.elements.Rectangle, + dataElementType: elements.Rectangle, initialize: function() { var me = this; @@ -104,13 +105,13 @@ module.exports = function(Chart) { update: function(reset) { var me = this; - var elements = me.getMeta().data; + var rects = me.getMeta().data; var i, ilen; me._ruler = me.getRuler(); - for (i = 0, ilen = elements.length; i < ilen; ++i) { - me.updateElement(elements[i], i, reset); + for (i = 0, ilen = rects.length; i < ilen; ++i) { + me.updateElement(rects[i], i, reset); } }, @@ -326,9 +327,9 @@ module.exports = function(Chart) { draw: function() { var me = this; var chart = me.chart; - var elements = me.getMeta().data; + var rects = me.getMeta().data; var dataset = me.getDataset(); - var ilen = elements.length; + var ilen = rects.length; var i = 0; var d; @@ -337,7 +338,7 @@ module.exports = function(Chart) { for (; i max ? borderWidth : max; max = hoverWidth > max ? hoverWidth : max; diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index d841ada64dc..dd7d01d6018 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var elements = require('../elements/index'); var helpers = require('../helpers/index'); defaults._set('line', { @@ -31,9 +32,9 @@ module.exports = function(Chart) { Chart.controllers.line = Chart.DatasetController.extend({ - datasetElementType: Chart.elements.Line, + datasetElementType: elements.Line, - dataElementType: Chart.elements.Point, + dataElementType: elements.Point, update: function(reset) { var me = this; diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index c0ac2993e38..e59aedfb98a 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var elements = require('../elements/index'); var helpers = require('../helpers/index'); defaults._set('polarArea', { @@ -111,7 +112,7 @@ module.exports = function(Chart) { Chart.controllers.polarArea = Chart.DatasetController.extend({ - dataElementType: Chart.elements.Arc, + dataElementType: elements.Arc, linkScales: helpers.noop, diff --git a/src/controllers/controller.radar.js b/src/controllers/controller.radar.js index b3bccdca970..5de4e4ede0a 100644 --- a/src/controllers/controller.radar.js +++ b/src/controllers/controller.radar.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var elements = require('../elements/index'); var helpers = require('../helpers/index'); defaults._set('radar', { @@ -18,9 +19,9 @@ module.exports = function(Chart) { Chart.controllers.radar = Chart.DatasetController.extend({ - datasetElementType: Chart.elements.Line, + datasetElementType: elements.Line, - dataElementType: Chart.elements.Point, + dataElementType: elements.Point, linkScales: helpers.noop, diff --git a/src/core/core.animation.js b/src/core/core.animation.js index bbd44cde18e..17d8cb554e5 100644 --- a/src/core/core.animation.js +++ b/src/core/core.animation.js @@ -2,6 +2,7 @@ 'use strict'; var defaults = require('./core.defaults'); +var Element = require('./core.element'); var helpers = require('../helpers/index'); defaults._set('global', { @@ -15,7 +16,7 @@ defaults._set('global', { module.exports = function(Chart) { - Chart.Animation = Chart.Element.extend({ + Chart.Animation = Element.extend({ chart: null, // the animation associated chart instance currentStep: 0, // the current animation step numSteps: 60, // default number of steps diff --git a/src/core/core.element.js b/src/core/core.element.js index ba508fddcda..016bf5d9e47 100644 --- a/src/core/core.element.js +++ b/src/core/core.element.js @@ -3,116 +3,113 @@ var color = require('chartjs-color'); var helpers = require('../helpers/index'); -module.exports = function(Chart) { +function interpolate(start, view, model, ease) { + var keys = Object.keys(model); + var i, ilen, key, actual, origin, target, type, c0, c1; - function interpolate(start, view, model, ease) { - var keys = Object.keys(model); - var i, ilen, key, actual, origin, target, type, c0, c1; + for (i=0, ilen=keys.length; i No Transition + if (!model || ease === 1) { + me._view = model; + me._start = null; return me; - }, - - transition: function(ease) { - var me = this; - var model = me._model; - var start = me._start; - var view = me._view; - - // No animation -> No Transition - if (!model || ease === 1) { - me._view = model; - me._start = null; - return me; - } + } - if (!view) { - view = me._view = {}; - } + if (!view) { + view = me._view = {}; + } - if (!start) { - start = me._start = {}; - } + if (!start) { + start = me._start = {}; + } - interpolate(start, view, model, ease); + interpolate(start, view, model, ease); - return me; - }, + return me; + }, - tooltipPosition: function() { - return { - x: this._model.x, - y: this._model.y - }; - }, + tooltipPosition: function() { + return { + x: this._model.x, + y: this._model.y + }; + }, - hasValue: function() { - return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y); - } - }); + hasValue: function() { + return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y); + } +}); - Chart.Element.extend = helpers.inherits; -}; +Element.extend = helpers.inherits; + +module.exports = Element; diff --git a/src/core/core.plugin.js b/src/core/core.plugin.js index 2c472ce0da4..484b694f92c 100644 --- a/src/core/core.plugin.js +++ b/src/core/core.plugin.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('./core.defaults'); +var Element = require('./core.element'); var helpers = require('../helpers/index'); defaults._set('global', { @@ -369,5 +370,5 @@ module.exports = function(Chart) { * @todo remove at version 3 * @private */ - Chart.PluginBase = Chart.Element.extend({}); + Chart.PluginBase = Element.extend({}); }; diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 942e4fff6b9..0fcc95c4766 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('./core.defaults'); +var Element = require('./core.element'); var helpers = require('../helpers/index'); var Ticks = require('./core.ticks'); @@ -85,7 +86,7 @@ module.exports = function(Chart) { helpers.valueOrDefault(options.fontSize, defaults.global.defaultFontSize)); } - Chart.Scale = Chart.Element.extend({ + Chart.Scale = Element.extend({ /** * Get the padding needed for the scale * @method getPadding diff --git a/src/core/core.tooltip.js b/src/core/core.tooltip.js index a1ded8e3b6b..896ddb677bc 100644 --- a/src/core/core.tooltip.js +++ b/src/core/core.tooltip.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('./core.defaults'); +var Element = require('./core.element'); var helpers = require('../helpers/index'); defaults._set('global', { @@ -380,7 +381,7 @@ module.exports = function(Chart) { }; } - Chart.Tooltip = Chart.Element.extend({ + Chart.Tooltip = Element.extend({ initialize: function() { this._model = getBaseModel(this._options); }, diff --git a/src/elements/element.arc.js b/src/elements/element.arc.js index 101302cf8aa..787ab5c88d9 100644 --- a/src/elements/element.arc.js +++ b/src/elements/element.arc.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var Element = require('../core/core.element'); var helpers = require('../helpers/index'); defaults._set('global', { @@ -13,96 +14,98 @@ defaults._set('global', { } }); -module.exports = function(Chart) { +module.exports = Element.extend({ + inLabelRange: function(mouseX) { + var vm = this._view; - Chart.elements.Arc = Chart.Element.extend({ - inLabelRange: function(mouseX) { - var vm = this._view; - - if (vm) { - return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2)); + if (vm) { + return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2)); + } + return false; + }, + + inRange: function(chartX, chartY) { + var vm = this._view; + + if (vm) { + var pointRelativePosition = helpers.getAngleFromPoint(vm, { + x: chartX, + y: chartY + }), + angle = pointRelativePosition.angle, + distance = pointRelativePosition.distance; + + // Sanitise angle range + var startAngle = vm.startAngle; + var endAngle = vm.endAngle; + while (endAngle < startAngle) { + endAngle += 2.0 * Math.PI; } - return false; - }, - inRange: function(chartX, chartY) { - var vm = this._view; - - if (vm) { - var pointRelativePosition = helpers.getAngleFromPoint(vm, { - x: chartX, - y: chartY - }), - angle = pointRelativePosition.angle, - distance = pointRelativePosition.distance; - - // Sanitise angle range - var startAngle = vm.startAngle; - var endAngle = vm.endAngle; - while (endAngle < startAngle) { - endAngle += 2.0 * Math.PI; - } - while (angle > endAngle) { - angle -= 2.0 * Math.PI; - } - while (angle < startAngle) { - angle += 2.0 * Math.PI; - } - - // Check if within the range of the open/close angle - var betweenAngles = (angle >= startAngle && angle <= endAngle), - withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius); - - return (betweenAngles && withinRadius); + while (angle > endAngle) { + angle -= 2.0 * Math.PI; } - return false; - }, - getCenterPoint: function() { - var vm = this._view; - var halfAngle = (vm.startAngle + vm.endAngle) / 2; - var halfRadius = (vm.innerRadius + vm.outerRadius) / 2; - return { - x: vm.x + Math.cos(halfAngle) * halfRadius, - y: vm.y + Math.sin(halfAngle) * halfRadius - }; - }, - getArea: function() { - var vm = this._view; - return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2)); - }, - tooltipPosition: function() { - var vm = this._view; - - var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2), - rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius; - return { - x: vm.x + (Math.cos(centreAngle) * rangeFromCentre), - y: vm.y + (Math.sin(centreAngle) * rangeFromCentre) - }; - }, - draw: function() { - - var ctx = this._chart.ctx, - vm = this._view, - sA = vm.startAngle, - eA = vm.endAngle; - - ctx.beginPath(); - - ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA); - ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true); - - ctx.closePath(); - ctx.strokeStyle = vm.borderColor; - ctx.lineWidth = vm.borderWidth; - - ctx.fillStyle = vm.backgroundColor; - - ctx.fill(); - ctx.lineJoin = 'bevel'; - - if (vm.borderWidth) { - ctx.stroke(); + while (angle < startAngle) { + angle += 2.0 * Math.PI; } + + // Check if within the range of the open/close angle + var betweenAngles = (angle >= startAngle && angle <= endAngle), + withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius); + + return (betweenAngles && withinRadius); } - }); -}; + return false; + }, + + getCenterPoint: function() { + var vm = this._view; + var halfAngle = (vm.startAngle + vm.endAngle) / 2; + var halfRadius = (vm.innerRadius + vm.outerRadius) / 2; + return { + x: vm.x + Math.cos(halfAngle) * halfRadius, + y: vm.y + Math.sin(halfAngle) * halfRadius + }; + }, + + getArea: function() { + var vm = this._view; + return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2)); + }, + + tooltipPosition: function() { + var vm = this._view; + + var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2), + rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius; + return { + x: vm.x + (Math.cos(centreAngle) * rangeFromCentre), + y: vm.y + (Math.sin(centreAngle) * rangeFromCentre) + }; + }, + + draw: function() { + + var ctx = this._chart.ctx, + vm = this._view, + sA = vm.startAngle, + eA = vm.endAngle; + + ctx.beginPath(); + + ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA); + ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true); + + ctx.closePath(); + ctx.strokeStyle = vm.borderColor; + ctx.lineWidth = vm.borderWidth; + + ctx.fillStyle = vm.backgroundColor; + + ctx.fill(); + ctx.lineJoin = 'bevel'; + + if (vm.borderWidth) { + ctx.stroke(); + } + } +}); diff --git a/src/elements/element.line.js b/src/elements/element.line.js index f2bfcf67dc9..1500d353c96 100644 --- a/src/elements/element.line.js +++ b/src/elements/element.line.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var Element = require('../core/core.element'); var helpers = require('../helpers/index'); var globalDefaults = defaults.global; @@ -22,72 +23,69 @@ defaults._set('global', { } }); -module.exports = function(Chart) { +module.exports = Element.extend({ + draw: function() { + var me = this; + var vm = me._view; + var ctx = me._chart.ctx; + var spanGaps = vm.spanGaps; + var points = me._children.slice(); // clone array + var globalOptionLineElements = globalDefaults.elements.line; + var lastDrawnIndex = -1; + var index, current, previous, currentVM; - Chart.elements.Line = Chart.Element.extend({ - draw: function() { - var me = this; - var vm = me._view; - var ctx = me._chart.ctx; - var spanGaps = vm.spanGaps; - var points = me._children.slice(); // clone array - var globalOptionLineElements = globalDefaults.elements.line; - var lastDrawnIndex = -1; - var index, current, previous, currentVM; + // If we are looping, adding the first point again + if (me._loop && points.length) { + points.push(points[0]); + } - // If we are looping, adding the first point again - if (me._loop && points.length) { - points.push(points[0]); - } + ctx.save(); - ctx.save(); + // Stroke Line Options + ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle; - // Stroke Line Options - ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle; + // IE 9 and 10 do not support line dash + if (ctx.setLineDash) { + ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash); + } - // IE 9 and 10 do not support line dash - if (ctx.setLineDash) { - ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash); - } + ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset; + ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle; + ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth; + ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor; - ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset; - ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle; - ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth; - ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor; + // Stroke Line + ctx.beginPath(); + lastDrawnIndex = -1; - // Stroke Line - ctx.beginPath(); - lastDrawnIndex = -1; + for (index = 0; index < points.length; ++index) { + current = points[index]; + previous = helpers.previousItem(points, index); + currentVM = current._view; - for (index = 0; index < points.length; ++index) { - current = points[index]; - previous = helpers.previousItem(points, index); - currentVM = current._view; + // First point moves to it's starting position no matter what + if (index === 0) { + if (!currentVM.skip) { + ctx.moveTo(currentVM.x, currentVM.y); + lastDrawnIndex = index; + } + } else { + previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex]; - // First point moves to it's starting position no matter what - if (index === 0) { - if (!currentVM.skip) { + if (!currentVM.skip) { + if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) { + // There was a gap and this is the first point after the gap ctx.moveTo(currentVM.x, currentVM.y); - lastDrawnIndex = index; - } - } else { - previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex]; - - if (!currentVM.skip) { - if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) { - // There was a gap and this is the first point after the gap - ctx.moveTo(currentVM.x, currentVM.y); - } else { - // Line to next point - helpers.canvas.lineTo(ctx, previous._view, current._view); - } - lastDrawnIndex = index; + } else { + // Line to next point + helpers.canvas.lineTo(ctx, previous._view, current._view); } + lastDrawnIndex = index; } } - - ctx.stroke(); - ctx.restore(); } - }); -}; + + ctx.stroke(); + ctx.restore(); + } +}); diff --git a/src/elements/element.point.js b/src/elements/element.point.js index 0b5d12d1286..919c648ec3f 100644 --- a/src/elements/element.point.js +++ b/src/elements/element.point.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var Element = require('../core/core.element'); var helpers = require('../helpers/index'); var defaultColor = defaults.global.defaultColor; @@ -21,85 +22,85 @@ defaults._set('global', { } }); -module.exports = function(Chart) { +function xRange(mouseX) { + var vm = this._view; + return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false; +} - function xRange(mouseX) { +function yRange(mouseY) { + var vm = this._view; + return vm ? (Math.pow(mouseY - vm.y, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false; +} + +module.exports = Element.extend({ + inRange: function(mouseX, mouseY) { 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(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false; + }, + + inLabelRange: xRange, + inXRange: xRange, + inYRange: yRange, - function yRange(mouseY) { + getCenterPoint: function() { var vm = this._view; - return vm ? (Math.pow(mouseY - vm.y, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false; - } + return { + x: vm.x, + y: vm.y + }; + }, - Chart.elements.Point = Chart.Element.extend({ - inRange: function(mouseX, mouseY) { - var vm = this._view; - return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false; - }, + getArea: function() { + return Math.PI * Math.pow(this._view.radius, 2); + }, - inLabelRange: xRange, - inXRange: xRange, - inYRange: yRange, + tooltipPosition: function() { + var vm = this._view; + return { + x: vm.x, + y: vm.y, + padding: vm.radius + vm.borderWidth + }; + }, - getCenterPoint: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y - }; - }, - getArea: function() { - return Math.PI * Math.pow(this._view.radius, 2); - }, - tooltipPosition: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y, - padding: vm.radius + vm.borderWidth - }; - }, - draw: function(chartArea) { - var vm = this._view; - var model = this._model; - var ctx = this._chart.ctx; - var pointStyle = vm.pointStyle; - var radius = vm.radius; - var x = vm.x; - var y = vm.y; - var color = helpers.color; - var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.) - var ratio = 0; + draw: function(chartArea) { + var vm = this._view; + var model = this._model; + var ctx = this._chart.ctx; + var pointStyle = vm.pointStyle; + var radius = vm.radius; + var x = vm.x; + var y = vm.y; + var color = helpers.color; + var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.) + var ratio = 0; - if (vm.skip) { - return; - } + if (vm.skip) { + return; + } - ctx.strokeStyle = vm.borderColor || defaultColor; - ctx.lineWidth = helpers.valueOrDefault(vm.borderWidth, defaults.global.elements.point.borderWidth); - ctx.fillStyle = vm.backgroundColor || defaultColor; + ctx.strokeStyle = vm.borderColor || defaultColor; + ctx.lineWidth = helpers.valueOrDefault(vm.borderWidth, defaults.global.elements.point.borderWidth); + ctx.fillStyle = vm.backgroundColor || defaultColor; - // Cliping for Points. - // going out from inner charArea? - if ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right*errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom*errMargin < model.y))) { - // Point fade out - if (model.x < chartArea.left) { - ratio = (x - model.x) / (chartArea.left - model.x); - } else if (chartArea.right*errMargin < model.x) { - ratio = (model.x - x) / (model.x - chartArea.right); - } else if (model.y < chartArea.top) { - ratio = (y - model.y) / (chartArea.top - model.y); - } else if (chartArea.bottom*errMargin < model.y) { - ratio = (model.y - y) / (model.y - chartArea.bottom); - } - ratio = Math.round(ratio*100) / 100; - ctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString(); - ctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString(); + // Cliping for Points. + // going out from inner charArea? + if ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right*errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom*errMargin < model.y))) { + // Point fade out + if (model.x < chartArea.left) { + ratio = (x - model.x) / (chartArea.left - model.x); + } else if (chartArea.right*errMargin < model.x) { + ratio = (model.x - x) / (model.x - chartArea.right); + } else if (model.y < chartArea.top) { + ratio = (y - model.y) / (chartArea.top - model.y); + } else if (chartArea.bottom*errMargin < model.y) { + ratio = (model.y - y) / (model.y - chartArea.bottom); } - - helpers.canvas.drawPoint(ctx, pointStyle, radius, x, y); + ratio = Math.round(ratio*100) / 100; + ctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString(); + ctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString(); } - }); -}; + + helpers.canvas.drawPoint(ctx, pointStyle, radius, x, y); + } +}); diff --git a/src/elements/element.rectangle.js b/src/elements/element.rectangle.js index 00f017e66e4..c4322063f7d 100644 --- a/src/elements/element.rectangle.js +++ b/src/elements/element.rectangle.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var Element = require('../core/core.element'); defaults._set('global', { elements: { @@ -13,200 +14,204 @@ defaults._set('global', { } }); -module.exports = function(Chart) { - - function isVertical(bar) { - return bar._view.width !== undefined; +function isVertical(bar) { + return bar._view.width !== undefined; +} + +/** + * Helper function to get the bounds of the bar regardless of the orientation + * @param bar {Chart.Element.Rectangle} the bar + * @return {Bounds} bounds of the bar + * @private + */ +function getBarBounds(bar) { + var vm = bar._view; + var x1, x2, y1, y2; + + if (isVertical(bar)) { + // vertical + var halfWidth = vm.width / 2; + x1 = vm.x - halfWidth; + x2 = vm.x + halfWidth; + y1 = Math.min(vm.y, vm.base); + y2 = Math.max(vm.y, vm.base); + } else { + // horizontal bar + var halfHeight = vm.height / 2; + x1 = Math.min(vm.x, vm.base); + x2 = Math.max(vm.x, vm.base); + y1 = vm.y - halfHeight; + y2 = vm.y + halfHeight; } - /** - * Helper function to get the bounds of the bar regardless of the orientation - * @private - * @param bar {Chart.Element.Rectangle} the bar - * @return {Bounds} bounds of the bar - */ - function getBarBounds(bar) { - var vm = bar._view; - var x1, x2, y1, y2; - - if (isVertical(bar)) { - // vertical - var halfWidth = vm.width / 2; - x1 = vm.x - halfWidth; - x2 = vm.x + halfWidth; - y1 = Math.min(vm.y, vm.base); - y2 = Math.max(vm.y, vm.base); + return { + left: x1, + top: y1, + right: x2, + bottom: y2 + }; +} + +module.exports = Element.extend({ + draw: function() { + var ctx = this._chart.ctx; + var vm = this._view; + var left, right, top, bottom, signX, signY, borderSkipped; + var borderWidth = vm.borderWidth; + + if (!vm.horizontal) { + // bar + left = vm.x - vm.width / 2; + right = vm.x + vm.width / 2; + top = vm.y; + bottom = vm.base; + signX = 1; + signY = bottom > top? 1: -1; + borderSkipped = vm.borderSkipped || 'bottom'; } else { // horizontal bar - var halfHeight = vm.height / 2; - x1 = Math.min(vm.x, vm.base); - x2 = Math.max(vm.x, vm.base); - y1 = vm.y - halfHeight; - y2 = vm.y + halfHeight; + left = vm.base; + right = vm.x; + top = vm.y - vm.height / 2; + bottom = vm.y + vm.height / 2; + signX = right > left? 1: -1; + signY = 1; + borderSkipped = vm.borderSkipped || 'left'; } - return { - left: x1, - top: y1, - right: x2, - bottom: y2 - }; - } - - Chart.elements.Rectangle = Chart.Element.extend({ - draw: function() { - var ctx = this._chart.ctx; - var vm = this._view; - var left, right, top, bottom, signX, signY, borderSkipped; - var borderWidth = vm.borderWidth; - - if (!vm.horizontal) { - // bar - left = vm.x - vm.width / 2; - right = vm.x + vm.width / 2; - top = vm.y; - bottom = vm.base; - signX = 1; - signY = bottom > top? 1: -1; - borderSkipped = vm.borderSkipped || 'bottom'; - } else { - // horizontal bar - left = vm.base; - right = vm.x; - top = vm.y - vm.height / 2; - bottom = vm.y + vm.height / 2; - signX = right > left? 1: -1; - signY = 1; - borderSkipped = vm.borderSkipped || 'left'; + // Canvas doesn't allow us to stroke inside the width so we can + // adjust the sizes to fit if we're setting a stroke on the line + if (borderWidth) { + // borderWidth shold be less than bar width and bar height. + var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom)); + borderWidth = borderWidth > barSize? barSize: borderWidth; + var halfStroke = borderWidth / 2; + // Adjust borderWidth when bar top position is near vm.base(zero). + var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0); + var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0); + var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0); + var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0); + // not become a vertical line? + if (borderLeft !== borderRight) { + top = borderTop; + bottom = borderBottom; } - - // Canvas doesn't allow us to stroke inside the width so we can - // adjust the sizes to fit if we're setting a stroke on the line - if (borderWidth) { - // borderWidth shold be less than bar width and bar height. - var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom)); - borderWidth = borderWidth > barSize? barSize: borderWidth; - var halfStroke = borderWidth / 2; - // Adjust borderWidth when bar top position is near vm.base(zero). - var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0); - var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0); - var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0); - var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0); - // not become a vertical line? - if (borderLeft !== borderRight) { - top = borderTop; - bottom = borderBottom; - } - // not become a horizontal line? - if (borderTop !== borderBottom) { - left = borderLeft; - right = borderRight; - } - } - - ctx.beginPath(); - ctx.fillStyle = vm.backgroundColor; - ctx.strokeStyle = vm.borderColor; - ctx.lineWidth = borderWidth; - - // Corner points, from bottom-left to bottom-right clockwise - // | 1 2 | - // | 0 3 | - var corners = [ - [left, bottom], - [left, top], - [right, top], - [right, bottom] - ]; - - // Find first (starting) corner with fallback to 'bottom' - var borders = ['bottom', 'left', 'top', 'right']; - var startCorner = borders.indexOf(borderSkipped, 0); - if (startCorner === -1) { - startCorner = 0; + // not become a horizontal line? + if (borderTop !== borderBottom) { + left = borderLeft; + right = borderRight; } + } - function cornerAt(index) { - return corners[(startCorner + index) % 4]; - } + ctx.beginPath(); + ctx.fillStyle = vm.backgroundColor; + ctx.strokeStyle = vm.borderColor; + ctx.lineWidth = borderWidth; + + // Corner points, from bottom-left to bottom-right clockwise + // | 1 2 | + // | 0 3 | + var corners = [ + [left, bottom], + [left, top], + [right, top], + [right, bottom] + ]; + + // Find first (starting) corner with fallback to 'bottom' + var borders = ['bottom', 'left', 'top', 'right']; + var startCorner = borders.indexOf(borderSkipped, 0); + if (startCorner === -1) { + startCorner = 0; + } - // Draw rectangle from 'startCorner' - var corner = cornerAt(0); - ctx.moveTo(corner[0], corner[1]); + function cornerAt(index) { + return corners[(startCorner + index) % 4]; + } - for (var i = 1; i < 4; i++) { - corner = cornerAt(i); - ctx.lineTo(corner[0], corner[1]); - } + // Draw rectangle from 'startCorner' + var corner = cornerAt(0); + ctx.moveTo(corner[0], corner[1]); - ctx.fill(); - if (borderWidth) { - ctx.stroke(); - } - }, - height: function() { - var vm = this._view; - return vm.base - vm.y; - }, - inRange: function(mouseX, mouseY) { - var inRange = false; - - if (this._view) { - var bounds = getBarBounds(this); - inRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom; - } + for (var i = 1; i < 4; i++) { + corner = cornerAt(i); + ctx.lineTo(corner[0], corner[1]); + } - return inRange; - }, - inLabelRange: function(mouseX, mouseY) { - var me = this; - if (!me._view) { - return false; - } + ctx.fill(); + if (borderWidth) { + ctx.stroke(); + } + }, - var inRange = false; - var bounds = getBarBounds(me); + height: function() { + var vm = this._view; + return vm.base - vm.y; + }, - if (isVertical(me)) { - inRange = mouseX >= bounds.left && mouseX <= bounds.right; - } else { - inRange = mouseY >= bounds.top && mouseY <= bounds.bottom; - } + inRange: function(mouseX, mouseY) { + var inRange = false; - return inRange; - }, - inXRange: function(mouseX) { - var bounds = getBarBounds(this); - return mouseX >= bounds.left && mouseX <= bounds.right; - }, - inYRange: function(mouseY) { + if (this._view) { var bounds = getBarBounds(this); - return mouseY >= bounds.top && mouseY <= bounds.bottom; - }, - getCenterPoint: function() { - var vm = this._view; - var x, y; - if (isVertical(this)) { - x = vm.x; - y = (vm.y + vm.base) / 2; - } else { - x = (vm.x + vm.base) / 2; - y = vm.y; - } + inRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom; + } + + return inRange; + }, + + inLabelRange: function(mouseX, mouseY) { + var me = this; + if (!me._view) { + return false; + } + + var inRange = false; + var bounds = getBarBounds(me); + + if (isVertical(me)) { + inRange = mouseX >= bounds.left && mouseX <= bounds.right; + } else { + inRange = mouseY >= bounds.top && mouseY <= bounds.bottom; + } - return {x: x, y: y}; - }, - getArea: function() { - var vm = this._view; - return vm.width * Math.abs(vm.y - vm.base); - }, - tooltipPosition: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y - }; + return inRange; + }, + + inXRange: function(mouseX) { + var bounds = getBarBounds(this); + return mouseX >= bounds.left && mouseX <= bounds.right; + }, + + inYRange: function(mouseY) { + var bounds = getBarBounds(this); + return mouseY >= bounds.top && mouseY <= bounds.bottom; + }, + + getCenterPoint: function() { + var vm = this._view; + var x, y; + if (isVertical(this)) { + x = vm.x; + y = (vm.y + vm.base) / 2; + } else { + x = (vm.x + vm.base) / 2; + y = vm.y; } - }); -}; + return {x: x, y: y}; + }, + + getArea: function() { + var vm = this._view; + return vm.width * Math.abs(vm.y - vm.base); + }, + + tooltipPosition: function() { + var vm = this._view; + return { + x: vm.x, + y: vm.y + }; + } +}); diff --git a/src/elements/index.js b/src/elements/index.js new file mode 100644 index 00000000000..175c9660e14 --- /dev/null +++ b/src/elements/index.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = {}; +module.exports.Arc = require('./element.arc'); +module.exports.Line = require('./element.line'); +module.exports.Point = require('./element.point'); +module.exports.Rectangle = require('./element.rectangle'); diff --git a/src/plugins/plugin.filler.js b/src/plugins/plugin.filler.js index 51aed7669cf..b42a570f6c4 100644 --- a/src/plugins/plugin.filler.js +++ b/src/plugins/plugin.filler.js @@ -7,6 +7,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var elements = require('../elements/index'); var helpers = require('../helpers/index'); defaults._set('global', { @@ -17,7 +18,7 @@ defaults._set('global', { } }); -module.exports = function(Chart) { +module.exports = function() { var mappers = { dataset: function(source) { @@ -272,7 +273,7 @@ module.exports = function(Chart) { el = meta.dataset; source = null; - if (el && el._model && el instanceof Chart.elements.Line) { + if (el && el._model && el instanceof elements.Line) { source = { visible: chart.isDatasetVisible(i), fill: decodeFill(el, i, count), diff --git a/src/plugins/plugin.legend.js b/src/plugins/plugin.legend.js index 1a32c079857..aafe521d137 100644 --- a/src/plugins/plugin.legend.js +++ b/src/plugins/plugin.legend.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var Element = require('../core/core.element'); var helpers = require('../helpers/index'); defaults._set('global', { @@ -95,7 +96,7 @@ module.exports = function(Chart) { labelOpts.boxWidth; } - Chart.Legend = Chart.Element.extend({ + Chart.Legend = Element.extend({ initialize: function(config) { helpers.extend(this, config); diff --git a/src/plugins/plugin.title.js b/src/plugins/plugin.title.js index 259863b62ac..765c30f8722 100644 --- a/src/plugins/plugin.title.js +++ b/src/plugins/plugin.title.js @@ -1,6 +1,7 @@ 'use strict'; var defaults = require('../core/core.defaults'); +var Element = require('../core/core.element'); var helpers = require('../helpers/index'); defaults._set('global', { @@ -21,7 +22,7 @@ module.exports = function(Chart) { var layout = Chart.layoutService; var noop = helpers.noop; - Chart.Title = Chart.Element.extend({ + Chart.Title = Element.extend({ initialize: function(config) { var me = this; helpers.extend(me, config);