Skip to content

Commit

Permalink
Implement label clipping
Browse files Browse the repository at this point in the history
Introduce the `clip` option (boolean, scriptable and indexable) which masks the part of the label which is outside the chart area (default `false`, no clipping).
  • Loading branch information
simonbrunel committed Jul 16, 2018
1 parent 542ec92 commit 499dbb7
Show file tree
Hide file tree
Showing 14 changed files with 239 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Available options:
| `borderColor` | [`Style`](#style-options)/`null` | Yes | Yes | `null`
| `borderRadius` | `Number` | Yes | Yes | `0`
| `borderWidth` | `Number` | Yes | Yes | `0`
| [`clip`](positioning.md#visibility) | `Boolean` | Yes | Yes | `false`
| `color` | [`Style`](#style-options) | Yes | Yes | `0`
| [`display`](positioning.md#visibility) | `Boolean` | Yes | Yes | `true`
| `font` | `Object` | Yes | Yes | -
Expand Down
2 changes: 2 additions & 0 deletions docs/positioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ display: function(context) {
return context.dataIndex % 2; // display labels with an odd index
}
```

When the `clip` option is `true`, the part of the label which is outside the chart area will be masked (see [CanvasRenderingContext2D.clip()](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip))
2 changes: 1 addition & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ gulp.task('lint', function() {
gulp.task('docs', function(done) {
var script = require.resolve('gitbook-cli/bin/gitbook.js');
var out = path.join(argv.output, argv.docsDir);
var cmd = process.execPath;
var cmd = '"' + process.execPath + '"';

exec([cmd, script, 'install', './'].join(' ')).then(() => {
return exec([cmd, script, argv.watch ? 'serve' : 'build', './', out].join(' '));
Expand Down
7 changes: 7 additions & 0 deletions src/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ export default {
*/
borderWidth: 0,

/**
* Clip the label drawing to the chart area.
* @member {Boolean|Array|Function}
* @default false (no clipping)
*/
clip: false,

/**
* The color used to draw the label text.
* @member {String|Array|Function}
Expand Down
18 changes: 16 additions & 2 deletions src/label.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ helpers.extend(Label.prototype, {
borderColor: resolve([config.borderColor, null], context, index),
borderRadius: resolve([config.borderRadius, 0], context, index),
borderWidth: resolve([config.borderWidth, 0], context, index),
clip: resolve([config.clip, false], context, index),
color: resolve([config.color, Chart.defaults.global.defaultFontColor], context, index),
font: font,
lines: lines,
Expand Down Expand Up @@ -226,10 +227,11 @@ helpers.extend(Label.prototype, {
me._model = model;
},

draw: function(ctx) {
draw: function(chart) {
var me = this;
var ctx = chart.ctx;
var model = me._model;
var rects, center;
var rects, center, area;

if (!model || !model.opacity) {
return;
Expand All @@ -240,6 +242,18 @@ helpers.extend(Label.prototype, {
me._hitbox.update(center, rects.frame, model.rotation);

ctx.save();

if (model.clip) {
area = chart.chartArea;
ctx.beginPath();
ctx.rect(
area.left,
area.top,
area.right - area.left,
area.bottom - area.top);
ctx.clip();
}

ctx.globalAlpha = utils.bound(0, model.opacity, 1);
ctx.translate(Math.round(center.x), Math.round(center.y));
ctx.rotate(model.rotation);
Expand Down
2 changes: 1 addition & 1 deletion src/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function drawLabels(chart, datasetIndex) {
el = elements[i];
label = el[EXPANDO_KEY];
if (label) {
label.draw(chart.ctx);
label.draw(chart);
}
}
}
Expand Down
75 changes: 75 additions & 0 deletions test/fixtures/options.clip/clip-indexable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
var data = [
{x: 0, y: 0},
{x: 0, y: 1},
{x: 0, y: 2},
{x: 1, y: 0},
{x: 1, y: 1},
{x: 1, y: 2},
{x: 2, y: 0},
{x: 2, y: 1},
{x: 2, y: 2}
];

export default {
config: {
type: 'bubble',
data: {
datasets: [{
data: data,
datalabels: {
backgroundColor: '#ff0077',
borderColor: 'white',
padding: 32,
clip: [
false,
true,
false,
true,
false,
true,
false,
true,
false
]
}
}, {
data: data,
datalabels: {
backgroundColor: '#00ff77',
borderColor: 'black',
padding: 16,
clip: [
true,
false,
true,
false,
true,
false,
true,
false,
true,
]
}
}]
},
options: {
layout: {
padding: 48
},
plugins: {
datalabels: {
borderWidth: 4,
font: {
size: 0
}
}
}
}
},
options: {
canvas: {
height: 256,
width: 256
}
}
};
Binary file added test/fixtures/options.clip/clip-indexable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions test/fixtures/options.clip/clip-scriptable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
var data = [
{x: 0, y: 0},
{x: 0, y: 1},
{x: 0, y: 2},
{x: 1, y: 0},
{x: 1, y: 1},
{x: 1, y: 2},
{x: 2, y: 0},
{x: 2, y: 1},
{x: 2, y: 2}
];

export default {
config: {
type: 'bubble',
data: {
datasets: [{
data: data,
datalabels: {
backgroundColor: '#ff0077',
borderColor: 'white',
padding: 32
}
}, {
data: data,
datalabels: {
backgroundColor: '#00ff77',
borderColor: 'black',
padding: 16
}
}]
},
options: {
layout: {
padding: 48
},
plugins: {
datalabels: {
borderWidth: 4,
clip: function(ctx) {
return (ctx.dataIndex + ctx.datasetIndex) % 2 === 0;
},
font: {
size: 0
}
}
}
}
},
options: {
canvas: {
height: 256,
width: 256
}
}
};
Binary file added test/fixtures/options.clip/clip-scriptable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 55 additions & 0 deletions test/fixtures/options.clip/clip-values.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
var data = [
{x: 0, y: 0},
{x: 0, y: 1},
{x: 0, y: 2},
{x: 1, y: 0},
{x: 1, y: 1},
{x: 1, y: 2},
{x: 2, y: 0},
{x: 2, y: 1},
{x: 2, y: 2}
];

export default {
config: {
type: 'bubble',
data: {
datasets: [{
data: data,
datalabels: {
backgroundColor: '#ff0077',
borderColor: 'white',
clip: true,
padding: 32
}
}, {
data: data,
datalabels: {
backgroundColor: '#00ff77',
borderColor: 'black',
clip: false,
padding: 16
}
}]
},
options: {
layout: {
padding: 48
},
plugins: {
datalabels: {
borderWidth: 4,
font: {
size: 0
}
}
}
}
},
options: {
canvas: {
height: 256,
width: 256
}
}
};
Binary file added test/fixtures/options.clip/clip-values.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions test/plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default {
'jasmine-chart-area': {
afterDraw: function(chart) {
var ctx = chart.ctx;
var area = chart.chartArea;

ctx.save();
ctx.beginPath();
ctx.rect(
area.left,
area.top,
area.right - area.left,
area.bottom - area.top);
ctx.strokeStyle = 'blue';
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
}
}
};
5 changes: 5 additions & 0 deletions test/specs/options.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ describe('options (scriptable)', function() {
[
'align',
'anchor',
'clip',
'opacity'
].forEach(function(key) {
it(key + ' should be called with a valid context', function() {
Expand Down Expand Up @@ -48,6 +49,10 @@ describe('option.align', function() {
describe('auto', jasmine.fixture.specs('options.align'));
});

describe('option.clip', function() {
describe('auto', jasmine.fixture.specs('options.clip'));
});

describe('option.anchor', function() {
describe('auto', jasmine.fixture.specs('options.anchor'));
});
Expand Down

0 comments on commit 499dbb7

Please sign in to comment.