Skip to content

Commit

Permalink
Implement clipping (chartjs#3658)
Browse files Browse the repository at this point in the history
Implements clipping of items outside the chart area. Resolves chartjs#3506 chartjs#3491 chartjs#2873
  • Loading branch information
KoyoSE authored and etimberg committed Dec 3, 2016
1 parent 71235cb commit f063f68
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/controllers/controller.bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 3 additions & 1 deletion src/controllers/controller.line.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
},

Expand Down
12 changes: 12 additions & 0 deletions src/core/core.canvasHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
};

};
24 changes: 23 additions & 1 deletion src/elements/element.point.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
});
Expand Down

0 comments on commit f063f68

Please sign in to comment.