From: Jukka Kurkela Date: Tue, 16 Mar 2021 12:49:19 +0000 (+0200) Subject: Exclude base-line from bar size (#8648) X-Git-Tag: v3.0.0-beta.14~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=420aa027b305c91380d96d05e39db2767ec1333a;p=thirdparty%2FChart.js.git Exclude base-line from bar size (#8648) * Exclude base-line from bar size * lint * add to types --- diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 0d4176f27..cbac98e51 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -447,6 +447,18 @@ export default class BarController extends DatasetController { head = base + size; } + const actualBase = baseValue || 0; + if (base === vScale.getPixelForValue(actualBase)) { + const halfGrid = vScale.getLineWidthForValue(actualBase) / 2; + if (size > 0) { + base += halfGrid; + size -= halfGrid; + } else if (size < 0) { + base -= halfGrid; + size += halfGrid; + } + } + return { size, base, diff --git a/src/core/core.scale.js b/src/core/core.scale.js index f62ec10e9..2da297290 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -1606,6 +1606,21 @@ export default class Scale extends Element { } } + getLineWidthForValue(value) { + const me = this; + const grid = me.options.grid; + if (!me._isVisible() || !grid.display) { + return 0; + } + const ticks = me.ticks; + const index = ticks.findIndex(t => t.value === value); + if (index >= 0) { + const opts = grid.setContext(me.getContext(index)); + return opts.lineWidth; + } + return 0; + } + /** * @protected */ diff --git a/test/fixtures/controller.bar/baseLine/bottom.js b/test/fixtures/controller.bar/baseLine/bottom.js new file mode 100644 index 000000000..272b8e99b --- /dev/null +++ b/test/fixtures/controller.bar/baseLine/bottom.js @@ -0,0 +1,40 @@ +module.exports = { + config: { + type: 'bar', + data: { + labels: ['a', 'b'], + datasets: [{ + backgroundColor: '#AAFFCC', + borderColor: '#0000FF', + borderWidth: 1, + data: [1, 2] + }] + }, + options: { + scales: { + x: { + display: false + }, + y: { + ticks: { + display: false + }, + grid: { + color: function(context) { + return context.tick.value === 0 ? 'red' : 'transparent'; + }, + lineWidth: 5, + tickLength: 0 + }, + } + }, + maintainAspectRatio: false + } + }, + options: { + canvas: { + width: 128, + height: 128 + } + } +}; diff --git a/test/fixtures/controller.bar/baseLine/bottom.png b/test/fixtures/controller.bar/baseLine/bottom.png new file mode 100644 index 000000000..d7107153b Binary files /dev/null and b/test/fixtures/controller.bar/baseLine/bottom.png differ diff --git a/test/fixtures/controller.bar/baseLine/left.js b/test/fixtures/controller.bar/baseLine/left.js new file mode 100644 index 000000000..56a68ce54 --- /dev/null +++ b/test/fixtures/controller.bar/baseLine/left.js @@ -0,0 +1,41 @@ +module.exports = { + config: { + type: 'bar', + data: { + labels: ['a', 'b'], + datasets: [{ + backgroundColor: '#AAFFCC', + borderColor: '#0000FF', + borderWidth: 1, + data: [1, 2] + }] + }, + options: { + indexAxis: 'y', + scales: { + y: { + display: false + }, + x: { + ticks: { + display: false + }, + grid: { + color: function(context) { + return context.tick.value === 0 ? 'red' : 'transparent'; + }, + lineWidth: 5, + tickLength: 0 + }, + } + }, + maintainAspectRatio: false + } + }, + options: { + canvas: { + width: 128, + height: 128 + } + } +}; diff --git a/test/fixtures/controller.bar/baseLine/left.png b/test/fixtures/controller.bar/baseLine/left.png new file mode 100644 index 000000000..ca5e1227b Binary files /dev/null and b/test/fixtures/controller.bar/baseLine/left.png differ diff --git a/test/fixtures/controller.bar/baseLine/mid-x.js b/test/fixtures/controller.bar/baseLine/mid-x.js new file mode 100644 index 000000000..ef6beb5c9 --- /dev/null +++ b/test/fixtures/controller.bar/baseLine/mid-x.js @@ -0,0 +1,41 @@ +module.exports = { + config: { + type: 'bar', + data: { + labels: ['a', 'b'], + datasets: [{ + backgroundColor: '#AAFFCC', + borderColor: '#0000FF', + borderWidth: 1, + data: [1, -1] + }] + }, + options: { + indexAxis: 'y', + scales: { + y: { + display: false + }, + x: { + ticks: { + display: false + }, + grid: { + color: function(context) { + return context.tick.value === 0 ? 'red' : 'transparent'; + }, + lineWidth: 5, + tickLength: 0 + }, + } + }, + maintainAspectRatio: false + } + }, + options: { + canvas: { + width: 128, + height: 128 + } + } +}; diff --git a/test/fixtures/controller.bar/baseLine/mid-x.png b/test/fixtures/controller.bar/baseLine/mid-x.png new file mode 100644 index 000000000..1f4feb2e3 Binary files /dev/null and b/test/fixtures/controller.bar/baseLine/mid-x.png differ diff --git a/test/fixtures/controller.bar/baseLine/mid-y.js b/test/fixtures/controller.bar/baseLine/mid-y.js new file mode 100644 index 000000000..d01c00a12 --- /dev/null +++ b/test/fixtures/controller.bar/baseLine/mid-y.js @@ -0,0 +1,40 @@ +module.exports = { + config: { + type: 'bar', + data: { + labels: ['a', 'b'], + datasets: [{ + backgroundColor: '#AAFFCC', + borderColor: '#0000FF', + borderWidth: 1, + data: [1, -1] + }] + }, + options: { + scales: { + x: { + display: false + }, + y: { + ticks: { + display: false + }, + grid: { + color: function(context) { + return context.tick.value === 0 ? 'red' : 'transparent'; + }, + lineWidth: 5, + tickLength: 0 + }, + } + }, + maintainAspectRatio: false + } + }, + options: { + canvas: { + width: 128, + height: 128 + } + } +}; diff --git a/test/fixtures/controller.bar/baseLine/mid-y.png b/test/fixtures/controller.bar/baseLine/mid-y.png new file mode 100644 index 000000000..88c21a153 Binary files /dev/null and b/test/fixtures/controller.bar/baseLine/mid-y.png differ diff --git a/test/fixtures/controller.bar/baseLine/right.js b/test/fixtures/controller.bar/baseLine/right.js new file mode 100644 index 000000000..1fc069f1f --- /dev/null +++ b/test/fixtures/controller.bar/baseLine/right.js @@ -0,0 +1,42 @@ +module.exports = { + config: { + type: 'bar', + data: { + labels: ['a', 'b'], + datasets: [{ + backgroundColor: '#AAFFCC', + borderColor: '#0000FF', + borderWidth: 1, + data: [-1, -2] + }] + }, + options: { + indexAxis: 'y', + scales: { + y: { + display: false + }, + x: { + ticks: { + display: false + }, + grid: { + color: function(context) { + return context.tick.value === 0 ? 'red' : 'transparent'; + }, + lineWidth: 5, + tickLength: 0, + borderWidth: 0 + }, + } + }, + maintainAspectRatio: false + } + }, + options: { + canvas: { + width: 128, + height: 128 + } + } +}; diff --git a/test/fixtures/controller.bar/baseLine/right.png b/test/fixtures/controller.bar/baseLine/right.png new file mode 100644 index 000000000..2ad1dfdb3 Binary files /dev/null and b/test/fixtures/controller.bar/baseLine/right.png differ diff --git a/test/fixtures/controller.bar/baseLine/top.js b/test/fixtures/controller.bar/baseLine/top.js new file mode 100644 index 000000000..86a7a378d --- /dev/null +++ b/test/fixtures/controller.bar/baseLine/top.js @@ -0,0 +1,41 @@ +module.exports = { + config: { + type: 'bar', + data: { + labels: ['a', 'b'], + datasets: [{ + backgroundColor: '#AAFFCC', + borderColor: '#0000FF', + borderWidth: 1, + data: [-1, -2] + }] + }, + options: { + scales: { + x: { + display: false + }, + y: { + ticks: { + display: false + }, + grid: { + color: function(context) { + return context.tick.value === 0 ? 'red' : 'transparent'; + }, + borderWidth: 0, + lineWidth: 5, + tickLength: 0 + }, + } + }, + maintainAspectRatio: false + } + }, + options: { + canvas: { + width: 128, + height: 128 + } + } +}; diff --git a/test/fixtures/controller.bar/baseLine/top.png b/test/fixtures/controller.bar/baseLine/top.png new file mode 100644 index 000000000..8472c0fbf Binary files /dev/null and b/test/fixtures/controller.bar/baseLine/top.png differ diff --git a/test/fixtures/controller.bar/baseLine/value-x.js b/test/fixtures/controller.bar/baseLine/value-x.js new file mode 100644 index 000000000..557a89863 --- /dev/null +++ b/test/fixtures/controller.bar/baseLine/value-x.js @@ -0,0 +1,42 @@ +module.exports = { + config: { + type: 'bar', + data: { + labels: ['a', 'b'], + datasets: [{ + backgroundColor: '#AAFFCC', + borderColor: '#0000FF', + borderWidth: 1, + data: [1, 3] + }] + }, + options: { + base: 2, + indexAxis: 'y', + scales: { + y: { + display: false + }, + x: { + ticks: { + display: false + }, + grid: { + color: function(context) { + return context.tick.value === 2 ? 'red' : 'transparent'; + }, + lineWidth: 5, + tickLength: 0 + }, + } + }, + maintainAspectRatio: false + } + }, + options: { + canvas: { + width: 128, + height: 128 + } + } +}; diff --git a/test/fixtures/controller.bar/baseLine/value-x.png b/test/fixtures/controller.bar/baseLine/value-x.png new file mode 100644 index 000000000..1fd0161a5 Binary files /dev/null and b/test/fixtures/controller.bar/baseLine/value-x.png differ diff --git a/test/fixtures/controller.bar/baseLine/value-y.js b/test/fixtures/controller.bar/baseLine/value-y.js new file mode 100644 index 000000000..caee084df --- /dev/null +++ b/test/fixtures/controller.bar/baseLine/value-y.js @@ -0,0 +1,41 @@ +module.exports = { + config: { + type: 'bar', + data: { + labels: ['a', 'b'], + datasets: [{ + backgroundColor: '#AAFFCC', + borderColor: '#0000FF', + borderWidth: 1, + data: [1, 3] + }] + }, + options: { + base: 2, + scales: { + x: { + display: false + }, + y: { + ticks: { + display: false + }, + grid: { + color: function(context) { + return context.tick.value === 2 ? 'red' : 'transparent'; + }, + lineWidth: 5, + tickLength: 0 + }, + } + }, + maintainAspectRatio: false + } + }, + options: { + canvas: { + width: 128, + height: 128 + } + } +}; diff --git a/test/fixtures/controller.bar/baseLine/value-y.png b/test/fixtures/controller.bar/baseLine/value-y.png new file mode 100644 index 000000000..15fe78710 Binary files /dev/null and b/test/fixtures/controller.bar/baseLine/value-y.png differ diff --git a/test/specs/controller.bar.tests.js b/test/specs/controller.bar.tests.js index 883a9ed58..6be8eb1ed 100644 --- a/test/specs/controller.bar.tests.js +++ b/test/specs/controller.bar.tests.js @@ -1528,9 +1528,10 @@ describe('Chart.controllers.bar', function() { }); var data = chart.getDatasetMeta(0).data; + var halfBaseLine = chart.scales.y.getLineWidthForValue(0) / 2; - expect(data[0].base - minBarLength).toEqual(data[0].y); - expect(data[1].base + minBarLength).toEqual(data[1].y); + expect(data[0].base - minBarLength + halfBaseLine).toEqual(data[0].y); + expect(data[1].base + minBarLength - halfBaseLine).toEqual(data[1].y); }); it('minBarLength settings should be used on X axis on horizontal bar chart', function() { @@ -1547,9 +1548,10 @@ describe('Chart.controllers.bar', function() { }); var data = chart.getDatasetMeta(0).data; + var halfBaseLine = chart.scales.x.getLineWidthForValue(0) / 2; - expect(data[0].base + minBarLength).toEqual(data[0].x); - expect(data[1].base - minBarLength).toEqual(data[1].x); + expect(data[0].base + minBarLength - halfBaseLine).toEqual(data[0].x); + expect(data[1].base - minBarLength + halfBaseLine).toEqual(data[1].x); }); it('should respect the data visibility settings', function() { diff --git a/types/index.esm.d.ts b/types/index.esm.d.ts index 8cdaf9921..0bafe17e6 100644 --- a/types/index.esm.d.ts +++ b/types/index.esm.d.ts @@ -1199,6 +1199,12 @@ export interface Scale extends El * @return {string} */ getLabelForValue(value: number): string; + + /** + * Returns the grid line width at given value + */ + getLineWidthForValue(value: number): number; + /** * Returns the location of the given data point. Value can either be an index or a numerical value * The coordinate (0, 0) is at the upper-left corner of the canvas