]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Exclude base-line from bar size (#8648)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Tue, 16 Mar 2021 12:49:19 +0000 (14:49 +0200)
committerGitHub <noreply@github.com>
Tue, 16 Mar 2021 12:49:19 +0000 (08:49 -0400)
* Exclude base-line from bar size

* lint

* add to types

20 files changed:
src/controllers/controller.bar.js
src/core/core.scale.js
test/fixtures/controller.bar/baseLine/bottom.js [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/bottom.png [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/left.js [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/left.png [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/mid-x.js [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/mid-x.png [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/mid-y.js [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/mid-y.png [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/right.js [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/right.png [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/top.js [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/top.png [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/value-x.js [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/value-x.png [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/value-y.js [new file with mode: 0644]
test/fixtures/controller.bar/baseLine/value-y.png [new file with mode: 0644]
test/specs/controller.bar.tests.js
types/index.esm.d.ts

index 0d4176f279a48ab00c024e2eab9fd87b44fedf96..cbac98e5130cbc57f20ff60c09a039c595d37fd9 100644 (file)
@@ -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,
index f62ec10e9565c7d05a0bfee4de65d532c5141426..2da29729094584c68ff2e927ea9a9c6c56121a71 100644 (file)
@@ -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 (file)
index 0000000..272b8e9
--- /dev/null
@@ -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 (file)
index 0000000..d710715
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 (file)
index 0000000..56a68ce
--- /dev/null
@@ -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 (file)
index 0000000..ca5e122
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 (file)
index 0000000..ef6beb5
--- /dev/null
@@ -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 (file)
index 0000000..1f4feb2
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 (file)
index 0000000..d01c00a
--- /dev/null
@@ -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 (file)
index 0000000..88c21a1
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 (file)
index 0000000..1fc069f
--- /dev/null
@@ -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 (file)
index 0000000..2ad1dfd
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 (file)
index 0000000..86a7a37
--- /dev/null
@@ -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 (file)
index 0000000..8472c0f
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 (file)
index 0000000..557a898
--- /dev/null
@@ -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 (file)
index 0000000..1fd0161
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 (file)
index 0000000..caee084
--- /dev/null
@@ -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 (file)
index 0000000..15fe787
Binary files /dev/null and b/test/fixtures/controller.bar/baseLine/value-y.png differ
index 883a9ed58e17b60fd2a97b0b8633c7534d7e69ee..6be8eb1ede7c53277a790e58f83dceecaef895fc 100644 (file)
@@ -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() {
index 8cdaf99215662fd6854283c4f8123bc8ea03469c..0bafe17e6b0235afbdfe1043037d7af2784d501b 100644 (file)
@@ -1199,6 +1199,12 @@ export interface Scale<O extends CoreScaleOptions = CoreScaleOptions> 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