From 524629d35b67f14cc9a02c19b01a7564bc564614 Mon Sep 17 00:00:00 2001 From: Akihiko Kusanagi Date: Fri, 28 Jul 2017 08:27:55 +1000 Subject: [PATCH] Improve offsetGridLine behavior --- docs/charts/bar.md | 10 +- src/controllers/controller.bar.js | 15 +-- src/controllers/controller.line.js | 3 +- src/core/core.controller.js | 13 +- src/core/core.scale.js | 13 -- src/scales/scale.category.js | 41 ++++--- src/scales/scale.time.js | 185 +++++++++++++++-------------- test/specs/scale.category.tests.js | 7 ++ test/specs/scale.time.tests.js | 16 +-- 9 files changed, 148 insertions(+), 155 deletions(-) diff --git a/docs/charts/bar.md b/docs/charts/bar.md index 64111d77966..ec427819519 100644 --- a/docs/charts/bar.md +++ b/docs/charts/bar.md @@ -98,10 +98,9 @@ The bar chart defines the following configuration options. These options are mer | `barThickness` | `Number` | | Manually set width of each bar in pixels. If not set, the bars are sized automatically using `barPercentage` and `categoryPercentage`; | `maxBarThickness` | `Number` | | Set this to ensure that the automatically sized bars are not sized thicker than this. Only works if `barThickness` is not set (automatic sizing is enabled). | `gridLines.offsetGridLines` | `Boolean` | `true` | If true, the bars for a particular data point fall between the grid lines. The grid line will move to the left by one half of the sample width. If false, the grid line will go right down the middle of the bars. [more...](#offsetgridlines) -| `sampleSize` | `Number/Object/String` | | Manually set width for each sample. The unit and the data type vary between scales. If not set, the sample size will be the available width (the space between the gridlines for small datasets). Only works if `barThickness` is not set (automatic sizing is enabled). [more...](#samplesize) ### offsetGridLines -If true, the bars for a particular data point fall between the grid lines. The grid line will move to the left by one half of the sample width, which is the space between the gridlines by default but can be customized using `sampleSize`. If false, the grid line will go right down the middle of the bars. This is set to true for a bar chart while false for other charts by default. +If true, the bars for a particular data point fall between the grid lines. The grid line will move to the left by one half of the sample width, which is the space between the bars. If false, the grid line will go right down the middle of the bars. This is set to true for a bar chart while false for other charts by default. This setting applies to the axis configuration. If axes are added to the chart, this setting will need to be set for each new axis. @@ -117,13 +116,6 @@ options = { } ``` -### sampleSize -If specified, the width for each sample will be calculated based on this value. If not specified, it will be the available width (the space between the gridlines). This only works if `barThickness` is not set. - -The unit and data type vary between scales. -* category scale: This has no effect -* time scale: `Number/Object/String` that [`moment.duration()`](https://momentjs.com/docs/#/durations/) accepts - ## Default Options It is common to want to apply a configuration setting to all created bar charts. The global bar chart settings are stored in `Chart.defaults.bar`. Changing the global options only affects charts created after the change. Existing charts are not changed. diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 70ca2f04503..bd39c0a53b8 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -275,16 +275,17 @@ module.exports = function(Chart) { var me = this; var options = scale.options; var stackIndex = me.getStackIndex(datasetIndex); - var barPixels = scale.getBarPixelsForIndex(index, datasetIndex); - var base = barPixels.min; - var sampleSize = barPixels.max - barPixels.min; + var pos = scale.getPixelForValue(null, index, datasetIndex); + var offset = scale.getPixelForValue(null, index, datasetIndex, true) - pos; + var base = options.gridLines.offsetGridLines ? pos : pos - offset; + var sampleSize = offset * 2; var categorySize = sampleSize * options.categoryPercentage; var categorySpacing = sampleSize - categorySize; var fullBarSize = categorySize / me.getStackCount(); var barSize = fullBarSize * options.barPercentage; var barSpacing = fullBarSize - barSize; - barSize = Math.min( + var size = Math.min( helpers.valueOrDefault(options.barThickness, barSize), helpers.valueOrDefault(options.maxBarThickness, Infinity)); @@ -293,10 +294,10 @@ module.exports = function(Chart) { base += barSpacing / 2; return { - size: barSize, + size: size, base: base, - head: base + barSize, - center: base + barSize / 2 + head: base + size, + center: base + size / 2 }; }, diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index 6502aac198b..fc24cb08546 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -159,8 +159,7 @@ module.exports = function(Chart) { var xScale = me.getScaleForId(meta.xAxisID); var pointOptions = me.chart.options.elements.point; var x, y; - var labels = me.chart.data.labels || []; - var includeOffset = (labels.length === 1 || dataset.data.length === 1) || xScale.options.gridLines.offsetGridLines; + var includeOffset = xScale.options.gridLines.offsetGridLines; // Compatibility: If the properties are defined with only the old name, use those values if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) { diff --git a/src/core/core.controller.js b/src/core/core.controller.js index 1ad5753b74a..9fb73b3c621 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -286,6 +286,7 @@ module.exports = function(Chart) { var me = this; var types = []; var newControllers = []; + var i, ilen; helpers.each(me.data.datasets, function(dataset, datasetIndex) { var meta = me.getDatasetMeta(datasetIndex); @@ -308,17 +309,7 @@ module.exports = function(Chart) { } }, me); - // isCombo is no longer used, but left for backwards compatibility - if (types.length > 1) { - for (var i = 1; i < types.length; i++) { - if (types[i] !== types[i - 1]) { - me.isCombo = true; - break; - } - } - } - - for (i = 0; i < types.length; i++) { + for (i = 0, ilen = types.length; i < ilen; i++) { if (types[i] === 'bar' || types[i] === 'horizontalBar') { me.hasBar = true; break; diff --git a/src/core/core.scale.js b/src/core/core.scale.js index b3ad70185fb..07fc51bd6bd 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -515,19 +515,6 @@ module.exports = function(Chart) { 0; }, - // Get the bar pixels for the data at the given index - getBarPixelsForIndex: function(index, datasetIndex) { - var me = this; - var base = me.getPixelForValue(null, index, datasetIndex, me.options.gridLines.offsetGridLines); - var fullSize = me.isHorizontal() ? me.width : me.height; - var size = fullSize / Math.max(me.ticks.length, 1); - - return { - min: base - size / 2, - max: base + size / 2 - }; - }, - // Actually draw the scale on the canvas // @param {rectangle} chartArea : the area of the chart to draw full grid lines on draw: function(chartArea) { diff --git a/src/scales/scale.category.js b/src/scales/scale.category.js index c1fbc9c4be9..008059a52ac 100644 --- a/src/scales/scale.category.js +++ b/src/scales/scale.category.js @@ -47,9 +47,13 @@ module.exports = function(Chart) { // If we are viewing some subset of labels, slice the original array me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1); - // Disable zero line if a chart has bars and offsetGridLines is false - if (me.chart.hasBar && !me.options.gridLines.offsetGridLines) { + // Offset ticks if a chart has bars and offsetGridLines is false + if ((labels.length === 1 || me.chart.hasBar) && !me.options.gridLines.offsetGridLines) { + me.tickOffset = true; me.zeroLineIndex = -1; + } else { + me.tickOffset = false; + me.zeroLineIndex = undefined; } }, @@ -67,10 +71,8 @@ module.exports = function(Chart) { // Used to get data value locations. Value can either be an index or a numerical value getPixelForValue: function(value, index, datasetIndex, includeOffset) { var me = this; - var offsetGridLines = me.options.gridLines.offsetGridLines; - var hasBar = me.chart.hasBar; // 1 is added because we need the length but we have the indexes - var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((offsetGridLines || hasBar) ? 0 : 1)), 1); + var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines || me.chart.hasBar) ? 0 : 1)), 1); // If value is a data object, then index is the index in the data array, // not the index of the scale. We need to change that. @@ -89,8 +91,13 @@ module.exports = function(Chart) { var valueWidth = me.width / offsetAmt; var widthOffset = (valueWidth * (index - me.minIndex)); - // Add extra offset regardless of includeOffset when offsetGridLines is false and the chart has bars - if (includeOffset || (!offsetGridLines && hasBar)) { + // Add extra offset + if (includeOffset) { + widthOffset += (valueWidth / 2); + } + + // Add extra offset when the chart has bars and offsetGridLines is false + if (me.tickOffset) { widthOffset += (valueWidth / 2); } @@ -99,8 +106,13 @@ module.exports = function(Chart) { var valueHeight = me.height / offsetAmt; var heightOffset = (valueHeight * (index - me.minIndex)); - // Add extra offset regardless of includeOffset when offsetGridLines is false and the chart has bars - if (includeOffset || (!offsetGridLines && hasBar)) { + // Add extra offset + if (includeOffset) { + heightOffset += (valueHeight / 2); + } + + // Add extra offset when the chart has bars and offsetGridLines is false + if (me.tickOffset) { heightOffset += (valueHeight / 2); } @@ -111,23 +123,24 @@ module.exports = function(Chart) { }, getValueForPixel: function(pixel) { var me = this; - var offsetGridLines = me.options.gridLines.offsetGridLines; - var hasBar = me.chart.hasBar; var value; - var offsetAmt = Math.max((me.ticks.length - ((offsetGridLines || hasBar) ? 0 : 1)), 1); + var offsetAmt = Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines || me.chart.hasBar) ? 0 : 1)), 1); var horz = me.isHorizontal(); var valueDimension = (horz ? me.width : me.height) / offsetAmt; pixel -= horz ? me.left : me.top; - if (offsetGridLines || hasBar) { + if (me.tickOffset) { + pixel -= (valueDimension / 2); + } + if (me.options.gridLines.offsetGridLines) { pixel -= (valueDimension / 2); } if (pixel <= 0) { value = 0; } else { - value = Math.round(pixel / valueDimension); + value = Math.round((pixel + 0.5) / valueDimension); } return value + me.minIndex; diff --git a/src/scales/scale.time.js b/src/scales/scale.time.js index 37782ea66ea..d7dc6915d3e 100644 --- a/src/scales/scale.time.js +++ b/src/scales/scale.time.js @@ -80,19 +80,21 @@ function sorter(a, b) { * case, all timestamps are linear, the table contains only min and max. */ function buildLookupTable(timestamps, min, max, linear) { - if (linear || !timestamps.length) { + if (!timestamps.length) { return [ - {time: min, pos: 0}, - {time: max, pos: 1} + {time: min, pos: 0, tick: 0}, + {time: max, pos: 1, tick: 0} ]; } var table = []; var items = timestamps.slice(0); + var start = 0; var i, ilen, prev, curr, next; if (min < timestamps[0]) { items.unshift(min); + start = -1; } if (max > timestamps[timestamps.length - 1]) { items.push(max); @@ -105,7 +107,11 @@ function buildLookupTable(timestamps, min, max, linear) { // only add points that breaks the scale linearity if (prev === undefined || next === undefined || Math.round((next + prev) / 2) !== curr) { - table.push({time: curr, pos: i / (ilen - 1)}); + table.push({ + time: curr, + pos: linear ? (curr - min) / (max - min) : i / (ilen - 1), + tick: start + i + }); } } @@ -383,18 +389,22 @@ module.exports = function(Chart) { var chart = me.chart; var timeOpts = me.options.time; var datasets = chart.data.datasets || []; - var dataMin = MAX_INTEGER; - var dataMax = MIN_INTEGER; + var min = MAX_INTEGER; + var max = MIN_INTEGER; var timestamps = []; var labels = []; - var i, j, ilen, jlen, data, timestamp, min, max; + var minInterval = MAX_INTEGER; + var prevTimestamp = MIN_INTEGER; + var i, j, ilen, jlen, data, timestamp; // Convert labels to timestamps for (i = 0, ilen = chart.data.labels.length; i < ilen; ++i) { timestamp = parse(chart.data.labels[i], me); - dataMin = Math.min(dataMin, timestamp); - dataMax = Math.max(dataMax, timestamp); + min = Math.min(min, timestamp); + max = Math.max(max, timestamp); labels.push(timestamp); + minInterval = Math.min(minInterval, timestamp - prevTimestamp); + prevTimestamp = timestamp; } // Convert data to timestamps @@ -405,12 +415,15 @@ module.exports = function(Chart) { // Let's consider that all data have the same format. if (helpers.isObject(data[0])) { timestamps[i] = []; + prevTimestamp = MIN_INTEGER; for (j = 0, jlen = data.length; j < jlen; ++j) { timestamp = parse(data[j], me); - dataMin = Math.min(dataMin, timestamp); - dataMax = Math.max(dataMax, timestamp); + min = Math.min(min, timestamp); + max = Math.max(max, timestamp); timestamps[i][j] = timestamp; + minInterval = Math.min(minInterval, timestamp - prevTimestamp); + prevTimestamp = timestamp; } } else { timestamps[i] = labels.slice(0); @@ -420,9 +433,16 @@ module.exports = function(Chart) { } } + minInterval = minInterval === MAX_INTEGER ? 0 : minInterval; + + // Extend the range when offsetGridLines is true or the chart has bars + if (me.options.gridLines.offsetGridLines || chart.hasBar) { + max += minInterval; + } + // Enforce limits with user min/max options - min = parse(timeOpts.min, me) || dataMin; - max = parse(timeOpts.max, me) || dataMax; + min = parse(timeOpts.min, me) || min; + max = parse(timeOpts.max, me) || max; // In case there is no valid min/max, let's use today limits min = min === MAX_INTEGER ? +moment().startOf('day') : min; @@ -432,10 +452,9 @@ module.exports = function(Chart) { datasets: timestamps, horizontal: me.isHorizontal(), labels: labels.sort(sorter), // Sort labels **after** data have been converted - dataMin: dataMin, - dataMax: dataMax, min: Math.min(min, max), // Make sure that max is **strictly** higher ... max: Math.max(min + 1, max), // ... than min (required by the lookup table) + minInterval: minInterval, table: [] }; }, @@ -447,7 +466,6 @@ module.exports = function(Chart) { var max = model.max; var timeOpts = me.options.time; var ticksOpts = me.options.ticks; - var offsetGridLines = me.options.gridLines.offsetGridLines; var formats = timeOpts.displayFormats; var capacity = me.getLabelCapacity(min); var unit = timeOpts.unit || determineUnit(timeOpts.minUnit, min, max, capacity); @@ -455,7 +473,6 @@ module.exports = function(Chart) { var timestamps = []; var ticks = []; var i, ilen, timestamp, stepSize; - var dataMin, dataMax, duration, sampleSizeMs, tickSizeMs, size; if (ticksOpts.source === 'auto') { stepSize = helpers.valueOrDefault(timeOpts.stepSize, timeOpts.unitStepSize) @@ -478,37 +495,13 @@ module.exports = function(Chart) { } } - // If the chart has bars, shift min and max based on the sample size - if (offsetGridLines || me.chart.hasBar) { - dataMin = model.dataMin; - dataMax = model.dataMax; - duration = max - min; - sampleSizeMs = moment.duration(me.options.sampleSize || 0).asMilliseconds(); - - tickSizeMs = duration; - for (i = 0, ilen = ticks.length - 1; i < ilen; ++i) { - tickSizeMs = ticks[i + 1] - ticks[i]; - if (dataMin < ticks[i + 1]) { - break; - } - } - size = sampleSizeMs || tickSizeMs; - min = Math.min(min, dataMin - (offsetGridLines ? 0 : size / 2)); - - tickSizeMs = duration; - for (i = ticks.length - 1; i > 0; --i) { - tickSizeMs = ticks[i] - ticks[i - 1]; - if (dataMin >= ticks[i - 1]) { - break; - } - } - size = sampleSizeMs || tickSizeMs; - max = Math.max(max, dataMax + (offsetGridLines ? size : size / 2)); - - // Disable zero line if min has been updated - if (min !== helpers.min(ticks)) { - me.zeroLineIndex = -1; - } + // Offset ticks if the chart has bars and offsetGridLines is false + if (me.chart.hasBar && !me.options.gridLines.offsetGridLines) { + me.tickOffset = true; + me.zeroLineIndex = -1; + } else { + me.tickOffset = false; + me.zeroLineIndex = undefined; } me.ticks = ticks; @@ -578,12 +571,24 @@ module.exports = function(Chart) { /** * @private */ - getPixelForOffset: function(time) { + getPixelForOffset: function(time, includeOffset) { var me = this; var model = me._model; var size = model.horizontal ? me.width : me.height; var start = model.horizontal ? me.left : me.top; - var pos = interpolate(model.table, 'time', time, 'pos'); + var pos; + + // Add extra time offset + if (includeOffset) { + time += me.getTimeOffset(time); + } + + pos = interpolate(model.table, 'time', time, 'pos'); + + // Add extra offset when the chart has bars and offsetGridLines is false + if (me.tickOffset) { + pos += interpolate(model.table, 'time', me.min + me.getTimeOffset(me.min), 'pos'); + } return start + size * pos; }, @@ -596,39 +601,41 @@ module.exports = function(Chart) { time = me._model.datasets[datasetIndex][index]; } - if (time === null) { + if (time === null || time === undefined) { time = parse(value, me); } - if (time !== null) { - // Add extra offset when offsetGridLines is true - if (me.options.gridLines.offsetGridLines && includeOffset) { - time += me.getSampleSize(time) / 2; - } - - return me.getPixelForOffset(time); + if (time !== null || time === undefined) { + return me.getPixelForOffset(time, includeOffset); } }, getPixelForTick: function(index, includeOffset) { var me = this; var ticks = me.ticks; + var minInterval = me._model.minInterval; + var offset; + if (index < 0 || index >= ticks.length) { return null; } - var offset = ticks[index].time; - // Add extra offset for labels + offset = ticks[index].time; + + // Add extra time offset for labels if (includeOffset) { - var tickSizeMs; - if (index < this.ticks.length - 1) { - tickSizeMs = ticks[index + 1].time - ticks[index].time; - } else if (index > 0) { - tickSizeMs = ticks[index].time - ticks[index - 1].time; + if (ticks.length < 2) { + offset += (me.max - me.min) / 2; + } else if (index >= ticks.length - 1) { + offset += minInterval / 2; } else { - tickSizeMs = me.max - ticks[index].time; + offset += (ticks[index + 1].time - ticks[index].time) / 2; } - offset += tickSizeMs / 2; + } + + // Check if grid lines and labels are in range + if ((me.tickOffset ? offset + minInterval : offset) > me.max) { + return MAX_INTEGER; } return me.getPixelForOffset(offset); @@ -645,34 +652,30 @@ module.exports = function(Chart) { return moment(time); }, - // Get the sample size for the data at the given time - getSampleSize: function(time) { + /** + * Calculate time offset for given time + * @private + */ + getTimeOffset: function(time) { var me = this; + var options = me.options; + var ticksOpts = options.ticks; var ticks = me.ticks; - var sampleSizeMs = moment.duration(me.options.sampleSize || 0).asMilliseconds(); - var tickSizeMs = me.max - me.min; - var i, ilen; + var model = me._model; + var minInterval = model.minInterval; + var index; - for (i = 0, ilen = ticks.length - 1; i < ilen; ++i) { - tickSizeMs = ticks[i + 1].time - ticks[i].time; - if (time < ticks[i + 1].time) { - break; - } + if (ticks.length < 2) { + return (me.max - me.min) / 2; } - return sampleSizeMs || tickSizeMs; - }, - - // Get the bar pixels for the data at the given index - getBarPixelsForIndex: function(index, datasetIndex) { - var me = this; - var offsetGridLines = me.options.gridLines.offsetGridLines; - var time = me._model.datasets[datasetIndex][index]; - var size = me.getSampleSize(time); - - return { - min: me.getPixelForOffset(time - (offsetGridLines ? 0 : size / 2)), - max: me.getPixelForOffset(time + (offsetGridLines ? size : size / 2)) - }; + if (ticksOpts.mode === 'linear' && (!options.gridLines.offsetGridLines || ticksOpts.source === 'auto') && minInterval) { + return minInterval / 2; + } + index = Math.floor(interpolate(model.table, 'time', time, 'tick')); + if (index < 0 || index >= ticks.length - 1) { + return minInterval / 2; + } + return (ticks[index + 1].time - ticks[index].time) / 2; }, /** diff --git a/test/specs/scale.category.tests.js b/test/specs/scale.category.tests.js index 400b5d24776..b59b7bba3f4 100644 --- a/test/specs/scale.category.tests.js +++ b/test/specs/scale.category.tests.js @@ -223,6 +223,7 @@ describe('Category scale tests', function() { expect(xScale.getValueForPixel(487)).toBe(4); xScale.options.gridLines.offsetGridLines = true; + chart.update(); expect(xScale.getPixelForValue(0, 0, 0, true)).toBeCloseToPixel(69); expect(xScale.getPixelForTick(0, true)).toBeCloseToPixel(69); @@ -271,6 +272,7 @@ describe('Category scale tests', function() { expect(xScale.getValueForPixel(440)).toBe(4); xScale.options.gridLines.offsetGridLines = false; + chart.update(); expect(xScale.getPixelForValue(0, 0, 0, false)).toBeCloseToPixel(69); expect(xScale.getPixelForTick(0, false)).toBeCloseToPixel(69); @@ -352,6 +354,7 @@ describe('Category scale tests', function() { expect(xScale.getValueForPixel(496)).toBe(3); xScale.options.gridLines.offsetGridLines = true; + chart.update(); expect(xScale.getPixelForValue(0, 1, 0, true)).toBeCloseToPixel(102); expect(xScale.getPixelForTick(0, true)).toBeCloseToPixel(102); @@ -406,6 +409,7 @@ describe('Category scale tests', function() { expect(xScale.getValueForPixel(348)).toBe(3); xScale.options.gridLines.offsetGridLines = false; + chart.update(); expect(xScale.getPixelForValue(0, 1, 0, false)).toBeCloseToPixel(162); expect(xScale.getPixelForValue(0, 1, 1, false)).toBeCloseToPixel(162); @@ -456,6 +460,7 @@ describe('Category scale tests', function() { expect(yScale.getValueForPixel(484)).toBe(4); yScale.options.gridLines.offsetGridLines = true; + chart.update(); expect(yScale.getPixelForValue(0, 0, 0, true)).toBe(77); expect(yScale.getPixelForTick(0, true)).toBeCloseToPixel(77); @@ -511,6 +516,7 @@ describe('Category scale tests', function() { expect(yScale.getValueForPixel(484)).toBe(3); yScale.options.gridLines.offsetGridLines = true; + chart.update(); expect(yScale.getPixelForValue(0, 1, 0, true)).toBe(107); expect(yScale.getPixelForTick(0, true)).toBeCloseToPixel(107); @@ -558,6 +564,7 @@ describe('Category scale tests', function() { expect(yScale.getValueForPixel(439)).toBe(4); yScale.options.gridLines.offsetGridLines = false; + chart.update(); expect(yScale.getPixelForValue(0, 0, 0, false)).toBe(77); expect(yScale.getPixelForTick(0, false)).toBeCloseToPixel(77); diff --git a/test/specs/scale.time.tests.js b/test/specs/scale.time.tests.js index 421469a57fd..75f8f80dd29 100755 --- a/test/specs/scale.time.tests.js +++ b/test/specs/scale.time.tests.js @@ -670,20 +670,20 @@ describe('Time scale tests', function() { }); var xScale = chart.scales.xScale0; - expect(xScale.getPixelForValue('', 1, 0)).toBeCloseToPixel(xScale.left + xScale.width * 5 / 18); - expect(xScale.getPixelForTick(1)).toBeCloseToPixel(xScale.left + xScale.width * 5 / 18); + expect(xScale.getPixelForValue('', 1, 0)).toBeCloseToPixel(xScale.left + xScale.width * 3 / 10); + expect(xScale.getPixelForTick(1)).toBeCloseToPixel(xScale.left + xScale.width * 3 / 10); - expect(xScale.getPixelForValue('', 3, 0)).toBeCloseToPixel(xScale.left + xScale.width * 13 / 18); - expect(xScale.getPixelForTick(3)).toBeCloseToPixel(xScale.left + xScale.width * 13 / 18); + expect(xScale.getPixelForValue('', 3, 0)).toBeCloseToPixel(xScale.left + xScale.width * 7 / 10); + expect(xScale.getPixelForTick(3)).toBeCloseToPixel(xScale.left + xScale.width * 7 / 10); xScale.options.gridLines.offsetGridLines = true; chart.update(); - expect(xScale.getPixelForValue('', 1, 0, true)).toBeCloseToPixel(xScale.left + xScale.width * 5 / 18); - expect(xScale.getPixelForTick(1, true)).toBeCloseToPixel(xScale.left + xScale.width * 3 / 9); + expect(xScale.getPixelForValue('', 1, 0, true)).toBeCloseToPixel(xScale.left + xScale.width * 3 / 10); + expect(xScale.getPixelForTick(1, true)).toBeCloseToPixel(xScale.left + xScale.width * 3 / 10); - expect(xScale.getPixelForValue('', 3, 0, true)).toBeCloseToPixel(xScale.left + xScale.width * 13 / 18); - expect(xScale.getPixelForTick(3, true)).toBeCloseToPixel(xScale.left + xScale.width * 7 / 9); + expect(xScale.getPixelForValue('', 3, 0, true)).toBeCloseToPixel(xScale.left + xScale.width * 7 / 10); + expect(xScale.getPixelForTick(3, true)).toBeCloseToPixel(xScale.left + xScale.width * 7 / 10); }); it ('Should get the correct pixel when there are mixed datasets', function() {