updateElements(bars, start, count, mode) {
const me = this;
const reset = mode === 'reset';
- const vscale = me._cachedMeta.vScale;
- const base = vscale.getBasePixel();
- const horizontal = vscale.isHorizontal();
+ const vScale = me._cachedMeta.vScale;
+ const base = vScale.getBasePixel();
+ const horizontal = vScale.isHorizontal();
const ruler = me._getRuler();
const firstOpts = me.resolveDataElementOptions(start, mode);
const sharedOptions = me.getSharedOptions(firstOpts);
me.updateSharedOptions(sharedOptions, mode, firstOpts);
for (let i = start; i < start + count; i++) {
- const vpixels = me._calculateBarValuePixels(i);
+ const vpixels = reset ? {base, head: base} : me._calculateBarValuePixels(i);
const ipixels = me._calculateBarIndexPixels(i, ruler);
const properties = {
horizontal,
- base: reset ? base : vpixels.base,
- x: horizontal ? reset ? base : vpixels.head : ipixels.center,
- y: horizontal ? ipixels.center : reset ? base : vpixels.head,
+ base: vpixels.base,
+ x: horizontal ? vpixels.head : ipixels.center,
+ y: horizontal ? ipixels.center : vpixels.head,
height: horizontal ? ipixels.size : undefined,
width: horizontal ? undefined : ipixels.size
};
*/
_getRuler() {
const me = this;
+ const opts = me.options;
const meta = me._cachedMeta;
const iScale = meta.iScale;
const pixels = [];
pixels.push(iScale.getPixelForValue(me.getParsed(i)[iScale.axis], i));
}
- // Note: a potential optimization would be to skip computing this
- // only if the barThickness option is defined
- // Since a scriptable option may return null or undefined that
- // means the option would have to be of type number
- const min = computeMinSampleSize(iScale);
+ const barThickness = opts.barThickness;
+ const min = barThickness || computeMinSampleSize(iScale);
return {
min,
start: iScale._startPixel,
end: iScale._endPixel,
stackCount: me._getStackCount(),
- scale: iScale
+ scale: iScale,
+ grouped: opts.grouped,
+ // bar thickness ratio used for non-grouped bars
+ ratio: barThickness ? 1 : opts.categoryPercentage * opts.barPercentage
};
}
*/
_calculateBarIndexPixels(index, ruler) {
const me = this;
+ const scale = ruler.scale;
const options = me.options;
- const stackCount = options.skipNull ? me._getStackCount(index) : ruler.stackCount;
- const range = options.barThickness === 'flex'
- ? computeFlexCategoryTraits(index, ruler, options, stackCount)
- : computeFitCategoryTraits(index, ruler, options, stackCount);
-
- const stackIndex = me._getStackIndex(me.index, me._cachedMeta.stack);
- const center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);
- const size = Math.min(
- valueOrDefault(options.maxBarThickness, Infinity),
- range.chunk * range.ratio);
+ const maxBarThickness = valueOrDefault(options.maxBarThickness, Infinity);
+ let center, size;
+ if (ruler.grouped) {
+ const stackCount = options.skipNull ? me._getStackCount(index) : ruler.stackCount;
+ const range = options.barThickness === 'flex'
+ ? computeFlexCategoryTraits(index, ruler, options, stackCount)
+ : computeFitCategoryTraits(index, ruler, options, stackCount);
+
+ const stackIndex = me._getStackIndex(me.index, me._cachedMeta.stack);
+ center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);
+ size = Math.min(maxBarThickness, range.chunk * range.ratio);
+ } else {
+ // For non-grouped bar charts, exact pixel values are used
+ center = scale.getPixelForValue(me.getParsed(index)[scale.axis], index);
+ size = Math.min(maxBarThickness, ruler.min * ruler.ratio);
+ }
return {
base: center - size / 2,
categoryPercentage: 0.8,
barPercentage: 0.9,
+ grouped: true,
animations: {
numbers: {
--- /dev/null
+const data1 = [
+ {
+ x: '2017-11-02T20:30:00',
+ y: 27
+ },
+ {
+ x: '2017-11-03T20:53:00',
+ y: 30
+ },
+ {
+ x: '2017-11-06T05:46:00',
+ y: 19
+ },
+ {
+ x: '2017-11-06T21:03:00',
+ y: 28
+ },
+ {
+ x: '2017-11-07T20:49:00',
+ y: 29
+ },
+ {
+ x: '2017-11-08T21:52:00',
+ y: 33
+ }
+];
+
+const data2 = [
+ {
+ x: '2017-11-03T13:07:00',
+ y: 45
+ },
+ {
+ x: '2017-11-04T04:50:00',
+ y: 40
+ },
+ {
+ x: '2017-11-06T12:48:00',
+ y: 38
+ },
+ {
+ x: '2017-11-07T12:28:00',
+ y: 42
+ },
+ {
+ x: '2017-11-08T12:45:00',
+ y: 51
+ },
+ {
+ x: '2017-11-09T05:23:00',
+ y: 57
+ }
+];
+
+const data3 = [
+ {
+ x: '2017-11-03T16:30:00',
+ y: 32
+ },
+ {
+ x: '2017-11-04T11:50:00',
+ y: 34
+ },
+ {
+ x: '2017-11-06T18:30:00',
+ y: 28
+ },
+ {
+ x: '2017-11-07T15:51:00',
+ y: 31
+ },
+ {
+ x: '2017-11-08T17:27:00',
+ y: 36
+ },
+ {
+ x: '2017-11-09T06:53:00',
+ y: 31
+ }
+];
+
+module.exports = {
+ description: 'https://github.com/chartjs/Chart.js/issues/5139',
+ config: {
+ type: 'bar',
+ data: {
+ datasets: [
+ {
+ data: data1,
+ backgroundColor: 'rgb(0,0,255)',
+ },
+ {
+ data: data2,
+ backgroundColor: 'rgb(255,0,0)',
+ },
+ {
+ data: data3,
+ backgroundColor: 'rgb(0,255,0)',
+ },
+ ]
+ },
+ options: {
+ barThickness: 10,
+ grouped: false,
+ scales: {
+ x: {
+ bounds: 'ticks',
+ type: 'time',
+ offset: false,
+ position: 'bottom',
+ display: true,
+ time: {
+ isoWeekday: true,
+ unit: 'day'
+ },
+ grid: {
+ offset: false
+ }
+ },
+ y: {
+ beginAtZero: true,
+ display: false
+ }
+ },
+ }
+ },
+ options: {
+ spriteText: true,
+ canvas: {
+ width: 1000,
+ height: 300
+ }
+ }
+};