Bar: inflate rects by 0.33px to avoid artifacts (#9399)
* Bar: inflate rects by 0.33px to avoid artifacts * Update fixture * YAGNI
@@ -1,5 +1,5 @@
|
||||
import Element from '../core/core.element';
|
||||
import {isObject} from '../helpers';
|
||||
import {isObject, _limitValue} from '../helpers';
|
||||
import {addRoundedRectPath} from '../helpers/helpers.canvas';
|
||||
import {toTRBL, toTRBLCorners} from '../helpers/helpers.options';
|
||||
|
||||
@@ -67,7 +67,7 @@ function startEnd(v, start, end) {
|
||||
}
|
||||
|
||||
function skipOrLimit(skip, value, min, max) {
|
||||
return skip ? 0 : Math.max(Math.min(value, max), min);
|
||||
return skip ? 0 : _limitValue(value, min, max);
|
||||
}
|
||||
|
||||
function parseBorderWidth(bar, maxW, maxH) {
|
||||
@@ -156,6 +156,20 @@ function addNormalRectPath(ctx, rect) {
|
||||
ctx.rect(rect.x, rect.y, rect.w, rect.h);
|
||||
}
|
||||
|
||||
function inflateRect(rect, amount, refRect = {}) {
|
||||
const x = rect.x !== refRect.x ? -amount : 0;
|
||||
const y = rect.y !== refRect.y ? -amount : 0;
|
||||
const w = (rect.x + rect.w !== refRect.x + refRect.w ? amount : 0) - x;
|
||||
const h = (rect.y + rect.h !== refRect.y + refRect.h ? amount : 0) - y;
|
||||
return {
|
||||
x: rect.x + x,
|
||||
y: rect.y + y,
|
||||
w: rect.w + w,
|
||||
h: rect.h + h,
|
||||
radius: rect.radius
|
||||
};
|
||||
}
|
||||
|
||||
export default class BarElement extends Element {
|
||||
|
||||
constructor(cfg) {
|
||||
@@ -176,20 +190,21 @@ export default class BarElement extends Element {
|
||||
const options = this.options;
|
||||
const {inner, outer} = boundingRects(this);
|
||||
const addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath;
|
||||
const inflateAmount = 0.33;
|
||||
|
||||
ctx.save();
|
||||
|
||||
if (outer.w !== inner.w || outer.h !== inner.h) {
|
||||
ctx.beginPath();
|
||||
addRectPath(ctx, outer);
|
||||
addRectPath(ctx, inflateRect(outer, inflateAmount, inner));
|
||||
ctx.clip();
|
||||
addRectPath(ctx, inner);
|
||||
addRectPath(ctx, inflateRect(inner, -inflateAmount, outer));
|
||||
ctx.fillStyle = options.borderColor;
|
||||
ctx.fill('evenodd');
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
addRectPath(ctx, inner);
|
||||
addRectPath(ctx, inflateRect(inner, inflateAmount, outer));
|
||||
ctx.fillStyle = options.backgroundColor;
|
||||
ctx.fill();
|
||||
|
||||
|
||||
BIN
test/fixtures/controller.bar/bar-base-value.png
vendored
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.6 KiB |
BIN
test/fixtures/controller.bar/baseLine/bottom.png
vendored
|
Before Width: | Height: | Size: 901 B After Width: | Height: | Size: 985 B |
BIN
test/fixtures/controller.bar/baseLine/left.png
vendored
|
Before Width: | Height: | Size: 647 B After Width: | Height: | Size: 764 B |
BIN
test/fixtures/controller.bar/baseLine/mid-x.png
vendored
|
Before Width: | Height: | Size: 758 B After Width: | Height: | Size: 850 B |
BIN
test/fixtures/controller.bar/baseLine/mid-y.png
vendored
|
Before Width: | Height: | Size: 930 B After Width: | Height: | Size: 988 B |
BIN
test/fixtures/controller.bar/baseLine/right.png
vendored
|
Before Width: | Height: | Size: 611 B After Width: | Height: | Size: 753 B |
BIN
test/fixtures/controller.bar/baseLine/top.png
vendored
|
Before Width: | Height: | Size: 895 B After Width: | Height: | Size: 966 B |
BIN
test/fixtures/controller.bar/baseLine/value-x.png
vendored
|
Before Width: | Height: | Size: 943 B After Width: | Height: | Size: 1.0 KiB |
BIN
test/fixtures/controller.bar/baseLine/value-y.png
vendored
|
Before Width: | Height: | Size: 951 B After Width: | Height: | Size: 1.0 KiB |
35
test/fixtures/controller.bar/borderColor/border+dpr.js
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
module.exports = {
|
||||
threshold: 0,
|
||||
tolerance: 0,
|
||||
config: {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [0, 1, 2, 3, 4, 5, 6],
|
||||
datasets: [
|
||||
{
|
||||
// option in dataset
|
||||
data: [5, 4, 3, 2, 3, 4, 5],
|
||||
},
|
||||
]
|
||||
},
|
||||
options: {
|
||||
events: [],
|
||||
devicePixelRatio: 1.5,
|
||||
barPercentage: 1,
|
||||
categoryPercentage: 1,
|
||||
backgroundColor: 'black',
|
||||
borderColor: 'black',
|
||||
borderWidth: 8,
|
||||
scales: {
|
||||
x: {display: false},
|
||||
y: {display: false}
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
canvas: {
|
||||
height: 256,
|
||||
width: 501
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
test/fixtures/controller.bar/borderColor/border+dpr.png
vendored
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 6.3 KiB |
33
test/fixtures/controller.bar/borderRadius/no-spacing.js
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
module.exports = {
|
||||
threshold: 0.01,
|
||||
config: {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
datasets: [
|
||||
{
|
||||
data: [9, 25, 13, 17, 12, 21, 20, 19, 6, 12, 14, 20],
|
||||
categoryPercentage: 1,
|
||||
barPercentage: 1,
|
||||
backgroundColor: '#2E5C76',
|
||||
borderWidth: 2,
|
||||
borderColor: '#377395',
|
||||
borderRadius: 5,
|
||||
},
|
||||
]
|
||||
},
|
||||
options: {
|
||||
devicePixelRatio: 1.25,
|
||||
scales: {
|
||||
x: {display: false},
|
||||
y: {display: false}
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
canvas: {
|
||||
height: 256,
|
||||
width: 512
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
test/fixtures/controller.bar/borderRadius/no-spacing.png
vendored
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 5.0 KiB |
BIN
test/fixtures/controller.bar/borderWidth/object.png
vendored
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 5.4 KiB |
BIN
test/fixtures/controller.bar/borderWidth/value.png
vendored
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 5.0 KiB |
BIN
test/fixtures/controller.bar/horizontal-borders.png
vendored
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.3 KiB |
16
test/fixtures/scale.category/ticks-from-data.js
vendored
@@ -4,19 +4,13 @@ module.exports = {
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 0, 25, 78]
|
||||
data: [10, 5, 0, 25, 78],
|
||||
backgroundColor: 'transparent'
|
||||
}],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
|
||||
},
|
||||
options: {
|
||||
indexAxis: 'y',
|
||||
elements: {
|
||||
bar: {
|
||||
backgroundColor: '#AAAAAA80',
|
||||
borderColor: '#80808080',
|
||||
borderWidth: {bottom: 6, left: 15, top: 6, right: 15}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {display: false},
|
||||
y: {display: true}
|
||||
@@ -24,6 +18,10 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
options: {
|
||||
spriteText: true
|
||||
spriteText: true,
|
||||
canvas: {
|
||||
width: 128,
|
||||
height: 256
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BIN
test/fixtures/scale.category/ticks-from-data.png
vendored
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 4.3 KiB |