diff --git a/src/controllers/controller.bubble.js b/src/controllers/controller.bubble.js index 48c0a2ee46d..641b574c5bf 100644 --- a/src/controllers/controller.bubble.js +++ b/src/controllers/controller.bubble.js @@ -79,6 +79,18 @@ module.exports = DatasetController.extend({ return parsed; }, + getMaxOverflow: function() { + var me = this; + var meta = me._cachedMeta; + var data = meta.data || []; + if (!data.length) { + return false; + } + var firstPoint = data[0].size(); + var lastPoint = data[data.length - 1].size(); + return Math.max(firstPoint, lastPoint) / 2; + }, + /** * @protected */ diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index 87baa5d2349..b19136c7f7d 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -29,50 +29,6 @@ defaults._set('line', { } }); -function scaleClip(scale, halfBorderWidth) { - var tickOpts = scale && scale.options.ticks || {}; - var reverse = tickOpts.reverse; - var min = tickOpts.min === undefined ? halfBorderWidth : 0; - var max = tickOpts.max === undefined ? halfBorderWidth : 0; - return { - start: reverse ? max : min, - end: reverse ? min : max - }; -} - -function defaultClip(xScale, yScale, borderWidth) { - var halfBorderWidth = borderWidth / 2; - var x = scaleClip(xScale, halfBorderWidth); - var y = scaleClip(yScale, halfBorderWidth); - - return { - top: y.end, - right: x.end, - bottom: y.start, - left: x.start - }; -} - -function toClip(value) { - var t, r, b, l; - - if (helpers.isObject(value)) { - t = value.top; - r = value.right; - b = value.bottom; - l = value.left; - } else { - t = r = b = l = value; - } - - return { - top: t, - right: r, - bottom: b, - left: l - }; -} - module.exports = DatasetController.extend({ datasetElementType: elements.Line, @@ -205,11 +161,22 @@ module.exports = DatasetController.extend({ values.tension = valueOrDefault(config.lineTension, lineOptions.tension); values.steppedLine = resolve([config.steppedLine, lineOptions.stepped]); - values.clip = toClip(valueOrDefault(config.clip, defaultClip(me._xScale, me._yScale, values.borderWidth))); - return values; }, + getMaxOverflow: function() { + var me = this; + var meta = me._cachedMeta; + var data = meta.data || []; + if (!data.length) { + return false; + } + var border = me._showLine ? meta.dataset._model.borderWidth : 0; + var firstPoint = data[0].size(); + var lastPoint = data[data.length - 1].size(); + return Math.max(border, firstPoint, lastPoint) / 2; + }, + updateBezierControlPoints: function() { var me = this; var chart = me.chart; @@ -271,24 +238,12 @@ module.exports = DatasetController.extend({ var meta = me.getMeta(); var points = meta.data || []; var area = chart.chartArea; - var canvas = chart.canvas; var i = 0; var ilen = points.length; - var clip; if (me._showLine) { - clip = meta.dataset._model.clip; - - helpers.canvas.clipArea(chart.ctx, { - left: clip.left === false ? 0 : area.left - clip.left, - right: clip.right === false ? canvas.width : area.right + clip.right, - top: clip.top === false ? 0 : area.top - clip.top, - bottom: clip.bottom === false ? canvas.height : area.bottom + clip.bottom - }); meta.dataset.draw(); - - helpers.canvas.unclipArea(chart.ctx); } // Draw the points diff --git a/src/core/core.controller.js b/src/core/core.controller.js index ad841ca6ec7..8f964ca8d2d 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -761,6 +761,10 @@ helpers.extend(Chart.prototype, /** @lends Chart */ { */ drawDataset: function(meta, easingValue) { var me = this; + var ctx = me.ctx; + var clip = meta._clip; + var canvas = me.canvas; + var area = me.chartArea; var args = { meta: meta, index: meta.index, @@ -771,8 +775,17 @@ helpers.extend(Chart.prototype, /** @lends Chart */ { return; } + helpers.canvas.clipArea(ctx, { + left: clip.left === false ? 0 : area.left - clip.left, + right: clip.right === false ? canvas.width : area.right + clip.right, + top: clip.top === false ? 0 : area.top - clip.top, + bottom: clip.bottom === false ? canvas.height : area.bottom + clip.bottom + }); + meta.controller.draw(easingValue); + helpers.canvas.unclipArea(ctx); + plugins.notify(me, 'afterDatasetDraw', [args]); }, diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index 70fdefe5347..fcace9110a6 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -48,6 +48,53 @@ function listenArrayEvents(array, listener) { }); } + +function scaleClip(scale, allowedOverflow) { + var tickOpts = scale && scale.options.ticks || {}; + var reverse = tickOpts.reverse; + var min = tickOpts.min === undefined ? allowedOverflow : 0; + var max = tickOpts.max === undefined ? allowedOverflow : 0; + return { + start: reverse ? max : min, + end: reverse ? min : max + }; +} + +function defaultClip(xScale, yScale, allowedOverflow) { + if (allowedOverflow === false) { + return false; + } + var x = scaleClip(xScale, allowedOverflow); + var y = scaleClip(yScale, allowedOverflow); + + return { + top: y.end, + right: x.end, + bottom: y.start, + left: x.start + }; +} + +function toClip(value) { + var t, r, b, l; + + if (helpers.isObject(value)) { + t = value.top; + r = value.right; + b = value.bottom; + l = value.left; + } else { + t = r = b = l = value; + } + + return { + top: t, + right: r, + bottom: b, + left: l + }; +} + /** * Removes the given array event listener and cleanup extra attached properties (such as * the _chartjs stub and overridden methods) if array doesn't have any more listeners. @@ -634,11 +681,16 @@ helpers.extend(DatasetController.prototype, { cache[valueScale.id] !== valueScale.options.stacked; }, + getMaxOverflow: function() { + return false; + }, + _update: function(reset) { var me = this; me._configure(); me._cachedDataOpts = null; me.update(reset); + me._cachedMeta._clip = toClip(helpers.valueOrDefault(me._config.clip, defaultClip(me._xScale, me._yScale, me.getMaxOverflow()))); me._cacheScaleStackStatus(); }, diff --git a/src/elements/element.point.js b/src/elements/element.point.js index 226ed06c04d..9ace194f784 100644 --- a/src/elements/element.point.js +++ b/src/elements/element.point.js @@ -53,6 +53,14 @@ module.exports = Element.extend({ }; }, + size: function() { + var vm = this._view; + var radius = vm.radius || 0; + var borderWidth = vm.borderWidth || 0; + return (radius + borderWidth) * 2; + + }, + tooltipPosition: function() { var vm = this._view; return { diff --git a/test/fixtures/controller.bubble/clip.js b/test/fixtures/controller.bubble/clip.js new file mode 100644 index 00000000000..9502ad1cd83 --- /dev/null +++ b/test/fixtures/controller.bubble/clip.js @@ -0,0 +1,35 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 5, 10, 15, 20, 25, 30, 50, 55, 60], + datasets: [{ + data: [6, 11, 10, 10, 3, 22, 7, 24], + type: 'bubble', + label: 'test', + borderColor: '#3e95cd', + fill: false + }] + }, + options: { + legend: false, + scales: { + xAxes: [{ticks: {display: false}}], + yAxes: [{ + ticks: { + display: false, + min: 8, + max: 25, + beginAtZero: true + } + }] + } + } + }, + options: { + canvas: { + height: 256, + width: 256 + } + } +}; diff --git a/test/fixtures/controller.bubble/clip.png b/test/fixtures/controller.bubble/clip.png new file mode 100644 index 00000000000..ad3f83ced14 Binary files /dev/null and b/test/fixtures/controller.bubble/clip.png differ diff --git a/test/fixtures/controller.bubble/point-style.json b/test/fixtures/controller.bubble/point-style.json index a645075168b..9849eef8c90 100644 --- a/test/fixtures/controller.bubble/point-style.json +++ b/test/fixtures/controller.bubble/point-style.json @@ -44,7 +44,7 @@ {"x": 9, "y": 2} ], "backgroundColor": "transparent", - "borderColor": "0000ff", + "borderColor": "#0000ff", "borderWidth": 0, "pointStyle": [ "circle",