Implement clipping (#3658)

Implements clipping of items outside the chart area. Resolves #3506 #3491 #2873
This commit is contained in:
SAiTO TOSHiKi 2016-12-04 05:09:45 +08:00 committed by Evert Timberg
parent bdcdbc2abf
commit 5a24bfa500
4 changed files with 40 additions and 2 deletions

View File

@ -229,12 +229,14 @@ module.exports = function(Chart) {
var dataset = me.getDataset();
var i, len;
Chart.canvasHelpers.clipArea(me.chart.chart.ctx, me.chart.chartArea);
for (i = 0, len = metaData.length; i < len; ++i) {
var d = dataset.data[i];
if (d !== null && d !== undefined && !isNaN(d)) {
metaData[i].transition(easingDecimal).draw();
}
}
Chart.canvasHelpers.unclipArea(me.chart.chart.ctx);
},
setHoverStyle: function(rectangle) {

View File

@ -292,14 +292,16 @@ module.exports = function(Chart) {
points[i].transition(easingDecimal);
}
Chart.canvasHelpers.clipArea(me.chart.chart.ctx, me.chart.chartArea);
// Transition and Draw the line
if (lineEnabled(me.getDataset(), me.chart.options)) {
meta.dataset.transition(easingDecimal).draw();
}
Chart.canvasHelpers.unclipArea(me.chart.chart.ctx);
// Draw the points
for (i=0, ilen=points.length; i<ilen; ++i) {
points[i].draw();
points[i].draw(me.chart.chartArea);
}
},

View File

@ -109,4 +109,16 @@ module.exports = function(Chart) {
ctx.stroke();
};
helpers.clipArea = function(ctx, clipArea) {
ctx.save();
ctx.beginPath();
ctx.rect(clipArea.left, clipArea.top, clipArea.right - clipArea.left, clipArea.bottom - clipArea.top);
ctx.clip();
};
helpers.unclipArea = function(ctx) {
ctx.restore();
};
};

View File

@ -56,13 +56,17 @@ module.exports = function(Chart) {
padding: vm.radius + vm.borderWidth
};
},
draw: function() {
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 = Chart.helpers.color;
var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)
var ratio = 0;
if (vm.skip) {
return;
@ -72,6 +76,24 @@ module.exports = function(Chart) {
ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.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();
}
Chart.canvasHelpers.drawPoint(ctx, pointStyle, radius, x, y);
}
});