Before labels can rotate, we need the appropriate left, right, top, & bottom attributes of the scale set with default values so that tick spacing can be determined. After ensuring that this happens, tests needed to be updated. Added unit testing for the scale service.

This commit is contained in:
Evert Timberg 2015-10-13 11:43:00 -04:00
parent 6001a1e4e7
commit e39298db3c
6 changed files with 354 additions and 89 deletions

View File

@ -103,9 +103,16 @@
setDimensions: function() {
// Set the unconstrained dimension before label rotation
if (this.isHorizontal()) {
// Reset position before calculating rotation
this.width = this.maxWidth;
this.left = 0;
this.right = this.width;
} else {
this.height = this.maxHeight;
// Reset position before calculating rotation
this.top = 0;
this.bottom = this.height
}
// Reset padding

View File

@ -262,13 +262,13 @@ describe('Bar controller tests', function() {
expect(bar1._xScale).toBe(chart.scales.firstXScaleID);
expect(bar1._yScale).toBe(chart.scales.firstYScaleID);
expect(bar1._model).toEqual({
x: 106.80000000000003,
x: 113.60000000000001,
y: 194,
label: 'label1',
datasetLabel: 'dataset2',
base: 194,
width: 12.240000000000002,
width: 13.680000000000001,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
@ -279,13 +279,13 @@ describe('Bar controller tests', function() {
expect(bar2._xScale).toBe(chart.scales.firstXScaleID);
expect(bar2._yScale).toBe(chart.scales.firstYScaleID);
expect(bar2._model).toEqual({
x: 140.8,
x: 151.60000000000002,
y: -15,
label: 'label2',
datasetLabel: 'dataset2',
base: 194,
width: 12.240000000000002,
width: 13.680000000000001,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,

View File

@ -270,13 +270,13 @@ describe('Line controller tests', function() {
tension: 0.1,
// Point
x: 63,
x: 71,
y: 62,
// Control points
controlPointPreviousX: 63,
controlPointPreviousX: 71,
controlPointPreviousY: 62,
controlPointNextX: 67.5,
controlPointNextX: 76,
controlPointNextY: 57.3,
});
@ -290,14 +290,14 @@ describe('Line controller tests', function() {
tension: 0.1,
// Point
x: 108,
x: 121,
y: 15,
// Control points
controlPointPreviousX: 105.27827106822767,
controlPointPreviousY: 12.125364948465183,
controlPointNextX: 114.17827106822767,
controlPointNextY: 21.52536494846518,
controlPointPreviousX: 117.82889384189087,
controlPointPreviousY: 12.04867347661131,
controlPointNextX: 127.92889384189088,
controlPointNextY: 21.44867347661131,
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
@ -310,14 +310,14 @@ describe('Line controller tests', function() {
tension: 0.1,
// Point
x: 152,
x: 172,
y: 156,
// Control points
controlPointPreviousX: 145.63719249781943,
controlPointPreviousY: 143.20289277651324,
controlPointNextX: 154.53719249781943,
controlPointNextY: 161.10289277651324,
controlPointPreviousX: 164.8815225337256,
controlPointPreviousY: 143.38408449046415,
controlPointNextX: 174.98152253372558,
controlPointNextY: 161.28408449046415,
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
@ -330,13 +330,13 @@ describe('Line controller tests', function() {
tension: 0.1,
// Point
x: 197,
x: 222,
y: 194,
// Control points
controlPointPreviousX: 192.5,
controlPointPreviousX: 217,
controlPointPreviousY: 190.2,
controlPointNextX: 197,
controlPointNextX: 222,
controlPointNextY: 194,
});
@ -390,13 +390,13 @@ describe('Line controller tests', function() {
tension: 0.2,
// Point
x: 63,
x: 71,
y: 62,
// Control points
controlPointPreviousX: 63,
controlPointPreviousX: 71,
controlPointPreviousY: 62,
controlPointNextX: 72,
controlPointNextX: 81,
controlPointNextY: 52.6,
});
@ -410,14 +410,14 @@ describe('Line controller tests', function() {
tension: 0.2,
// Point
x: 108,
x: 121,
y: 15,
// Control points
controlPointPreviousX: 102.55654213645535,
controlPointPreviousY: 9.250729896930364,
controlPointNextX: 120.35654213645535,
controlPointNextY: 28.050729896930367,
controlPointPreviousX: 114.65778768378175,
controlPointPreviousY: 9.097346953222619,
controlPointNextX: 134.85778768378177,
controlPointNextY: 27.897346953222623,
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
@ -430,14 +430,14 @@ describe('Line controller tests', function() {
tension: 0.2,
// Point
x: 152,
x: 172,
y: 156,
// Control points
controlPointPreviousX: 139.27438499563885,
controlPointPreviousY: 130.40578555302648,
controlPointNextX: 157.07438499563887,
controlPointNextY: 166.20578555302646,
controlPointPreviousX: 157.76304506745115,
controlPointPreviousY: 130.76816898092827,
controlPointNextX: 177.96304506745116,
controlPointNextY: 166.56816898092828,
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
@ -450,13 +450,13 @@ describe('Line controller tests', function() {
tension: 0.2,
// Point
x: 197,
x: 222,
y: 194,
// Control points
controlPointPreviousX: 188,
controlPointPreviousX: 212,
controlPointPreviousY: 186.4,
controlPointNextX: 197,
controlPointNextX: 222,
controlPointNextY: 194,
});
@ -516,13 +516,13 @@ describe('Line controller tests', function() {
tension: 0.15,
// Point
x: 63,
x: 71,
y: 62,
// Control points
controlPointPreviousX: 63,
controlPointPreviousX: 71,
controlPointPreviousY: 62,
controlPointNextX: 69.75,
controlPointNextX: 78.5,
controlPointNextY: 54.95,
});
});

View File

@ -0,0 +1,257 @@
// Tests of the scale service
describe('Test the scale service', function() {
it('should fit a simple chart with 2 scales', function() {
var chartInstance = {
scales: [],
};
var xScaleID = 'xScale';
var yScaleID = 'yScale';
var mockData = {
datasets: [{
yAxisID: yScaleID,
data: [10, 5, 0, 25, 78, -10]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var mockContext = window.createMockContext();
var xScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
var XConstructor = Chart.scaleService.getScaleConstructor('category');
var xScale = new XConstructor({
ctx: mockContext,
options: xScaleConfig,
data: mockData,
id: xScaleID
});
var yScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
var YConstructor = Chart.scaleService.getScaleConstructor('linear');
var yScale = new YConstructor({
ctx: mockContext,
options: yScaleConfig,
data: mockData,
id: yScaleID
});
chartInstance.scales.push(xScale);
chartInstance.scales.push(yScale);
var canvasWidth = 250;
var canvasHeight = 150;
Chart.scaleService.update(chartInstance, canvasWidth, canvasHeight);
expect(chartInstance.chartArea).toEqual({
left: 45,
right: 245,
top: 5,
bottom: 76.0423977855504,
});
// Is xScale at the right spot
expect(xScale.left).toBe(45);
expect(xScale.right).toBe(245);
expect(xScale.top).toBe(76.0423977855504);
expect(xScale.bottom).toBe(145);
expect(xScale.labelRotation).toBe(55);
// Is yScale at the right spot
expect(yScale.left).toBe(5);
expect(yScale.right).toBe(45);
expect(yScale.top).toBe(5);
expect(yScale.bottom).toBe(76.0423977855504);
});
it('should fit scales that are in the top and right positions', function() {
var chartInstance = {
scales: [],
};
var xScaleID = 'xScale';
var yScaleID = 'yScale';
var mockData = {
datasets: [{
yAxisID: yScaleID,
data: [10, 5, 0, 25, 78, -10]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var mockContext = window.createMockContext();
var xScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
xScaleConfig.position = 'top';
var XConstructor = Chart.scaleService.getScaleConstructor('category');
var xScale = new XConstructor({
ctx: mockContext,
options: xScaleConfig,
data: mockData,
id: xScaleID
});
var yScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
yScaleConfig.position = 'right';
var YConstructor = Chart.scaleService.getScaleConstructor('linear');
var yScale = new YConstructor({
ctx: mockContext,
options: yScaleConfig,
data: mockData,
id: yScaleID
});
chartInstance.scales.push(xScale);
chartInstance.scales.push(yScale);
var canvasWidth = 250;
var canvasHeight = 150;
Chart.scaleService.update(chartInstance, canvasWidth, canvasHeight);
expect(chartInstance.chartArea).toEqual({
left: 5,
right: 205,
top: 73.9576022144496,
bottom: 145,
});
// Is xScale at the right spot
expect(xScale.left).toBe(5);
expect(xScale.right).toBe(205);
expect(xScale.top).toBe(5);
expect(xScale.bottom).toBe(73.9576022144496);
expect(xScale.labelRotation).toBe(55);
// Is yScale at the right spot
expect(yScale.left).toBe(205);
expect(yScale.right).toBe(245);
expect(yScale.top).toBe(73.9576022144496);
expect(yScale.bottom).toBe(145);
});
it('should fit multiple axes in the same position', function() {
var chartInstance = {
scales: [],
};
var xScaleID = 'xScale';
var yScaleID1 = 'yScale1';
var yScaleID2 = 'yScale2';
var mockData = {
datasets: [{
yAxisID: yScaleID1,
data: [10, 5, 0, 25, 78, -10]
}, {
yAxisID: yScaleID2,
data: [-19, -20, 0, -99, -50, 0]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var mockContext = window.createMockContext();
var xScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
var XConstructor = Chart.scaleService.getScaleConstructor('category');
var xScale = new XConstructor({
ctx: mockContext,
options: xScaleConfig,
data: mockData,
id: xScaleID
});
var yScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
var YConstructor = Chart.scaleService.getScaleConstructor('linear');
var yScale1 = new YConstructor({
ctx: mockContext,
options: yScaleConfig,
data: mockData,
id: yScaleID1
});
var yScale2 = new YConstructor({
ctx: mockContext,
options: yScaleConfig,
data: mockData,
id: yScaleID2
});
chartInstance.scales.push(xScale);
chartInstance.scales.push(yScale1);
chartInstance.scales.push(yScale2);
var canvasWidth = 250;
var canvasHeight = 150;
Chart.scaleService.update(chartInstance, canvasWidth, canvasHeight);
expect(chartInstance.chartArea).toEqual({
left: 95,
right: 245,
top: 5,
bottom: 70.01536896070459,
});
// Is xScale at the right spot
expect(xScale.left).toBe(95);
expect(xScale.right).toBe(245);
expect(xScale.top).toBe(70.01536896070459);
expect(xScale.bottom).toBe(145);
// Are yScales at the right spot
expect(yScale1.left).toBe(5);
expect(yScale1.right).toBe(45);
expect(yScale1.top).toBe(5);
expect(yScale1.bottom).toBe(70.01536896070459);
expect(yScale2.left).toBe(45);
expect(yScale2.right).toBe(95);
expect(yScale2.top).toBe(5);
expect(yScale2.bottom).toBe(70.01536896070459);
});
// This is an oddball case. What happens is, when the scales are fit the first time they must fit within the assigned size. In this case,
// the labels on the xScale need to rotate to fit. However, when the scales are fit again after the width of the left axis is determined,
// the labels do not need to rotate. Previously, the chart was too small because the chartArea did not expand to take up the space freed up
// due to the lack of label rotation
it('should fit scales that overlap the chart area', function() {
var chartInstance = {
scales: [],
};
var scaleID = 'scaleID';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78, -10]
}, {
yAxisID: scaleID,
data: [-19, -20, 0, -99, -50, 0]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var mockContext = window.createMockContext();
var scaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
var ScaleConstructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scale = new ScaleConstructor({
ctx: mockContext,
options: scaleConfig,
data: mockData,
id: scaleID
});
chartInstance.scales.push(scale);
var canvasWidth = 300;
var canvasHeight = 350;
Chart.scaleService.update(chartInstance, canvasWidth, canvasHeight);
expect(chartInstance.chartArea).toEqual({
left: 5,
right: 295,
top: 5,
bottom: 345,
});
expect(scale.left).toBe(5);
expect(scale.right).toBe(295);
expect(scale.top).toBe(5);
expect(scale.bottom).toBe(345);
expect(scale.width).toBe(290);
expect(scale.height).toBe(340)
});
});

View File

@ -94,9 +94,9 @@ describe('Category scale tests', function() {
id: scaleID
});
var minSize = scale.update(200, 100);
var minSize = scale.update(600, 100);
expect(scale.width).toBe(200);
expect(scale.width).toBe(600);
expect(scale.height).toBe(28);
expect(scale.paddingTop).toBe(0);
expect(scale.paddingBottom).toBe(0);
@ -105,28 +105,28 @@ describe('Category scale tests', function() {
expect(scale.labelRotation).toBe(0);
expect(minSize).toEqual({
width: 200,
width: 600,
height: 28,
});
scale.left = 5;
scale.top = 5;
scale.right = 205;
scale.right = 605;
scale.bottom = 33;
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(33);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(45);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(85);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(132);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(145);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(452);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(505);
config.gridLines.offsetGridLines = false;
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(33);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(33);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(157);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(157);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(557);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(557);
});
it ('should get the correct pixel for a value when vertical', function() {

View File

@ -578,46 +578,47 @@ describe('Linear Scale', function() {
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
config.position = "bottom";
var Constructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScale = new Constructor({
var horizontalScale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID
});
var minSize = verticalScale.update(100, 300);
var minSize = horizontalScale.update(200, 300);
expect(minSize).toEqual({
width: 100,
width: 200,
height: 28,
});
expect(verticalScale.width).toBe(100);
expect(verticalScale.height).toBe(28);
expect(verticalScale.paddingTop).toBe(0);
expect(verticalScale.paddingBottom).toBe(0);
expect(verticalScale.paddingLeft).toBe(18);
expect(verticalScale.paddingRight).toBe(13);
expect(horizontalScale.width).toBe(200);
expect(horizontalScale.height).toBe(28);
expect(horizontalScale.paddingTop).toBe(0);
expect(horizontalScale.paddingBottom).toBe(0);
expect(horizontalScale.paddingLeft).toBe(13);
expect(horizontalScale.paddingRight).toBe(8);
expect(horizontalScale.labelRotation).toBe(0);
// Refit with margins to see the padding go away
minSize = verticalScale.update(100, 28, {
minSize = horizontalScale.update(200, 28, {
left: 10,
right: 6,
top: 15,
bottom: 3
});
expect(minSize).toEqual({
width: 100,
width: 200,
height: 28,
});
expect(verticalScale.paddingTop).toBe(0);
expect(verticalScale.paddingBottom).toBe(0);
expect(verticalScale.paddingLeft).toBe(8);
expect(verticalScale.paddingRight).toBe(7);
expect(horizontalScale.paddingTop).toBe(0);
expect(horizontalScale.paddingBottom).toBe(0);
expect(horizontalScale.paddingLeft).toBe(3);
expect(horizontalScale.paddingRight).toBe(2);
// Extra size when scale label showing
config.scaleLabel.show = true;
minSize = verticalScale.update(100, 300);
minSize = horizontalScale.update(200, 300);
expect(minSize).toEqual({
width: 100,
width: 200,
height: 46,
});
});
@ -644,8 +645,8 @@ describe('Linear Scale', function() {
id: scaleID
});
var minSize = horizontalScale.update(100, 300);
minSize = horizontalScale.update(100, 28, {
var minSize = horizontalScale.update(200, 300);
minSize = horizontalScale.update(200, 28, {
left: 10,
right: 6,
top: 15,
@ -654,12 +655,12 @@ describe('Linear Scale', function() {
horizontalScale.left = 0;
horizontalScale.right = minSize.width;
horizontalScale.top = 0;
horizontalScale.bottom = minSize.height;
horizontalScale.top = 100;
horizontalScale.bottom = 100 + minSize.height;
var chartArea = {
top: 100,
bottom: 0,
top: 0,
bottom: 100,
left: 0,
right: minSize.width
};
@ -680,16 +681,16 @@ describe('Linear Scale', function() {
"args": []
}, {
"name": "moveTo",
"args": [8.5, 0]
"args": [3.5, 100]
}, {
"name": "lineTo",
"args": [8.5, 10]
"args": [3.5, 110]
}, {
"name": "moveTo",
"args": [8.5, 100]
"args": [3.5, 0]
}, {
"name": "lineTo",
"args": [8.5, 0]
"args": [3.5, 100]
}, {
"name": "stroke",
"args": []
@ -698,13 +699,13 @@ describe('Linear Scale', function() {
"args": []
}, {
"name": "translate",
"args": [8, 10]
"args": [3, 110]
}, {
"name": "rotate",
"args": [-0]
}, {
"name": "fillText",
"args": ["-10", 0, 0]
"args": ["-5", 0, 0]
}, {
"name": "restore",
"args": []
@ -719,16 +720,16 @@ describe('Linear Scale', function() {
"args": []
}, {
"name": "moveTo",
"args": [51.5, 0]
"args": [101.5, 100]
}, {
"name": "lineTo",
"args": [51.5, 10]
"args": [101.5, 110]
}, {
"name": "moveTo",
"args": [51.5, 100]
"args": [101.5, 0]
}, {
"name": "lineTo",
"args": [51.5, 0]
"args": [101.5, 100]
}, {
"name": "stroke",
"args": []
@ -737,7 +738,7 @@ describe('Linear Scale', function() {
"args": []
}, {
"name": "translate",
"args": [51, 10]
"args": [101, 110]
}, {
"name": "rotate",
"args": [-0]
@ -758,16 +759,16 @@ describe('Linear Scale', function() {
"args": []
}, {
"name": "moveTo",
"args": [93.5, 0]
"args": [198.5, 100]
}, {
"name": "lineTo",
"args": [93.5, 10]
"args": [198.5, 110]
}, {
"name": "moveTo",
"args": [93.5, 100]
"args": [198.5, 0]
}, {
"name": "lineTo",
"args": [93.5, 0]
"args": [198.5, 100]
}, {
"name": "stroke",
"args": []
@ -776,13 +777,13 @@ describe('Linear Scale', function() {
"args": []
}, {
"name": "translate",
"args": [93, 10]
"args": [198, 110]
}, {
"name": "rotate",
"args": [-0]
}, {
"name": "fillText",
"args": ["10", 0, 0]
"args": ["5", 0, 0]
}, {
"name": "restore",
"args": []
@ -840,7 +841,7 @@ describe('Linear Scale', function() {
"args": []
}, {
"name": "fillText",
"args": ["myLabel", 50, 22]
"args": ["myLabel", 100, 122]
}]);
// Turn off display