From: Evert Timberg Date: Sat, 30 Apr 2016 00:03:15 +0000 (-0400) Subject: Merge from feature/pan-support X-Git-Tag: 2.1.0~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6df9b24ecda2f739192435ac5d4ab9da8b9c716e;p=thirdparty%2FChart.js.git Merge from feature/pan-support All tests are passing --- 6df9b24ecda2f739192435ac5d4ab9da8b9c716e diff --cc src/scales/scale.linear.js index 918db2cd3,868d6581c..90fcab9fe --- a/src/scales/scale.linear.js +++ b/src/scales/scale.linear.js @@@ -251,6 -250,19 +251,19 @@@ module.exports = function(Chart) return Math.round(pixel); } }, + getValueForPixel: function(pixel) { + var offset; + + if (this.isHorizontal()) { + var innerWidth = this.width - (this.paddingLeft + this.paddingRight); + offset = (pixel - this.left - this.paddingLeft) / innerWidth; + } else { + var innerHeight = this.height - (this.paddingTop + this.paddingBottom); + offset = (this.bottom - this.paddingBottom - pixel) / innerHeight; + } + - return this.min + ((this.max - this.min) * offset); ++ return this.start + ((this.end - this.start) * offset); + }, getPixelForTick: function(index, includeOffset) { return this.getPixelForValue(this.ticksAsNumbers[index], null, null, includeOffset); } diff --cc src/scales/scale.time.js index 860bccaad,1d31bf233..af3a624a6 --- a/src/scales/scale.time.js +++ b/src/scales/scale.time.js @@@ -326,6 -316,12 +326,12 @@@ module.exports = function(Chart) } } }, + getValueForPixel: function(pixel) { + var innerDimension = this.isHorizontal() ? this.width - (this.paddingLeft + this.paddingRight) : this.height - (this.paddingTop + this.paddingBottom); + var offset = (pixel - (this.isHorizontal() ? this.left + this.paddingLeft : this.top + this.paddingTop)) / innerDimension; - offset *= this.scaleSizeInUnits; - return this.firstTick.clone().add(offset, this.tickUnit); ++ offset *= (this.scaleSizeInUnits - (this.leadingUnitBuffer > 0 ? 1 : 0)); ++ return this.firstTick.clone().add(moment.duration(offset, this.tickUnit).asSeconds(), 'seconds'); + }, parseTime: function(label) { if (typeof this.options.time.parser === 'string') { return moment(label, this.options.time.parser); diff --cc test/scale.linear.tests.js index ff783a229,59af5968f..40e60ce86 --- a/test/scale.linear.tests.js +++ b/test/scale.linear.tests.js @@@ -585,39 -742,82 +585,47 @@@ describe('Linear Scale', function() }); it('Should get the correct pixel value for a point', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - xAxisID: scaleID, // for the horizontal scale - yAxisID: scaleID, - data: [] - }] - }; - - var mockContext = window.createMockContext(); - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear')); - var Constructor = Chart.scaleService.getScaleConstructor('linear'); - var verticalScale = new Constructor({ - ctx: mockContext, - options: config, - chart: { - data: mockData - }, - id: scaleID - }); - - // Update - verticalScale.update(50, 100); - - // Fake out positioning of the scale service - verticalScale.left = 0; - verticalScale.top = 0; - verticalScale.right = 50; - verticalScale.bottom = 110; - verticalScale.paddingTop = 5; - verticalScale.paddingBottom = 5; - verticalScale.width = 50; - verticalScale.height = 110; - - expect(verticalScale.getPixelForValue(1, 0, 0)).toBe(5); // top + paddingTop - expect(verticalScale.getValueForPixel(5)).toBe(1); - - expect(verticalScale.getPixelForValue(-1, 0, 0)).toBe(105); // bottom - paddingBottom - expect(verticalScale.getValueForPixel(105)).toBe(-1); - - expect(verticalScale.getPixelForValue(0, 0, 0)).toBe(55); // halfway - expect(verticalScale.getValueForPixel(55)).toBe(0); - - var horizontalConfig = Chart.helpers.clone(config); - horizontalConfig.position = 'bottom'; - var horizontalScale = new Constructor({ - ctx: mockContext, - options: horizontalConfig, - chart: { - data: mockData + chartInstance = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + xAxisID: 'xScale0', + yAxisID: 'yScale0', + data: [] + }], }, - id: scaleID, + options: { + scales: { + xAxes: [{ + id: 'xScale0', + type: 'linear', + position: 'bottom' + }], + yAxes: [{ + id: 'yScale0', + type: 'linear' + }] + } + } }); + + var xScale = chartInstance.scales.xScale0; + expect(xScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(501); // right - paddingRight + expect(xScale.getPixelForValue(-1, 0, 0)).toBeCloseToPixel(41); // left + paddingLeft + expect(xScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(271); // halfway*/ - horizontalScale.update(100, 50); ++ expect(xScale.getValueForPixel(501)).toBeCloseTo(1, 1e-2); ++ expect(xScale.getValueForPixel(41)).toBeCloseTo(-1, 1e-2); ++ expect(xScale.getValueForPixel(271)).toBeCloseTo(0, 1e-2); + - // Fake out positioning of the scale service - horizontalScale.left = 0; - horizontalScale.top = 0; - horizontalScale.right = 110; - horizontalScale.bottom = 50; - horizontalScale.paddingLeft = 5; - horizontalScale.paddingRight = 5; - horizontalScale.width = 110; - horizontalScale.height = 50; + var yScale = chartInstance.scales.yScale0; - expect(yScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(32); // top + paddingTop - expect(yScale.getPixelForValue(-1, 0, 0)).toBeCloseToPixel(484); // bottom - paddingBottom - expect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(258); // halfway ++ expect(yScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(32); // right - paddingRight ++ expect(yScale.getPixelForValue(-1, 0, 0)).toBeCloseToPixel(484); // left + paddingLeft ++ expect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(258); // halfway*/ + - // Range expands to [-2, 2] due to nicenum algorithm - expect(horizontalScale.getPixelForValue(2, 0, 0)).toBe(105); // right - paddingRight - expect(horizontalScale.getValueForPixel(105)).toBe(2); - - expect(horizontalScale.getPixelForValue(-2, 0, 0)).toBe(5); // left + paddingLeft - expect(horizontalScale.getValueForPixel(5)).toBe(-2); - - expect(horizontalScale.getPixelForValue(0, 0, 0)).toBe(55); // halfway - expect(horizontalScale.getValueForPixel(55)).toBe(0); ++ expect(yScale.getValueForPixel(32)).toBe(1); ++ expect(yScale.getValueForPixel(484)).toBe(-1); ++ expect(yScale.getValueForPixel(258)).toBe(0); }); it('should fit correctly', function() { diff --cc test/scale.logarithmic.tests.js index f87d411e9,f49865a94..4fcfc691d --- a/test/scale.logarithmic.tests.js +++ b/test/scale.logarithmic.tests.js @@@ -51,512 -43,600 +51,520 @@@ describe('Logarithmic Scale tests', fun expect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function)); }); - it('Should correctly determine the max & min data values', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [10, 5, 5000, 78, 450] - }, { - yAxisID: 'second scale', - data: [1, 1000, 10, 100], - }, { - yAxisID: scaleID, - data: [150] - }] - }; - - var mockContext = window.createMockContext(); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: Chart.scaleService.getScaleDefaults('logarithmic'), // use default config for scale - chart: { - data: mockData, + it('should correctly determine the max & min data values', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + yAxisID: 'yScale0', + data: [42, 1000, 64, 100], + }, { + yAxisID: 'yScale1', + data: [10, 5, 5000, 78, 450] + }, { + yAxisID: 'yScale1', + data: [150] + }], + labels: ['a', 'b', 'c', 'd', 'e'] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale0', + type: 'logarithmic' + }, { + id: 'yScale1', + type: 'logarithmic' + }] + } + } }); - expect(scale).not.toEqual(undefined); // must construct - expect(scale.min).toBe(undefined); // not yet set - expect(scale.max).toBe(undefined); + expect(chart.scales.yScale0).not.toEqual(undefined); // must construct + expect(chart.scales.yScale0.min).toBe(10); + expect(chart.scales.yScale0.max).toBe(1000); - scale.update(400, 400); - expect(scale.min).toBe(1); - expect(scale.max).toBe(5000); + expect(chart.scales.yScale1).not.toEqual(undefined); // must construct + expect(chart.scales.yScale1.min).toBe(1); + expect(chart.scales.yScale1.max).toBe(5000); }); - it('Should correctly determine the max & min of string data values', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: ['10', '5', '5000', '78', '450'] - }, { - yAxisID: 'second scale', - data: ['1', '1000', '10', '100'], - }, { - yAxisID: scaleID, - data: ['150'] - }] - }; - - var mockContext = window.createMockContext(); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: Chart.scaleService.getScaleDefaults('logarithmic'), // use default config for scale - chart: { - data: mockData, + it('should correctly determine the max & min of string data values', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + yAxisID: 'yScale0', + data: ['42', '1000', '64', '100'], + }, { + yAxisID: 'yScale1', + data: ['10', '5', '5000', '78', '450'] + }, { + yAxisID: 'yScale1', + data: ['150'] + }], + labels: ['a', 'b', 'c', 'd', 'e'] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale0', + type: 'logarithmic' + }, { + id: 'yScale1', + type: 'logarithmic' + }] + } + } }); - expect(scale).not.toEqual(undefined); // must construct - expect(scale.min).toBe(undefined); // not yet set - expect(scale.max).toBe(undefined); + expect(chart.scales.yScale0).not.toEqual(undefined); // must construct + expect(chart.scales.yScale0.min).toBe(10); + expect(chart.scales.yScale0.max).toBe(1000); - scale.update(400, 400); - expect(scale.min).toBe(1); - expect(scale.max).toBe(5000); + expect(chart.scales.yScale1).not.toEqual(undefined); // must construct + expect(chart.scales.yScale1.min).toBe(1); + expect(chart.scales.yScale1.max).toBe(5000); }); - it('Should correctly determine the max & min data values when there are hidden datasets', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [10, 5, 5000, 78, 450] - }, { - yAxisID: 'second scale', - data: [1, 1000, 10, 100], - }, { - yAxisID: scaleID, - data: [50000], - hidden: true - }] - }; - - var mockContext = window.createMockContext(); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: Chart.scaleService.getScaleDefaults('logarithmic'), // use default config for scale - chart: { - data: mockData + it('should correctly determine the max & min data values when there are hidden datasets', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + yAxisID: 'yScale1', + data: [10, 5, 5000, 78, 450] + }, { + yAxisID: 'yScale0', + data: [42, 1000, 64, 100], + }, { + yAxisID: 'yScale1', + data: [50000], + hidden: true + }], + labels: ['a', 'b', 'c', 'd', 'e'] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale0', + type: 'logarithmic' + }, { + id: 'yScale1', + type: 'logarithmic' + }] + } + } }); - expect(scale).not.toEqual(undefined); // must construct - expect(scale.min).toBe(undefined); // not yet set - expect(scale.max).toBe(undefined); - - scale.update(400, 400); - expect(scale.min).toBe(1); - expect(scale.max).toBe(5000); + expect(chart.scales.yScale1).not.toEqual(undefined); // must construct + expect(chart.scales.yScale1.min).toBe(1); + expect(chart.scales.yScale1.max).toBe(5000); }); - it('Should correctly determine the max & min data values when there is NaN data', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [undefined, 10, null, 5, 5000, NaN, 78, 450] - }] - }; - - var mockContext = window.createMockContext(); - var options = Chart.scaleService.getScaleDefaults('logarithmic'); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: options, // use default config for scale - chart: { - data: mockData + it('should correctly determine the max & min data values when there is NaN data', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + data: [undefined, 10, null, 5, 5000, NaN, 78, 450] + }, { + data: [undefined, 28, null, 1000, 500, NaN, 50, 42] + }], + labels: ['a', 'b', 'c', 'd', 'e', 'f' ,'g'] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale', + type: 'logarithmic' + }] + } + } }); - expect(scale).not.toEqual(undefined); // must construct - expect(scale.min).toBe(undefined); // not yet set - expect(scale.max).toBe(undefined); - - scale.update(400, 400); - expect(scale.min).toBe(1); - expect(scale.max).toBe(5000); + expect(chart.scales.yScale).not.toEqual(undefined); // must construct + expect(chart.scales.yScale.min).toBe(1); + expect(chart.scales.yScale.max).toBe(5000); // Turn on stacked mode since it uses it's own - options.stacked = true; + chart.options.scales.yAxes[0].stacked = true; + chart.update(); - scale.update(400, 400); - expect(scale.min).toBe(1); - expect(scale.max).toBe(5000); + expect(chart.scales.yScale.min).toBe(10); + expect(chart.scales.yScale.max).toBe(6000); }); - - it('Should correctly determine the max & min for scatter data', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - xAxisID: scaleID, // for the horizontal scale - yAxisID: scaleID, - data: [{ - x: 10, - y: 100 - }, { - x: 2, - y: 6 - }, { - x: 65, - y: 121 - }, { - x: 99, - y: 7 + it('should correctly determine the max & min for scatter data', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + data: [ + { x: 10, y: 100 }, + { x: 2, y: 6 }, + { x: 65, y: 121 }, + { x: 99, y: 7 } + ] }] - }] - }; - - var mockContext = window.createMockContext(); - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic')); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var verticalScale = new Constructor({ - ctx: mockContext, - options: config, - chart: { - data: mockData }, - id: scaleID + options: { + scales: { + xAxes: [{ + id: 'xScale', + type: 'logarithmic', + position: 'bottom' + }], + yAxes: [{ + id: 'yScale', + type: 'logarithmic' + }] + } + } }); - verticalScale.update(400, 400); - expect(verticalScale.min).toBe(1); - expect(verticalScale.max).toBe(200); - - var horizontalConfig = Chart.helpers.clone(config); - horizontalConfig.position = 'bottom'; - var horizontalScale = new Constructor({ - ctx: mockContext, - options: horizontalConfig, - chart: { - data: mockData - }, - id: scaleID, - }); + expect(chart.scales.xScale.min).toBe(1); + expect(chart.scales.xScale.max).toBe(100); - horizontalScale.update(400, 400); - expect(horizontalScale.min).toBe(1); - expect(horizontalScale.max).toBe(100); + expect(chart.scales.yScale.min).toBe(1); + expect(chart.scales.yScale.max).toBe(200); }); - it('Should correctly determine the min and max data values when stacked mode is turned on', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [10, 5, 1, 5, 78, 100], - type: 'bar' - }, { - yAxisID: 'second scale', - data: [-1000, 1000], - }, { - yAxisID: scaleID, - data: [150, 10, 10, 100, 10, 9], - type: 'bar' - }, { - yAxisID: scaleID, - data: [100, 100, 100, 100, 100, 100], - type: 'line' - }] - }; - - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic')); - config.stacked = true; // enable scale stacked mode - - var mockContext = window.createMockContext(); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: config, - chart: { - data: mockData + it('should correctly determine the min and max data values when stacked mode is turned on', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + type: 'bar', + yAxisID: 'yScale0', + data: [10, 5, 1, 5, 78, 100] + }, { + yAxisID: 'yScale1', + data: [-1000, 1000], + }, { + type: 'bar', + yAxisID: 'yScale0', + data: [150, 10, 10, 100, 10, 9] + }, { + type: 'line', + yAxisID: 'yScale0', + data: [100, 100, 100, 100, 100, 100] + }], + labels: ['a', 'b', 'c', 'd', 'e', 'f'] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale0', + type: 'logarithmic', + stacked: true + }, { + id: 'yScale1', + type: 'logarithmic' + }] + } + } }); - scale.update(400, 400); - expect(scale.min).toBe(10); - expect(scale.max).toBe(200); + expect(chart.scales.yScale0.min).toBe(10); + expect(chart.scales.yScale0.max).toBe(200); }); - it('Should correctly determine the min and max data values when stacked mode is turned on ignoring hidden datasets', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [10, 5, 1, 5, 78, 100], - type: 'bar' - }, { - yAxisID: 'second scale', - data: [-1000, 1000], - type: 'bar' - }, { - yAxisID: scaleID, - data: [150, 10, 10, 100, 10, 9], - type: 'bar' - }, { - yAxisID: scaleID, - data: [10000, 10000, 10000, 10000, 10000, 10000], - hidden: true, - type: 'bar' - }] - }; - - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic')); - config.stacked = true; // enable scale stacked mode - - var mockContext = window.createMockContext(); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: config, - chart: { - data: mockData + it('should correctly determine the min and max data values when stacked mode is turned on ignoring hidden datasets', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + yAxisID: 'yScale0', + data: [10, 5, 1, 5, 78, 100], + type: 'bar' + }, { + yAxisID: 'yScale1', + data: [-1000, 1000], + type: 'bar' + }, { + yAxisID: 'yScale0', + data: [150, 10, 10, 100, 10, 9], + type: 'bar' + }, { + yAxisID: 'yScale0', + data: [10000, 10000, 10000, 10000, 10000, 10000], + hidden: true, + type: 'bar' + }], + labels: ['a', 'b', 'c', 'd', 'e', 'f'] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale0', + type: 'logarithmic', + stacked: true + }, { + id: 'yScale1', + type: 'logarithmic' + }] + } + } }); - scale.update(400, 400); - expect(scale.min).toBe(10); - expect(scale.max).toBe(200); + expect(chart.scales.yScale0.min).toBe(10); + expect(chart.scales.yScale0.max).toBe(200); }); - it('Should ensure that the scale has a max and min that are not equal', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [] - }; - - var mockContext = window.createMockContext(); - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic')); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: config, - chart: { - data: mockData + it('should ensure that the scale has a max and min that are not equal', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + data: [] + }], + labels: [] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale', + type: 'logarithmic' + }] + } + } }); - scale.update(400, 00); - expect(scale.min).toBe(1); - expect(scale.max).toBe(10); + expect(chart.scales.yScale.min).toBe(1); + expect(chart.scales.yScale.max).toBe(10); - mockData.datasets = [{ - yAxisID: scaleID, - data: [0.15, 0.15] - }]; + chart.data.datasets[0].data = [0.15, 0.15]; + chart.update(); - scale.update(400, 400); - expect(scale.min).toBe(0.01); - expect(scale.max).toBe(1); + expect(chart.scales.yScale.min).toBe(0.01); + expect(chart.scales.yScale.max).toBe(1); }); - - it('Should use the min and max options', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [1, 1, 1, 2, 1, 0] - }] - }; - - var mockContext = window.createMockContext(); - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic')); - - config.ticks.min = 10; - config.ticks.max = 1010; - - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: config, - chart: { - data: mockData + it('should use the min and max options', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + data: [1, 1, 1, 2, 1, 0] + }], + labels: [] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale', + type: 'logarithmic', + ticks: { + min: 10, + max: 1010, + callback: function(value) { + return value; + } + } + }] + } + } }); - scale.update(400, 00); - scale.buildTicks(); - expect(scale.min).toBe(10); - expect(scale.max).toBe(1010); - expect(scale.ticks[0]).toBe(1010); - expect(scale.ticks[scale.ticks.length - 1]).toBe(10); + var yScale = chart.scales.yScale; + var tickCount = yScale.ticks.length; + expect(yScale.min).toBe(10); + expect(yScale.max).toBe(1010); + expect(yScale.ticks[0]).toBe(1010); + expect(yScale.ticks[tickCount - 1]).toBe(10); }); - it('Should generate tick marks', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [10, 5, 1, 25, 78] - }, ] - }; - - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic')); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: {}, - options: config, - chart: { - data: mockData + it('should generate tick marks', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + data: [10, 5, 1, 25, 78] + }], + labels: [] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale', + type: 'logarithmic', + ticks: { + callback: function(value) { + return value; + } + } + }] + } + } }); - // Set arbitrary width and height for now - scale.width = 50; - scale.height = 400; - - scale.determineDataLimits(); - scale.buildTicks(); - // Counts down because the lines are drawn top to bottom - expect(scale.ticks).toEqual([80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]); - expect(scale.start).toBe(1); - expect(scale.end).toBe(80); + expect(chart.scales.yScale).toEqual(jasmine.objectContaining({ + ticks: [80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], + start: 1, + end: 80 + })); }); - it('Should generate tick marks in the correct order in reversed mode', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [10, 5, 1, 25, 78] - }, ] - }; - - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic')); - config.ticks.reverse = true; - - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: {}, - options: config, - chart: { - data: mockData + it('should generate tick marks in the correct order in reversed mode', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + data: [10, 5, 1, 25, 78] + }], + labels: [] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale', + type: 'logarithmic', + ticks: { + reverse: true, + callback: function(value) { + return value; + } + } + }] + } + } }); - // Set arbitrary width and height for now - scale.width = 50; - scale.height = 400; - - scale.determineDataLimits(); - scale.buildTicks(); - // Counts down because the lines are drawn top to bottom - expect(scale.ticks).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80]); - expect(scale.start).toBe(80); - expect(scale.end).toBe(1); + expect(chart.scales.yScale).toEqual(jasmine.objectContaining({ + ticks: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80], + start: 80, + end: 1 + })); }); - it('Should build labels using the default template', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [10, 5, 1, 25, 78] - }, ] - }; - - var mockContext = window.createMockContext(); - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic')); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: config, - chart: { - data: mockData + it('should build labels using the default template', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + data: [10, 5, 1, 25, 78] + }], + labels: [] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale', + type: 'logarithmic' + }] + } + } }); - scale.update(400, 400); - - expect(scale.ticks).toEqual(['8e+1', '', '', '5e+1', '', '', '2e+1', '1e+1', '', '', '', '', '5e+0', '', '', '2e+0', '1e+0']); + expect(chart.scales.yScale.ticks).toEqual(['8e+1', '', '', '5e+1', '', '', '2e+1', '1e+1', '', '', '', '', '5e+0', '', '', '2e+0', '1e+0']); }); - it('Should build labels using the user supplied callback', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [10, 5, 1, 25, 78] - }, ] - }; - - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic')); - config.ticks.userCallback = function(value, index) { - return index.toString(); - }; - - var mockContext = window.createMockContext(); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: config, - chart: { - data: mockData + it('should build labels using the user supplied callback', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + data: [10, 5, 1, 25, 78] + }], + labels: [] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale', + type: 'logarithmic', + ticks: { + callback: function(value, index) { + return index.toString(); + } + } + }] + } + } }); - scale.update(400, 400); - // Just the index - expect(scale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']); + expect(chart.scales.yScale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']); }); - it('Should correctly get the correct label for a data item', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - yAxisID: scaleID, - data: [10, 5, 5000, 78, 450] - }, { - yAxisID: 'second scale', - data: [1, 1000, 10, 100], - }, { - yAxisID: scaleID, - data: [150] - }] - }; - - var mockContext = window.createMockContext(); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var scale = new Constructor({ - ctx: mockContext, - options: Chart.scaleService.getScaleDefaults('logarithmic'), // use default config for scale - chart: { - data: mockData, + it('should correctly get the correct label for a data item', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + yAxisID: 'yScale0', + data: [10, 5, 5000, 78, 450] + }, { + yAxisID: 'yScale1', + data: [1, 1000, 10, 100], + }, { + yAxisID: 'yScale0', + data: [150] + }], + labels: [] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'yScale0', + type: 'logarithmic' + }, { + id: 'yScale1', + type: 'logarithmic' + }] + } + } }); - scale.update(400, 400); - - expect(scale.getLabelForIndex(0, 2)).toBe(150); + expect(chart.scales.yScale1.getLabelForIndex(0, 2)).toBe(150); }); - it('Should get the correct pixel value for a point', function() { - var scaleID = 'myScale'; - - var mockData = { - datasets: [{ - xAxisID: scaleID, // for the horizontal scale - yAxisID: scaleID, - data: [10, 5, 1, 25, 78] - }] - }; - - var mockContext = window.createMockContext(); - var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic')); - var Constructor = Chart.scaleService.getScaleConstructor('logarithmic'); - var verticalScale = new Constructor({ - ctx: mockContext, - options: config, - chart: { - data: mockData + it('should get the correct pixel value for a point', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + xAxisID: 'xScale', // for the horizontal scale + yAxisID: 'yScale', + data: [10, 5, 1, 25, 78] + }], + labels: [] }, - id: scaleID + options: { + scales: { + yAxes: [{ + id: 'xScale', + type: 'logarithmic', + position: 'bottom' + }, { + id: 'yScale', + type: 'logarithmic' + }] + } + } }); - verticalScale.update(50, 100); - - // Fake out positioning of the scale service - verticalScale.left = 0; - verticalScale.top = 0; - verticalScale.right = 50; - verticalScale.bottom = 110; - verticalScale.paddingTop = 5; - verticalScale.paddingBottom = 5; - verticalScale.width = 50; - verticalScale.height = 110; - - expect(verticalScale.getPixelForValue(80, 0, 0)).toBe(5); // top + paddingTop - expect(verticalScale.getValueForPixel(5)).toBeCloseTo(80, 1e-4); - - expect(verticalScale.getPixelForValue(1, 0, 0)).toBe(105); // bottom - paddingBottom - expect(verticalScale.getValueForPixel(105)).toBeCloseTo(1, 1e-4); - - expect(verticalScale.getPixelForValue(10, 0, 0)).toBeCloseTo(52.4, 1e-4); // halfway - expect(verticalScale.getValueForPixel(52.4)).toBeCloseTo(10, 1e-4); - - expect(verticalScale.getPixelForValue(0, 0, 0)).toBe(5); // 0 is invalid. force it on top - - var horizontalConfig = Chart.helpers.clone(config); - horizontalConfig.position = 'bottom'; - var horizontalScale = new Constructor({ - ctx: mockContext, - options: horizontalConfig, - chart: { - data: mockData - }, - id: scaleID, - }); - - horizontalScale.update(100, 50); - - // Fake out positioning of the scale service - horizontalScale.left = 0; - horizontalScale.top = 0; - horizontalScale.right = 110; - horizontalScale.bottom = 50; - horizontalScale.paddingLeft = 5; - horizontalScale.paddingRight = 5; - horizontalScale.width = 110; - horizontalScale.height = 50; - - expect(horizontalScale.getPixelForValue(80, 0, 0)).toBe(105); // right - paddingRight - expect(horizontalScale.getValueForPixel(105)).toBeCloseTo(80, 1e-4); - - expect(horizontalScale.getPixelForValue(1, 0, 0)).toBe(5); // left + paddingLeft - expect(horizontalScale.getValueForPixel(5)).toBeCloseTo(1, 1e-4); - - expect(horizontalScale.getPixelForValue(10, 0, 0)).toBeCloseTo(57.5, 1e-4); // halfway - expect(horizontalScale.getValueForPixel(57.5)).toBeCloseTo(10, 1e-4); - - expect(horizontalScale.getPixelForValue(0, 0, 0)).toBe(5); // 0 is invalid, put it on the left. + var xScale = chart.scales.xScale; + expect(xScale.getPixelForValue(80, 0, 0)).toBeCloseToPixel(495); // right - paddingRight + expect(xScale.getPixelForValue( 1, 0, 0)).toBeCloseToPixel(48); // left + paddingLeft + expect(xScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(283); // halfway + expect(xScale.getPixelForValue( 0, 0, 0)).toBeCloseToPixel(48); // 0 is invalid, put it on the left. + ++ expect(xScale.getValueForPixel(495)).toBeCloseTo(80, 1e-4); ++ expect(xScale.getValueForPixel(48)).toBeCloseTo(1, 1e-4); ++ expect(xScale.getValueForPixel(283)).toBeCloseTo(10, 1e-4); ++ + var yScale = chart.scales.yScale; + expect(yScale.getPixelForValue(80, 0, 0)).toBeCloseToPixel(32); // top + paddingTop + expect(yScale.getPixelForValue( 1, 0, 0)).toBeCloseToPixel(456); // bottom - paddingBottom + expect(yScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(234); // halfway + expect(yScale.getPixelForValue( 0, 0, 0)).toBeCloseToPixel(32); // 0 is invalid. force it on top ++ ++ expect(yScale.getValueForPixel(32)).toBeCloseTo(80, 1e-4); ++ expect(yScale.getValueForPixel(456)).toBeCloseTo(1, 1e-4); ++ expect(yScale.getValueForPixel(234)).toBeCloseTo(10, 1e-4); }); }); diff --cc test/scale.time.tests.js index abee86e94,087bc0bbb..c63938f5e --- a/test/scale.time.tests.js +++ b/test/scale.time.tests.js @@@ -1,18 -1,41 +1,36 @@@ // Time scale tests describe('Time scale tests', function() { + var chartInstance; beforeEach(function() { + window.addDefaultMatchers(jasmine); ++ ++ // Need a time matcher for getValueFromPixel + jasmine.addMatchers({ - toEqualOneOf: function() { - return { - compare: function(actual, expecteds) { - var result = false; - for (var i = 0, l = expecteds.length; i < l; i++) { - if (actual === expecteds[i]) { - result = true; - break; - } - } - return { - pass: result - }; - } - }; - }, + toBeCloseToTime: function() { + return { + compare: function(actual, expected) { + var result = false; + + var diff = actual.diff(expected.value, expected.unit, true); - result = Math.abs(diff) < 0.25; ++ result = Math.abs(diff) < 0.3; + + return { + pass: result + }; + } + } + } + }); }); + afterEach(function() { + if (chartInstance) + { + releaseChart(chartInstance); + } + }); + it('Should load moment.js as a dependency', function() { expect(window.moment).not.toBe(undefined); }); @@@ -309,36 -321,79 +327,45 @@@ }); it('should get the correct pixel for a value', function() { - var scaleID = 'myScale'; - - var mockData = { - labels: ["2015-01-01T20:00:00", "2015-01-02T21:00:00", "2015-01-03T22:00:00", "2015-01-05T23:00:00", "2015-01-07T03:00", "2015-01-08T10:00", "2015-01-10T12:00"], // days - datasets: [{ - data: [], - }] - }; - - var mockContext = window.createMockContext(); - var Constructor = Chart.scaleService.getScaleConstructor('time'); - var scale = new Constructor({ - ctx: mockContext, - options: Chart.scaleService.getScaleDefaults('time'), // use default config for scale - chart: { - data: mockData + chartInstance = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + xAxisID: 'xScale0', + yAxisID: 'yScale0', + data: [] + }], + labels: ["2015-01-01T20:00:00", "2015-01-02T21:00:00", "2015-01-03T22:00:00", "2015-01-05T23:00:00", "2015-01-07T03:00", "2015-01-08T10:00", "2015-01-10T12:00"], // days }, - id: scaleID + options: { + scales: { + xAxes: [{ + id: 'xScale0', + type: 'time', + position: 'bottom' + }], + yAxes: [{ + id: 'yScale0', + type: 'linear', + position: 'left' + }] + } + } }); - scale.update(400, 50); - - expect(scale.width).toBe(400); - expect(scale.height).toBe(28); - scale.left = 0; - scale.right = 400; - scale.top = 10; - scale.bottom = 38; + var xScale = chartInstance.scales.xScale0; - expect(scale.getPixelForValue('', 0, 0)).toBe(81); + expect(xScale.getPixelForValue('', 0, 0)).toBeCloseToPixel(78); + expect(xScale.getPixelForValue('', 6, 0)).toBeCloseToPixel(466); + - // For some reason this passes in Chrome on Windows but fails elsewhere. Seems like a moment issue - /*expect(scale.getValueForPixel(81)).toBeCloseToTime({ - value: moment(mockData.labels[0]), ++ expect(xScale.getValueForPixel(78)).toBeCloseToTime({ ++ value: moment(chartInstance.data.labels[0]), + unit: 'hour' - });*/ - - expect(scale.getPixelForValue('', 6, 0)).toBe(323); - /*expect(scale.getValueForPixel(323)).toBeCloseToTime({ - value: moment(mockData.labels[6]), - unit: 'hour' - });*/ - - var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time')); - verticalScaleConfig.position = "left"; - - var verticalScale = new Constructor({ - ctx: mockContext, - options: verticalScaleConfig, - chart: { - data: mockData - }, - id: scaleID + }); - verticalScale.update(50, 400); - expect(verticalScale.width).toBe(50); - expect(verticalScale.height).toBe(400); - verticalScale.top = 0; - verticalScale.left = 0; - verticalScale.right = 50; - verticalScale.bottom = 400; - - expect(verticalScale.getPixelForValue('', 0, 0)).toBe(38); - /*expect(verticalScale.getValueForPixel(38)).toBeCloseToTime({ - value: moment(mockData.labels[0]), - unit: 'hour' - });*/ - - expect(verticalScale.getPixelForValue('', 6, 0)).toBe(375); - /*expect(verticalScale.getValueForPixel(375)).toBeCloseToTime({ - value: moment(mockData.labels[6]), ++ expect(xScale.getValueForPixel(466)).toBeCloseToTime({ ++ value: moment(chartInstance.data.labels[6]), + unit: 'hour' - });*/ ++ }); }); it('should get the correct label for a data value', function() {