From: Ekaterina Dontsova Date: Thu, 25 Aug 2016 16:52:12 +0000 (+0300) Subject: Fix #3044 Line chart single data point centering (#3166) X-Git-Tag: v2.2.2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4a4dccd6c1255b49041e54666cd9ca78d842dc54;p=thirdparty%2FChart.js.git Fix #3044 Line chart single data point centering (#3166) In line charts, when there is only one label and data point, both are now horizontally centered. --- diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index 567083e32..a7746ee27 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -174,6 +174,8 @@ 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) || me.chart.isCombo; // Compatibility: If the properties are defined with only the old name, use those values if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) { @@ -183,7 +185,7 @@ module.exports = function(Chart) { dataset.pointHitRadius = dataset.hitRadius; } - x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, me.chart.isCombo); + x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset); y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex); // Utility diff --git a/src/scales/scale.category.js b/src/scales/scale.category.js index 35d5475e8..7e7d552fc 100644 --- a/src/scales/scale.category.js +++ b/src/scales/scale.category.js @@ -21,7 +21,7 @@ module.exports = function(Chart) { // Implement this so that determineDataLimits: function() { var me = this; - var labels = me.getLabels(); + var labels = me.getLabels(); me.minIndex = 0; me.maxIndex = labels.length - 1; var findIndex; @@ -70,9 +70,9 @@ module.exports = function(Chart) { var valueWidth = innerWidth / offsetAmt; var widthOffset = (valueWidth * (index - me.minIndex)) + me.paddingLeft; - if (me.options.gridLines.offsetGridLines && includeOffset) { + if (me.options.gridLines.offsetGridLines && includeOffset || me.maxIndex === me.minIndex && includeOffset) { widthOffset += (valueWidth / 2); - } + } return me.left + Math.round(widthOffset); } else { diff --git a/test/controller.line.tests.js b/test/controller.line.tests.js index 7f0f43903..498c723a7 100644 --- a/test/controller.line.tests.js +++ b/test/controller.line.tests.js @@ -1,6 +1,6 @@ // Test the line controller describe('Line controller tests', function() { - + beforeEach(function() { window.addDefaultMatchers(jasmine); }); @@ -8,7 +8,7 @@ describe('Line controller tests', function() { afterEach(function() { window.releaseAllCharts(); }); - + it('should be constructed', function() { var chart = window.acquireChart({ type: 'line', @@ -130,7 +130,7 @@ describe('Line controller tests', function() { spyOn(meta.data[3], 'draw'); chart.update(); - + expect(meta.dataset.draw.calls.count()).toBe(0); expect(meta.data[0].draw.calls.count()).toBe(1); expect(meta.data[1].draw.calls.count()).toBe(1); @@ -162,7 +162,7 @@ describe('Line controller tests', function() { spyOn(meta.data[3], 'draw'); chart.update(); - + expect(meta.dataset.draw.calls.count()).toBe(0); expect(meta.data[0].draw.calls.count()).toBe(1); expect(meta.data[1].draw.calls.count()).toBe(1); @@ -200,17 +200,17 @@ describe('Line controller tests', function() { } }, }); - + var meta = chart.getDatasetMeta(0); expect(meta.data.length).toBe(4); - + chart.data.datasets[0].data = [1, 2]; // remove 2 items chart.data.datasets[0].borderWidth = 1; chart.update(); expect(meta.data.length).toBe(2); - - + + [ { x: 44, y: 484 }, { x: 193, y: 32 } ].forEach(function(expected, i) { @@ -225,13 +225,75 @@ describe('Line controller tests', function() { borderColor: 'blue', })); }); - + chart.data.datasets[0].data = [1, 2, 3]; // add 1 items chart.update(); expect(meta.data.length).toBe(3); // should add a new meta data item }); + it('should correctly calculate x scale for label and point', function(){ + var chart = window.acquireChart({ + type: 'line', + data: { + labels: ["One"], + datasets: [{ + data: [1], + }] + }, + options: { + hover: { + mode: 'single' + }, + scales: { + yAxes: [{ + ticks: { + beginAtZero:true + } + }] + } + } + }); + + var meta = chart.getDatasetMeta(0); + // 1 point + var point = meta.data[0]; + expect(point._model.x).toBeCloseToPixel(267); + + // 2 points + chart.data.labels = ["One", "Two"]; + chart.data.datasets[0].data = [1, 2]; + chart.update(); + + var points = meta.data; + + expect(points[0]._model.x).toBeCloseToPixel(37); + expect(points[1]._model.x).toBeCloseToPixel(498); + + // 3 points + chart.data.labels = ["One", "Two", "Three"]; + chart.data.datasets[0].data = [1, 2, 3]; + chart.update(); + + points = meta.data; + + expect(points[0]._model.x).toBeCloseToPixel(37); + expect(points[1]._model.x).toBeCloseToPixel(265); + expect(points[2]._model.x).toBeCloseToPixel(493); + + // 4 points + chart.data.labels = ["One", "Two", "Three", "Four"]; + chart.data.datasets[0].data = [1, 2, 3, 4]; + chart.update(); + + points = meta.data; + + expect(points[0]._model.x).toBeCloseToPixel(37); + expect(points[1]._model.x).toBeCloseToPixel(190); + expect(points[2]._model.x).toBeCloseToPixel(343); + expect(points[3]._model.x).toBeCloseToPixel(497); + }); + it('should update elements when the y scale is stacked', function() { var chart = window.acquireChart({ type: 'line', @@ -253,7 +315,7 @@ describe('Line controller tests', function() { } } }); - + var meta0 = chart.getDatasetMeta(0); [ { x: 38, y: 161 }, @@ -275,7 +337,7 @@ describe('Line controller tests', function() { expect(meta1.data[i]._model.x).toBeCloseToPixel(values.x); expect(meta1.data[i]._model.y).toBeCloseToPixel(values.y); }); - + }); it('should update elements when the y scale is stacked with multiple axes', function() { @@ -306,7 +368,7 @@ describe('Line controller tests', function() { } } }); - + var meta0 = chart.getDatasetMeta(0); [ { x: 76, y: 161 }, @@ -328,7 +390,7 @@ describe('Line controller tests', function() { expect(meta1.data[i]._model.x).toBeCloseToPixel(values.x); expect(meta1.data[i]._model.y).toBeCloseToPixel(values.y); }); - + }); it('should update elements when the y scale is stacked and datasets is scatter data', function() { @@ -376,7 +438,7 @@ describe('Line controller tests', function() { } } }); - + var meta0 = chart.getDatasetMeta(0); [ { x: 38, y: 161 }, @@ -398,7 +460,7 @@ describe('Line controller tests', function() { expect(meta1.data[i]._model.x).toBeCloseToPixel(values.x); expect(meta1.data[i]._model.y).toBeCloseToPixel(values.y); }); - + }); it('should update elements when the y scale is stacked and data is strings', function() { @@ -422,7 +484,7 @@ describe('Line controller tests', function() { } } }); - + var meta0 = chart.getDatasetMeta(0); [ { x: 38, y: 161 }, @@ -444,7 +506,7 @@ describe('Line controller tests', function() { expect(meta1.data[i]._model.x).toBeCloseToPixel(values.x); expect(meta1.data[i]._model.y).toBeCloseToPixel(values.y); }); - + }); it('should find the correct scale zero when the data is all positive', function() { @@ -458,9 +520,9 @@ describe('Line controller tests', function() { labels: ['label1', 'label2', 'label3', 'label4'] }, }); - + var meta = chart.getDatasetMeta(0); - + expect(meta.dataset._model).toEqual(jasmine.objectContaining({ scaleTop: 32, scaleBottom: 484, @@ -479,9 +541,9 @@ describe('Line controller tests', function() { labels: ['label1', 'label2', 'label3', 'label4'] }, }); - + var meta = chart.getDatasetMeta(0); - + expect(meta.dataset._model).toEqual(jasmine.objectContaining({ scaleTop: 32, scaleBottom: 484, @@ -496,7 +558,7 @@ describe('Line controller tests', function() { datasets: [{ data: [0, 0], label: 'dataset1', - + // line styles backgroundColor: 'rgb(98, 98, 98)', borderColor: 'rgb(8, 8, 8)', @@ -524,9 +586,9 @@ describe('Line controller tests', function() { labels: ['label1', 'label2', 'label3', 'label4'] } }); - + var meta = chart.getDatasetMeta(0); - + chart.data.datasets[0].data = [1, 2]; // remove 2 items chart.update(); expect(meta.data.length).toBe(2); @@ -567,7 +629,7 @@ describe('Line controller tests', function() { } } }); - + var meta = chart.getDatasetMeta(0); var point = meta.data[0];