mirror of
https://gitlab.com/JKANetwork/CheckServer.git
synced 2026-02-20 12:11:34 +01:00
Start again
This commit is contained in:
440
vendors/Chart.js/test/controller.bar.tests.js
vendored
Normal file
440
vendors/Chart.js/test/controller.bar.tests.js
vendored
Normal file
@@ -0,0 +1,440 @@
|
||||
// Test the bar controller
|
||||
describe('Bar controller tests', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.releaseAllCharts();
|
||||
});
|
||||
|
||||
it('should be constructed', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [
|
||||
{ data: [] },
|
||||
{ data: [] }
|
||||
],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
expect(meta.type).toEqual('bar');
|
||||
expect(meta.data).toEqual([]);
|
||||
expect(meta.hidden).toBe(null);
|
||||
expect(meta.controller).not.toBe(undefined);
|
||||
expect(meta.controller.index).toBe(1);
|
||||
expect(meta.xAxisID).not.toBe(null);
|
||||
expect(meta.yAxisID).not.toBe(null);
|
||||
|
||||
meta.controller.updateIndex(0);
|
||||
expect(meta.controller.index).toBe(0);
|
||||
});
|
||||
|
||||
it('should use the first scale IDs if the dataset does not specify them', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [
|
||||
{ data: [] },
|
||||
{ data: [] }
|
||||
],
|
||||
labels: []
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'firstXScaleID'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'firstYScaleID'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
expect(meta.xAxisID).toBe('firstXScaleID');
|
||||
expect(meta.yAxisID).toBe('firstYScaleID');
|
||||
});
|
||||
|
||||
it('should correctly count the number of bar datasets', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [
|
||||
{ data: [], type: 'line' },
|
||||
{ data: [], hidden: true },
|
||||
{ data: [] },
|
||||
{ data: [] }
|
||||
],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
expect(meta.controller.getBarCount()).toBe(2);
|
||||
});
|
||||
|
||||
it('should correctly get the bar index accounting for hidden datasets', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [
|
||||
{ data: [] },
|
||||
{ data: [], hidden: true },
|
||||
{ data: [], type: 'line' },
|
||||
{ data: [] }
|
||||
],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
expect(meta.controller.getBarIndex(0)).toBe(0);
|
||||
expect(meta.controller.getBarIndex(3)).toBe(1);
|
||||
});
|
||||
|
||||
it('should create rectangle elements for each data item during initialization', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [
|
||||
{ data: [] },
|
||||
{ data: [10, 15, 0, -4] }
|
||||
],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
expect(meta.data.length).toBe(4); // 4 rectangles created
|
||||
expect(meta.data[0] instanceof Chart.elements.Rectangle).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Rectangle).toBe(true);
|
||||
expect(meta.data[2] instanceof Chart.elements.Rectangle).toBe(true);
|
||||
expect(meta.data[3] instanceof Chart.elements.Rectangle).toBe(true);
|
||||
});
|
||||
|
||||
it('should update elements when modifying data', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [1, 2],
|
||||
label: 'dataset1'
|
||||
}, {
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2',
|
||||
borderColor: 'blue'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
elements: {
|
||||
rectangle: {
|
||||
backgroundColor: 'red',
|
||||
borderSkipped: 'top',
|
||||
borderColor: 'green',
|
||||
borderWidth: 2,
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'firstXScaleID',
|
||||
type: 'category'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'firstYScaleID',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
expect(meta.data.length).toBe(4);
|
||||
|
||||
chart.data.datasets[1].data = [1, 2]; // remove 2 items
|
||||
chart.data.datasets[1].borderWidth = 1;
|
||||
chart.update();
|
||||
|
||||
expect(meta.data.length).toBe(2);
|
||||
|
||||
[ { x: 122, y: 484 },
|
||||
{ x: 234, y: 32 }
|
||||
].forEach(function(expected, i) {
|
||||
expect(meta.data[i]._datasetIndex).toBe(1);
|
||||
expect(meta.data[i]._index).toBe(i);
|
||||
expect(meta.data[i]._xScale).toBe(chart.scales.firstXScaleID);
|
||||
expect(meta.data[i]._yScale).toBe(chart.scales.firstYScaleID);
|
||||
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
|
||||
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
|
||||
expect(meta.data[i]._model.base).toBeCloseToPixel(484);
|
||||
expect(meta.data[i]._model.width).toBeCloseToPixel(40);
|
||||
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
|
||||
datasetLabel: chart.config.data.datasets[1].label,
|
||||
label: chart.config.data.labels[i],
|
||||
backgroundColor: 'red',
|
||||
borderSkipped: 'top',
|
||||
borderColor: 'blue',
|
||||
borderWidth: 1
|
||||
}));
|
||||
});
|
||||
|
||||
chart.data.datasets[1].data = [1, 2, 3]; // add 1 items
|
||||
chart.update();
|
||||
|
||||
expect(meta.data.length).toBe(3); // should add a new meta data item
|
||||
});
|
||||
|
||||
it('should get the correct bar points when datasets of different types exist', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [1, 2],
|
||||
label: 'dataset1'
|
||||
}, {
|
||||
type: 'line',
|
||||
data: [4, 6],
|
||||
label: 'dataset2'
|
||||
}, {
|
||||
data: [8, 10],
|
||||
label: 'dataset3'
|
||||
}],
|
||||
labels: ['label1', 'label2']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
type: 'category'
|
||||
}],
|
||||
yAxes: [{
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(2);
|
||||
expect(meta.data.length).toBe(2);
|
||||
|
||||
var bar1 = meta.data[0];
|
||||
var bar2 = meta.data[1];
|
||||
|
||||
expect(bar1._model.x).toBeCloseToPixel(194);
|
||||
expect(bar1._model.y).toBeCloseToPixel(132);
|
||||
expect(bar2._model.x).toBeCloseToPixel(424);
|
||||
expect(bar2._model.y).toBeCloseToPixel(32);
|
||||
});
|
||||
|
||||
it('should update elements when the scales are stacked', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, -10, 10, -10],
|
||||
label: 'dataset1'
|
||||
}, {
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
type: 'category',
|
||||
stacked: true
|
||||
}],
|
||||
yAxes: [{
|
||||
type: 'linear',
|
||||
stacked: true
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta0 = chart.getDatasetMeta(0);
|
||||
|
||||
[ { b: 290, w: 91, x: 95, y: 161 },
|
||||
{ b: 290, w: 91, x: 209, y: 419 },
|
||||
{ b: 290, w: 91, x: 322, y: 161 },
|
||||
{ b: 290, w: 91, x: 436, y: 419 }
|
||||
].forEach(function(values, i) {
|
||||
expect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);
|
||||
expect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);
|
||||
expect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);
|
||||
expect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);
|
||||
});
|
||||
|
||||
var meta1 = chart.getDatasetMeta(1);
|
||||
|
||||
[ { b: 161, w: 91, x: 95, y: 32 },
|
||||
{ b: 290, w: 91, x: 209, y: 97 },
|
||||
{ b: 161, w: 91, x: 322, y: 161 },
|
||||
{ b: 419, w: 91, x: 436, y: 471 }
|
||||
].forEach(function(values, i) {
|
||||
expect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);
|
||||
expect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);
|
||||
expect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);
|
||||
expect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);
|
||||
});
|
||||
});
|
||||
|
||||
it('should draw all bars', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [],
|
||||
}, {
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
|
||||
spyOn(meta.data[0], 'draw');
|
||||
spyOn(meta.data[1], 'draw');
|
||||
spyOn(meta.data[2], 'draw');
|
||||
spyOn(meta.data[3], 'draw');
|
||||
|
||||
chart.update();
|
||||
|
||||
expect(meta.data[0].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[1].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[2].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[3].draw.calls.count()).toBe(1);
|
||||
});
|
||||
|
||||
it('should set hover styles on rectangles', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [],
|
||||
}, {
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
elements: {
|
||||
rectangle: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
borderWidth: 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
var bar = meta.data[0];
|
||||
|
||||
meta.controller.setHoverStyle(bar);
|
||||
expect(bar._model.backgroundColor).toBe('rgb(230, 0, 0)');
|
||||
expect(bar._model.borderColor).toBe('rgb(0, 0, 230)');
|
||||
expect(bar._model.borderWidth).toBe(2);
|
||||
|
||||
// Set a dataset style
|
||||
chart.data.datasets[1].hoverBackgroundColor = 'rgb(128, 128, 128)';
|
||||
chart.data.datasets[1].hoverBorderColor = 'rgb(0, 0, 0)';
|
||||
chart.data.datasets[1].hoverBorderWidth = 5;
|
||||
|
||||
meta.controller.setHoverStyle(bar);
|
||||
expect(bar._model.backgroundColor).toBe('rgb(128, 128, 128)');
|
||||
expect(bar._model.borderColor).toBe('rgb(0, 0, 0)');
|
||||
expect(bar._model.borderWidth).toBe(5);
|
||||
|
||||
// Should work with array styles so that we can set per bar
|
||||
chart.data.datasets[1].hoverBackgroundColor = ['rgb(255, 255, 255)', 'rgb(128, 128, 128)'];
|
||||
chart.data.datasets[1].hoverBorderColor = ['rgb(9, 9, 9)', 'rgb(0, 0, 0)'];
|
||||
chart.data.datasets[1].hoverBorderWidth = [2.5, 5];
|
||||
|
||||
meta.controller.setHoverStyle(bar);
|
||||
expect(bar._model.backgroundColor).toBe('rgb(255, 255, 255)');
|
||||
expect(bar._model.borderColor).toBe('rgb(9, 9, 9)');
|
||||
expect(bar._model.borderWidth).toBe(2.5);
|
||||
|
||||
// Should allow a custom style
|
||||
bar.custom = {
|
||||
hoverBackgroundColor: 'rgb(255, 0, 0)',
|
||||
hoverBorderColor: 'rgb(0, 255, 0)',
|
||||
hoverBorderWidth: 1.5
|
||||
};
|
||||
|
||||
meta.controller.setHoverStyle(bar);
|
||||
expect(bar._model.backgroundColor).toBe('rgb(255, 0, 0)');
|
||||
expect(bar._model.borderColor).toBe('rgb(0, 255, 0)');
|
||||
expect(bar._model.borderWidth).toBe(1.5);
|
||||
});
|
||||
|
||||
it('should remove a hover style from a bar', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [],
|
||||
}, {
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
elements: {
|
||||
rectangle: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
borderWidth: 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
var bar = meta.data[0];
|
||||
|
||||
// Change default
|
||||
chart.options.elements.rectangle.backgroundColor = 'rgb(128, 128, 128)';
|
||||
chart.options.elements.rectangle.borderColor = 'rgb(15, 15, 15)';
|
||||
chart.options.elements.rectangle.borderWidth = 3.14;
|
||||
|
||||
// Remove to defaults
|
||||
meta.controller.removeHoverStyle(bar);
|
||||
expect(bar._model.backgroundColor).toBe('rgb(128, 128, 128)');
|
||||
expect(bar._model.borderColor).toBe('rgb(15, 15, 15)');
|
||||
expect(bar._model.borderWidth).toBe(3.14);
|
||||
|
||||
// Should work with array styles so that we can set per bar
|
||||
chart.data.datasets[1].backgroundColor = ['rgb(255, 255, 255)', 'rgb(128, 128, 128)'];
|
||||
chart.data.datasets[1].borderColor = ['rgb(9, 9, 9)', 'rgb(0, 0, 0)'];
|
||||
chart.data.datasets[1].borderWidth = [2.5, 5];
|
||||
|
||||
meta.controller.removeHoverStyle(bar);
|
||||
expect(bar._model.backgroundColor).toBe('rgb(255, 255, 255)');
|
||||
expect(bar._model.borderColor).toBe('rgb(9, 9, 9)');
|
||||
expect(bar._model.borderWidth).toBe(2.5);
|
||||
|
||||
// Should allow a custom style
|
||||
bar.custom = {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
borderWidth: 1.5
|
||||
};
|
||||
|
||||
meta.controller.removeHoverStyle(bar);
|
||||
expect(bar._model.backgroundColor).toBe('rgb(255, 0, 0)');
|
||||
expect(bar._model.borderColor).toBe('rgb(0, 255, 0)');
|
||||
expect(bar._model.borderWidth).toBe(1.5);
|
||||
});
|
||||
});
|
||||
440
vendors/Chart.js/test/controller.bubble.tests.js
vendored
Normal file
440
vendors/Chart.js/test/controller.bubble.tests.js
vendored
Normal file
@@ -0,0 +1,440 @@
|
||||
// Test the bubble controller
|
||||
describe('Bubble controller tests', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.releaseAllCharts();
|
||||
});
|
||||
|
||||
it('should be constructed', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bubble',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: []
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta.type).toBe('bubble');
|
||||
expect(meta.controller).not.toBe(undefined);
|
||||
expect(meta.controller.index).toBe(0);
|
||||
expect(meta.data).toEqual([]);
|
||||
|
||||
meta.controller.updateIndex(1);
|
||||
expect(meta.controller.index).toBe(1);
|
||||
});
|
||||
|
||||
it('should use the first scale IDs if the dataset does not specify them', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bubble',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: []
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'firstXScaleID'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'firstYScaleID'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
expect(meta.xAxisID).toBe('firstXScaleID');
|
||||
expect(meta.yAxisID).toBe('firstYScaleID');
|
||||
});
|
||||
|
||||
it('should create point elements for each data item during initialization', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bubble',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4]
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
expect(meta.data.length).toBe(4); // 4 points created
|
||||
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
|
||||
});
|
||||
|
||||
it('should draw all elements', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bubble',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4]
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
animation: false,
|
||||
showLines: true
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
spyOn(meta.data[0], 'draw');
|
||||
spyOn(meta.data[1], 'draw');
|
||||
spyOn(meta.data[2], 'draw');
|
||||
spyOn(meta.data[3], 'draw');
|
||||
|
||||
chart.update();
|
||||
|
||||
expect(meta.data[0].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[1].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[2].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[3].draw.calls.count()).toBe(1);
|
||||
});
|
||||
|
||||
it('should update elements when modifying style', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bubble',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [{
|
||||
x: 10,
|
||||
y: 10,
|
||||
r: 5
|
||||
}, {
|
||||
x: -15,
|
||||
y: -10,
|
||||
r: 1
|
||||
}, {
|
||||
x: 0,
|
||||
y: -9,
|
||||
r: 2
|
||||
}, {
|
||||
x: -4,
|
||||
y: 10,
|
||||
r: 1
|
||||
}]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
type: 'category'
|
||||
}],
|
||||
yAxes: [{
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
[ { r: 5, x: 38, y: 32 },
|
||||
{ r: 1, x: 189, y: 484 },
|
||||
{ r: 2, x: 341, y: 461 },
|
||||
{ r: 1, x: 492, y: 32 }
|
||||
].forEach(function(expected, i) {
|
||||
expect(meta.data[i]._model.radius).toBe(expected.r);
|
||||
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
|
||||
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
|
||||
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: Chart.defaults.global.defaultColor,
|
||||
borderColor: Chart.defaults.global.defaultColor,
|
||||
borderWidth: 1,
|
||||
hitRadius: 1,
|
||||
skip: false
|
||||
}));
|
||||
});
|
||||
|
||||
// Use dataset level styles for lines & points
|
||||
chart.data.datasets[0].backgroundColor = 'rgb(98, 98, 98)';
|
||||
chart.data.datasets[0].borderColor = 'rgb(8, 8, 8)';
|
||||
chart.data.datasets[0].borderWidth = 0.55;
|
||||
|
||||
// point styles
|
||||
chart.data.datasets[0].radius = 22;
|
||||
chart.data.datasets[0].hitRadius = 3.3;
|
||||
|
||||
chart.update();
|
||||
|
||||
for (var i=0; i<4; ++i) {
|
||||
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: 'rgb(98, 98, 98)',
|
||||
borderColor: 'rgb(8, 8, 8)',
|
||||
borderWidth: 0.55,
|
||||
hitRadius: 3.3,
|
||||
skip: false
|
||||
}));
|
||||
}
|
||||
|
||||
// point styles
|
||||
meta.data[0].custom = {
|
||||
radius: 2.2,
|
||||
backgroundColor: 'rgb(0, 1, 3)',
|
||||
borderColor: 'rgb(4, 6, 8)',
|
||||
borderWidth: 0.787,
|
||||
tension: 0.15,
|
||||
hitRadius: 5,
|
||||
skip: true
|
||||
};
|
||||
|
||||
chart.update();
|
||||
|
||||
expect(meta.data[0]._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: 'rgb(0, 1, 3)',
|
||||
borderColor: 'rgb(4, 6, 8)',
|
||||
borderWidth: 0.787,
|
||||
hitRadius: 5,
|
||||
skip: true
|
||||
}));
|
||||
});
|
||||
|
||||
it('should handle number of data point changes in update', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bubble',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [{
|
||||
x: 10,
|
||||
y: 10,
|
||||
r: 5
|
||||
}, {
|
||||
x: -15,
|
||||
y: -10,
|
||||
r: 1
|
||||
}, {
|
||||
x: 0,
|
||||
y: -9,
|
||||
r: 2
|
||||
}, {
|
||||
x: -4,
|
||||
y: 10,
|
||||
r: 1
|
||||
}]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
expect(meta.data.length).toBe(4);
|
||||
|
||||
chart.data.datasets[0].data = [{
|
||||
x: 1,
|
||||
y: 1,
|
||||
r: 10
|
||||
}, {
|
||||
x: 10,
|
||||
y: 5,
|
||||
r: 2
|
||||
}]; // remove 2 items
|
||||
|
||||
chart.update();
|
||||
|
||||
expect(meta.data.length).toBe(2);
|
||||
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
|
||||
|
||||
chart.data.datasets[0].data = [{
|
||||
x: 10,
|
||||
y: 10,
|
||||
r: 5
|
||||
}, {
|
||||
x: -15,
|
||||
y: -10,
|
||||
r: 1
|
||||
}, {
|
||||
x: 0,
|
||||
y: -9,
|
||||
r: 2
|
||||
}, {
|
||||
x: -4,
|
||||
y: 10,
|
||||
r: 1
|
||||
}, {
|
||||
x: -5,
|
||||
y: 0,
|
||||
r: 3
|
||||
}]; // add 3 items
|
||||
|
||||
chart.update();
|
||||
|
||||
expect(meta.data.length).toBe(5);
|
||||
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[4] instanceof Chart.elements.Point).toBe(true);
|
||||
});
|
||||
|
||||
it('should set hover styles', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bubble',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [{
|
||||
x: 10,
|
||||
y: 10,
|
||||
r: 5
|
||||
}, {
|
||||
x: -15,
|
||||
y: -10,
|
||||
r: 1
|
||||
}, {
|
||||
x: 0,
|
||||
y: -9,
|
||||
r: 2
|
||||
}, {
|
||||
x: -4,
|
||||
y: 10,
|
||||
r: 1
|
||||
}]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
elements: {
|
||||
point: {
|
||||
backgroundColor: 'rgb(255, 255, 0)',
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgb(255, 255, 255)',
|
||||
hitRadius: 1,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 1,
|
||||
radius: 3
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
var point = meta.data[0];
|
||||
|
||||
meta.controller.setHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');
|
||||
expect(point._model.borderColor).toBe('rgb(230, 230, 230)');
|
||||
expect(point._model.borderWidth).toBe(1);
|
||||
expect(point._model.radius).toBe(9);
|
||||
|
||||
// Can set hover style per dataset
|
||||
chart.data.datasets[0].hoverRadius = 3.3;
|
||||
chart.data.datasets[0].hoverBackgroundColor = 'rgb(77, 79, 81)';
|
||||
chart.data.datasets[0].hoverBorderColor = 'rgb(123, 125, 127)';
|
||||
chart.data.datasets[0].hoverBorderWidth = 2.1;
|
||||
|
||||
meta.controller.setHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
|
||||
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
|
||||
expect(point._model.borderWidth).toBe(2.1);
|
||||
expect(point._model.radius).toBe(8.3);
|
||||
|
||||
// Custom style
|
||||
point.custom = {
|
||||
hoverRadius: 4.4,
|
||||
hoverBorderWidth: 5.5,
|
||||
hoverBackgroundColor: 'rgb(0, 0, 0)',
|
||||
hoverBorderColor: 'rgb(10, 10, 10)'
|
||||
};
|
||||
|
||||
meta.controller.setHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
|
||||
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
|
||||
expect(point._model.borderWidth).toBe(5.5);
|
||||
expect(point._model.radius).toBe(4.4);
|
||||
});
|
||||
|
||||
it('should remove hover styles', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bubble',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [{
|
||||
x: 10,
|
||||
y: 10,
|
||||
r: 5
|
||||
}, {
|
||||
x: -15,
|
||||
y: -10,
|
||||
r: 1
|
||||
}, {
|
||||
x: 0,
|
||||
y: -9,
|
||||
r: 2
|
||||
}, {
|
||||
x: -4,
|
||||
y: 10,
|
||||
r: 1
|
||||
}]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
elements: {
|
||||
point: {
|
||||
backgroundColor: 'rgb(255, 255, 0)',
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgb(255, 255, 255)',
|
||||
hitRadius: 1,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 1,
|
||||
radius: 3
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
var point = meta.data[0];
|
||||
|
||||
chart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';
|
||||
chart.options.elements.point.borderColor = 'rgb(50, 51, 52)';
|
||||
chart.options.elements.point.borderWidth = 10.1;
|
||||
chart.options.elements.point.radius = 1.01;
|
||||
|
||||
meta.controller.removeHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');
|
||||
expect(point._model.borderColor).toBe('rgb(50, 51, 52)');
|
||||
expect(point._model.borderWidth).toBe(10.1);
|
||||
expect(point._model.radius).toBe(5);
|
||||
|
||||
// Can set hover style per dataset
|
||||
chart.data.datasets[0].radius = 3.3;
|
||||
chart.data.datasets[0].backgroundColor = 'rgb(77, 79, 81)';
|
||||
chart.data.datasets[0].borderColor = 'rgb(123, 125, 127)';
|
||||
chart.data.datasets[0].borderWidth = 2.1;
|
||||
|
||||
meta.controller.removeHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
|
||||
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
|
||||
expect(point._model.borderWidth).toBe(2.1);
|
||||
expect(point._model.radius).toBe(5);
|
||||
|
||||
// Custom style
|
||||
point.custom = {
|
||||
radius: 4.4,
|
||||
borderWidth: 5.5,
|
||||
backgroundColor: 'rgb(0, 0, 0)',
|
||||
borderColor: 'rgb(10, 10, 10)'
|
||||
};
|
||||
|
||||
meta.controller.removeHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
|
||||
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
|
||||
expect(point._model.borderWidth).toBe(5.5);
|
||||
expect(point._model.radius).toBe(4.4);
|
||||
});
|
||||
});
|
||||
348
vendors/Chart.js/test/controller.doughnut.tests.js
vendored
Normal file
348
vendors/Chart.js/test/controller.doughnut.tests.js
vendored
Normal file
@@ -0,0 +1,348 @@
|
||||
// Test the bar controller
|
||||
describe('Doughnut controller tests', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.releaseAllCharts();
|
||||
});
|
||||
|
||||
it('should be constructed', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: []
|
||||
}],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta.type).toBe('doughnut');
|
||||
expect(meta.controller).not.toBe(undefined);
|
||||
expect(meta.controller.index).toBe(0);
|
||||
expect(meta.data).toEqual([]);
|
||||
|
||||
meta.controller.updateIndex(1);
|
||||
expect(meta.controller.index).toBe(1);
|
||||
});
|
||||
|
||||
it('should create arc elements for each data item during initialization', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, 4]
|
||||
}],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta.data.length).toBe(4); // 4 rectangles created
|
||||
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);
|
||||
});
|
||||
|
||||
it ('should reset and update elements', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [1, 2, 3, 4],
|
||||
hidden: true
|
||||
}, {
|
||||
data: [5, 6, 0, 7]
|
||||
}, {
|
||||
data: [8, 9, 10, 11]
|
||||
}],
|
||||
labels: ['label0', 'label1', 'label2', 'label3']
|
||||
},
|
||||
options: {
|
||||
animation: {
|
||||
animateRotate: true,
|
||||
animateScale: false
|
||||
},
|
||||
cutoutPercentage: 50,
|
||||
rotation: Math.PI * -0.5,
|
||||
circumference: Math.PI * 2.0,
|
||||
elements: {
|
||||
arc: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
borderWidth: 2,
|
||||
hoverBackgroundColor: 'rgb(255, 255, 255)'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
|
||||
meta.controller.reset(); // reset first
|
||||
|
||||
expect(meta.data.length).toBe(4);
|
||||
|
||||
[ { c: 0 },
|
||||
{ c: 0 },
|
||||
{ c: 0, },
|
||||
{ c: 0 }
|
||||
].forEach(function(expected, i) {
|
||||
expect(meta.data[i]._model.x).toBeCloseToPixel(256);
|
||||
expect(meta.data[i]._model.y).toBeCloseToPixel(272);
|
||||
expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(239);
|
||||
expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(179);
|
||||
expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
|
||||
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
|
||||
startAngle: Math.PI * -0.5,
|
||||
endAngle: Math.PI * -0.5,
|
||||
label: chart.data.labels[i],
|
||||
hoverBackgroundColor: 'rgb(255, 255, 255)',
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
borderWidth: 2
|
||||
}));
|
||||
})
|
||||
|
||||
chart.update();
|
||||
|
||||
[ { c: 1.7453292519, s: -1.5707963267, e: 0.1745329251 },
|
||||
{ c: 2.0943951023, s: 0.1745329251, e: 2.2689280275 },
|
||||
{ c: 0, s: 2.2689280275, e: 2.2689280275 },
|
||||
{ c: 2.4434609527, s: 2.2689280275, e: 4.7123889803 }
|
||||
].forEach(function(expected, i) {
|
||||
expect(meta.data[i]._model.x).toBeCloseToPixel(256);
|
||||
expect(meta.data[i]._model.y).toBeCloseToPixel(272);
|
||||
expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(239);
|
||||
expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(179);
|
||||
expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
|
||||
expect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);
|
||||
expect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);
|
||||
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
|
||||
label: chart.data.labels[i],
|
||||
hoverBackgroundColor: 'rgb(255, 255, 255)',
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
borderWidth: 2
|
||||
}));
|
||||
})
|
||||
|
||||
// Change the amount of data and ensure that arcs are updated accordingly
|
||||
chart.data.datasets[1].data = [1, 2]; // remove 2 elements from dataset 0
|
||||
chart.update();
|
||||
|
||||
expect(meta.data.length).toBe(2);
|
||||
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
|
||||
|
||||
// Add data
|
||||
chart.data.datasets[1].data = [1, 2, 3, 4];
|
||||
chart.update();
|
||||
|
||||
expect(meta.data.length).toBe(4);
|
||||
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);
|
||||
});
|
||||
|
||||
it ('should rotate and limit circumference', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [2, 4],
|
||||
hidden: true
|
||||
}, {
|
||||
data: [1, 3]
|
||||
}, {
|
||||
data: [1, 0]
|
||||
}],
|
||||
labels: ['label0', 'label1']
|
||||
},
|
||||
options: {
|
||||
cutoutPercentage: 50,
|
||||
rotation: Math.PI,
|
||||
circumference: Math.PI * 0.5,
|
||||
elements: {
|
||||
arc: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
borderWidth: 2,
|
||||
hoverBackgroundColor: 'rgb(255, 255, 255)'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
|
||||
expect(meta.data.length).toBe(2);
|
||||
|
||||
// Only startAngle, endAngle and circumference should be different.
|
||||
[ { c: Math.PI / 8, s: Math.PI, e: Math.PI + Math.PI / 8 },
|
||||
{ c: 3 * Math.PI / 8, s: Math.PI + Math.PI / 8, e: Math.PI + Math.PI / 2 }
|
||||
].forEach(function(expected, i) {
|
||||
expect(meta.data[i]._model.x).toBeCloseToPixel(495);
|
||||
expect(meta.data[i]._model.y).toBeCloseToPixel(511);
|
||||
expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(478);
|
||||
expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(359);
|
||||
expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c,8);
|
||||
expect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);
|
||||
expect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);
|
||||
})
|
||||
});
|
||||
|
||||
it ('should draw all arcs', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, 4]
|
||||
}],
|
||||
labels: ['label0', 'label1', 'label2', 'label3']
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
spyOn(meta.data[0], 'draw');
|
||||
spyOn(meta.data[1], 'draw');
|
||||
spyOn(meta.data[2], 'draw');
|
||||
spyOn(meta.data[3], 'draw');
|
||||
|
||||
chart.update();
|
||||
|
||||
expect(meta.data[0].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[1].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[2].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[3].draw.calls.count()).toBe(1);
|
||||
});
|
||||
|
||||
it ('should set the hover style of an arc', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, 4]
|
||||
}],
|
||||
labels: ['label0', 'label1', 'label2', 'label3']
|
||||
},
|
||||
options: {
|
||||
elements: {
|
||||
arc: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
borderWidth: 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
var arc = meta.data[0];
|
||||
|
||||
meta.controller.setHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(230, 0, 0)');
|
||||
expect(arc._model.borderColor).toBe('rgb(0, 0, 230)');
|
||||
expect(arc._model.borderWidth).toBe(2);
|
||||
|
||||
// Set a dataset style to take precedence
|
||||
chart.data.datasets[0].hoverBackgroundColor = 'rgb(9, 9, 9)';
|
||||
chart.data.datasets[0].hoverBorderColor = 'rgb(18, 18, 18)';
|
||||
chart.data.datasets[0].hoverBorderWidth = 1.56;
|
||||
|
||||
meta.controller.setHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)');
|
||||
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
|
||||
expect(arc._model.borderWidth).toBe(1.56);
|
||||
|
||||
// Dataset styles can be an array
|
||||
chart.data.datasets[0].hoverBackgroundColor = ['rgb(255, 255, 255)', 'rgb(9, 9, 9)'];
|
||||
chart.data.datasets[0].hoverBorderColor = ['rgb(18, 18, 18)'];
|
||||
chart.data.datasets[0].hoverBorderWidth = [0.1, 1.56];
|
||||
|
||||
meta.controller.setHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)');
|
||||
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
|
||||
expect(arc._model.borderWidth).toBe(0.1);
|
||||
|
||||
// Element custom styles also work
|
||||
arc.custom = {
|
||||
hoverBackgroundColor: 'rgb(7, 7, 7)',
|
||||
hoverBorderColor: 'rgb(17, 17, 17)',
|
||||
hoverBorderWidth: 3.14159,
|
||||
};
|
||||
|
||||
meta.controller.setHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)');
|
||||
expect(arc._model.borderColor).toBe('rgb(17, 17, 17)');
|
||||
expect(arc._model.borderWidth).toBe(3.14159);
|
||||
});
|
||||
|
||||
it ('should unset the hover style of an arc', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, 4]
|
||||
}],
|
||||
labels: ['label0', 'label1', 'label2', 'label3']
|
||||
},
|
||||
options: {
|
||||
elements: {
|
||||
arc: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
borderWidth: 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
var arc = meta.data[0];
|
||||
|
||||
meta.controller.removeHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(255, 0, 0)');
|
||||
expect(arc._model.borderColor).toBe('rgb(0, 0, 255)');
|
||||
expect(arc._model.borderWidth).toBe(2);
|
||||
|
||||
// Set a dataset style to take precedence
|
||||
chart.data.datasets[0].backgroundColor = 'rgb(9, 9, 9)';
|
||||
chart.data.datasets[0].borderColor = 'rgb(18, 18, 18)';
|
||||
chart.data.datasets[0].borderWidth = 1.56;
|
||||
|
||||
meta.controller.removeHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)');
|
||||
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
|
||||
expect(arc._model.borderWidth).toBe(1.56);
|
||||
|
||||
// Dataset styles can be an array
|
||||
chart.data.datasets[0].backgroundColor = ['rgb(255, 255, 255)', 'rgb(9, 9, 9)'];
|
||||
chart.data.datasets[0].borderColor = ['rgb(18, 18, 18)'];
|
||||
chart.data.datasets[0].borderWidth = [0.1, 1.56];
|
||||
|
||||
meta.controller.removeHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)');
|
||||
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
|
||||
expect(arc._model.borderWidth).toBe(0.1);
|
||||
|
||||
// Element custom styles also work
|
||||
arc.custom = {
|
||||
backgroundColor: 'rgb(7, 7, 7)',
|
||||
borderColor: 'rgb(17, 17, 17)',
|
||||
borderWidth: 3.14159,
|
||||
};
|
||||
|
||||
meta.controller.removeHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)');
|
||||
expect(arc._model.borderColor).toBe('rgb(17, 17, 17)');
|
||||
expect(arc._model.borderWidth).toBe(3.14159);
|
||||
});
|
||||
});
|
||||
493
vendors/Chart.js/test/controller.line.tests.js
vendored
Normal file
493
vendors/Chart.js/test/controller.line.tests.js
vendored
Normal file
@@ -0,0 +1,493 @@
|
||||
// Test the line controller
|
||||
describe('Line controller tests', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.releaseAllCharts();
|
||||
});
|
||||
|
||||
it('should be constructed', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: []
|
||||
}],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta.type).toBe('line');
|
||||
expect(meta.controller).not.toBe(undefined);
|
||||
expect(meta.controller.index).toBe(0);
|
||||
expect(meta.data).toEqual([]);
|
||||
|
||||
meta.controller.updateIndex(1);
|
||||
expect(meta.controller.index).toBe(1);
|
||||
});
|
||||
|
||||
it('Should use the first scale IDs if the dataset does not specify them', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: []
|
||||
}],
|
||||
labels: []
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'firstXScaleID'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'firstYScaleID'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta.xAxisID).toBe('firstXScaleID');
|
||||
expect(meta.yAxisID).toBe('firstYScaleID');
|
||||
});
|
||||
|
||||
it('Should create line elements and point elements for each data item during initialization', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset1'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta.data.length).toBe(4); // 4 points created
|
||||
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.dataset instanceof Chart.elements.Line).toBe(true); // 1 line element
|
||||
});
|
||||
|
||||
it('should draw all elements', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset1'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
showLines: true
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
spyOn(meta.dataset, 'draw');
|
||||
spyOn(meta.data[0], 'draw');
|
||||
spyOn(meta.data[1], 'draw');
|
||||
spyOn(meta.data[2], 'draw');
|
||||
spyOn(meta.data[3], 'draw');
|
||||
|
||||
chart.update();
|
||||
|
||||
expect(meta.data[0].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[1].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[2].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[3].draw.calls.count()).toBe(1);
|
||||
});
|
||||
|
||||
it('should draw all elements except lines', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset1'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
showLines: false
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
spyOn(meta.dataset, 'draw');
|
||||
spyOn(meta.data[0], 'draw');
|
||||
spyOn(meta.data[1], 'draw');
|
||||
spyOn(meta.data[2], 'draw');
|
||||
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);
|
||||
expect(meta.data[2].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[3].draw.calls.count()).toBe(1);
|
||||
});
|
||||
|
||||
it('should update elements when modifying data', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset',
|
||||
xAxisID: 'firstXScaleID',
|
||||
yAxisID: 'firstYScaleID'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
showLines: true,
|
||||
elements: {
|
||||
point: {
|
||||
backgroundColor: 'red',
|
||||
borderColor: 'blue',
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'firstXScaleID'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'firstYScaleID'
|
||||
}]
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
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) {
|
||||
expect(meta.data[i]._datasetIndex).toBe(0);
|
||||
expect(meta.data[i]._index).toBe(i);
|
||||
expect(meta.data[i]._xScale).toBe(chart.scales.firstXScaleID);
|
||||
expect(meta.data[i]._yScale).toBe(chart.scales.firstYScaleID);
|
||||
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
|
||||
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
|
||||
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: 'red',
|
||||
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 update elements when the y scale is stacked', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, -10, 10, -10],
|
||||
label: 'dataset1'
|
||||
}, {
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
stacked: true
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta0 = chart.getDatasetMeta(0);
|
||||
|
||||
[ { x: 38, y: 161 },
|
||||
{ x: 189, y: 419 },
|
||||
{ x: 341, y: 161 },
|
||||
{ x: 492, y: 419 }
|
||||
].forEach(function(values, i) {
|
||||
expect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);
|
||||
expect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);
|
||||
});
|
||||
|
||||
var meta1 = chart.getDatasetMeta(1);
|
||||
|
||||
[ { x: 38, y: 32 },
|
||||
{ x: 189, y: 97 },
|
||||
{ x: 341, y: 161 },
|
||||
{ x: 492, y: 471 }
|
||||
].forEach(function(values, i) {
|
||||
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() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 20, 20],
|
||||
label: 'dataset1',
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
expect(meta.dataset._model).toEqual(jasmine.objectContaining({
|
||||
scaleTop: 32,
|
||||
scaleBottom: 484,
|
||||
scaleZero: 484,
|
||||
}));
|
||||
});
|
||||
|
||||
it('should find the correct scale zero when the data is all negative', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [-10, -15, -20, -20],
|
||||
label: 'dataset1',
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
expect(meta.dataset._model).toEqual(jasmine.objectContaining({
|
||||
scaleTop: 32,
|
||||
scaleBottom: 484,
|
||||
scaleZero: 32,
|
||||
}));
|
||||
});
|
||||
|
||||
it('should fall back to the line styles for points', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [0, 0],
|
||||
label: 'dataset1',
|
||||
|
||||
// line styles
|
||||
backgroundColor: 'rgb(98, 98, 98)',
|
||||
borderColor: 'rgb(8, 8, 8)',
|
||||
borderWidth: 0.55,
|
||||
}],
|
||||
labels: ['label1', 'label2']
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
expect(meta.dataset._model.backgroundColor).toBe('rgb(98, 98, 98)');
|
||||
expect(meta.dataset._model.borderColor).toBe('rgb(8, 8, 8)');
|
||||
expect(meta.dataset._model.borderWidth).toBe(0.55);
|
||||
});
|
||||
|
||||
it('should handle number of data point changes in update', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset1',
|
||||
}],
|
||||
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);
|
||||
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
|
||||
|
||||
chart.data.datasets[0].data = [1, 2, 3, 4, 5]; // add 3 items
|
||||
chart.update();
|
||||
expect(meta.data.length).toBe(5);
|
||||
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[4] instanceof Chart.elements.Point).toBe(true);
|
||||
});
|
||||
|
||||
it('should set point hover styles', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset1',
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
elements: {
|
||||
point: {
|
||||
backgroundColor: 'rgb(255, 255, 0)',
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgb(255, 255, 255)',
|
||||
hitRadius: 1,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 1,
|
||||
radius: 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
var point = meta.data[0];
|
||||
|
||||
meta.controller.setHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');
|
||||
expect(point._model.borderColor).toBe('rgb(230, 230, 230)');
|
||||
expect(point._model.borderWidth).toBe(1);
|
||||
expect(point._model.radius).toBe(4);
|
||||
|
||||
// Can set hover style per dataset
|
||||
chart.data.datasets[0].pointHoverRadius = 3.3;
|
||||
chart.data.datasets[0].pointHoverBackgroundColor = 'rgb(77, 79, 81)';
|
||||
chart.data.datasets[0].pointHoverBorderColor = 'rgb(123, 125, 127)';
|
||||
chart.data.datasets[0].pointHoverBorderWidth = 2.1;
|
||||
|
||||
meta.controller.setHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
|
||||
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
|
||||
expect(point._model.borderWidth).toBe(2.1);
|
||||
expect(point._model.radius).toBe(3.3);
|
||||
|
||||
// Use the consistent name "pointRadius", setting but overwriting
|
||||
// another value in "radius"
|
||||
chart.data.datasets[0].pointRadius = 250;
|
||||
chart.data.datasets[0].radius = 20;
|
||||
|
||||
meta.controller.setHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
|
||||
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
|
||||
expect(point._model.borderWidth).toBe(2.1);
|
||||
expect(point._model.radius).toBe(3.3);
|
||||
|
||||
// Custom style
|
||||
point.custom = {
|
||||
hoverRadius: 4.4,
|
||||
hoverBorderWidth: 5.5,
|
||||
hoverBackgroundColor: 'rgb(0, 0, 0)',
|
||||
hoverBorderColor: 'rgb(10, 10, 10)'
|
||||
};
|
||||
|
||||
meta.controller.setHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
|
||||
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
|
||||
expect(point._model.borderWidth).toBe(5.5);
|
||||
expect(point._model.radius).toBe(4.4);
|
||||
});
|
||||
|
||||
it('should remove hover styles', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset1',
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
elements: {
|
||||
point: {
|
||||
backgroundColor: 'rgb(255, 255, 0)',
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgb(255, 255, 255)',
|
||||
hitRadius: 1,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 1,
|
||||
radius: 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
var point = meta.data[0];
|
||||
|
||||
chart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';
|
||||
chart.options.elements.point.borderColor = 'rgb(50, 51, 52)';
|
||||
chart.options.elements.point.borderWidth = 10.1;
|
||||
chart.options.elements.point.radius = 1.01;
|
||||
|
||||
meta.controller.removeHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');
|
||||
expect(point._model.borderColor).toBe('rgb(50, 51, 52)');
|
||||
expect(point._model.borderWidth).toBe(10.1);
|
||||
expect(point._model.radius).toBe(1.01);
|
||||
|
||||
// Can set hover style per dataset
|
||||
chart.data.datasets[0].radius = 3.3;
|
||||
chart.data.datasets[0].pointBackgroundColor = 'rgb(77, 79, 81)';
|
||||
chart.data.datasets[0].pointBorderColor = 'rgb(123, 125, 127)';
|
||||
chart.data.datasets[0].pointBorderWidth = 2.1;
|
||||
|
||||
meta.controller.removeHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
|
||||
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
|
||||
expect(point._model.borderWidth).toBe(2.1);
|
||||
expect(point._model.radius).toBe(3.3);
|
||||
|
||||
// Use the consistent name "pointRadius", setting but overwriting
|
||||
// another value in "radius"
|
||||
chart.data.datasets[0].pointRadius = 250;
|
||||
chart.data.datasets[0].radius = 20;
|
||||
|
||||
meta.controller.removeHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
|
||||
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
|
||||
expect(point._model.borderWidth).toBe(2.1);
|
||||
expect(point._model.radius).toBe(250);
|
||||
|
||||
// Custom style
|
||||
point.custom = {
|
||||
radius: 4.4,
|
||||
borderWidth: 5.5,
|
||||
backgroundColor: 'rgb(0, 0, 0)',
|
||||
borderColor: 'rgb(10, 10, 10)'
|
||||
};
|
||||
|
||||
meta.controller.removeHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
|
||||
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
|
||||
expect(point._model.borderWidth).toBe(5.5);
|
||||
expect(point._model.radius).toBe(4.4);
|
||||
});
|
||||
});
|
||||
318
vendors/Chart.js/test/controller.polarArea.tests.js
vendored
Normal file
318
vendors/Chart.js/test/controller.polarArea.tests.js
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
// Test the polar area controller
|
||||
describe('Polar area controller tests', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.releaseAllCharts();
|
||||
});
|
||||
|
||||
it('should be constructed', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'polarArea',
|
||||
data: {
|
||||
datasets: [
|
||||
{ data: [] },
|
||||
{ data: [] }
|
||||
],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
expect(meta.type).toEqual('polarArea');
|
||||
expect(meta.data).toEqual([]);
|
||||
expect(meta.hidden).toBe(null);
|
||||
expect(meta.controller).not.toBe(undefined);
|
||||
expect(meta.controller.index).toBe(1);
|
||||
|
||||
meta.controller.updateIndex(0);
|
||||
expect(meta.controller.index).toBe(0);
|
||||
});
|
||||
|
||||
it('should create arc elements for each data item during initialization', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'polarArea',
|
||||
data: {
|
||||
datasets: [
|
||||
{ data: [] },
|
||||
{ data: [10, 15, 0, -4] }
|
||||
],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(1);
|
||||
expect(meta.data.length).toBe(4); // 4 arcs created
|
||||
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);
|
||||
});
|
||||
|
||||
it('should draw all elements', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'polarArea',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
spyOn(meta.data[0], 'draw');
|
||||
spyOn(meta.data[1], 'draw');
|
||||
spyOn(meta.data[2], 'draw');
|
||||
spyOn(meta.data[3], 'draw');
|
||||
|
||||
chart.update();
|
||||
|
||||
expect(meta.data[0].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[1].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[2].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[3].draw.calls.count()).toBe(1);
|
||||
});
|
||||
|
||||
it('should update elements when modifying data', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'polarArea',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
showLines: true,
|
||||
elements: {
|
||||
arc: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
borderWidth: 1.2
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta.data.length).toBe(4);
|
||||
|
||||
[ { o: 156, s: -0.5 * Math.PI, e: 0 },
|
||||
{ o: 211, s: 0, e: 0.5 * Math.PI },
|
||||
{ o: 45, s: 0.5 * Math.PI, e: Math.PI },
|
||||
{ o: 0, s: Math.PI, e: 1.5 * Math.PI }
|
||||
].forEach(function(expected, i) {
|
||||
expect(meta.data[i]._model.x).toBeCloseToPixel(256);
|
||||
expect(meta.data[i]._model.y).toBeCloseToPixel(272);
|
||||
expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(0);
|
||||
expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(expected.o);
|
||||
expect(meta.data[i]._model.startAngle).toBe(expected.s);
|
||||
expect(meta.data[i]._model.endAngle).toBe(expected.e);
|
||||
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
borderWidth: 1.2,
|
||||
label: chart.data.labels[i]
|
||||
}));
|
||||
});
|
||||
|
||||
// arc styles
|
||||
chart.data.datasets[0].backgroundColor = 'rgb(128, 129, 130)';
|
||||
chart.data.datasets[0].borderColor = 'rgb(56, 57, 58)';
|
||||
chart.data.datasets[0].borderWidth = 1.123;
|
||||
|
||||
chart.update();
|
||||
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
expect(meta.data[i]._model.backgroundColor).toBe('rgb(128, 129, 130)');
|
||||
expect(meta.data[i]._model.borderColor).toBe('rgb(56, 57, 58)');
|
||||
expect(meta.data[i]._model.borderWidth).toBe(1.123);
|
||||
}
|
||||
|
||||
// arc styles
|
||||
meta.data[0].custom = {
|
||||
backgroundColor: 'rgb(0, 1, 3)',
|
||||
borderColor: 'rgb(4, 6, 8)',
|
||||
borderWidth: 0.787
|
||||
};
|
||||
|
||||
chart.update();
|
||||
|
||||
expect(meta.data[0]._model.x).toBeCloseToPixel(256);
|
||||
expect(meta.data[0]._model.y).toBeCloseToPixel(272);
|
||||
expect(meta.data[0]._model.innerRadius).toBeCloseToPixel(0);
|
||||
expect(meta.data[0]._model.outerRadius).toBeCloseToPixel(156);
|
||||
expect(meta.data[0]._model).toEqual(jasmine.objectContaining({
|
||||
startAngle: -0.5 * Math.PI,
|
||||
endAngle: 0,
|
||||
backgroundColor: 'rgb(0, 1, 3)',
|
||||
borderWidth: 0.787,
|
||||
borderColor: 'rgb(4, 6, 8)',
|
||||
label: 'label1'
|
||||
}));
|
||||
});
|
||||
|
||||
it('should handle number of data point changes in update', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'polarArea',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
showLines: true,
|
||||
elements: {
|
||||
arc: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
borderWidth: 1.2
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta.data.length).toBe(4);
|
||||
|
||||
// remove 2 items
|
||||
chart.data.labels = ['label1', 'label2'];
|
||||
chart.data.datasets[0].data = [1, 2];
|
||||
chart.update();
|
||||
|
||||
expect(meta.data.length).toBe(2);
|
||||
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
|
||||
|
||||
// add 3 items
|
||||
chart.data.labels = ['label1', 'label2', 'label3', 'label4', 'label5'];
|
||||
chart.data.datasets[0].data = [1, 2, 3, 4, 5];
|
||||
chart.update();
|
||||
|
||||
expect(meta.data.length).toBe(5);
|
||||
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);
|
||||
expect(meta.data[4] instanceof Chart.elements.Arc).toBe(true);
|
||||
});
|
||||
|
||||
it('should set arc hover styles', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'polarArea',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
showLines: true,
|
||||
elements: {
|
||||
arc: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
borderWidth: 1.2
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
var arc = meta.data[0];
|
||||
|
||||
meta.controller.setHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(230, 0, 0)');
|
||||
expect(arc._model.borderColor).toBe('rgb(0, 230, 0)');
|
||||
expect(arc._model.borderWidth).toBe(1.2);
|
||||
|
||||
// Can set hover style per dataset
|
||||
chart.data.datasets[0].hoverBackgroundColor = 'rgb(77, 79, 81)';
|
||||
chart.data.datasets[0].hoverBorderColor = 'rgb(123, 125, 127)';
|
||||
chart.data.datasets[0].hoverBorderWidth = 2.1;
|
||||
|
||||
meta.controller.setHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(77, 79, 81)');
|
||||
expect(arc._model.borderColor).toBe('rgb(123, 125, 127)');
|
||||
expect(arc._model.borderWidth).toBe(2.1);
|
||||
|
||||
// Custom style
|
||||
arc.custom = {
|
||||
hoverBorderWidth: 5.5,
|
||||
hoverBackgroundColor: 'rgb(0, 0, 0)',
|
||||
hoverBorderColor: 'rgb(10, 10, 10)'
|
||||
};
|
||||
|
||||
meta.controller.setHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(0, 0, 0)');
|
||||
expect(arc._model.borderColor).toBe('rgb(10, 10, 10)');
|
||||
expect(arc._model.borderWidth).toBe(5.5);
|
||||
});
|
||||
|
||||
it('should remove hover styles', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'polarArea',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, -4],
|
||||
label: 'dataset2'
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
showLines: true,
|
||||
elements: {
|
||||
arc: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
borderWidth: 1.2
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
var arc = meta.data[0];
|
||||
|
||||
chart.options.elements.arc.backgroundColor = 'rgb(45, 46, 47)';
|
||||
chart.options.elements.arc.borderColor = 'rgb(50, 51, 52)';
|
||||
chart.options.elements.arc.borderWidth = 10.1;
|
||||
|
||||
meta.controller.removeHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(45, 46, 47)');
|
||||
expect(arc._model.borderColor).toBe('rgb(50, 51, 52)');
|
||||
expect(arc._model.borderWidth).toBe(10.1);
|
||||
|
||||
// Can set hover style per dataset
|
||||
chart.data.datasets[0].backgroundColor = 'rgb(77, 79, 81)';
|
||||
chart.data.datasets[0].borderColor = 'rgb(123, 125, 127)';
|
||||
chart.data.datasets[0].borderWidth = 2.1;
|
||||
|
||||
meta.controller.removeHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(77, 79, 81)');
|
||||
expect(arc._model.borderColor).toBe('rgb(123, 125, 127)');
|
||||
expect(arc._model.borderWidth).toBe(2.1);
|
||||
|
||||
// Custom style
|
||||
arc.custom = {
|
||||
borderWidth: 5.5,
|
||||
backgroundColor: 'rgb(0, 0, 0)',
|
||||
borderColor: 'rgb(10, 10, 10)'
|
||||
};
|
||||
|
||||
meta.controller.removeHoverStyle(arc);
|
||||
expect(arc._model.backgroundColor).toBe('rgb(0, 0, 0)');
|
||||
expect(arc._model.borderColor).toBe('rgb(10, 10, 10)');
|
||||
expect(arc._model.borderWidth).toBe(5.5);
|
||||
});
|
||||
});
|
||||
465
vendors/Chart.js/test/controller.radar.tests.js
vendored
Normal file
465
vendors/Chart.js/test/controller.radar.tests.js
vendored
Normal file
@@ -0,0 +1,465 @@
|
||||
// Test the polar area controller
|
||||
describe('Radar controller tests', function() {
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.releaseAllCharts();
|
||||
});
|
||||
|
||||
it('Should be constructed', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: []
|
||||
}],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta.type).toBe('radar');
|
||||
expect(meta.controller).not.toBe(undefined);
|
||||
expect(meta.controller.index).toBe(0);
|
||||
expect(meta.data).toEqual([]);
|
||||
|
||||
meta.controller.updateIndex(1);
|
||||
expect(meta.controller.index).toBe(1);
|
||||
});
|
||||
|
||||
it('Should create arc elements for each data item during initialization', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, 4]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
}
|
||||
});
|
||||
|
||||
var controller = new Chart.controllers.radar(chart, 0);
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta.dataset instanceof Chart.elements.Line).toBe(true); // line element
|
||||
expect(meta.data.length).toBe(4); // 4 points created
|
||||
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
|
||||
expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
|
||||
});
|
||||
|
||||
it('should draw all elements', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, 4]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
spyOn(meta.dataset, 'draw');
|
||||
spyOn(meta.data[0], 'draw');
|
||||
spyOn(meta.data[1], 'draw');
|
||||
spyOn(meta.data[2], 'draw');
|
||||
spyOn(meta.data[3], 'draw');
|
||||
|
||||
chart.update();
|
||||
|
||||
expect(meta.dataset.draw.calls.count()).toBe(1);
|
||||
expect(meta.data[0].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[1].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[2].draw.calls.count()).toBe(1);
|
||||
expect(meta.data[3].draw.calls.count()).toBe(1);
|
||||
});
|
||||
|
||||
it('should update elements', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, 4]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
showLines: true,
|
||||
elements: {
|
||||
line: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderCapStyle: 'round',
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.1,
|
||||
borderJoinStyle: 'bevel',
|
||||
borderWidth: 1.2,
|
||||
fill: true,
|
||||
tension: 0.1,
|
||||
},
|
||||
point: {
|
||||
backgroundColor: Chart.defaults.global.defaultColor,
|
||||
borderWidth: 1,
|
||||
borderColor: Chart.defaults.global.defaultColor,
|
||||
hitRadius: 1,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 1,
|
||||
radius: 3,
|
||||
pointStyle: 'circle'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
meta.controller.reset(); // reset first
|
||||
|
||||
// Line element
|
||||
expect(meta.dataset._model.scaleTop).toBeCloseToPixel(32);
|
||||
expect(meta.dataset._model.scaleBottom).toBeCloseToPixel(512);
|
||||
expect(meta.dataset._model.scaleZero.x).toBeCloseToPixel(256);
|
||||
expect(meta.dataset._model.scaleZero.y).toBeCloseToPixel(272);
|
||||
expect(meta.dataset._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderCapStyle: 'round',
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.1,
|
||||
borderJoinStyle: 'bevel',
|
||||
borderWidth: 1.2,
|
||||
fill: true,
|
||||
tension: 0.1,
|
||||
}));
|
||||
|
||||
[
|
||||
{ x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},
|
||||
{ x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},
|
||||
{ x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},
|
||||
{ x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},
|
||||
].forEach(function(expected, i) {
|
||||
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
|
||||
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
|
||||
expect(meta.data[i]._model.controlPointPreviousX).toBeCloseToPixel(expected.cppx);
|
||||
expect(meta.data[i]._model.controlPointPreviousY).toBeCloseToPixel(expected.cppy);
|
||||
expect(meta.data[i]._model.controlPointNextX).toBeCloseToPixel(expected.cpnx);
|
||||
expect(meta.data[i]._model.controlPointNextY).toBeCloseToPixel(expected.cpny);
|
||||
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: Chart.defaults.global.defaultColor,
|
||||
borderWidth: 1,
|
||||
borderColor: Chart.defaults.global.defaultColor,
|
||||
hitRadius: 1,
|
||||
radius: 3,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0.1,
|
||||
}));
|
||||
});
|
||||
|
||||
// Now update controller and ensure proper updates
|
||||
meta.controller.update();
|
||||
|
||||
[
|
||||
{ x: 256, y: 133, cppx: 246, cppy: 133, cpnx: 272, cpny: 133 },
|
||||
{ x: 464, y: 272, cppx: 464, cppy: 264, cpnx: 464, cpny: 278 },
|
||||
{ x: 256, y: 272, cppx: 276.9, cppy: 272, cpnx: 250.4, cpny: 272 },
|
||||
{ x: 200, y: 272, cppx: 200, cppy: 275, cpnx: 200, cpny: 261 },
|
||||
].forEach(function(expected, i) {
|
||||
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
|
||||
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
|
||||
expect(meta.data[i]._model.controlPointPreviousX).toBeCloseToPixel(expected.cppx);
|
||||
expect(meta.data[i]._model.controlPointPreviousY).toBeCloseToPixel(expected.cppy);
|
||||
expect(meta.data[i]._model.controlPointNextX).toBeCloseToPixel(expected.cpnx);
|
||||
expect(meta.data[i]._model.controlPointNextY).toBeCloseToPixel(expected.cpny);
|
||||
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: Chart.defaults.global.defaultColor,
|
||||
borderWidth: 1,
|
||||
borderColor: Chart.defaults.global.defaultColor,
|
||||
hitRadius: 1,
|
||||
radius: 3,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0.1,
|
||||
}));
|
||||
});
|
||||
|
||||
// Use dataset level styles for lines & points
|
||||
chart.data.datasets[0].tension = 0;
|
||||
chart.data.datasets[0].backgroundColor = 'rgb(98, 98, 98)';
|
||||
chart.data.datasets[0].borderColor = 'rgb(8, 8, 8)';
|
||||
chart.data.datasets[0].borderWidth = 0.55;
|
||||
chart.data.datasets[0].borderCapStyle = 'butt';
|
||||
chart.data.datasets[0].borderDash = [2, 3];
|
||||
chart.data.datasets[0].borderDashOffset = 7;
|
||||
chart.data.datasets[0].borderJoinStyle = 'miter';
|
||||
chart.data.datasets[0].fill = false;
|
||||
|
||||
// point styles
|
||||
chart.data.datasets[0].pointRadius = 22;
|
||||
chart.data.datasets[0].hitRadius = 3.3;
|
||||
chart.data.datasets[0].pointBackgroundColor = 'rgb(128, 129, 130)';
|
||||
chart.data.datasets[0].pointBorderColor = 'rgb(56, 57, 58)';
|
||||
chart.data.datasets[0].pointBorderWidth = 1.123;
|
||||
|
||||
meta.controller.update();
|
||||
|
||||
expect(meta.dataset._model.scaleTop).toBeCloseToPixel(32);
|
||||
expect(meta.dataset._model.scaleBottom).toBeCloseToPixel(512);
|
||||
expect(meta.dataset._model.scaleZero.x).toBeCloseToPixel(256);
|
||||
expect(meta.dataset._model.scaleZero.y).toBeCloseToPixel(272);
|
||||
expect(meta.dataset._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: 'rgb(98, 98, 98)',
|
||||
borderCapStyle: 'butt',
|
||||
borderColor: 'rgb(8, 8, 8)',
|
||||
borderDash: [2, 3],
|
||||
borderDashOffset: 7,
|
||||
borderJoinStyle: 'miter',
|
||||
borderWidth: 0.55,
|
||||
fill: false,
|
||||
tension: 0,
|
||||
}));
|
||||
|
||||
// Since tension is now 0, we don't care about the control points
|
||||
[
|
||||
{ x: 256, y: 133 },
|
||||
{ x: 464, y: 272 },
|
||||
{ x: 256, y: 272 },
|
||||
{ x: 200, y: 272 },
|
||||
].forEach(function(expected, i) {
|
||||
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
|
||||
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
|
||||
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: 'rgb(128, 129, 130)',
|
||||
borderWidth: 1.123,
|
||||
borderColor: 'rgb(56, 57, 58)',
|
||||
hitRadius: 3.3,
|
||||
radius: 22,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0,
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
// Use custom styles for lines & first point
|
||||
meta.dataset.custom = {
|
||||
tension: 0.25,
|
||||
backgroundColor: 'rgb(55, 55, 54)',
|
||||
borderColor: 'rgb(8, 7, 6)',
|
||||
borderWidth: 0.3,
|
||||
borderCapStyle: 'square',
|
||||
borderDash: [4, 3],
|
||||
borderDashOffset: 4.4,
|
||||
borderJoinStyle: 'round',
|
||||
fill: true,
|
||||
};
|
||||
|
||||
// point styles
|
||||
meta.data[0].custom = {
|
||||
radius: 2.2,
|
||||
backgroundColor: 'rgb(0, 1, 3)',
|
||||
borderColor: 'rgb(4, 6, 8)',
|
||||
borderWidth: 0.787,
|
||||
tension: 0.15,
|
||||
skip: true,
|
||||
hitRadius: 5,
|
||||
};
|
||||
|
||||
meta.controller.update();
|
||||
|
||||
expect(meta.dataset._model.scaleTop).toBeCloseToPixel(32);
|
||||
expect(meta.dataset._model.scaleBottom).toBeCloseToPixel(512);
|
||||
expect(meta.dataset._model.scaleZero.x).toBeCloseToPixel(256);
|
||||
expect(meta.dataset._model.scaleZero.y).toBeCloseToPixel(272);
|
||||
expect(meta.dataset._model).toEqual(jasmine.objectContaining({
|
||||
backgroundColor: 'rgb(55, 55, 54)',
|
||||
borderCapStyle: 'square',
|
||||
borderColor: 'rgb(8, 7, 6)',
|
||||
borderDash: [4, 3],
|
||||
borderDashOffset: 4.4,
|
||||
borderJoinStyle: 'round',
|
||||
borderWidth: 0.3,
|
||||
fill: true,
|
||||
tension: 0.25,
|
||||
}));
|
||||
|
||||
expect(meta.data[0]._model.x).toBeCloseToPixel(256);
|
||||
expect(meta.data[0]._model.y).toBeCloseToPixel(133);
|
||||
expect(meta.data[0]._model.controlPointPreviousX).toBeCloseToPixel(241);
|
||||
expect(meta.data[0]._model.controlPointPreviousY).toBeCloseToPixel(133);
|
||||
expect(meta.data[0]._model.controlPointNextX).toBeCloseToPixel(281);
|
||||
expect(meta.data[0]._model.controlPointNextY).toBeCloseToPixel(133);
|
||||
expect(meta.data[0]._model).toEqual(jasmine.objectContaining({
|
||||
radius: 2.2,
|
||||
backgroundColor: 'rgb(0, 1, 3)',
|
||||
borderColor: 'rgb(4, 6, 8)',
|
||||
borderWidth: 0.787,
|
||||
tension: 0.15,
|
||||
skip: true,
|
||||
hitRadius: 5,
|
||||
}));
|
||||
});
|
||||
|
||||
it('should set point hover styles', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, 4]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
showLines: true,
|
||||
elements: {
|
||||
line: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderCapStyle: 'round',
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.1,
|
||||
borderJoinStyle: 'bevel',
|
||||
borderWidth: 1.2,
|
||||
fill: true,
|
||||
skipNull: true,
|
||||
tension: 0.1,
|
||||
},
|
||||
point: {
|
||||
backgroundColor: 'rgb(255, 255, 0)',
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgb(255, 255, 255)',
|
||||
hitRadius: 1,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 1,
|
||||
radius: 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
meta.controller.update(); // reset first
|
||||
|
||||
var point = meta.data[0];
|
||||
|
||||
meta.controller.setHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');
|
||||
expect(point._model.borderColor).toBe('rgb(230, 230, 230)');
|
||||
expect(point._model.borderWidth).toBe(1);
|
||||
expect(point._model.radius).toBe(4);
|
||||
|
||||
// Can set hover style per dataset
|
||||
chart.data.datasets[0].pointHoverRadius = 3.3;
|
||||
chart.data.datasets[0].pointHoverBackgroundColor = 'rgb(77, 79, 81)';
|
||||
chart.data.datasets[0].pointHoverBorderColor = 'rgb(123, 125, 127)';
|
||||
chart.data.datasets[0].pointHoverBorderWidth = 2.1;
|
||||
|
||||
meta.controller.setHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
|
||||
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
|
||||
expect(point._model.borderWidth).toBe(2.1);
|
||||
expect(point._model.radius).toBe(3.3);
|
||||
|
||||
// Custom style
|
||||
point.custom = {
|
||||
hoverRadius: 4.4,
|
||||
hoverBorderWidth: 5.5,
|
||||
hoverBackgroundColor: 'rgb(0, 0, 0)',
|
||||
hoverBorderColor: 'rgb(10, 10, 10)'
|
||||
};
|
||||
|
||||
meta.controller.setHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
|
||||
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
|
||||
expect(point._model.borderWidth).toBe(5.5);
|
||||
expect(point._model.radius).toBe(4.4);
|
||||
});
|
||||
|
||||
|
||||
it('should remove hover styles', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 15, 0, 4]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
showLines: true,
|
||||
elements: {
|
||||
line: {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
borderCapStyle: 'round',
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.1,
|
||||
borderJoinStyle: 'bevel',
|
||||
borderWidth: 1.2,
|
||||
fill: true,
|
||||
skipNull: true,
|
||||
tension: 0.1,
|
||||
},
|
||||
point: {
|
||||
backgroundColor: 'rgb(255, 255, 0)',
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgb(255, 255, 255)',
|
||||
hitRadius: 1,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 1,
|
||||
radius: 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
|
||||
meta.controller.update(); // reset first
|
||||
|
||||
var point = meta.data[0];
|
||||
|
||||
chart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';
|
||||
chart.options.elements.point.borderColor = 'rgb(50, 51, 52)';
|
||||
chart.options.elements.point.borderWidth = 10.1;
|
||||
chart.options.elements.point.radius = 1.01;
|
||||
|
||||
meta.controller.removeHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');
|
||||
expect(point._model.borderColor).toBe('rgb(50, 51, 52)');
|
||||
expect(point._model.borderWidth).toBe(10.1);
|
||||
expect(point._model.radius).toBe(1.01);
|
||||
|
||||
// Can set hover style per dataset
|
||||
chart.data.datasets[0].radius = 3.3;
|
||||
chart.data.datasets[0].pointBackgroundColor = 'rgb(77, 79, 81)';
|
||||
chart.data.datasets[0].pointBorderColor = 'rgb(123, 125, 127)';
|
||||
chart.data.datasets[0].pointBorderWidth = 2.1;
|
||||
|
||||
meta.controller.removeHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
|
||||
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
|
||||
expect(point._model.borderWidth).toBe(2.1);
|
||||
expect(point._model.radius).toBe(3.3);
|
||||
|
||||
// Custom style
|
||||
point.custom = {
|
||||
radius: 4.4,
|
||||
borderWidth: 5.5,
|
||||
backgroundColor: 'rgb(0, 0, 0)',
|
||||
borderColor: 'rgb(10, 10, 10)'
|
||||
};
|
||||
|
||||
meta.controller.removeHoverStyle(point);
|
||||
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
|
||||
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
|
||||
expect(point._model.borderWidth).toBe(5.5);
|
||||
expect(point._model.radius).toBe(4.4);
|
||||
});
|
||||
});
|
||||
45
vendors/Chart.js/test/core.element.tests.js
vendored
Normal file
45
vendors/Chart.js/test/core.element.tests.js
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Test the core element functionality
|
||||
describe('Core element tests', function() {
|
||||
it ('should transition model properties', function() {
|
||||
var element = new Chart.Element({
|
||||
_model: {
|
||||
numberProp: 0,
|
||||
numberProp2: 100,
|
||||
_underscoreProp: 0,
|
||||
stringProp: 'abc',
|
||||
objectProp: {
|
||||
myObject: true
|
||||
},
|
||||
colorProp: 'rgb(0, 0, 0)'
|
||||
}
|
||||
});
|
||||
|
||||
// First transition clones model into view
|
||||
element.transition(0.25);
|
||||
expect(element._view).toEqual(element._model);
|
||||
expect(element._start).toEqual(element._model); // also cloned
|
||||
|
||||
expect(element._view.objectProp).toBe(element._model.objectProp); // not cloned
|
||||
expect(element._start.objectProp).toEqual(element._model.objectProp); // not cloned
|
||||
|
||||
element._model.numberProp = 100;
|
||||
element._model.numberProp2 = 250;
|
||||
element._model._underscoreProp = 200;
|
||||
element._model.stringProp = 'def'
|
||||
element._model.newStringProp = 'newString';
|
||||
element._model.colorProp = 'rgb(255, 255, 0)'
|
||||
|
||||
element.transition(0.25);
|
||||
expect(element._view).toEqual({
|
||||
numberProp: 25,
|
||||
numberProp2: 137.5,
|
||||
_underscoreProp: 0, // underscore props are not transition to a new value
|
||||
stringProp: 'def',
|
||||
newStringProp: 'newString',
|
||||
objectProp: {
|
||||
myObject: true
|
||||
},
|
||||
colorProp: 'rgb(64, 64, 0)',
|
||||
});
|
||||
});
|
||||
});
|
||||
718
vendors/Chart.js/test/core.helpers.tests.js
vendored
Normal file
718
vendors/Chart.js/test/core.helpers.tests.js
vendored
Normal file
@@ -0,0 +1,718 @@
|
||||
describe('Core helper tests', function() {
|
||||
|
||||
var helpers;
|
||||
|
||||
beforeAll(function() {
|
||||
helpers = window.Chart.helpers;
|
||||
});
|
||||
|
||||
it('should iterate over an array and pass the extra data to that function', function() {
|
||||
var testData = [0, 9, "abc"];
|
||||
var scope = {}; // fake out the scope and ensure that 'this' is the correct thing
|
||||
|
||||
helpers.each(testData, function(item, index) {
|
||||
expect(item).not.toBe(undefined);
|
||||
expect(index).not.toBe(undefined);
|
||||
|
||||
expect(testData[index]).toBe(item);
|
||||
expect(this).toBe(scope);
|
||||
}, scope);
|
||||
|
||||
// Reverse iteration
|
||||
var iterated = [];
|
||||
helpers.each(testData, function(item, index) {
|
||||
expect(item).not.toBe(undefined);
|
||||
expect(index).not.toBe(undefined);
|
||||
|
||||
expect(testData[index]).toBe(item);
|
||||
expect(this).toBe(scope);
|
||||
|
||||
iterated.push(item);
|
||||
}, scope, true);
|
||||
|
||||
expect(iterated.slice().reverse()).toEqual(testData);
|
||||
});
|
||||
|
||||
it('should iterate over properties in an object', function() {
|
||||
var testData = {
|
||||
myProp1: 'abc',
|
||||
myProp2: 276,
|
||||
myProp3: ['a', 'b']
|
||||
};
|
||||
|
||||
helpers.each(testData, function(value, key) {
|
||||
if (key === 'myProp1') {
|
||||
expect(value).toBe('abc');
|
||||
} else if (key === 'myProp2') {
|
||||
expect(value).toBe(276);
|
||||
} else if (key === 'myProp3') {
|
||||
expect(value).toEqual(['a', 'b']);
|
||||
} else {
|
||||
expect(false).toBe(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should not error when iterating over a null object', function() {
|
||||
expect(function() {
|
||||
helpers.each(undefined);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should clone an object', function() {
|
||||
var testData = {
|
||||
myProp1: 'abc',
|
||||
myProp2: ['a', 'b'],
|
||||
myProp3: {
|
||||
myProp4: 5,
|
||||
myProp5: [1, 2]
|
||||
}
|
||||
};
|
||||
|
||||
var clone = helpers.clone(testData);
|
||||
expect(clone).toEqual(testData);
|
||||
expect(clone).not.toBe(testData);
|
||||
|
||||
expect(clone.myProp2).not.toBe(testData.myProp2);
|
||||
expect(clone.myProp3).not.toBe(testData.myProp3);
|
||||
expect(clone.myProp3.myProp5).not.toBe(testData.myProp3.myProp5);
|
||||
});
|
||||
|
||||
it('should extend an object', function() {
|
||||
var original = {
|
||||
myProp1: 'abc',
|
||||
myProp2: 56
|
||||
};
|
||||
|
||||
var extension = {
|
||||
myProp3: [2, 5, 6],
|
||||
myProp2: 0
|
||||
};
|
||||
|
||||
helpers.extend(original, extension);
|
||||
|
||||
expect(original).toEqual({
|
||||
myProp1: 'abc',
|
||||
myProp2: 0,
|
||||
myProp3: [2, 5, 6],
|
||||
});
|
||||
});
|
||||
|
||||
it('should merge a normal config without scales', function() {
|
||||
var baseConfig = {
|
||||
valueProp: 5,
|
||||
arrayProp: [1, 2, 3, 4, 5, 6],
|
||||
objectProp: {
|
||||
prop1: 'abc',
|
||||
prop2: 56
|
||||
}
|
||||
};
|
||||
|
||||
var toMerge = {
|
||||
valueProp2: null,
|
||||
arrayProp: ['a', 'c'],
|
||||
objectProp: {
|
||||
prop1: 'c',
|
||||
prop3: 'prop3'
|
||||
}
|
||||
};
|
||||
|
||||
var merged = helpers.configMerge(baseConfig, toMerge);
|
||||
expect(merged).toEqual({
|
||||
valueProp: 5,
|
||||
valueProp2: null,
|
||||
arrayProp: ['a', 'c', 3, 4, 5, 6],
|
||||
objectProp: {
|
||||
prop1: 'c',
|
||||
prop2: 56,
|
||||
prop3: 'prop3'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should merge arrays containing objects', function() {
|
||||
var baseConfig = {
|
||||
arrayProp: [{
|
||||
prop1: 'abc',
|
||||
prop2: 56
|
||||
}],
|
||||
};
|
||||
|
||||
var toMerge = {
|
||||
arrayProp: [{
|
||||
prop1: 'myProp1',
|
||||
prop3: 'prop3'
|
||||
}, 2, {
|
||||
prop1: 'myProp1'
|
||||
}],
|
||||
};
|
||||
|
||||
var merged = helpers.configMerge(baseConfig, toMerge);
|
||||
expect(merged).toEqual({
|
||||
arrayProp: [{
|
||||
prop1: 'myProp1',
|
||||
prop2: 56,
|
||||
prop3: 'prop3'
|
||||
},
|
||||
2, {
|
||||
prop1: 'myProp1'
|
||||
}
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should merge scale configs', function() {
|
||||
var baseConfig = {
|
||||
scales: {
|
||||
prop1: {
|
||||
abc: 123,
|
||||
def: '456'
|
||||
},
|
||||
prop2: 777,
|
||||
yAxes: [{
|
||||
type: 'linear',
|
||||
}, {
|
||||
type: 'log'
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
var toMerge = {
|
||||
scales: {
|
||||
prop1: {
|
||||
def: 'bbb',
|
||||
ghi: 78
|
||||
},
|
||||
prop2: null,
|
||||
yAxes: [{
|
||||
type: 'linear',
|
||||
axisProp: 456
|
||||
}, {
|
||||
// pulls in linear default config since axis type changes
|
||||
type: 'linear',
|
||||
position: 'right'
|
||||
}, {
|
||||
// Pulls in linear default config since axis not in base
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
var merged = helpers.configMerge(baseConfig, toMerge);
|
||||
expect(merged).toEqual({
|
||||
scales: {
|
||||
prop1: {
|
||||
abc: 123,
|
||||
def: 'bbb',
|
||||
ghi: 78
|
||||
},
|
||||
prop2: null,
|
||||
yAxes: [{
|
||||
type: 'linear',
|
||||
axisProp: 456
|
||||
}, {
|
||||
display: true,
|
||||
|
||||
gridLines: {
|
||||
color: "rgba(0, 0, 0, 0.1)",
|
||||
drawBorder: true,
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true, // draw ticks extending towards the label
|
||||
tickMarkLength: 10,
|
||||
lineWidth: 1,
|
||||
offsetGridLines: false,
|
||||
display: true,
|
||||
zeroLineColor: "rgba(0,0,0,0.25)",
|
||||
zeroLineWidth: 1,
|
||||
},
|
||||
position: "right",
|
||||
scaleLabel: {
|
||||
labelString: '',
|
||||
display: false,
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: false,
|
||||
minRotation: 0,
|
||||
maxRotation: 50,
|
||||
mirror: false,
|
||||
padding: 10,
|
||||
reverse: false,
|
||||
display: true,
|
||||
callback: merged.scales.yAxes[1].ticks.callback, // make it nicer, then check explicitly below
|
||||
autoSkip: true,
|
||||
autoSkipPadding: 0,
|
||||
labelOffset: 0,
|
||||
},
|
||||
type: 'linear'
|
||||
}, {
|
||||
display: true,
|
||||
|
||||
gridLines: {
|
||||
color: "rgba(0, 0, 0, 0.1)",
|
||||
drawBorder: true,
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true, // draw ticks extending towards the label,
|
||||
tickMarkLength: 10,
|
||||
lineWidth: 1,
|
||||
offsetGridLines: false,
|
||||
display: true,
|
||||
zeroLineColor: "rgba(0,0,0,0.25)",
|
||||
zeroLineWidth: 1,
|
||||
},
|
||||
position: "left",
|
||||
scaleLabel: {
|
||||
labelString: '',
|
||||
display: false,
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: false,
|
||||
minRotation: 0,
|
||||
maxRotation: 50,
|
||||
mirror: false,
|
||||
padding: 10,
|
||||
reverse: false,
|
||||
display: true,
|
||||
callback: merged.scales.yAxes[2].ticks.callback, // make it nicer, then check explicitly below
|
||||
autoSkip: true,
|
||||
autoSkipPadding: 0,
|
||||
labelOffset: 0,
|
||||
},
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
// Are these actually functions
|
||||
expect(merged.scales.yAxes[1].ticks.callback).toEqual(jasmine.any(Function));
|
||||
expect(merged.scales.yAxes[2].ticks.callback).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it('should get value or default', function() {
|
||||
expect(helpers.getValueAtIndexOrDefault(98, 0, 56)).toBe(98);
|
||||
expect(helpers.getValueAtIndexOrDefault(0, 0, 56)).toBe(0);
|
||||
expect(helpers.getValueAtIndexOrDefault(undefined, undefined, 56)).toBe(56);
|
||||
expect(helpers.getValueAtIndexOrDefault([1, 2, 3], 1, 100)).toBe(2);
|
||||
expect(helpers.getValueAtIndexOrDefault([1, 2, 3], 3, 100)).toBe(100);
|
||||
});
|
||||
|
||||
it('should filter an array', function() {
|
||||
var data = [-10, 0, 6, 0, 7];
|
||||
var callback = function(item) {
|
||||
return item > 2
|
||||
};
|
||||
expect(helpers.where(data, callback)).toEqual([6, 7]);
|
||||
expect(helpers.findNextWhere(data, callback)).toEqual(6);
|
||||
expect(helpers.findNextWhere(data, callback, 2)).toBe(7);
|
||||
expect(helpers.findNextWhere(data, callback, 4)).toBe(undefined);
|
||||
expect(helpers.findPreviousWhere(data, callback)).toBe(7);
|
||||
expect(helpers.findPreviousWhere(data, callback, 3)).toBe(6);
|
||||
expect(helpers.findPreviousWhere(data, callback, 0)).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should get the correct sign', function() {
|
||||
expect(helpers.sign(0)).toBe(0);
|
||||
expect(helpers.sign(10)).toBe(1);
|
||||
expect(helpers.sign(-5)).toBe(-1);
|
||||
});
|
||||
|
||||
it('should do a log10 operation', function() {
|
||||
expect(helpers.log10(0)).toBe(-Infinity);
|
||||
expect(helpers.log10(1)).toBe(0);
|
||||
expect(helpers.log10(1000)).toBeCloseTo(3, 1e-9);
|
||||
});
|
||||
|
||||
it('should correctly determine if two numbers are essentially equal', function() {
|
||||
expect(helpers.almostEquals(0, Number.EPSILON, 2 * Number.EPSILON)).toBe(true);
|
||||
expect(helpers.almostEquals(1, 1.1, 0.0001)).toBe(false);
|
||||
expect(helpers.almostEquals(1e30, 1e30 + Number.EPSILON, 0)).toBe(false);
|
||||
expect(helpers.almostEquals(1e30, 1e30 + Number.EPSILON, 2 * Number.EPSILON)).toBe(true);
|
||||
});
|
||||
|
||||
it('should generate integer ids', function() {
|
||||
var uid = helpers.uid();
|
||||
expect(uid).toEqual(jasmine.any(Number));
|
||||
expect(helpers.uid()).toBe(uid + 1);
|
||||
expect(helpers.uid()).toBe(uid + 2);
|
||||
expect(helpers.uid()).toBe(uid + 3);
|
||||
});
|
||||
|
||||
it('should detect a number', function() {
|
||||
expect(helpers.isNumber(123)).toBe(true);
|
||||
expect(helpers.isNumber('123')).toBe(true);
|
||||
expect(helpers.isNumber(null)).toBe(false);
|
||||
expect(helpers.isNumber(NaN)).toBe(false);
|
||||
expect(helpers.isNumber(undefined)).toBe(false);
|
||||
expect(helpers.isNumber('cbc')).toBe(false);
|
||||
});
|
||||
|
||||
it('should convert between radians and degrees', function() {
|
||||
expect(helpers.toRadians(180)).toBe(Math.PI);
|
||||
expect(helpers.toRadians(90)).toBe(0.5 * Math.PI);
|
||||
expect(helpers.toDegrees(Math.PI)).toBe(180);
|
||||
expect(helpers.toDegrees(Math.PI * 3 / 2)).toBe(270);
|
||||
});
|
||||
|
||||
it('should get an angle from a point', function() {
|
||||
var center = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
|
||||
expect(helpers.getAngleFromPoint(center, {
|
||||
x: 0,
|
||||
y: 10
|
||||
})).toEqual({
|
||||
angle: Math.PI / 2,
|
||||
distance: 10,
|
||||
});
|
||||
|
||||
expect(helpers.getAngleFromPoint(center, {
|
||||
x: Math.sqrt(2),
|
||||
y: Math.sqrt(2)
|
||||
})).toEqual({
|
||||
angle: Math.PI / 4,
|
||||
distance: 2
|
||||
});
|
||||
|
||||
expect(helpers.getAngleFromPoint(center, {
|
||||
x: -1.0 * Math.sqrt(2),
|
||||
y: -1.0 * Math.sqrt(2)
|
||||
})).toEqual({
|
||||
angle: Math.PI * 1.25,
|
||||
distance: 2
|
||||
});
|
||||
});
|
||||
|
||||
it('should spline curves', function() {
|
||||
expect(helpers.splineCurve({
|
||||
x: 0,
|
||||
y: 0
|
||||
}, {
|
||||
x: 1,
|
||||
y: 1
|
||||
}, {
|
||||
x: 2,
|
||||
y: 0
|
||||
}, 0)).toEqual({
|
||||
previous: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
},
|
||||
next: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
}
|
||||
});
|
||||
|
||||
expect(helpers.splineCurve({
|
||||
x: 0,
|
||||
y: 0
|
||||
}, {
|
||||
x: 1,
|
||||
y: 1
|
||||
}, {
|
||||
x: 2,
|
||||
y: 0
|
||||
}, 1)).toEqual({
|
||||
previous: {
|
||||
x: 0,
|
||||
y: 1,
|
||||
},
|
||||
next: {
|
||||
x: 2,
|
||||
y: 1,
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should get the next or previous item in an array', function() {
|
||||
var testData = [0, 1, 2];
|
||||
|
||||
expect(helpers.nextItem(testData, 0, false)).toEqual(1);
|
||||
expect(helpers.nextItem(testData, 2, false)).toEqual(2);
|
||||
expect(helpers.nextItem(testData, 2, true)).toEqual(0);
|
||||
expect(helpers.nextItem(testData, 1, true)).toEqual(2);
|
||||
expect(helpers.nextItem(testData, -1, false)).toEqual(0);
|
||||
|
||||
expect(helpers.previousItem(testData, 0, false)).toEqual(0);
|
||||
expect(helpers.previousItem(testData, 0, true)).toEqual(2);
|
||||
expect(helpers.previousItem(testData, 2, false)).toEqual(1);
|
||||
expect(helpers.previousItem(testData, 1, true)).toEqual(0);
|
||||
});
|
||||
|
||||
it('should clear a canvas', function() {
|
||||
var context = window.createMockContext();
|
||||
helpers.clear({
|
||||
width: 100,
|
||||
height: 150,
|
||||
ctx: context
|
||||
});
|
||||
|
||||
expect(context.getCalls()).toEqual([{
|
||||
name: 'clearRect',
|
||||
args: [0, 0, 100, 150]
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should draw a rounded rectangle', function() {
|
||||
var context = window.createMockContext();
|
||||
helpers.drawRoundedRectangle(context, 10, 20, 30, 40, 5);
|
||||
|
||||
expect(context.getCalls()).toEqual([{
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [15, 20]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [35, 20]
|
||||
}, {
|
||||
name: 'quadraticCurveTo',
|
||||
args: [40, 20, 40, 25]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [40, 55]
|
||||
}, {
|
||||
name: 'quadraticCurveTo',
|
||||
args: [40, 60, 35, 60]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [15, 60]
|
||||
}, {
|
||||
name: 'quadraticCurveTo',
|
||||
args: [10, 60, 10, 55]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10, 25]
|
||||
}, {
|
||||
name: 'quadraticCurveTo',
|
||||
args: [10, 20, 15, 20]
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: []
|
||||
}])
|
||||
});
|
||||
|
||||
it ('should get the maximum width and height for a node', function() {
|
||||
// Create div with fixed size as a test bed
|
||||
var div = document.createElement('div');
|
||||
div.style.width = "200px";
|
||||
div.style.height = "300px";
|
||||
|
||||
document.body.appendChild(div);
|
||||
|
||||
// Create the div we want to get the max size for
|
||||
var innerDiv = document.createElement('div');
|
||||
div.appendChild(innerDiv);
|
||||
|
||||
expect(helpers.getMaximumWidth(innerDiv)).toBe(200);
|
||||
expect(helpers.getMaximumHeight(innerDiv)).toBe(300);
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it ('should get the maximum width of a node that has a max-width style', function() {
|
||||
// Create div with fixed size as a test bed
|
||||
var div = document.createElement('div');
|
||||
div.style.width = "200px";
|
||||
div.style.height = "300px";
|
||||
|
||||
document.body.appendChild(div);
|
||||
|
||||
// Create the div we want to get the max size for and set a max-width style
|
||||
var innerDiv = document.createElement('div');
|
||||
innerDiv.style.maxWidth = "150px";
|
||||
div.appendChild(innerDiv);
|
||||
|
||||
expect(helpers.getMaximumWidth(innerDiv)).toBe(150);
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it ('should get the maximum height of a node that has a max-height style', function() {
|
||||
// Create div with fixed size as a test bed
|
||||
var div = document.createElement('div');
|
||||
div.style.width = "200px";
|
||||
div.style.height = "300px";
|
||||
|
||||
document.body.appendChild(div);
|
||||
|
||||
// Create the div we want to get the max size for and set a max-height style
|
||||
var innerDiv = document.createElement('div');
|
||||
innerDiv.style.maxHeight = "150px";
|
||||
div.appendChild(innerDiv);
|
||||
|
||||
expect(helpers.getMaximumHeight(innerDiv)).toBe(150);
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it ('should get the maximum width of a node when the parent has a max-width style', function() {
|
||||
// Create div with fixed size as a test bed
|
||||
var div = document.createElement('div');
|
||||
div.style.width = "200px";
|
||||
div.style.height = "300px";
|
||||
|
||||
document.body.appendChild(div);
|
||||
|
||||
// Create an inner wrapper around our div we want to size and give that a max-width style
|
||||
var parentDiv = document.createElement('div');
|
||||
parentDiv.style.maxWidth = "150px";
|
||||
div.appendChild(parentDiv);
|
||||
|
||||
// Create the div we want to get the max size for
|
||||
var innerDiv = document.createElement('div');
|
||||
parentDiv.appendChild(innerDiv);
|
||||
|
||||
expect(helpers.getMaximumWidth(innerDiv)).toBe(150);
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it ('should get the maximum height of a node when the parent has a max-height style', function() {
|
||||
// Create div with fixed size as a test bed
|
||||
var div = document.createElement('div');
|
||||
div.style.width = "200px";
|
||||
div.style.height = "300px";
|
||||
|
||||
document.body.appendChild(div);
|
||||
|
||||
// Create an inner wrapper around our div we want to size and give that a max-height style
|
||||
var parentDiv = document.createElement('div');
|
||||
parentDiv.style.maxHeight = "150px";
|
||||
div.appendChild(parentDiv);
|
||||
|
||||
// Create the div we want to get the max size for
|
||||
var innerDiv = document.createElement('div');
|
||||
innerDiv.style.height = "300px"; // make it large
|
||||
parentDiv.appendChild(innerDiv);
|
||||
|
||||
expect(helpers.getMaximumHeight(innerDiv)).toBe(150);
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it ('should get the maximum width of a node that has a percentage max-width style', function() {
|
||||
// Create div with fixed size as a test bed
|
||||
var div = document.createElement('div');
|
||||
div.style.width = "200px";
|
||||
div.style.height = "300px";
|
||||
|
||||
document.body.appendChild(div);
|
||||
|
||||
// Create the div we want to get the max size for and set a max-width style
|
||||
var innerDiv = document.createElement('div');
|
||||
innerDiv.style.maxWidth = "50%";
|
||||
div.appendChild(innerDiv);
|
||||
|
||||
expect(helpers.getMaximumWidth(innerDiv)).toBe(100);
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it ('should get the maximum height of a node that has a percentage max-height style', function() {
|
||||
// Create div with fixed size as a test bed
|
||||
var div = document.createElement('div');
|
||||
div.style.width = "200px";
|
||||
div.style.height = "300px";
|
||||
|
||||
document.body.appendChild(div);
|
||||
|
||||
// Create the div we want to get the max size for and set a max-height style
|
||||
var innerDiv = document.createElement('div');
|
||||
innerDiv.style.maxHeight = "50%";
|
||||
div.appendChild(innerDiv);
|
||||
|
||||
expect(helpers.getMaximumHeight(innerDiv)).toBe(150);
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it ('should get the maximum width of a node when the parent has a percentage max-width style', function() {
|
||||
// Create div with fixed size as a test bed
|
||||
var div = document.createElement('div');
|
||||
div.style.width = "200px";
|
||||
div.style.height = "300px";
|
||||
|
||||
document.body.appendChild(div);
|
||||
|
||||
// Create an inner wrapper around our div we want to size and give that a max-width style
|
||||
var parentDiv = document.createElement('div');
|
||||
parentDiv.style.maxWidth = "50%";
|
||||
div.appendChild(parentDiv);
|
||||
|
||||
// Create the div we want to get the max size for
|
||||
var innerDiv = document.createElement('div');
|
||||
parentDiv.appendChild(innerDiv);
|
||||
|
||||
expect(helpers.getMaximumWidth(innerDiv)).toBe(100);
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it ('should get the maximum height of a node when the parent has a percentage max-height style', function() {
|
||||
// Create div with fixed size as a test bed
|
||||
var div = document.createElement('div');
|
||||
div.style.width = "200px";
|
||||
div.style.height = "300px";
|
||||
|
||||
document.body.appendChild(div);
|
||||
|
||||
// Create an inner wrapper around our div we want to size and give that a max-height style
|
||||
var parentDiv = document.createElement('div');
|
||||
parentDiv.style.maxHeight = "50%";
|
||||
div.appendChild(parentDiv);
|
||||
|
||||
var innerDiv = document.createElement('div');
|
||||
innerDiv.style.height = "300px"; // make it large
|
||||
parentDiv.appendChild(innerDiv);
|
||||
|
||||
expect(helpers.getMaximumHeight(innerDiv)).toBe(150);
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
describe('Color helper', function() {
|
||||
function isColorInstance(obj) {
|
||||
return typeof obj === 'object' && obj.hasOwnProperty('values') && obj.values.hasOwnProperty('rgb');
|
||||
}
|
||||
|
||||
it('should return a color when called with a color', function() {
|
||||
expect(isColorInstance(helpers.color('rgb(1, 2, 3)'))).toBe(true);
|
||||
});
|
||||
|
||||
it('should return a color when called with a CanvasGradient instance', function() {
|
||||
var context = document.createElement('canvas').getContext('2d');
|
||||
var gradient = context.createLinearGradient(0, 1, 2, 3);
|
||||
|
||||
expect(isColorInstance(helpers.color(gradient))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Background hover color helper', function() {
|
||||
it('should return a CanvasPattern when called with a CanvasPattern', function(done) {
|
||||
var dots = new Image();
|
||||
dots.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAD1BMVEUAAAD///////////////+PQt5oAAAABXRSTlMAHlFhZsfk/BEAAAAqSURBVHgBY2BgZGJmYmSAAUYWEIDzmcBcJhiXGcxlRpPFrhdmMiqgvX0AcGIBEUAo6UAAAAAASUVORK5CYII=';
|
||||
dots.onload = function() {
|
||||
var chartContext = document.createElement('canvas').getContext('2d');
|
||||
var patternCanvas = document.createElement('canvas');
|
||||
var patternContext = patternCanvas.getContext('2d');
|
||||
var pattern = patternContext.createPattern(dots, 'repeat');
|
||||
patternContext.fillStyle = pattern;
|
||||
|
||||
var backgroundColor = helpers.getHoverColor(chartContext.createPattern(patternCanvas, 'repeat'));
|
||||
|
||||
expect(backgroundColor instanceof CanvasPattern).toBe(true);
|
||||
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('should return a modified version of color when called with a color', function() {
|
||||
var originalColorRGB = 'rgb(70, 191, 189)';
|
||||
|
||||
expect(helpers.getHoverColor('#46BFBD')).not.toEqual(originalColorRGB);
|
||||
});
|
||||
});
|
||||
});
|
||||
244
vendors/Chart.js/test/core.layoutService.tests.js
vendored
Normal file
244
vendors/Chart.js/test/core.layoutService.tests.js
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
// Tests of the scale service
|
||||
describe('Test the layout service', function() {
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.releaseAllCharts();
|
||||
});
|
||||
|
||||
it('should fit a simple chart with 2 scales', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [
|
||||
{ data: [10, 5, 0, 25, 78, -10] }
|
||||
],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale',
|
||||
type: 'category'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
height: '150px',
|
||||
width: '250px'
|
||||
});
|
||||
|
||||
expect(chart.chartArea.bottom).toBeCloseToPixel(112);
|
||||
expect(chart.chartArea.left).toBeCloseToPixel(41);
|
||||
expect(chart.chartArea.right).toBeCloseToPixel(250);
|
||||
expect(chart.chartArea.top).toBeCloseToPixel(32);
|
||||
|
||||
// Is xScale at the right spot
|
||||
expect(chart.scales.xScale.bottom).toBeCloseToPixel(150);
|
||||
expect(chart.scales.xScale.left).toBeCloseToPixel(41);
|
||||
expect(chart.scales.xScale.right).toBeCloseToPixel(250);
|
||||
expect(chart.scales.xScale.top).toBeCloseToPixel(112);
|
||||
expect(chart.scales.xScale.labelRotation).toBeCloseTo(25);
|
||||
|
||||
// Is yScale at the right spot
|
||||
expect(chart.scales.yScale.bottom).toBeCloseToPixel(112);
|
||||
expect(chart.scales.yScale.left).toBeCloseToPixel(0);
|
||||
expect(chart.scales.yScale.right).toBeCloseToPixel(41);
|
||||
expect(chart.scales.yScale.top).toBeCloseToPixel(32);
|
||||
expect(chart.scales.yScale.labelRotation).toBeCloseTo(0);
|
||||
});
|
||||
|
||||
it('should fit scales that are in the top and right positions', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [
|
||||
{ data: [10, 5, 0, 25, 78, -10] }
|
||||
],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale',
|
||||
type: 'category',
|
||||
position: 'top'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'linear',
|
||||
position: 'right'
|
||||
}]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
height: '150px',
|
||||
width: '250px'
|
||||
});
|
||||
|
||||
expect(chart.chartArea.bottom).toBeCloseToPixel(150);
|
||||
expect(chart.chartArea.left).toBeCloseToPixel(0);
|
||||
expect(chart.chartArea.right).toBeCloseToPixel(209);
|
||||
expect(chart.chartArea.top).toBeCloseToPixel(71);
|
||||
|
||||
// Is xScale at the right spot
|
||||
expect(chart.scales.xScale.bottom).toBeCloseToPixel(71);
|
||||
expect(chart.scales.xScale.left).toBeCloseToPixel(0);
|
||||
expect(chart.scales.xScale.right).toBeCloseToPixel(209);
|
||||
expect(chart.scales.xScale.top).toBeCloseToPixel(32);
|
||||
expect(chart.scales.xScale.labelRotation).toBeCloseTo(25);
|
||||
|
||||
// Is yScale at the right spot
|
||||
expect(chart.scales.yScale.bottom).toBeCloseToPixel(150);
|
||||
expect(chart.scales.yScale.left).toBeCloseToPixel(209);
|
||||
expect(chart.scales.yScale.right).toBeCloseToPixel(250);
|
||||
expect(chart.scales.yScale.top).toBeCloseToPixel(71);
|
||||
expect(chart.scales.yScale.labelRotation).toBeCloseTo(0);
|
||||
});
|
||||
|
||||
it('should fit scales that overlap the chart area', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 0, 25, 78, -10]
|
||||
}, {
|
||||
data: [-19, -20, 0, -99, -50, 0]
|
||||
}],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']
|
||||
}
|
||||
});
|
||||
|
||||
expect(chart.chartArea.bottom).toBeCloseToPixel(512);
|
||||
expect(chart.chartArea.left).toBeCloseToPixel(0);
|
||||
expect(chart.chartArea.right).toBeCloseToPixel(512);
|
||||
expect(chart.chartArea.top).toBeCloseToPixel(32);
|
||||
|
||||
expect(chart.scale.bottom).toBeCloseToPixel(512);
|
||||
expect(chart.scale.left).toBeCloseToPixel(0);
|
||||
expect(chart.scale.right).toBeCloseToPixel(512);
|
||||
expect(chart.scale.top).toBeCloseToPixel(32);
|
||||
expect(chart.scale.width).toBeCloseToPixel(512);
|
||||
expect(chart.scale.height).toBeCloseToPixel(480)
|
||||
});
|
||||
|
||||
it('should fit multiple axes in the same position', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale1',
|
||||
data: [10, 5, 0, 25, 78, -10]
|
||||
}, {
|
||||
yAxisID: 'yScale2',
|
||||
data: [-19, -20, 0, -99, -50, 0]
|
||||
}],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale',
|
||||
type: 'category'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale1',
|
||||
type: 'linear'
|
||||
}, {
|
||||
id: 'yScale2',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
height: '150px',
|
||||
width: '250px'
|
||||
});
|
||||
|
||||
expect(chart.chartArea.bottom).toBeCloseToPixel(102);
|
||||
expect(chart.chartArea.left).toBeCloseToPixel(86);
|
||||
expect(chart.chartArea.right).toBeCloseToPixel(250);
|
||||
expect(chart.chartArea.top).toBeCloseToPixel(32);
|
||||
|
||||
// Is xScale at the right spot
|
||||
expect(chart.scales.xScale.bottom).toBeCloseToPixel(150);
|
||||
expect(chart.scales.xScale.left).toBeCloseToPixel(86);
|
||||
expect(chart.scales.xScale.right).toBeCloseToPixel(250);
|
||||
expect(chart.scales.xScale.top).toBeCloseToPixel(103);
|
||||
expect(chart.scales.xScale.labelRotation).toBeCloseTo(50);
|
||||
|
||||
// Are yScales at the right spot
|
||||
expect(chart.scales.yScale1.bottom).toBeCloseToPixel(102);
|
||||
expect(chart.scales.yScale1.left).toBeCloseToPixel(0);
|
||||
expect(chart.scales.yScale1.right).toBeCloseToPixel(41);
|
||||
expect(chart.scales.yScale1.top).toBeCloseToPixel(32);
|
||||
expect(chart.scales.yScale1.labelRotation).toBeCloseTo(0);
|
||||
|
||||
expect(chart.scales.yScale2.bottom).toBeCloseToPixel(102);
|
||||
expect(chart.scales.yScale2.left).toBeCloseToPixel(41);
|
||||
expect(chart.scales.yScale2.right).toBeCloseToPixel(86);
|
||||
expect(chart.scales.yScale2.top).toBeCloseToPixel(32);
|
||||
expect(chart.scales.yScale2.labelRotation).toBeCloseTo(0);
|
||||
});
|
||||
|
||||
it ('should fix a full width box correctly', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
xAxisID: 'xScale1',
|
||||
data: [10, 5, 0, 25, 78, -10]
|
||||
}, {
|
||||
xAxisID: 'xScale2',
|
||||
data: [-19, -20, 0, -99, -50, 0]
|
||||
}],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale1',
|
||||
type: 'category'
|
||||
}, {
|
||||
id: 'xScale2',
|
||||
type: 'category',
|
||||
position: 'top',
|
||||
fullWidth: true
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chart.chartArea.bottom).toBeCloseToPixel(484);
|
||||
expect(chart.chartArea.left).toBeCloseToPixel(45);
|
||||
expect(chart.chartArea.right).toBeCloseToPixel(512);
|
||||
expect(chart.chartArea.top).toBeCloseToPixel(60);
|
||||
|
||||
// Are xScales at the right spot
|
||||
expect(chart.scales.xScale1.bottom).toBeCloseToPixel(512);
|
||||
expect(chart.scales.xScale1.left).toBeCloseToPixel(45);
|
||||
expect(chart.scales.xScale1.right).toBeCloseToPixel(512);
|
||||
expect(chart.scales.xScale1.top).toBeCloseToPixel(484);
|
||||
|
||||
expect(chart.scales.xScale2.bottom).toBeCloseToPixel(28);
|
||||
expect(chart.scales.xScale2.left).toBeCloseToPixel(0);
|
||||
expect(chart.scales.xScale2.right).toBeCloseToPixel(512);
|
||||
expect(chart.scales.xScale2.top).toBeCloseToPixel(0);
|
||||
|
||||
// Is yScale at the right spot
|
||||
expect(chart.scales.yScale.bottom).toBeCloseToPixel(484);
|
||||
expect(chart.scales.yScale.left).toBeCloseToPixel(0);
|
||||
expect(chart.scales.yScale.right).toBeCloseToPixel(45);
|
||||
expect(chart.scales.yScale.top).toBeCloseToPixel(60);
|
||||
});
|
||||
});
|
||||
308
vendors/Chart.js/test/core.legend.tests.js
vendored
Normal file
308
vendors/Chart.js/test/core.legend.tests.js
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
// Test the rectangle element
|
||||
describe('Legend block tests', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.releaseAllCharts();
|
||||
});
|
||||
|
||||
it('Should be constructed', function() {
|
||||
var legend = new Chart.Legend({});
|
||||
expect(legend).not.toBe(undefined);
|
||||
});
|
||||
|
||||
it('should have the correct default config', function() {
|
||||
expect(Chart.defaults.global.legend).toEqual({
|
||||
display: true,
|
||||
position: 'top',
|
||||
fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
|
||||
reverse: false,
|
||||
|
||||
// a callback that will handle
|
||||
onClick: jasmine.any(Function),
|
||||
|
||||
labels: {
|
||||
boxWidth: 40,
|
||||
padding: 10,
|
||||
generateLabels: jasmine.any(Function)
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should update correctly', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'dataset1',
|
||||
backgroundColor: '#f31',
|
||||
borderCapStyle: 'butt',
|
||||
borderDash: [2, 2],
|
||||
borderDashOffset: 5.5,
|
||||
data: []
|
||||
}, {
|
||||
label: 'dataset2',
|
||||
hidden: true,
|
||||
borderJoinStyle: 'miter',
|
||||
data: []
|
||||
}, {
|
||||
label: 'dataset3',
|
||||
borderWidth: 10,
|
||||
borderColor: 'green',
|
||||
data: []
|
||||
}],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
expect(chart.legend.legendItems).toEqual([{
|
||||
text: 'dataset1',
|
||||
fillStyle: '#f31',
|
||||
hidden: false,
|
||||
lineCap: 'butt',
|
||||
lineDash: [2, 2],
|
||||
lineDashOffset: 5.5,
|
||||
lineJoin: undefined,
|
||||
lineWidth: undefined,
|
||||
strokeStyle: undefined,
|
||||
datasetIndex: 0
|
||||
}, {
|
||||
text: 'dataset2',
|
||||
fillStyle: undefined,
|
||||
hidden: true,
|
||||
lineCap: undefined,
|
||||
lineDash: undefined,
|
||||
lineDashOffset: undefined,
|
||||
lineJoin: 'miter',
|
||||
lineWidth: undefined,
|
||||
strokeStyle: undefined,
|
||||
datasetIndex: 1
|
||||
}, {
|
||||
text: 'dataset3',
|
||||
fillStyle: undefined,
|
||||
hidden: false,
|
||||
lineCap: undefined,
|
||||
lineDash: undefined,
|
||||
lineDashOffset: undefined,
|
||||
lineJoin: undefined,
|
||||
lineWidth: 10,
|
||||
strokeStyle: 'green',
|
||||
datasetIndex: 2
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should draw correctly', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'dataset1',
|
||||
backgroundColor: '#f31',
|
||||
borderCapStyle: 'butt',
|
||||
borderDash: [2, 2],
|
||||
borderDashOffset: 5.5,
|
||||
data: []
|
||||
}, {
|
||||
label: 'dataset2',
|
||||
hidden: true,
|
||||
borderJoinStyle: 'miter',
|
||||
data: []
|
||||
}, {
|
||||
label: 'dataset3',
|
||||
borderWidth: 10,
|
||||
borderColor: 'green',
|
||||
data: []
|
||||
}],
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
|
||||
expect(chart.legend.legendHitBoxes.length).toBe(3);
|
||||
|
||||
[ { h: 12, l: 101, t: 10, w: 93 },
|
||||
{ h: 12, l: 205, t: 10, w: 93 },
|
||||
{ h: 12, l: 308, t: 10, w: 93 }
|
||||
].forEach(function(expected, i) {
|
||||
expect(chart.legend.legendHitBoxes[i].height).toBeCloseToPixel(expected.h);
|
||||
expect(chart.legend.legendHitBoxes[i].left).toBeCloseToPixel(expected.l);
|
||||
expect(chart.legend.legendHitBoxes[i].top).toBeCloseToPixel(expected.t);
|
||||
expect(chart.legend.legendHitBoxes[i].width).toBeCloseToPixel(expected.w);
|
||||
})
|
||||
|
||||
// NOTE(SB) We should get ride of the following tests and use image diff instead.
|
||||
// For now, as discussed with Evert Timberg, simply comment out.
|
||||
// See http://humblesoftware.github.io/js-imagediff/test.html
|
||||
/*chart.legend.ctx = window.createMockContext();
|
||||
chart.update();
|
||||
|
||||
expect(chart.legend.ctx .getCalls()).toEqual([{
|
||||
"name": "measureText",
|
||||
"args": ["dataset1"]
|
||||
}, {
|
||||
"name": "measureText",
|
||||
"args": ["dataset2"]
|
||||
}, {
|
||||
"name": "measureText",
|
||||
"args": ["dataset3"]
|
||||
}, {
|
||||
"name": "measureText",
|
||||
"args": ["dataset1"]
|
||||
}, {
|
||||
"name": "measureText",
|
||||
"args": ["dataset2"]
|
||||
}, {
|
||||
"name": "measureText",
|
||||
"args": ["dataset3"]
|
||||
}, {
|
||||
"name": "setLineWidth",
|
||||
"args": [0.5]
|
||||
}, {
|
||||
"name": "setStrokeStyle",
|
||||
"args": ["#666"]
|
||||
}, {
|
||||
"name": "setFillStyle",
|
||||
"args": ["#666"]
|
||||
}, {
|
||||
"name": "measureText",
|
||||
"args": ["dataset1"]
|
||||
}, {
|
||||
"name": "save",
|
||||
"args": []
|
||||
}, {
|
||||
"name": "setFillStyle",
|
||||
"args": ["#f31"]
|
||||
}, {
|
||||
"name": "setLineCap",
|
||||
"args": ["butt"]
|
||||
}, {
|
||||
"name": "setLineDashOffset",
|
||||
"args": [5.5]
|
||||
}, {
|
||||
"name": "setLineJoin",
|
||||
"args": ["miter"]
|
||||
}, {
|
||||
"name": "setLineWidth",
|
||||
"args": [3]
|
||||
}, {
|
||||
"name": "setStrokeStyle",
|
||||
"args": ["rgba(0,0,0,0.1)"]
|
||||
}, {
|
||||
"name": "setLineDash",
|
||||
"args": [
|
||||
[2, 2]
|
||||
]
|
||||
}, {
|
||||
"name": "strokeRect",
|
||||
"args": [114, 110, 40, 12]
|
||||
}, {
|
||||
"name": "fillRect",
|
||||
"args": [114, 110, 40, 12]
|
||||
}, {
|
||||
"name": "restore",
|
||||
"args": []
|
||||
}, {
|
||||
"name": "fillText",
|
||||
"args": ["dataset1", 160, 110]
|
||||
}, {
|
||||
"name": "measureText",
|
||||
"args": ["dataset2"]
|
||||
}, {
|
||||
"name": "save",
|
||||
"args": []
|
||||
}, {
|
||||
"name": "setFillStyle",
|
||||
"args": ["rgba(0,0,0,0.1)"]
|
||||
}, {
|
||||
"name": "setLineCap",
|
||||
"args": ["butt"]
|
||||
}, {
|
||||
"name": "setLineDashOffset",
|
||||
"args": [0]
|
||||
}, {
|
||||
"name": "setLineJoin",
|
||||
"args": ["miter"]
|
||||
}, {
|
||||
"name": "setLineWidth",
|
||||
"args": [3]
|
||||
}, {
|
||||
"name": "setStrokeStyle",
|
||||
"args": ["rgba(0,0,0,0.1)"]
|
||||
}, {
|
||||
"name": "setLineDash",
|
||||
"args": [
|
||||
[]
|
||||
]
|
||||
}, {
|
||||
"name": "strokeRect",
|
||||
"args": [250, 110, 40, 12]
|
||||
}, {
|
||||
"name": "fillRect",
|
||||
"args": [250, 110, 40, 12]
|
||||
}, {
|
||||
"name": "restore",
|
||||
"args": []
|
||||
}, {
|
||||
"name": "fillText",
|
||||
"args": ["dataset2", 296, 110]
|
||||
}, {
|
||||
"name": "beginPath",
|
||||
"args": []
|
||||
}, {
|
||||
"name": "setLineWidth",
|
||||
"args": [2]
|
||||
}, {
|
||||
"name": "moveTo",
|
||||
"args": [296, 116]
|
||||
}, {
|
||||
"name": "lineTo",
|
||||
"args": [376, 116]
|
||||
}, {
|
||||
"name": "stroke",
|
||||
"args": []
|
||||
}, {
|
||||
"name": "measureText",
|
||||
"args": ["dataset3"]
|
||||
}, {
|
||||
"name": "save",
|
||||
"args": []
|
||||
}, {
|
||||
"name": "setFillStyle",
|
||||
"args": ["rgba(0,0,0,0.1)"]
|
||||
}, {
|
||||
"name": "setLineCap",
|
||||
"args": ["butt"]
|
||||
}, {
|
||||
"name": "setLineDashOffset",
|
||||
"args": [0]
|
||||
}, {
|
||||
"name": "setLineJoin",
|
||||
"args": ["miter"]
|
||||
}, {
|
||||
"name": "setLineWidth",
|
||||
"args": [10]
|
||||
}, {
|
||||
"name": "setStrokeStyle",
|
||||
"args": ["green"]
|
||||
}, {
|
||||
"name": "setLineDash",
|
||||
"args": [
|
||||
[]
|
||||
]
|
||||
}, {
|
||||
"name": "strokeRect",
|
||||
"args": [182, 132, 40, 12]
|
||||
}, {
|
||||
"name": "fillRect",
|
||||
"args": [182, 132, 40, 12]
|
||||
}, {
|
||||
"name": "restore",
|
||||
"args": []
|
||||
}, {
|
||||
"name": "fillText",
|
||||
"args": ["dataset3", 228, 132]
|
||||
}]);*/
|
||||
});
|
||||
});
|
||||
43
vendors/Chart.js/test/core.plugin.tests.js
vendored
Normal file
43
vendors/Chart.js/test/core.plugin.tests.js
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// Plugin tests
|
||||
describe('Test the plugin system', function() {
|
||||
beforeEach(function() {
|
||||
Chart.plugins = [];
|
||||
});
|
||||
|
||||
it ('Should register plugins', function() {
|
||||
var myplugin = {};
|
||||
Chart.pluginService.register(myplugin);
|
||||
expect(Chart.plugins.length).toBe(1);
|
||||
|
||||
// Should only add plugin once
|
||||
Chart.pluginService.register(myplugin);
|
||||
expect(Chart.plugins.length).toBe(1);
|
||||
});
|
||||
|
||||
it ('Should allow unregistering plugins', function() {
|
||||
var myplugin = {};
|
||||
Chart.pluginService.register(myplugin);
|
||||
expect(Chart.plugins.length).toBe(1);
|
||||
|
||||
// Should only add plugin once
|
||||
Chart.pluginService.remove(myplugin);
|
||||
expect(Chart.plugins.length).toBe(0);
|
||||
|
||||
// Removing a plugin that doesn't exist should not error
|
||||
Chart.pluginService.remove(myplugin);
|
||||
});
|
||||
|
||||
it ('Should allow notifying plugins', function() {
|
||||
var myplugin = {
|
||||
count: 0,
|
||||
trigger: function(chart) {
|
||||
myplugin.count = chart.count;
|
||||
}
|
||||
};
|
||||
Chart.pluginService.register(myplugin);
|
||||
|
||||
Chart.pluginService.notifyPlugins('trigger', [{ count: 10 }]);
|
||||
|
||||
expect(myplugin.count).toBe(10);
|
||||
});
|
||||
});
|
||||
29
vendors/Chart.js/test/core.scaleService.tests.js
vendored
Normal file
29
vendors/Chart.js/test/core.scaleService.tests.js
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Tests of the scale service
|
||||
describe('Test the scale service', function() {
|
||||
|
||||
it('should update scale defaults', function() {
|
||||
var defaults = {
|
||||
testProp: true
|
||||
};
|
||||
var type = 'my_test_type';
|
||||
var Constructor = function() {
|
||||
this.initialized = true;
|
||||
};
|
||||
Chart.scaleService.registerScaleType(type, Constructor, defaults);
|
||||
|
||||
// Should equal defaults but not be an identical object
|
||||
expect(Chart.scaleService.getScaleDefaults(type)).toEqual(jasmine.objectContaining({
|
||||
testProp: true
|
||||
}));
|
||||
|
||||
Chart.scaleService.updateScaleDefaults(type, {
|
||||
testProp: 'red',
|
||||
newProp: 42
|
||||
});
|
||||
|
||||
expect(Chart.scaleService.getScaleDefaults(type)).toEqual(jasmine.objectContaining({
|
||||
testProp: 'red',
|
||||
newProp: 42
|
||||
}));
|
||||
});
|
||||
});
|
||||
210
vendors/Chart.js/test/core.title.tests.js
vendored
Normal file
210
vendors/Chart.js/test/core.title.tests.js
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
// Test the rectangle element
|
||||
|
||||
describe('Title block tests', function() {
|
||||
it('Should be constructed', function() {
|
||||
var title = new Chart.Title({});
|
||||
expect(title).not.toBe(undefined);
|
||||
});
|
||||
|
||||
it('Should have the correct default config', function() {
|
||||
expect(Chart.defaults.global.title).toEqual({
|
||||
display: false,
|
||||
position: 'top',
|
||||
fullWidth: true,
|
||||
fontStyle: 'bold',
|
||||
padding: 10,
|
||||
text: ''
|
||||
})
|
||||
});
|
||||
|
||||
it('should update correctly', function() {
|
||||
var chart = {};
|
||||
|
||||
var options = Chart.helpers.clone(Chart.defaults.global.title);
|
||||
options.text = "My title";
|
||||
|
||||
var title = new Chart.Title({
|
||||
chart: chart,
|
||||
options: options
|
||||
});
|
||||
|
||||
var minSize = title.update(400, 200);
|
||||
|
||||
expect(minSize).toEqual({
|
||||
width: 400,
|
||||
height: 0
|
||||
});
|
||||
|
||||
// Now we have a height since we display
|
||||
title.options.display = true;
|
||||
|
||||
minSize = title.update(400, 200);
|
||||
|
||||
expect(minSize).toEqual({
|
||||
width: 400,
|
||||
height: 32
|
||||
});
|
||||
});
|
||||
|
||||
it('should update correctly when vertical', function() {
|
||||
var chart = {};
|
||||
|
||||
var options = Chart.helpers.clone(Chart.defaults.global.title);
|
||||
options.text = "My title";
|
||||
options.position = 'left';
|
||||
|
||||
var title = new Chart.Title({
|
||||
chart: chart,
|
||||
options: options
|
||||
});
|
||||
|
||||
var minSize = title.update(200, 400);
|
||||
|
||||
expect(minSize).toEqual({
|
||||
width: 0,
|
||||
height: 400
|
||||
});
|
||||
|
||||
// Now we have a height since we display
|
||||
title.options.display = true;
|
||||
|
||||
minSize = title.update(200, 400);
|
||||
|
||||
expect(minSize).toEqual({
|
||||
width: 32,
|
||||
height: 400
|
||||
});
|
||||
});
|
||||
|
||||
it('should draw correctly horizontally', function() {
|
||||
var chart = {};
|
||||
var context = window.createMockContext();
|
||||
|
||||
var options = Chart.helpers.clone(Chart.defaults.global.title);
|
||||
options.text = "My title";
|
||||
|
||||
var title = new Chart.Title({
|
||||
chart: chart,
|
||||
options: options,
|
||||
ctx: context
|
||||
});
|
||||
|
||||
title.update(400, 200);
|
||||
title.draw();
|
||||
|
||||
expect(context.getCalls()).toEqual([]);
|
||||
|
||||
// Now we have a height since we display
|
||||
title.options.display = true;
|
||||
|
||||
var minSize = title.update(400, 200);
|
||||
title.top = 50;
|
||||
title.left = 100;
|
||||
title.bottom = title.top + minSize.height;
|
||||
title.right = title.left + minSize.width;
|
||||
title.draw();
|
||||
|
||||
expect(context.getCalls()).toEqual([{
|
||||
name: 'setFillStyle',
|
||||
args: ['#666']
|
||||
}, {
|
||||
name: 'save',
|
||||
args: []
|
||||
}, {
|
||||
name: 'translate',
|
||||
args: [300, 66]
|
||||
}, {
|
||||
name: 'rotate',
|
||||
args: [0]
|
||||
}, {
|
||||
name: 'fillText',
|
||||
args: ['My title', 0, 0]
|
||||
}, {
|
||||
name: 'restore',
|
||||
args: []
|
||||
}]);
|
||||
});
|
||||
|
||||
it ('should draw correctly vertically', function() {
|
||||
var chart = {};
|
||||
var context = window.createMockContext();
|
||||
|
||||
var options = Chart.helpers.clone(Chart.defaults.global.title);
|
||||
options.text = "My title";
|
||||
options.position = 'left';
|
||||
|
||||
var title = new Chart.Title({
|
||||
chart: chart,
|
||||
options: options,
|
||||
ctx: context
|
||||
});
|
||||
|
||||
title.update(200, 400);
|
||||
title.draw();
|
||||
|
||||
expect(context.getCalls()).toEqual([]);
|
||||
|
||||
// Now we have a height since we display
|
||||
title.options.display = true;
|
||||
|
||||
var minSize = title.update(200, 400);
|
||||
title.top = 50;
|
||||
title.left = 100;
|
||||
title.bottom = title.top + minSize.height;
|
||||
title.right = title.left + minSize.width;
|
||||
title.draw();
|
||||
|
||||
expect(context.getCalls()).toEqual([{
|
||||
name: 'setFillStyle',
|
||||
args: ['#666']
|
||||
}, {
|
||||
name: 'save',
|
||||
args: []
|
||||
}, {
|
||||
name: 'translate',
|
||||
args: [106, 250]
|
||||
}, {
|
||||
name: 'rotate',
|
||||
args: [-0.5 * Math.PI]
|
||||
}, {
|
||||
name: 'fillText',
|
||||
args: ['My title', 0, 0]
|
||||
}, {
|
||||
name: 'restore',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
// Rotation is other way on right side
|
||||
title.options.position = 'right';
|
||||
|
||||
// Reset call tracker
|
||||
context.resetCalls();
|
||||
|
||||
minSize = title.update(200, 400);
|
||||
title.top = 50;
|
||||
title.left = 100;
|
||||
title.bottom = title.top + minSize.height;
|
||||
title.right = title.left + minSize.width;
|
||||
title.draw();
|
||||
|
||||
expect(context.getCalls()).toEqual([{
|
||||
name: 'setFillStyle',
|
||||
args: ['#666']
|
||||
}, {
|
||||
name: 'save',
|
||||
args: []
|
||||
}, {
|
||||
name: 'translate',
|
||||
args: [126, 250]
|
||||
}, {
|
||||
name: 'rotate',
|
||||
args: [0.5 * Math.PI]
|
||||
}, {
|
||||
name: 'fillText',
|
||||
args: ['My title', 0, 0]
|
||||
}, {
|
||||
name: 'restore',
|
||||
args: []
|
||||
}]);
|
||||
});
|
||||
});
|
||||
293
vendors/Chart.js/test/defaultConfig.tests.js
vendored
Normal file
293
vendors/Chart.js/test/defaultConfig.tests.js
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
// Test the bubble chart default config
|
||||
describe("Test the bubble chart default config", function() {
|
||||
it('should reutrn correct tooltip strings', function() {
|
||||
var config = Chart.defaults.bubble;
|
||||
|
||||
// Title is always blank
|
||||
expect(config.tooltips.callbacks.title()).toBe('');
|
||||
|
||||
// Item label
|
||||
var data = {
|
||||
datasets: [{
|
||||
label: 'My dataset',
|
||||
data: [{
|
||||
x: 10,
|
||||
y: 12,
|
||||
r: 5
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
var tooltipItem = {
|
||||
datasetIndex: 0,
|
||||
index: 0
|
||||
};
|
||||
|
||||
expect(config.tooltips.callbacks.label(tooltipItem, data)).toBe('My dataset: (10, 12, 5)');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test the doughnut chart default config', function() {
|
||||
it('should return correct tooltip strings', function() {
|
||||
var config = Chart.defaults.doughnut;
|
||||
|
||||
// Title is always blank
|
||||
expect(config.tooltips.callbacks.title()).toBe('');
|
||||
|
||||
// Item label
|
||||
var data = {
|
||||
labels: ['label1', 'label2', 'label3'],
|
||||
datasets: [{
|
||||
data: [10, 20, 30],
|
||||
}]
|
||||
};
|
||||
|
||||
var tooltipItem = {
|
||||
datasetIndex: 0,
|
||||
index: 1
|
||||
};
|
||||
|
||||
expect(config.tooltips.callbacks.label(tooltipItem, data)).toBe('label2: 20');
|
||||
});
|
||||
|
||||
it('should return the correct html legend', function() {
|
||||
var config = Chart.defaults.doughnut;
|
||||
|
||||
var chart = {
|
||||
id: 'mychart',
|
||||
data: {
|
||||
labels: ['label1', 'label2'],
|
||||
datasets: [{
|
||||
data: [10, 20],
|
||||
backgroundColor: ['red', 'green']
|
||||
}]
|
||||
}
|
||||
};
|
||||
var expectedLegend = '<ul class="mychart-legend"><li><span style="background-color:red"></span>label1</li><li><span style="background-color:green"></span>label2</li></ul>';
|
||||
|
||||
expect(config.legendCallback(chart)).toBe(expectedLegend);
|
||||
});
|
||||
|
||||
it('should return correct legend label objects', function() {
|
||||
var config = Chart.defaults.doughnut;
|
||||
var data = {
|
||||
labels: ['label1', 'label2', 'label3'],
|
||||
datasets: [{
|
||||
data: [10, 20, NaN],
|
||||
backgroundColor: ['red', 'green', 'blue'],
|
||||
metaData: [{}, {}, {}]
|
||||
}]
|
||||
};
|
||||
|
||||
var expected = [{
|
||||
text: 'label1',
|
||||
fillStyle: 'red',
|
||||
hidden: false,
|
||||
index: 0,
|
||||
strokeStyle: '#000',
|
||||
lineWidth: 2
|
||||
}, {
|
||||
text: 'label2',
|
||||
fillStyle: 'green',
|
||||
hidden: false,
|
||||
index: 1,
|
||||
strokeStyle: '#000',
|
||||
lineWidth: 2
|
||||
}, {
|
||||
text: 'label3',
|
||||
fillStyle: 'blue',
|
||||
hidden: true,
|
||||
index: 2,
|
||||
strokeStyle: '#000',
|
||||
lineWidth: 2
|
||||
}];
|
||||
|
||||
var chart = {
|
||||
data: data,
|
||||
options: {
|
||||
elements: {
|
||||
arc: {
|
||||
borderWidth: 2,
|
||||
borderColor: '#000'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
expect(config.legend.labels.generateLabels.call({ chart: chart }, data)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should hide the correct arc when a legend item is clicked', function() {
|
||||
var config = Chart.defaults.doughnut;
|
||||
|
||||
var legendItem = {
|
||||
text: 'label1',
|
||||
fillStyle: 'red',
|
||||
hidden: false,
|
||||
index: 0
|
||||
};
|
||||
|
||||
var chart = {
|
||||
data: {
|
||||
labels: ['label1', 'label2', 'label3'],
|
||||
datasets: [{
|
||||
data: [10, 20, NaN],
|
||||
backgroundColor: ['red', 'green', 'blue']
|
||||
}]
|
||||
},
|
||||
update: function() {}
|
||||
};
|
||||
|
||||
spyOn(chart, 'update');
|
||||
var scope = {
|
||||
chart: chart
|
||||
};
|
||||
|
||||
config.legend.onClick.call(scope, null, legendItem);
|
||||
|
||||
expect(chart.data.datasets[0].metaHiddenData).toEqual([10]);
|
||||
expect(chart.data.datasets[0].data).toEqual([NaN, 20, NaN]);
|
||||
|
||||
expect(chart.update).toHaveBeenCalled();
|
||||
|
||||
config.legend.onClick.call(scope, null, legendItem);
|
||||
expect(chart.data.datasets[0].data).toEqual([10, 20, NaN]);
|
||||
|
||||
// Should not toggle index 2 since there was never data for it
|
||||
legendItem.index = 2;
|
||||
config.legend.onClick.call(scope, null, legendItem);
|
||||
expect(chart.data.datasets[0].data).toEqual([10, 20, NaN]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test the polar area chart default config', function() {
|
||||
it('should return correct tooltip strings', function() {
|
||||
var config = Chart.defaults.polarArea;
|
||||
|
||||
// Title is always blank
|
||||
expect(config.tooltips.callbacks.title()).toBe('');
|
||||
|
||||
// Item label
|
||||
var data = {
|
||||
labels: ['label1', 'label2', 'label3'],
|
||||
datasets: [{
|
||||
data: [10, 20, 30],
|
||||
}]
|
||||
};
|
||||
|
||||
var tooltipItem = {
|
||||
datasetIndex: 0,
|
||||
index: 1,
|
||||
yLabel: 20
|
||||
};
|
||||
|
||||
expect(config.tooltips.callbacks.label(tooltipItem, data)).toBe('label2: 20');
|
||||
});
|
||||
|
||||
it('should return the correct html legend', function() {
|
||||
var config = Chart.defaults.polarArea;
|
||||
|
||||
var chart = {
|
||||
id: 'mychart',
|
||||
data: {
|
||||
labels: ['label1', 'label2'],
|
||||
datasets: [{
|
||||
data: [10, 20],
|
||||
backgroundColor: ['red', 'green']
|
||||
}]
|
||||
}
|
||||
};
|
||||
var expectedLegend = '<ul class="mychart-legend"><li><span style="background-color:red">label1</span></li><li><span style="background-color:green">label2</span></li></ul>';
|
||||
|
||||
expect(config.legendCallback(chart)).toBe(expectedLegend);
|
||||
});
|
||||
|
||||
it('should return correct legend label objects', function() {
|
||||
var config = Chart.defaults.polarArea;
|
||||
var data = {
|
||||
labels: ['label1', 'label2', 'label3'],
|
||||
datasets: [{
|
||||
data: [10, 20, NaN],
|
||||
backgroundColor: ['red', 'green', 'blue'],
|
||||
metaData: [{}, {}, {}]
|
||||
}]
|
||||
};
|
||||
|
||||
var expected = [{
|
||||
text: 'label1',
|
||||
fillStyle: 'red',
|
||||
hidden: false,
|
||||
index: 0,
|
||||
strokeStyle: '#000',
|
||||
lineWidth: 2
|
||||
}, {
|
||||
text: 'label2',
|
||||
fillStyle: 'green',
|
||||
hidden: false,
|
||||
index: 1,
|
||||
strokeStyle: '#000',
|
||||
lineWidth: 2
|
||||
}, {
|
||||
text: 'label3',
|
||||
fillStyle: 'blue',
|
||||
hidden: true,
|
||||
index: 2,
|
||||
strokeStyle: '#000',
|
||||
lineWidth: 2
|
||||
}];
|
||||
|
||||
var chart = {
|
||||
data: data,
|
||||
options: {
|
||||
elements: {
|
||||
arc: {
|
||||
borderWidth: 2,
|
||||
borderColor: '#000'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
expect(config.legend.labels.generateLabels.call({ chart: chart }, data)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should hide the correct arc when a legend item is clicked', function() {
|
||||
var config = Chart.defaults.polarArea;
|
||||
|
||||
var legendItem = {
|
||||
text: 'label1',
|
||||
fillStyle: 'red',
|
||||
hidden: false,
|
||||
index: 0
|
||||
};
|
||||
|
||||
var chart = {
|
||||
data: {
|
||||
labels: ['label1', 'label2', 'label3'],
|
||||
datasets: [{
|
||||
data: [10, 20, NaN],
|
||||
backgroundColor: ['red', 'green', 'blue']
|
||||
}]
|
||||
},
|
||||
update: function() {}
|
||||
};
|
||||
|
||||
spyOn(chart, 'update');
|
||||
var scope = {
|
||||
chart: chart
|
||||
};
|
||||
|
||||
config.legend.onClick.call(scope, null, legendItem);
|
||||
|
||||
expect(chart.data.datasets[0].metaHiddenData).toEqual([10]);
|
||||
expect(chart.data.datasets[0].data).toEqual([NaN, 20, NaN]);
|
||||
|
||||
expect(chart.update).toHaveBeenCalled();
|
||||
|
||||
config.legend.onClick.call(scope, null, legendItem);
|
||||
expect(chart.data.datasets[0].data).toEqual([10, 20, NaN]);
|
||||
|
||||
// Should not toggle index 2 since there was never data for it
|
||||
legendItem.index = 2;
|
||||
config.legend.onClick.call(scope, null, legendItem);
|
||||
expect(chart.data.datasets[0].data).toEqual([10, 20, NaN]);
|
||||
});
|
||||
});
|
||||
176
vendors/Chart.js/test/element.arc.tests.js
vendored
Normal file
176
vendors/Chart.js/test/element.arc.tests.js
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
// Test the rectangle element
|
||||
|
||||
describe('Arc element tests', function() {
|
||||
it ('Should be constructed', function() {
|
||||
var arc = new Chart.elements.Arc({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
expect(arc).not.toBe(undefined);
|
||||
expect(arc._datasetIndex).toBe(2);
|
||||
expect(arc._index).toBe(1);
|
||||
});
|
||||
|
||||
it ('should determine if in range', function() {
|
||||
var arc = new Chart.elements.Arc({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
// Make sure we can run these before the view is added
|
||||
expect(arc.inRange(2, 2)).toBe(false);
|
||||
expect(arc.inLabelRange(2)).toBe(false);
|
||||
|
||||
// Mock out the view as if the controller put it there
|
||||
arc._view = {
|
||||
startAngle: 0,
|
||||
endAngle: Math.PI / 2,
|
||||
x: 0,
|
||||
y: 0,
|
||||
innerRadius: 5,
|
||||
outerRadius: 10,
|
||||
};
|
||||
|
||||
expect(arc.inRange(2, 2)).toBe(false);
|
||||
expect(arc.inRange(7, 0)).toBe(true);
|
||||
expect(arc.inRange(0, 11)).toBe(false);
|
||||
expect(arc.inRange(Math.sqrt(32), Math.sqrt(32))).toBe(true);
|
||||
expect(arc.inRange(-1.0 * Math.sqrt(7), Math.sqrt(7))).toBe(false);
|
||||
});
|
||||
|
||||
it ('should get the tooltip position', function() {
|
||||
var arc = new Chart.elements.Arc({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
// Mock out the view as if the controller put it there
|
||||
arc._view = {
|
||||
startAngle: 0,
|
||||
endAngle: Math.PI / 2,
|
||||
x: 0,
|
||||
y: 0,
|
||||
innerRadius: 0,
|
||||
outerRadius: Math.sqrt(2),
|
||||
};
|
||||
|
||||
var pos = arc.tooltipPosition();
|
||||
expect(pos.x).toBeCloseTo(0.5);
|
||||
expect(pos.y).toBeCloseTo(0.5);
|
||||
});
|
||||
|
||||
it ('should draw correctly with no border', function() {
|
||||
var mockContext = window.createMockContext();
|
||||
var arc = new Chart.elements.Arc({
|
||||
_datasetIndex: 2,
|
||||
_index: 1,
|
||||
_chart: {
|
||||
ctx: mockContext,
|
||||
}
|
||||
});
|
||||
|
||||
// Mock out the view as if the controller put it there
|
||||
arc._view = {
|
||||
startAngle: 0,
|
||||
endAngle: Math.PI / 2,
|
||||
x: 10,
|
||||
y: 5,
|
||||
innerRadius: 1,
|
||||
outerRadius: 3,
|
||||
|
||||
backgroundColor: 'rgb(0, 0, 255)',
|
||||
borderColor: 'rgb(255, 0, 0)',
|
||||
};
|
||||
|
||||
arc.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'arc',
|
||||
args: [10, 5, 3, 0, Math.PI / 2]
|
||||
}, {
|
||||
name: 'arc',
|
||||
args: [10, 5, 1, Math.PI / 2, 0, true]
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgb(255, 0, 0)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [undefined]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgb(0, 0, 255)']
|
||||
}, {
|
||||
name: 'fill',
|
||||
args: []
|
||||
}, {
|
||||
name: 'setLineJoin',
|
||||
args: ['bevel']
|
||||
}]);
|
||||
});
|
||||
|
||||
it ('should draw correctly with a border', function() {
|
||||
var mockContext = window.createMockContext();
|
||||
var arc = new Chart.elements.Arc({
|
||||
_datasetIndex: 2,
|
||||
_index: 1,
|
||||
_chart: {
|
||||
ctx: mockContext,
|
||||
}
|
||||
});
|
||||
|
||||
// Mock out the view as if the controller put it there
|
||||
arc._view = {
|
||||
startAngle: 0,
|
||||
endAngle: Math.PI / 2,
|
||||
x: 10,
|
||||
y: 5,
|
||||
innerRadius: 1,
|
||||
outerRadius: 3,
|
||||
|
||||
backgroundColor: 'rgb(0, 0, 255)',
|
||||
borderColor: 'rgb(255, 0, 0)',
|
||||
borderWidth: 5
|
||||
};
|
||||
|
||||
arc.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'arc',
|
||||
args: [10, 5, 3, 0, Math.PI / 2]
|
||||
}, {
|
||||
name: 'arc',
|
||||
args: [10, 5, 1, Math.PI / 2, 0, true]
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgb(255, 0, 0)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [5]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgb(0, 0, 255)']
|
||||
}, {
|
||||
name: 'fill',
|
||||
args: []
|
||||
}, {
|
||||
name: 'setLineJoin',
|
||||
args: ['bevel']
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
});
|
||||
});
|
||||
1048
vendors/Chart.js/test/element.line.tests.js
vendored
Normal file
1048
vendors/Chart.js/test/element.line.tests.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
465
vendors/Chart.js/test/element.point.tests.js
vendored
Normal file
465
vendors/Chart.js/test/element.point.tests.js
vendored
Normal file
@@ -0,0 +1,465 @@
|
||||
// Test the point element
|
||||
|
||||
describe('Point element tests', function() {
|
||||
it ('Should be constructed', function() {
|
||||
var point = new Chart.elements.Point({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
expect(point).not.toBe(undefined);
|
||||
expect(point._datasetIndex).toBe(2);
|
||||
expect(point._index).toBe(1);
|
||||
});
|
||||
|
||||
it ('Should correctly identify as in range', function() {
|
||||
var point = new Chart.elements.Point({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
// Safely handles if these are called before the viewmodel is instantiated
|
||||
expect(point.inRange(5)).toBe(false);
|
||||
expect(point.inLabelRange(5)).toBe(false);
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
point._view = {
|
||||
radius: 2,
|
||||
hitRadius: 3,
|
||||
x: 10,
|
||||
y: 15
|
||||
};
|
||||
|
||||
expect(point.inRange(10, 15)).toBe(true);
|
||||
expect(point.inRange(10, 10)).toBe(false);
|
||||
expect(point.inRange(10, 5)).toBe(false);
|
||||
expect(point.inRange(5, 5)).toBe(false);
|
||||
|
||||
expect(point.inLabelRange(5)).toBe(false);
|
||||
expect(point.inLabelRange(7)).toBe(true);
|
||||
expect(point.inLabelRange(10)).toBe(true);
|
||||
expect(point.inLabelRange(12)).toBe(true);
|
||||
expect(point.inLabelRange(15)).toBe(false);
|
||||
expect(point.inLabelRange(20)).toBe(false);
|
||||
});
|
||||
|
||||
it ('should get the correct tooltip position', function() {
|
||||
var point = new Chart.elements.Point({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
point._view = {
|
||||
radius: 2,
|
||||
borderWidth: 6,
|
||||
x: 10,
|
||||
y: 15
|
||||
};
|
||||
|
||||
expect(point.tooltipPosition()).toEqual({
|
||||
x: 10,
|
||||
y: 15,
|
||||
padding: 8
|
||||
});
|
||||
});
|
||||
|
||||
it ('should draw correctly', function() {
|
||||
var mockContext = window.createMockContext();
|
||||
var point = new Chart.elements.Point({
|
||||
_datasetIndex: 2,
|
||||
_index: 1,
|
||||
_chart: {
|
||||
ctx: mockContext,
|
||||
}
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
point._view = {
|
||||
radius: 2,
|
||||
pointStyle: 'circle',
|
||||
hitRadius: 3,
|
||||
borderColor: 'rgba(1, 2, 3, 1)',
|
||||
borderWidth: 6,
|
||||
backgroundColor: 'rgba(0, 255, 0)',
|
||||
x: 10,
|
||||
y: 15,
|
||||
ctx: mockContext
|
||||
};
|
||||
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'arc',
|
||||
args: [10, 15, 2, 0, 2 * Math.PI]
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'fill',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'triangle';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10 - 3 * 2 / Math.sqrt(3) / 2, 15 + 3 * 2 / Math.sqrt(3) * Math.sqrt(3) / 2 / 3]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10 + 3 * 2 / Math.sqrt(3) / 2, 15 + 3 * 2 / Math.sqrt(3) * Math.sqrt(3) / 2 / 3],
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10, 15 - 2 * 3 * 2 / Math.sqrt(3) * Math.sqrt(3) / 2 / 3],
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'fill',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'rect';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'fillRect',
|
||||
args: [10 - 1 / Math.SQRT2 * 2, 15 - 1 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2]
|
||||
}, {
|
||||
name: 'strokeRect',
|
||||
args: [10 - 1 / Math.SQRT2 * 2, 15 - 1 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2]
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'rectRot';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'translate',
|
||||
args: [10, 15]
|
||||
}, {
|
||||
name: 'rotate',
|
||||
args: [Math.PI / 4]
|
||||
}, {
|
||||
name: 'fillRect',
|
||||
args: [-1 / Math.SQRT2 * 2, -1 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2],
|
||||
}, {
|
||||
name: 'strokeRect',
|
||||
args: [-1 / Math.SQRT2 * 2, -1 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2],
|
||||
}, {
|
||||
name: 'setTransform',
|
||||
args: [1, 0, 0, 1, 0, 0],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'cross';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10, 17]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10, 13],
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [8, 15],
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [12, 15],
|
||||
},{
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'crossRot';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10 - Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10 + Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10 - Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10 + Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'star';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10, 17]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10, 13],
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [8, 15],
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [12, 15],
|
||||
},{
|
||||
name: 'moveTo',
|
||||
args: [10 - Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10 + Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10 - Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10 + Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'line';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [8, 15]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [12, 15],
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'dash';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10, 15]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [12, 15],
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
});
|
||||
|
||||
it ('should draw correctly with default settings if necessary', function() {
|
||||
var mockContext = window.createMockContext();
|
||||
var point = new Chart.elements.Point({
|
||||
_datasetIndex: 2,
|
||||
_index: 1,
|
||||
_chart: {
|
||||
ctx: mockContext,
|
||||
}
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
point._view = {
|
||||
radius: 2,
|
||||
hitRadius: 3,
|
||||
x: 10,
|
||||
y: 15,
|
||||
ctx: mockContext
|
||||
};
|
||||
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(0,0,0,0.1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [1]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0,0,0,0.1)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'arc',
|
||||
args: [10, 15, 2, 0, 2 * Math.PI]
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'fill',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
});
|
||||
|
||||
it ('should not draw if skipped', function() {
|
||||
var mockContext = window.createMockContext();
|
||||
var point = new Chart.elements.Point({
|
||||
_datasetIndex: 2,
|
||||
_index: 1,
|
||||
_chart: {
|
||||
ctx: mockContext,
|
||||
}
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
point._view = {
|
||||
radius: 2,
|
||||
hitRadius: 3,
|
||||
x: 10,
|
||||
y: 15,
|
||||
ctx: mockContext,
|
||||
skip: true
|
||||
};
|
||||
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([]);
|
||||
});
|
||||
});
|
||||
303
vendors/Chart.js/test/element.rectangle.tests.js
vendored
Normal file
303
vendors/Chart.js/test/element.rectangle.tests.js
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
// Test the rectangle element
|
||||
|
||||
describe('Rectangle element tests', function() {
|
||||
it ('Should be constructed', function() {
|
||||
var rectangle = new Chart.elements.Rectangle({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
expect(rectangle).not.toBe(undefined);
|
||||
expect(rectangle._datasetIndex).toBe(2);
|
||||
expect(rectangle._index).toBe(1);
|
||||
});
|
||||
|
||||
it ('Should correctly identify as in range', function() {
|
||||
var rectangle = new Chart.elements.Rectangle({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
// Safely handles if these are called before the viewmodel is instantiated
|
||||
expect(rectangle.inRange(5)).toBe(false);
|
||||
expect(rectangle.inLabelRange(5)).toBe(false);
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
rectangle._view = {
|
||||
base: 0,
|
||||
width: 4,
|
||||
x: 10,
|
||||
y: 15
|
||||
};
|
||||
|
||||
expect(rectangle.inRange(10, 15)).toBe(true);
|
||||
expect(rectangle.inRange(10, 10)).toBe(true);
|
||||
expect(rectangle.inRange(10, 16)).toBe(false);
|
||||
expect(rectangle.inRange(5, 5)).toBe(false);
|
||||
|
||||
expect(rectangle.inLabelRange(5)).toBe(false);
|
||||
expect(rectangle.inLabelRange(7)).toBe(false);
|
||||
expect(rectangle.inLabelRange(10)).toBe(true);
|
||||
expect(rectangle.inLabelRange(12)).toBe(true);
|
||||
expect(rectangle.inLabelRange(15)).toBe(false);
|
||||
expect(rectangle.inLabelRange(20)).toBe(false);
|
||||
|
||||
// Test when the y is below the base (negative bar)
|
||||
var negativeRectangle = new Chart.elements.Rectangle({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
negativeRectangle._view = {
|
||||
base: 0,
|
||||
width: 4,
|
||||
x: 10,
|
||||
y: -15
|
||||
};
|
||||
|
||||
expect(negativeRectangle.inRange(10, -16)).toBe(false);
|
||||
expect(negativeRectangle.inRange(10, 1)).toBe(false);
|
||||
expect(negativeRectangle.inRange(10, -5)).toBe(true);
|
||||
});
|
||||
|
||||
it ('should get the correct height', function() {
|
||||
var rectangle = new Chart.elements.Rectangle({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
rectangle._view = {
|
||||
base: 0,
|
||||
width: 4,
|
||||
x: 10,
|
||||
y: 15
|
||||
};
|
||||
|
||||
expect(rectangle.height()).toBe(-15);
|
||||
|
||||
// Test when the y is below the base (negative bar)
|
||||
var negativeRectangle = new Chart.elements.Rectangle({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
negativeRectangle._view = {
|
||||
base: -10,
|
||||
width: 4,
|
||||
x: 10,
|
||||
y: -15
|
||||
};
|
||||
expect(negativeRectangle.height()).toBe(5);
|
||||
});
|
||||
|
||||
it ('should get the correct tooltip position', function() {
|
||||
var rectangle = new Chart.elements.Rectangle({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
rectangle._view = {
|
||||
base: 0,
|
||||
width: 4,
|
||||
x: 10,
|
||||
y: 15
|
||||
};
|
||||
|
||||
expect(rectangle.tooltipPosition()).toEqual({
|
||||
x: 10,
|
||||
y: 15,
|
||||
});
|
||||
|
||||
// Test when the y is below the base (negative bar)
|
||||
var negativeRectangle = new Chart.elements.Rectangle({
|
||||
_datasetIndex: 2,
|
||||
_index: 1
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
negativeRectangle._view = {
|
||||
base: -10,
|
||||
width: 4,
|
||||
x: 10,
|
||||
y: -15
|
||||
};
|
||||
|
||||
expect(negativeRectangle.tooltipPosition()).toEqual({
|
||||
x: 10,
|
||||
y: -15,
|
||||
});
|
||||
});
|
||||
|
||||
it ('should draw correctly', function() {
|
||||
var mockContext = window.createMockContext();
|
||||
var rectangle = new Chart.elements.Rectangle({
|
||||
_datasetIndex: 2,
|
||||
_index: 1,
|
||||
_chart: {
|
||||
ctx: mockContext,
|
||||
}
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
rectangle._view = {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
base: 0,
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
borderWidth: 1,
|
||||
ctx: mockContext,
|
||||
width: 4,
|
||||
x: 10,
|
||||
y: 15,
|
||||
};
|
||||
|
||||
rectangle.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'beginPath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgb(255, 0, 0)']
|
||||
}, {
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgb(0, 0, 255)'],
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [1]
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [8.5, 0]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [8.5, 15.5]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [11.5, 15.5]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [11.5, 0]
|
||||
}, {
|
||||
name: 'fill',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
});
|
||||
|
||||
it ('should draw correctly with no stroke', function() {
|
||||
var mockContext = window.createMockContext();
|
||||
var rectangle = new Chart.elements.Rectangle({
|
||||
_datasetIndex: 2,
|
||||
_index: 1,
|
||||
_chart: {
|
||||
ctx: mockContext,
|
||||
}
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
rectangle._view = {
|
||||
backgroundColor: 'rgb(255, 0, 0)',
|
||||
base: 0,
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
ctx: mockContext,
|
||||
width: 4,
|
||||
x: 10,
|
||||
y: 15,
|
||||
};
|
||||
|
||||
rectangle.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'beginPath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgb(255, 0, 0)']
|
||||
}, {
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgb(0, 0, 255)'],
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [undefined]
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [8, 0]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [8, 15]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [12, 15]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [12, 0]
|
||||
}, {
|
||||
name: 'fill',
|
||||
args: [],
|
||||
}]);
|
||||
});
|
||||
|
||||
function testBorderSkipped (borderSkipped, expectedDrawCalls) {
|
||||
var mockContext = window.createMockContext();
|
||||
var rectangle = new Chart.elements.Rectangle({
|
||||
_chart: { ctx: mockContext }
|
||||
});
|
||||
|
||||
// Attach a view object as if we were the controller
|
||||
rectangle._view = {
|
||||
borderSkipped: borderSkipped, // set tested 'borderSkipped' parameter
|
||||
ctx: mockContext,
|
||||
base: 0,
|
||||
width: 4,
|
||||
x: 10,
|
||||
y: 15,
|
||||
};
|
||||
|
||||
rectangle.draw();
|
||||
|
||||
var drawCalls = rectangle._view.ctx.getCalls().splice(4, 4);
|
||||
expect(drawCalls).toEqual(expectedDrawCalls);
|
||||
}
|
||||
|
||||
it ('should draw correctly respecting "borderSkipped" == "bottom"', function() {
|
||||
testBorderSkipped ('bottom', [
|
||||
{ name: 'moveTo', args: [8, 0] },
|
||||
{ name: 'lineTo', args: [8, 15] },
|
||||
{ name: 'lineTo', args: [12, 15] },
|
||||
{ name: 'lineTo', args: [12, 0] },
|
||||
]);
|
||||
});
|
||||
|
||||
it ('should draw correctly respecting "borderSkipped" == "left"', function() {
|
||||
testBorderSkipped ('left', [
|
||||
{ name: 'moveTo', args: [8, 15] },
|
||||
{ name: 'lineTo', args: [12, 15] },
|
||||
{ name: 'lineTo', args: [12, 0] },
|
||||
{ name: 'lineTo', args: [8, 0] },
|
||||
]);
|
||||
});
|
||||
|
||||
it ('should draw correctly respecting "borderSkipped" == "top"', function() {
|
||||
testBorderSkipped ('top', [
|
||||
{ name: 'moveTo', args: [12, 15] },
|
||||
{ name: 'lineTo', args: [12, 0] },
|
||||
{ name: 'lineTo', args: [8, 0] },
|
||||
{ name: 'lineTo', args: [8, 15] },
|
||||
]);
|
||||
});
|
||||
|
||||
it ('should draw correctly respecting "borderSkipped" == "right"', function() {
|
||||
testBorderSkipped ('right', [
|
||||
{ name: 'moveTo', args: [12, 0] },
|
||||
{ name: 'lineTo', args: [8, 0] },
|
||||
{ name: 'lineTo', args: [8, 15] },
|
||||
{ name: 'lineTo', args: [12, 15] },
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
238
vendors/Chart.js/test/mockContext.js
vendored
Normal file
238
vendors/Chart.js/test/mockContext.js
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
(function() {
|
||||
// Code from http://stackoverflow.com/questions/4406864/html-canvas-unit-testing
|
||||
var Context = function() {
|
||||
this._calls = []; // names/args of recorded calls
|
||||
this._initMethods();
|
||||
|
||||
this._fillStyle = null;
|
||||
this._lineCap = null;
|
||||
this._lineDashOffset = null;
|
||||
this._lineJoin = null;
|
||||
this._lineWidth = null;
|
||||
this._strokeStyle = null;
|
||||
|
||||
// Define properties here so that we can record each time they are set
|
||||
Object.defineProperties(this, {
|
||||
"fillStyle": {
|
||||
'get': function() { return this._fillStyle; },
|
||||
'set': function(style) {
|
||||
this._fillStyle = style;
|
||||
this.record('setFillStyle', [style]);
|
||||
}
|
||||
},
|
||||
'lineCap': {
|
||||
'get': function() { return this._lineCap; },
|
||||
'set': function(cap) {
|
||||
this._lineCap = cap;
|
||||
this.record('setLineCap', [cap]);
|
||||
}
|
||||
},
|
||||
'lineDashOffset': {
|
||||
'get': function() { return this._lineDashOffset; },
|
||||
'set': function(offset) {
|
||||
this._lineDashOffset = offset;
|
||||
this.record('setLineDashOffset', [offset]);
|
||||
}
|
||||
},
|
||||
'lineJoin': {
|
||||
'get': function() { return this._lineJoin; },
|
||||
'set': function(join) {
|
||||
this._lineJoin = join;
|
||||
this.record('setLineJoin', [join]);
|
||||
}
|
||||
},
|
||||
'lineWidth': {
|
||||
'get': function() { return this._lineWidth; },
|
||||
'set': function (width) {
|
||||
this._lineWidth = width;
|
||||
this.record('setLineWidth', [width]);
|
||||
}
|
||||
},
|
||||
'strokeStyle': {
|
||||
'get': function() { return this._strokeStyle; },
|
||||
'set': function(style) {
|
||||
this._strokeStyle = style;
|
||||
this.record('setStrokeStyle', [style]);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
Context.prototype._initMethods = function() {
|
||||
// define methods to test here
|
||||
// no way to introspect so we have to do some extra work :(
|
||||
var methods = {
|
||||
arc: function() {},
|
||||
beginPath: function() {},
|
||||
bezierCurveTo: function() {},
|
||||
clearRect: function() {},
|
||||
closePath: function() {},
|
||||
fill: function() {},
|
||||
fillRect: function() {},
|
||||
fillText: function() {},
|
||||
lineTo: function(x, y) {},
|
||||
measureText: function(text) {
|
||||
// return the number of characters * fixed size
|
||||
return text ? { width: text.length * 10 } : {width: 0};
|
||||
},
|
||||
moveTo: function(x, y) {},
|
||||
quadraticCurveTo: function() {},
|
||||
restore: function() {},
|
||||
rotate: function() {},
|
||||
save: function() {},
|
||||
setLineDash: function() {},
|
||||
stroke: function() {},
|
||||
strokeRect: function(x, y, w, h) {},
|
||||
setTransform: function(a, b, c, d, e, f) {},
|
||||
translate: function(x, y) {},
|
||||
};
|
||||
|
||||
// attach methods to the class itself
|
||||
var scope = this;
|
||||
var addMethod = function(name, method) {
|
||||
scope[methodName] = function() {
|
||||
scope.record(name, arguments);
|
||||
return method.apply(scope, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
for (var methodName in methods) {
|
||||
var method = methods[methodName];
|
||||
|
||||
addMethod(methodName, method);
|
||||
}
|
||||
};
|
||||
|
||||
Context.prototype.record = function(methodName, args) {
|
||||
this._calls.push({
|
||||
name: methodName,
|
||||
args: Array.prototype.slice.call(args)
|
||||
});
|
||||
},
|
||||
|
||||
Context.prototype.getCalls = function() {
|
||||
return this._calls;
|
||||
}
|
||||
|
||||
Context.prototype.resetCalls = function() {
|
||||
this._calls = [];
|
||||
};
|
||||
|
||||
window.createMockContext = function() {
|
||||
return new Context();
|
||||
};
|
||||
|
||||
// Custom matcher
|
||||
function toBeCloseToPixel() {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
var result = false;
|
||||
|
||||
if (!isNaN(actual) && !isNaN(expected)) {
|
||||
var diff = Math.abs(actual - expected);
|
||||
var A = Math.abs(actual);
|
||||
var B = Math.abs(expected);
|
||||
var percentDiff = 0.005; // 0.5% diff
|
||||
result = (diff <= (A > B ? A : B) * percentDiff) || diff < 2; // 2 pixels is fine
|
||||
}
|
||||
|
||||
return { pass: result };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function toEqualOneOf() {
|
||||
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
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
window.addDefaultMatchers = function(jasmine) {
|
||||
jasmine.addMatchers({
|
||||
toBeCloseToPixel: toBeCloseToPixel,
|
||||
toEqualOneOf: toEqualOneOf
|
||||
});
|
||||
}
|
||||
|
||||
// Canvas injection helpers
|
||||
var charts = {};
|
||||
|
||||
function acquireChart(config, style) {
|
||||
var wrapper = document.createElement("div");
|
||||
var canvas = document.createElement("canvas");
|
||||
wrapper.className = 'chartjs-wrapper';
|
||||
|
||||
style = style || { height: '512px', width: '512px' };
|
||||
for (var k in style) {
|
||||
wrapper.style[k] = style[k];
|
||||
canvas.style[k] = style[k];
|
||||
}
|
||||
|
||||
canvas.height = canvas.style.height && parseInt(canvas.style.height);
|
||||
canvas.width = canvas.style.width && parseInt(canvas.style.width);
|
||||
|
||||
// by default, remove chart animation and auto resize
|
||||
var options = config.options = config.options || {};
|
||||
options.animation = options.animation === undefined? false : options.animation;
|
||||
options.responsive = options.responsive === undefined? false : options.responsive;
|
||||
options.defaultFontFamily = options.defaultFontFamily || 'Arial';
|
||||
|
||||
wrapper.appendChild(canvas);
|
||||
window.document.body.appendChild(wrapper);
|
||||
var chart = new Chart(canvas.getContext("2d"), config);
|
||||
charts[chart.id] = chart;
|
||||
return chart;
|
||||
}
|
||||
|
||||
function releaseChart(chart) {
|
||||
chart.chart.canvas.parentNode.remove();
|
||||
delete charts[chart.id];
|
||||
delete chart;
|
||||
}
|
||||
|
||||
function releaseAllCharts(scope) {
|
||||
for (var id in charts) {
|
||||
var chart = charts[id];
|
||||
releaseChart(chart);
|
||||
}
|
||||
}
|
||||
|
||||
function injectCSS(css) {
|
||||
// http://stackoverflow.com/q/3922139
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var style = document.createElement('style');
|
||||
style.setAttribute('type', 'text/css');
|
||||
if (style.styleSheet) { // IE
|
||||
style.styleSheet.cssText = css;
|
||||
} else {
|
||||
style.appendChild(document.createTextNode(css));
|
||||
}
|
||||
head.appendChild(style);
|
||||
}
|
||||
|
||||
window.acquireChart = acquireChart;
|
||||
window.releaseChart = releaseChart;
|
||||
window.releaseAllCharts = releaseAllCharts;
|
||||
|
||||
// some style initialization to limit differences between browsers across different plateforms.
|
||||
injectCSS(
|
||||
'.chartjs-wrapper, .chartjs-wrapper canvas {' +
|
||||
'border: 0;' +
|
||||
'margin: 0;' +
|
||||
'padding: 0;' +
|
||||
'}' +
|
||||
'.chartjs-wrapper {' +
|
||||
'position: absolute' +
|
||||
'}');
|
||||
})();
|
||||
360
vendors/Chart.js/test/scale.category.tests.js
vendored
Normal file
360
vendors/Chart.js/test/scale.category.tests.js
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
// Test the category scale
|
||||
|
||||
describe('Category scale tests', function() {
|
||||
it('Should register the constructor with the scale service', function() {
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('category');
|
||||
expect(Constructor).not.toBe(undefined);
|
||||
expect(typeof Constructor).toBe('function');
|
||||
});
|
||||
|
||||
it('Should have the correct default config', function() {
|
||||
var defaultConfig = Chart.scaleService.getScaleDefaults('category');
|
||||
expect(defaultConfig).toEqual({
|
||||
display: true,
|
||||
|
||||
gridLines: {
|
||||
color: "rgba(0, 0, 0, 0.1)",
|
||||
drawBorder: true,
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true, // draw ticks extending towards the label
|
||||
tickMarkLength: 10,
|
||||
lineWidth: 1,
|
||||
offsetGridLines: false,
|
||||
display: true,
|
||||
zeroLineColor: "rgba(0,0,0,0.25)",
|
||||
zeroLineWidth: 1
|
||||
},
|
||||
position: "bottom",
|
||||
scaleLabel: {
|
||||
labelString: '',
|
||||
display: false
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: false,
|
||||
minRotation: 0,
|
||||
maxRotation: 50,
|
||||
mirror: false,
|
||||
padding: 10,
|
||||
reverse: false,
|
||||
display: true,
|
||||
callback: defaultConfig.ticks.callback, // make this nicer, then check explicitly below
|
||||
autoSkip: true,
|
||||
autoSkipPadding: 0,
|
||||
labelOffset: 0
|
||||
}
|
||||
});
|
||||
|
||||
// Is this actually a function
|
||||
expect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it('Should generate ticks from the data labales', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
datasets: [{
|
||||
yAxisID: scaleID,
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
|
||||
};
|
||||
|
||||
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('category');
|
||||
var scale = new Constructor({
|
||||
ctx: {},
|
||||
options: config,
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
scale.determineDataLimits();
|
||||
scale.buildTicks();
|
||||
expect(scale.ticks).toEqual(mockData.labels);
|
||||
});
|
||||
|
||||
it ('should get the correct label for the index', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
datasets: [{
|
||||
yAxisID: scaleID,
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
|
||||
};
|
||||
|
||||
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('category');
|
||||
var scale = new Constructor({
|
||||
ctx: {},
|
||||
options: config,
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
scale.determineDataLimits();
|
||||
scale.buildTicks();
|
||||
|
||||
expect(scale.getLabelForIndex(1)).toBe('tick2');
|
||||
});
|
||||
|
||||
it ('Should get the correct pixel for a value when horizontal', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
datasets: [{
|
||||
yAxisID: scaleID,
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']
|
||||
};
|
||||
|
||||
var mockContext = window.createMockContext();
|
||||
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
|
||||
config.gridLines.offsetGridLines = true;
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('category');
|
||||
var scale = new Constructor({
|
||||
ctx: mockContext,
|
||||
options: config,
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
var minSize = scale.update(600, 100);
|
||||
|
||||
expect(scale.width).toBe(600);
|
||||
expect(scale.height).toBe(28);
|
||||
expect(scale.paddingTop).toBe(0);
|
||||
expect(scale.paddingBottom).toBe(0);
|
||||
expect(scale.paddingLeft).toBe(28);
|
||||
expect(scale.paddingRight).toBe(48);
|
||||
expect(scale.labelRotation).toBe(0);
|
||||
|
||||
expect(minSize).toEqual({
|
||||
width: 600,
|
||||
height: 28,
|
||||
});
|
||||
|
||||
scale.left = 5;
|
||||
scale.top = 5;
|
||||
scale.right = 605;
|
||||
scale.bottom = 33;
|
||||
|
||||
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(33);
|
||||
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(85);
|
||||
expect(scale.getValueForPixel(33)).toBe(0);
|
||||
expect(scale.getValueForPixel(85)).toBe(0);
|
||||
|
||||
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(452);
|
||||
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(505);
|
||||
expect(scale.getValueForPixel(452)).toBe(4);
|
||||
expect(scale.getValueForPixel(505)).toBe(4);
|
||||
|
||||
config.gridLines.offsetGridLines = false;
|
||||
|
||||
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(33);
|
||||
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(33);
|
||||
expect(scale.getValueForPixel(33)).toBe(0);
|
||||
|
||||
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(557);
|
||||
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(557);
|
||||
expect(scale.getValueForPixel(557)).toBe(4);
|
||||
});
|
||||
|
||||
it ('Should get the correct pixel for a value when horizontal and zoomed', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
datasets: [{
|
||||
yAxisID: scaleID,
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']
|
||||
};
|
||||
|
||||
var mockContext = window.createMockContext();
|
||||
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
|
||||
config.gridLines.offsetGridLines = true;
|
||||
config.ticks.min = "tick2";
|
||||
config.ticks.max = "tick4";
|
||||
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('category');
|
||||
var scale = new Constructor({
|
||||
ctx: mockContext,
|
||||
options: config,
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
var minSize = scale.update(600, 100);
|
||||
|
||||
expect(scale.width).toBe(600);
|
||||
expect(scale.height).toBe(28);
|
||||
expect(scale.paddingTop).toBe(0);
|
||||
expect(scale.paddingBottom).toBe(0);
|
||||
expect(scale.paddingLeft).toBe(28);
|
||||
expect(scale.paddingRight).toBe(28);
|
||||
expect(scale.labelRotation).toBe(0);
|
||||
|
||||
expect(minSize).toEqual({
|
||||
width: 600,
|
||||
height: 28,
|
||||
});
|
||||
|
||||
scale.left = 5;
|
||||
scale.top = 5;
|
||||
scale.right = 605;
|
||||
scale.bottom = 33;
|
||||
|
||||
expect(scale.getPixelForValue(0, 1, 0, false)).toBe(33);
|
||||
expect(scale.getPixelForValue(0, 1, 0, true)).toBe(124);
|
||||
|
||||
expect(scale.getPixelForValue(0, 3, 0, false)).toBe(396);
|
||||
expect(scale.getPixelForValue(0, 3, 0, true)).toBe(486);
|
||||
|
||||
config.gridLines.offsetGridLines = false;
|
||||
|
||||
expect(scale.getPixelForValue(0, 1, 0, false)).toBe(33);
|
||||
expect(scale.getPixelForValue(0, 1, 0, true)).toBe(33);
|
||||
|
||||
expect(scale.getPixelForValue(0, 3, 0, false)).toBe(577);
|
||||
expect(scale.getPixelForValue(0, 3, 0, true)).toBe(577);
|
||||
});
|
||||
|
||||
it ('should get the correct pixel for a value when vertical', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
datasets: [{
|
||||
yAxisID: scaleID,
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']
|
||||
};
|
||||
|
||||
var mockContext = window.createMockContext();
|
||||
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
|
||||
config.gridLines.offsetGridLines = true;
|
||||
config.position = "left";
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('category');
|
||||
var scale = new Constructor({
|
||||
ctx: mockContext,
|
||||
options: config,
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
var minSize = scale.update(100, 200);
|
||||
|
||||
expect(scale.width).toBe(100);
|
||||
expect(scale.height).toBe(200);
|
||||
expect(scale.paddingTop).toBe(6);
|
||||
expect(scale.paddingBottom).toBe(6);
|
||||
expect(scale.paddingLeft).toBe(0);
|
||||
expect(scale.paddingRight).toBe(0);
|
||||
expect(scale.labelRotation).toBe(0);
|
||||
|
||||
expect(minSize).toEqual({
|
||||
width: 100,
|
||||
height: 200,
|
||||
});
|
||||
|
||||
scale.left = 5;
|
||||
scale.top = 5;
|
||||
scale.right = 105;
|
||||
scale.bottom = 205;
|
||||
|
||||
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(11);
|
||||
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(30);
|
||||
expect(scale.getValueForPixel(11)).toBe(0);
|
||||
expect(scale.getValueForPixel(30)).toBe(0);
|
||||
|
||||
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(161);
|
||||
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(180);
|
||||
expect(scale.getValueForPixel(161)).toBe(4);
|
||||
|
||||
config.gridLines.offsetGridLines = false;
|
||||
|
||||
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(11);
|
||||
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(11);
|
||||
expect(scale.getValueForPixel(11)).toBe(0);
|
||||
|
||||
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(199);
|
||||
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(199);
|
||||
expect(scale.getValueForPixel(199)).toBe(4);
|
||||
});
|
||||
|
||||
it ('should get the correct pixel for a value when vertical and zoomed', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
datasets: [{
|
||||
yAxisID: scaleID,
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']
|
||||
};
|
||||
|
||||
var mockContext = window.createMockContext();
|
||||
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
|
||||
config.gridLines.offsetGridLines = true;
|
||||
config.ticks.min = "tick2";
|
||||
config.ticks.max = "tick4";
|
||||
config.position = "left";
|
||||
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('category');
|
||||
var scale = new Constructor({
|
||||
ctx: mockContext,
|
||||
options: config,
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
var minSize = scale.update(100, 200);
|
||||
|
||||
expect(scale.width).toBe(70);
|
||||
expect(scale.height).toBe(200);
|
||||
expect(scale.paddingTop).toBe(6);
|
||||
expect(scale.paddingBottom).toBe(6);
|
||||
expect(scale.paddingLeft).toBe(0);
|
||||
expect(scale.paddingRight).toBe(0);
|
||||
expect(scale.labelRotation).toBe(0);
|
||||
|
||||
expect(minSize).toEqual({
|
||||
width: 70,
|
||||
height: 200,
|
||||
});
|
||||
|
||||
scale.left = 5;
|
||||
scale.top = 5;
|
||||
scale.right = 75;
|
||||
scale.bottom = 205;
|
||||
|
||||
expect(scale.getPixelForValue(0, 1, 0, false)).toBe(11);
|
||||
expect(scale.getPixelForValue(0, 1, 0, true)).toBe(42);
|
||||
|
||||
expect(scale.getPixelForValue(0, 3, 0, false)).toBe(136);
|
||||
expect(scale.getPixelForValue(0, 3, 0, true)).toBe(168);
|
||||
|
||||
config.gridLines.offsetGridLines = false;
|
||||
|
||||
expect(scale.getPixelForValue(0, 1, 0, false)).toBe(11);
|
||||
expect(scale.getPixelForValue(0, 1, 0, true)).toBe(11);
|
||||
|
||||
expect(scale.getPixelForValue(0, 3, 0, false)).toBe(199);
|
||||
expect(scale.getPixelForValue(0, 3, 0, true)).toBe(199);
|
||||
});
|
||||
});
|
||||
731
vendors/Chart.js/test/scale.linear.tests.js
vendored
Normal file
731
vendors/Chart.js/test/scale.linear.tests.js
vendored
Normal file
@@ -0,0 +1,731 @@
|
||||
describe('Linear Scale', function() {
|
||||
var chartInstance;
|
||||
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
if (chartInstance)
|
||||
{
|
||||
releaseChart(chartInstance);
|
||||
}
|
||||
});
|
||||
|
||||
it('Should register the constructor with the scale service', function() {
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('linear');
|
||||
expect(Constructor).not.toBe(undefined);
|
||||
expect(typeof Constructor).toBe('function');
|
||||
});
|
||||
|
||||
it('Should have the correct default config', function() {
|
||||
var defaultConfig = Chart.scaleService.getScaleDefaults('linear');
|
||||
expect(defaultConfig).toEqual({
|
||||
display: true,
|
||||
|
||||
gridLines: {
|
||||
color: "rgba(0, 0, 0, 0.1)",
|
||||
drawBorder: true,
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true, // draw ticks extending towards the label
|
||||
tickMarkLength: 10,
|
||||
lineWidth: 1,
|
||||
offsetGridLines: false,
|
||||
display: true,
|
||||
zeroLineColor: "rgba(0,0,0,0.25)",
|
||||
zeroLineWidth: 1,
|
||||
},
|
||||
position: "left",
|
||||
scaleLabel: {
|
||||
labelString: '',
|
||||
display: false,
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: false,
|
||||
minRotation: 0,
|
||||
maxRotation: 50,
|
||||
mirror: false,
|
||||
padding: 10,
|
||||
reverse: false,
|
||||
display: true,
|
||||
callback: defaultConfig.ticks.callback, // make this work nicer, then check below
|
||||
autoSkip: true,
|
||||
autoSkipPadding: 0,
|
||||
labelOffset: 0
|
||||
}
|
||||
});
|
||||
|
||||
expect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it('Should correctly determine the max & min data values', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: [10, 5, 0, -5, 78, -100]
|
||||
}, {
|
||||
yAxisID: 'yScale1',
|
||||
data: [-1000, 1000],
|
||||
}, {
|
||||
yAxisID: 'yScale0',
|
||||
data: [150]
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear'
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chartInstance.scales.yScale0.min).toBe(-100);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(150);
|
||||
});
|
||||
|
||||
it('Should correctly determine the max & min of string data values', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: ['10', '5', '0', '-5', '78', '-100']
|
||||
}, {
|
||||
yAxisID: 'yScale1',
|
||||
data: ['-1000', '1000'],
|
||||
}, {
|
||||
yAxisID: 'yScale0',
|
||||
data: ['150']
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear'
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chartInstance.scales.yScale0.min).toBe(-100);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(150);
|
||||
});
|
||||
|
||||
it('Should correctly determine the max & min data values ignoring hidden datasets', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: ['10', '5', '0', '-5', '78', '-100']
|
||||
}, {
|
||||
yAxisID: 'yScale1',
|
||||
data: ['-1000', '1000'],
|
||||
}, {
|
||||
yAxisID: 'yScale0',
|
||||
data: ['150'],
|
||||
hidden: true
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear'
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chartInstance.scales.yScale0.min).toBe(-100);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(80);
|
||||
});
|
||||
|
||||
it('Should correctly determine the max & min data values ignoring data that is NaN', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: [null, 90, NaN, undefined, 45, 30]
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scales.yScale0.min).toBe(30);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(90);
|
||||
|
||||
// Scale is now stacked
|
||||
chartInstance.scales.yScale0.options.stacked = true;
|
||||
chartInstance.update();
|
||||
|
||||
expect(chartInstance.scales.yScale0.min).toBe(0);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(90);
|
||||
});
|
||||
|
||||
it('Should correctly determine the max & min for scatter data', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
xAxisID: 'xScale0',
|
||||
yAxisID: 'yScale0',
|
||||
data: [{
|
||||
x: 10,
|
||||
y: 100
|
||||
}, {
|
||||
x: -10,
|
||||
y: 0
|
||||
}, {
|
||||
x: 0,
|
||||
y: 0
|
||||
}, {
|
||||
x: 99,
|
||||
y: 7
|
||||
}]
|
||||
}],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale0',
|
||||
type: 'linear',
|
||||
position: 'bottom'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
chartInstance.update();
|
||||
|
||||
expect(chartInstance.scales.xScale0.min).toBe(-20);
|
||||
expect(chartInstance.scales.xScale0.max).toBe(100);
|
||||
expect(chartInstance.scales.yScale0.min).toBe(0);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(100);
|
||||
});
|
||||
|
||||
it('Should correctly get the label for the given index', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
xAxisID: 'xScale0',
|
||||
yAxisID: 'yScale0',
|
||||
data: [{
|
||||
x: 10,
|
||||
y: 100
|
||||
}, {
|
||||
x: -10,
|
||||
y: 0
|
||||
}, {
|
||||
x: 0,
|
||||
y: 0
|
||||
}, {
|
||||
x: 99,
|
||||
y: 7
|
||||
}]
|
||||
}],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale0',
|
||||
type: 'linear',
|
||||
position: 'bottom'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
chartInstance.update();
|
||||
|
||||
expect(chartInstance.scales.yScale0.getLabelForIndex(3, 0)).toBe(7);
|
||||
});
|
||||
|
||||
it('Should correctly determine the min and max data values when stacked mode is turned on', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: [10, 5, 0, -5, 78, -100],
|
||||
type: 'bar'
|
||||
}, {
|
||||
yAxisID: 'yScale1',
|
||||
data: [-1000, 1000],
|
||||
}, {
|
||||
yAxisID: 'yScale0',
|
||||
data: [150, 0, 0, -100, -10, 9],
|
||||
type: 'bar'
|
||||
}, {
|
||||
yAxisID: 'yScale0',
|
||||
data: [10, 10, 10, 10, 10, 10],
|
||||
type: 'line'
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
stacked: true
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
chartInstance.update();
|
||||
|
||||
expect(chartInstance.scales.yScale0.min).toBe(-150);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(200);
|
||||
});
|
||||
|
||||
it('Should correctly determine the min and max data values when stacked mode is turned on and there are hidden datasets', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: [10, 5, 0, -5, 78, -100],
|
||||
}, {
|
||||
yAxisID: 'yScale1',
|
||||
data: [-1000, 1000],
|
||||
}, {
|
||||
yAxisID: 'yScale0',
|
||||
data: [150, 0, 0, -100, -10, 9],
|
||||
}, {
|
||||
yAxisID: 'yScale0',
|
||||
data: [10, 20, 30, 40, 50, 60],
|
||||
hidden: true
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
stacked: true
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
chartInstance.update();
|
||||
|
||||
expect(chartInstance.scales.yScale0.min).toBe(-150);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(200);
|
||||
});
|
||||
|
||||
it('Should correctly determine the min and max data values when stacked mode is turned on there are multiple types of datasets', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
type: 'bar',
|
||||
data: [10, 5, 0, -5, 78, -100]
|
||||
}, {
|
||||
type: 'line',
|
||||
data: [10, 10, 10, 10, 10, 10],
|
||||
}, {
|
||||
type: 'bar',
|
||||
data: [150, 0, 0, -100, -10, 9]
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
stacked: true
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
chartInstance.scales.yScale0.determineDataLimits();
|
||||
expect(chartInstance.scales.yScale0.min).toBe(-105);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(160);
|
||||
});
|
||||
|
||||
it('Should ensure that the scale has a max and min that are not equal', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chartInstance.scales.yScale0.min).toBe(-1);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(1);
|
||||
});
|
||||
|
||||
it('Should ensure that the scale has a max and min that are not equal when beginAtZero is set', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chartInstance.scales.yScale0.min).toBe(0);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(1);
|
||||
});
|
||||
|
||||
it('Should use the suggestedMin and suggestedMax options', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: [1, 1, 1, 2, 1, 0]
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
ticks: {
|
||||
suggestedMax: 10,
|
||||
suggestedMin: -10
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chartInstance.scales.yScale0.min).toBe(-10);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(10);
|
||||
});
|
||||
|
||||
it('Should use the min and max options', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: [1, 1, 1, 2, 1, 0]
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
ticks: {
|
||||
max: 1010,
|
||||
min: -1010
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chartInstance.scales.yScale0.min).toBe(-1010);
|
||||
expect(chartInstance.scales.yScale0.max).toBe(1010);
|
||||
expect(chartInstance.scales.yScale0.ticks[0]).toBe('1010');
|
||||
expect(chartInstance.scales.yScale0.ticks[chartInstance.scales.yScale0.ticks.length - 1]).toBe('-1010');
|
||||
});
|
||||
|
||||
it('should forcibly include 0 in the range if the beginAtZero option is used', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: [20, 30, 40, 50]
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chartInstance.scales.yScale0.ticks).toEqual(['50', '45', '40', '35', '30', '25', '20']);
|
||||
|
||||
chartInstance.scales.yScale0.options.ticks.beginAtZero = true;
|
||||
chartInstance.update();
|
||||
expect(chartInstance.scales.yScale0.ticks).toEqual(['50', '45', '40', '35', '30', '25', '20', '15', '10', '5', '0']);
|
||||
|
||||
chartInstance.data.datasets[0].data = [-20, -30, -40, -50];
|
||||
chartInstance.update();
|
||||
expect(chartInstance.scales.yScale0.ticks).toEqual(['0', '-5', '-10', '-15', '-20', '-25', '-30', '-35', '-40', '-45', '-50']);
|
||||
|
||||
chartInstance.scales.yScale0.options.ticks.beginAtZero = false;
|
||||
chartInstance.update();
|
||||
expect(chartInstance.scales.yScale0.ticks).toEqual(['-20', '-25', '-30', '-35', '-40', '-45', '-50']);
|
||||
});
|
||||
|
||||
it('Should generate tick marks in the correct order in reversed mode', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
ticks: {
|
||||
reverse: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scales.yScale0.ticks).toEqual(['0', '10', '20', '30', '40', '50', '60', '70', '80']);
|
||||
expect(chartInstance.scales.yScale0.start).toBe(80);
|
||||
expect(chartInstance.scales.yScale0.end).toBe(0);
|
||||
});
|
||||
|
||||
it('should use the correct number of decimal places in the default format function', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: [0.06, 0.005, 0, 0.025, 0.0078]
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
expect(chartInstance.scales.yScale0.ticks).toEqual(['0.06', '0.05', '0.04', '0.03', '0.02', '0.01', '0']);
|
||||
});
|
||||
|
||||
it('Should build labels using the user supplied callback', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
yAxisID: 'yScale0',
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['a', 'b', 'c', 'd']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
ticks: {
|
||||
callback: function(value, index) {
|
||||
return index.toString();
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Just the index
|
||||
expect(chartInstance.scales.yScale0.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8']);
|
||||
});
|
||||
|
||||
it('Should get the correct pixel value for a point', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
xAxisID: 'xScale0',
|
||||
yAxisID: 'yScale0',
|
||||
data: []
|
||||
}],
|
||||
},
|
||||
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*/
|
||||
|
||||
expect(xScale.getValueForPixel(501)).toBeCloseTo(1, 1e-2);
|
||||
expect(xScale.getValueForPixel(41)).toBeCloseTo(-1, 1e-2);
|
||||
expect(xScale.getValueForPixel(271)).toBeCloseTo(0, 1e-2);
|
||||
|
||||
var yScale = chartInstance.scales.yScale0;
|
||||
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*/
|
||||
|
||||
expect(yScale.getValueForPixel(32)).toBe(1);
|
||||
expect(yScale.getValueForPixel(484)).toBe(-1);
|
||||
expect(yScale.getValueForPixel(258)).toBe(0);
|
||||
});
|
||||
|
||||
it('should fit correctly', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
xAxisID: 'xScale0',
|
||||
yAxisID: 'yScale0',
|
||||
data: [{
|
||||
x: 10,
|
||||
y: 100
|
||||
}, {
|
||||
x: -10,
|
||||
y: 0
|
||||
}, {
|
||||
x: 0,
|
||||
y: 0
|
||||
}, {
|
||||
x: 99,
|
||||
y: 7
|
||||
}]
|
||||
}],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale0',
|
||||
type: 'linear',
|
||||
position: 'bottom'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var xScale = chartInstance.scales.xScale0;
|
||||
expect(xScale.paddingTop).toBeCloseToPixel(0);
|
||||
expect(xScale.paddingBottom).toBeCloseToPixel(0);
|
||||
expect(xScale.paddingLeft).toBeCloseToPixel(0);
|
||||
expect(xScale.paddingRight).toBeCloseToPixel(13.5);
|
||||
expect(xScale.width).toBeCloseToPixel(471);
|
||||
expect(xScale.height).toBeCloseToPixel(28);
|
||||
|
||||
var yScale = chartInstance.scales.yScale0;
|
||||
expect(yScale.paddingTop).toBeCloseToPixel(0);
|
||||
expect(yScale.paddingBottom).toBeCloseToPixel(0);
|
||||
expect(yScale.paddingLeft).toBeCloseToPixel(0);
|
||||
expect(yScale.paddingRight).toBeCloseToPixel(0);
|
||||
expect(yScale.width).toBeCloseToPixel(41);
|
||||
expect(yScale.height).toBeCloseToPixel(452);
|
||||
|
||||
// Extra size when scale label showing
|
||||
xScale.options.scaleLabel.display = true;
|
||||
yScale.options.scaleLabel.display = true;
|
||||
chartInstance.update();
|
||||
|
||||
expect(xScale.paddingTop).toBeCloseToPixel(0);
|
||||
expect(xScale.paddingBottom).toBeCloseToPixel(0);
|
||||
expect(xScale.paddingLeft).toBeCloseToPixel(0);
|
||||
expect(xScale.paddingRight).toBeCloseToPixel(13.5);
|
||||
expect(xScale.width).toBeCloseToPixel(453);
|
||||
expect(xScale.height).toBeCloseToPixel(46);
|
||||
|
||||
expect(yScale.paddingTop).toBeCloseToPixel(0);
|
||||
expect(yScale.paddingBottom).toBeCloseToPixel(0);
|
||||
expect(yScale.paddingLeft).toBeCloseToPixel(0);
|
||||
expect(yScale.paddingRight).toBeCloseToPixel(0);
|
||||
expect(yScale.width).toBeCloseToPixel(59);
|
||||
expect(yScale.height).toBeCloseToPixel(434);
|
||||
});
|
||||
});
|
||||
573
vendors/Chart.js/test/scale.logarithmic.tests.js
vendored
Normal file
573
vendors/Chart.js/test/scale.logarithmic.tests.js
vendored
Normal file
@@ -0,0 +1,573 @@
|
||||
describe('Logarithmic Scale tests', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.releaseAllCharts();
|
||||
});
|
||||
|
||||
it('should register the constructor with the scale service', function() {
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
|
||||
expect(Constructor).not.toBe(undefined);
|
||||
expect(typeof Constructor).toBe('function');
|
||||
});
|
||||
|
||||
it('should have the correct default config', function() {
|
||||
var defaultConfig = Chart.scaleService.getScaleDefaults('logarithmic');
|
||||
expect(defaultConfig).toEqual({
|
||||
display: true,
|
||||
gridLines: {
|
||||
color: "rgba(0, 0, 0, 0.1)",
|
||||
drawBorder: true,
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true,
|
||||
tickMarkLength: 10,
|
||||
lineWidth: 1,
|
||||
offsetGridLines: false,
|
||||
display: true,
|
||||
zeroLineColor: "rgba(0,0,0,0.25)",
|
||||
zeroLineWidth: 1,
|
||||
},
|
||||
position: "left",
|
||||
scaleLabel: {
|
||||
labelString: '',
|
||||
display: false,
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: false,
|
||||
minRotation: 0,
|
||||
maxRotation: 50,
|
||||
mirror: false,
|
||||
padding: 10,
|
||||
reverse: false,
|
||||
display: true,
|
||||
callback: defaultConfig.ticks.callback, // make this nicer, then check explicitly below
|
||||
autoSkip: true,
|
||||
autoSkipPadding: 0,
|
||||
labelOffset: 0
|
||||
},
|
||||
});
|
||||
|
||||
// Is this actually a function
|
||||
expect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
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']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'logarithmic'
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chart.scales.yScale0.min).toBe(10);
|
||||
expect(chart.scales.yScale0.max).toBe(1000);
|
||||
|
||||
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 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']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'logarithmic'
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chart.scales.yScale0.min).toBe(10);
|
||||
expect(chart.scales.yScale0.max).toBe(1000);
|
||||
|
||||
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 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']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'logarithmic'
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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 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']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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
|
||||
chart.options.scales.yAxes[0].stacked = true;
|
||||
chart.update();
|
||||
|
||||
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 chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [
|
||||
{ x: 10, y: 100 },
|
||||
{ x: 2, y: 6 },
|
||||
{ x: 65, y: 121 },
|
||||
{ x: 99, y: 7 }
|
||||
]
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale',
|
||||
type: 'logarithmic',
|
||||
position: 'bottom'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chart.scales.xScale.min).toBe(1);
|
||||
expect(chart.scales.xScale.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 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']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'logarithmic',
|
||||
stacked: true
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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 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']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'logarithmic',
|
||||
stacked: true
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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 chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: []
|
||||
}],
|
||||
labels: []
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chart.scales.yScale.min).toBe(1);
|
||||
expect(chart.scales.yScale.max).toBe(10);
|
||||
|
||||
chart.data.datasets[0].data = [0.15, 0.15];
|
||||
chart.update();
|
||||
|
||||
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 chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [1, 1, 1, 2, 1, 0]
|
||||
}],
|
||||
labels: []
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'logarithmic',
|
||||
ticks: {
|
||||
min: 10,
|
||||
max: 1010,
|
||||
callback: function(value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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 chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 1, 25, 78]
|
||||
}],
|
||||
labels: []
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'logarithmic',
|
||||
ticks: {
|
||||
callback: function(value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Counts down because the lines are drawn top to bottom
|
||||
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 chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 1, 25, 78]
|
||||
}],
|
||||
labels: []
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'logarithmic',
|
||||
ticks: {
|
||||
reverse: true,
|
||||
callback: function(value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Counts down because the lines are drawn top to bottom
|
||||
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 chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 1, 25, 78]
|
||||
}],
|
||||
labels: []
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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 chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 1, 25, 78]
|
||||
}],
|
||||
labels: []
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale',
|
||||
type: 'logarithmic',
|
||||
ticks: {
|
||||
callback: function(value, index) {
|
||||
return index.toString();
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Just the index
|
||||
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 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: []
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'logarithmic'
|
||||
}, {
|
||||
id: 'yScale1',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chart.scales.yScale1.getLabelForIndex(0, 2)).toBe(150);
|
||||
});
|
||||
|
||||
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: []
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
id: 'xScale',
|
||||
type: 'logarithmic',
|
||||
position: 'bottom'
|
||||
}, {
|
||||
id: 'yScale',
|
||||
type: 'logarithmic'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
423
vendors/Chart.js/test/scale.radialLinear.tests.js
vendored
Normal file
423
vendors/Chart.js/test/scale.radialLinear.tests.js
vendored
Normal file
@@ -0,0 +1,423 @@
|
||||
// Tests for the radial linear scale used by the polar area and radar charts
|
||||
describe('Test the radial linear scale', function() {
|
||||
var chartInstance;
|
||||
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
if (chartInstance) {
|
||||
releaseChart(chartInstance);
|
||||
}
|
||||
});
|
||||
|
||||
it('Should register the constructor with the scale service', function() {
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
|
||||
expect(Constructor).not.toBe(undefined);
|
||||
expect(typeof Constructor).toBe('function');
|
||||
});
|
||||
|
||||
it('Should have the correct default config', function() {
|
||||
var defaultConfig = Chart.scaleService.getScaleDefaults('radialLinear');
|
||||
expect(defaultConfig).toEqual({
|
||||
angleLines: {
|
||||
display: true,
|
||||
color: "rgba(0, 0, 0, 0.1)",
|
||||
lineWidth: 1
|
||||
},
|
||||
animate: true,
|
||||
display: true,
|
||||
gridLines: {
|
||||
color: "rgba(0, 0, 0, 0.1)",
|
||||
drawBorder: true,
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true,
|
||||
tickMarkLength: 10,
|
||||
lineWidth: 1,
|
||||
offsetGridLines: false,
|
||||
display: true,
|
||||
zeroLineColor: "rgba(0,0,0,0.25)",
|
||||
zeroLineWidth: 1,
|
||||
},
|
||||
lineArc: false,
|
||||
pointLabels: {
|
||||
fontSize: 10,
|
||||
callback: defaultConfig.pointLabels.callback, // make this nicer, then check explicitly below
|
||||
},
|
||||
position: "chartArea",
|
||||
scaleLabel: {
|
||||
labelString: '',
|
||||
display: false,
|
||||
},
|
||||
ticks: {
|
||||
backdropColor: "rgba(255,255,255,0.75)",
|
||||
backdropPaddingY: 2,
|
||||
backdropPaddingX: 2,
|
||||
beginAtZero: false,
|
||||
minRotation: 0,
|
||||
maxRotation: 50,
|
||||
mirror: false,
|
||||
padding: 10,
|
||||
reverse: false,
|
||||
showLabelBackdrop: true,
|
||||
display: true,
|
||||
callback: defaultConfig.ticks.callback, // make this nicer, then check explicitly below
|
||||
autoSkip: true,
|
||||
autoSkipPadding: 0,
|
||||
labelOffset: 0
|
||||
},
|
||||
});
|
||||
|
||||
// Is this actually a function
|
||||
expect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));
|
||||
expect(defaultConfig.pointLabels.callback).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it('Should correctly determine the max & min data values', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 0, -5, 78, -100]
|
||||
}, {
|
||||
data: [150]
|
||||
}],
|
||||
labels: ['lablel1', 'label2', 'label3', 'label4', 'label5', 'label6']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.min).toBe(-100);
|
||||
expect(chartInstance.scale.max).toBe(150);
|
||||
});
|
||||
|
||||
it('Should correctly determine the max & min of string data values', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: ['10', '5', '0', '-5', '78', '-100']
|
||||
}, {
|
||||
data: ['150']
|
||||
}],
|
||||
labels: ['lablel1', 'label2', 'label3', 'label4', 'label5', 'label6']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.min).toBe(-100);
|
||||
expect(chartInstance.scale.max).toBe(150);
|
||||
});
|
||||
|
||||
it('Should correctly determine the max & min data values when there are hidden datasets', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: ['10', '5', '0', '-5', '78', '-100']
|
||||
}, {
|
||||
data: ['150']
|
||||
}, {
|
||||
data: [1000],
|
||||
hidden: true
|
||||
}],
|
||||
labels: ['lablel1', 'label2', 'label3', 'label4', 'label5', 'label6']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.min).toBe(-100);
|
||||
expect(chartInstance.scale.max).toBe(150);
|
||||
});
|
||||
|
||||
it('Should correctly determine the max & min data values when there is NaN data', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [50, 60, NaN, 70, null, undefined]
|
||||
}],
|
||||
labels: ['lablel1', 'label2', 'label3', 'label4', 'label5', 'label6']
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.min).toBe(50);
|
||||
expect(chartInstance.scale.max).toBe(70);
|
||||
});
|
||||
|
||||
it('Should ensure that the scale has a max and min that are not equal', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
datasets: [],
|
||||
labels: []
|
||||
};
|
||||
|
||||
var mockContext = window.createMockContext();
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
|
||||
var scale = new Constructor({
|
||||
ctx: mockContext,
|
||||
options: Chart.scaleService.getScaleDefaults('radialLinear'), // use default config for scale
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID,
|
||||
});
|
||||
|
||||
scale.update(200, 300);
|
||||
expect(scale.min).toBe(-1);
|
||||
expect(scale.max).toBe(1);
|
||||
});
|
||||
|
||||
it('Should use the suggestedMin and suggestedMax options', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [1, 1, 1, 2, 1, 0]
|
||||
}],
|
||||
labels: ['lablel1', 'label2', 'label3', 'label4', 'label5', 'label6']
|
||||
},
|
||||
options: {
|
||||
scale: {
|
||||
ticks: {
|
||||
suggestedMin: -10,
|
||||
suggestedMax: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.min).toBe(-10);
|
||||
expect(chartInstance.scale.max).toBe(10);
|
||||
});
|
||||
|
||||
it('Should use the min and max options', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [1, 1, 1, 2, 1, 0]
|
||||
}],
|
||||
labels: ['lablel1', 'label2', 'label3', 'label4', 'label5', 'label6']
|
||||
},
|
||||
options: {
|
||||
scale: {
|
||||
ticks: {
|
||||
min: -1010,
|
||||
max: 1010
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.min).toBe(-1010);
|
||||
expect(chartInstance.scale.max).toBe(1010);
|
||||
expect(chartInstance.scale.ticks).toEqual(['-1010', '-1000', '-500', '0', '500', '1000', '1010']);
|
||||
});
|
||||
|
||||
it('should forcibly include 0 in the range if the beginAtZero option is used', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [20, 30, 40, 50]
|
||||
}],
|
||||
labels: ['lablel1', 'label2', 'label3', 'label4']
|
||||
},
|
||||
options: {
|
||||
scale: {
|
||||
ticks: {
|
||||
beginAtZero: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.ticks).toEqual(['20', '25', '30', '35', '40', '45', '50']);
|
||||
|
||||
chartInstance.scale.options.ticks.beginAtZero = true;
|
||||
chartInstance.update();
|
||||
|
||||
expect(chartInstance.scale.ticks).toEqual(['0', '5', '10', '15', '20', '25', '30', '35', '40', '45', '50']);
|
||||
|
||||
chartInstance.data.datasets[0].data = [-20, -30, -40, -50];
|
||||
chartInstance.update();
|
||||
|
||||
expect(chartInstance.scale.ticks).toEqual(['-50', '-45', '-40', '-35', '-30', '-25', '-20', '-15', '-10', '-5', '0']);
|
||||
|
||||
chartInstance.scale.options.ticks.beginAtZero = false;
|
||||
chartInstance.update();
|
||||
|
||||
expect(chartInstance.scale.ticks).toEqual(['-50', '-45', '-40', '-35', '-30', '-25', '-20']);
|
||||
});
|
||||
|
||||
it('Should generate tick marks in the correct order in reversed mode', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['lablel1', 'label2', 'label3', 'label4', 'label5']
|
||||
},
|
||||
options: {
|
||||
scale: {
|
||||
ticks: {
|
||||
reverse: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.ticks).toEqual(['80', '70', '60', '50', '40', '30', '20', '10', '0']);
|
||||
expect(chartInstance.scale.start).toBe(80);
|
||||
expect(chartInstance.scale.end).toBe(0);
|
||||
});
|
||||
|
||||
it('Should build labels using the user supplied callback', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4', 'label5']
|
||||
},
|
||||
options: {
|
||||
scale: {
|
||||
ticks: {
|
||||
callback: function(value, index) {
|
||||
return index.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8']);
|
||||
expect(chartInstance.scale.pointLabels).toEqual(['label1', 'label2', 'label3', 'label4', 'label5']);
|
||||
});
|
||||
|
||||
it('Should build point labels using the user supplied callback', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4', 'label5']
|
||||
},
|
||||
options: {
|
||||
scale: {
|
||||
pointLabels: {
|
||||
callback: function(value, index) {
|
||||
return index.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.pointLabels).toEqual(['0', '1', '2', '3', '4']);
|
||||
});
|
||||
|
||||
it('should correctly set the center point', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4', 'label5']
|
||||
},
|
||||
options: {
|
||||
scale: {
|
||||
pointLabels: {
|
||||
callback: function(value, index) {
|
||||
return index.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.drawingArea).toBe(225);
|
||||
expect(chartInstance.scale.xCenter).toBe(256);
|
||||
expect(chartInstance.scale.yCenter).toBe(272);
|
||||
});
|
||||
|
||||
it('should correctly get the label for a given data index', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4', 'label5']
|
||||
},
|
||||
options: {
|
||||
scale: {
|
||||
pointLabels: {
|
||||
callback: function(value, index) {
|
||||
return index.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
expect(chartInstance.scale.getLabelForIndex(1, 0)).toBe(5);
|
||||
});
|
||||
|
||||
it('should get the correct distance from the center point', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'radar',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [10, 5, 0, 25, 78]
|
||||
}],
|
||||
labels: ['label1', 'label2', 'label3', 'label4', 'label5']
|
||||
},
|
||||
options: {
|
||||
scale: {
|
||||
pointLabels: {
|
||||
callback: function(value, index) {
|
||||
return index.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chartInstance.scale.getDistanceFromCenterForValue(chartInstance.scale.min)).toBe(0);
|
||||
expect(chartInstance.scale.getDistanceFromCenterForValue(chartInstance.scale.max)).toBe(225);
|
||||
expect(chartInstance.scale.getPointPositionForValue(1, 5)).toEqual({
|
||||
x: 269,
|
||||
y: 268,
|
||||
});
|
||||
|
||||
chartInstance.scale.options.reverse = true;
|
||||
chartInstance.update();
|
||||
|
||||
expect(chartInstance.scale.getDistanceFromCenterForValue(chartInstance.scale.min)).toBe(225);
|
||||
expect(chartInstance.scale.getDistanceFromCenterForValue(chartInstance.scale.max)).toBe(0);
|
||||
});
|
||||
});
|
||||
438
vendors/Chart.js/test/scale.time.tests.js
vendored
Normal file
438
vendors/Chart.js/test/scale.time.tests.js
vendored
Normal file
@@ -0,0 +1,438 @@
|
||||
// Time scale tests
|
||||
describe('Time scale tests', function() {
|
||||
var chartInstance;
|
||||
|
||||
beforeEach(function() {
|
||||
window.addDefaultMatchers(jasmine);
|
||||
|
||||
// Need a time matcher for getValueFromPixel
|
||||
jasmine.addMatchers({
|
||||
toBeCloseToTime: function() {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
var result = false;
|
||||
|
||||
var diff = actual.diff(expected.value, expected.unit, true);
|
||||
result = Math.abs(diff) < (expected.threshold !== undefined ? expected.threshold : 0.5);
|
||||
|
||||
return {
|
||||
pass: result
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
if (chartInstance)
|
||||
{
|
||||
releaseChart(chartInstance);
|
||||
}
|
||||
});
|
||||
|
||||
it('Should load moment.js as a dependency', function() {
|
||||
expect(window.moment).not.toBe(undefined);
|
||||
});
|
||||
|
||||
it('Should register the constructor with the scale service', function() {
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('time');
|
||||
expect(Constructor).not.toBe(undefined);
|
||||
expect(typeof Constructor).toBe('function');
|
||||
});
|
||||
|
||||
it('Should have the correct default config', function() {
|
||||
var defaultConfig = Chart.scaleService.getScaleDefaults('time');
|
||||
expect(defaultConfig).toEqual({
|
||||
display: true,
|
||||
gridLines: {
|
||||
color: "rgba(0, 0, 0, 0.1)",
|
||||
drawBorder: true,
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true,
|
||||
tickMarkLength: 10,
|
||||
lineWidth: 1,
|
||||
offsetGridLines: false,
|
||||
display: true,
|
||||
zeroLineColor: "rgba(0,0,0,0.25)",
|
||||
zeroLineWidth: 1
|
||||
},
|
||||
position: "bottom",
|
||||
scaleLabel: {
|
||||
labelString: '',
|
||||
display: false
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: false,
|
||||
minRotation: 0,
|
||||
maxRotation: 50,
|
||||
mirror: false,
|
||||
padding: 10,
|
||||
reverse: false,
|
||||
display: true,
|
||||
callback: defaultConfig.ticks.callback, // make this nicer, then check explicitly below,
|
||||
autoSkip: false,
|
||||
autoSkipPadding: 0,
|
||||
labelOffset: 0
|
||||
},
|
||||
time: {
|
||||
parser: false,
|
||||
format: false,
|
||||
unit: false,
|
||||
round: false,
|
||||
isoWeekday: false,
|
||||
displayFormat: false,
|
||||
displayFormats: {
|
||||
'millisecond': 'h:mm:ss.SSS a', // 11:20:01.123 AM
|
||||
'second': 'h:mm:ss a', // 11:20:01 AM
|
||||
'minute': 'h:mm:ss a', // 11:20:01 AM
|
||||
'hour': 'MMM D, hA', // Sept 4, 5PM
|
||||
'day': 'll', // Sep 4 2015
|
||||
'week': 'll', // Week 46, or maybe "[W]WW - YYYY" ?
|
||||
'month': 'MMM YYYY', // Sept 2015
|
||||
'quarter': '[Q]Q - YYYY', // Q3
|
||||
'year': 'YYYY' // 2015
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Is this actually a function
|
||||
expect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it('should build ticks using days', 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
|
||||
};
|
||||
|
||||
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
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
//scale.buildTicks();
|
||||
scale.update(400, 50);
|
||||
|
||||
// Counts down because the lines are drawn top to bottom
|
||||
expect(scale.ticks).toEqual([ 'Dec 28, 2014', 'Jan 4, 2015', 'Jan 11, 2015' ]);
|
||||
});
|
||||
|
||||
it('should build ticks using date objects', function() {
|
||||
// Helper to build date objects
|
||||
function newDateFromRef(days) {
|
||||
return moment('01/01/2015 12:00', 'DD/MM/YYYY HH:mm').add(days, 'd').toDate();
|
||||
}
|
||||
|
||||
var scaleID = 'myScale';
|
||||
var mockData = {
|
||||
labels: [newDateFromRef(0), newDateFromRef(1), newDateFromRef(2), newDateFromRef(4), newDateFromRef(6), newDateFromRef(7), newDateFromRef(9)], // days
|
||||
};
|
||||
|
||||
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
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
scale.update(400, 50);
|
||||
|
||||
// Counts down because the lines are drawn top to bottom
|
||||
expect(scale.ticks).toEqual([ 'Dec 28, 2014', 'Jan 4, 2015', 'Jan 11, 2015' ]);
|
||||
});
|
||||
|
||||
it('should build ticks when the data is xy points', function() {
|
||||
// Helper to build date objects
|
||||
function newDateFromRef(days) {
|
||||
return moment('01/01/2015 12:00', 'DD/MM/YYYY HH:mm').add(days, 'd').toDate();
|
||||
}
|
||||
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
xAxisID: 'xScale0',
|
||||
yAxisID: 'yScale0',
|
||||
data: [{
|
||||
x: newDateFromRef(0),
|
||||
y: 1
|
||||
}, {
|
||||
x: newDateFromRef(1),
|
||||
y: 10
|
||||
}, {
|
||||
x: newDateFromRef(2),
|
||||
y: 0
|
||||
}, {
|
||||
x: newDateFromRef(4),
|
||||
y: 5
|
||||
}, {
|
||||
x: newDateFromRef(6),
|
||||
y: 77
|
||||
}, {
|
||||
x: newDateFromRef(7),
|
||||
y: 9
|
||||
}, {
|
||||
x: newDateFromRef(9),
|
||||
y: 5
|
||||
}]
|
||||
}],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale0',
|
||||
type: 'time',
|
||||
position: 'bottom'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Counts down because the lines are drawn top to bottom
|
||||
var xScale = chartInstance.scales.xScale0;
|
||||
expect(xScale.ticks).toEqual([ 'Jan 1, 2015', 'Jan 3, 2015', 'Jan 5, 2015', 'Jan 7, 2015', 'Jan 9, 2015', 'Jan 11, 2015' ]);
|
||||
});
|
||||
|
||||
it('should allow custom time parsers', function() {
|
||||
chartInstance = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
xAxisID: 'xScale0',
|
||||
yAxisID: 'yScale0',
|
||||
data: [{
|
||||
x: 375068900,
|
||||
y: 1
|
||||
}]
|
||||
}],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale0',
|
||||
type: 'time',
|
||||
position: 'bottom',
|
||||
time: {
|
||||
unit: 'day',
|
||||
round: true,
|
||||
parser: function customTimeParser(label) {
|
||||
return moment.unix(label);
|
||||
}
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Counts down because the lines are drawn top to bottom
|
||||
var xScale = chartInstance.scales.xScale0;
|
||||
|
||||
// Counts down because the lines are drawn top to bottom
|
||||
expect(xScale.ticks[0]).toEqualOneOf(['Nov 19, 1981', 'Nov 20, 1981', 'Nov 21, 1981']); // handle time zone changes
|
||||
expect(xScale.ticks[1]).toEqualOneOf(['Nov 19, 1981', 'Nov 20, 1981', 'Nov 21, 1981']); // handle time zone changes
|
||||
});
|
||||
|
||||
it('should build ticks using the config unit', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
labels: ["2015-01-01T20:00:00", "2015-01-02T21:00:00"], // days
|
||||
};
|
||||
|
||||
var mockContext = window.createMockContext();
|
||||
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));
|
||||
config.time.unit = 'hour';
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('time');
|
||||
var scale = new Constructor({
|
||||
ctx: mockContext,
|
||||
options: config, // use default config for scale
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
//scale.buildTicks();
|
||||
scale.update(400, 50);
|
||||
expect(scale.ticks).toEqual(['Jan 1, 8PM', 'Jan 1, 9PM', 'Jan 1, 10PM', 'Jan 1, 11PM', 'Jan 2, 12AM', 'Jan 2, 1AM', 'Jan 2, 2AM', 'Jan 2, 3AM', 'Jan 2, 4AM', 'Jan 2, 5AM', 'Jan 2, 6AM', 'Jan 2, 7AM', 'Jan 2, 8AM', 'Jan 2, 9AM', 'Jan 2, 10AM', 'Jan 2, 11AM', 'Jan 2, 12PM', 'Jan 2, 1PM', 'Jan 2, 2PM', 'Jan 2, 3PM', 'Jan 2, 4PM', 'Jan 2, 5PM', 'Jan 2, 6PM', 'Jan 2, 7PM', 'Jan 2, 8PM', 'Jan 2, 9PM']);
|
||||
});
|
||||
|
||||
it('should build ticks using the config diff', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
labels: ["2015-01-01T20:00:00", "2015-02-02T21:00:00", "2015-02-21T01:00:00"], // days
|
||||
};
|
||||
|
||||
var mockContext = window.createMockContext();
|
||||
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));
|
||||
config.time.unit = 'week';
|
||||
config.time.round = 'week';
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('time');
|
||||
var scale = new Constructor({
|
||||
ctx: mockContext,
|
||||
options: config, // use default config for scale
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
//scale.buildTicks();
|
||||
scale.update(400, 50);
|
||||
|
||||
// last date is feb 15 because we round to start of week
|
||||
expect(scale.ticks).toEqual(['Dec 28, 2014', 'Jan 4, 2015', 'Jan 11, 2015', 'Jan 18, 2015', 'Jan 25, 2015', 'Feb 1, 2015', 'Feb 8, 2015', 'Feb 15, 2015']);
|
||||
});
|
||||
|
||||
it('Should use the min and max options', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
labels: ["2015-01-01T20:00:00", "2015-01-02T20:00:00", "2015-01-03T20:00:00"], // days
|
||||
};
|
||||
|
||||
var mockContext = window.createMockContext();
|
||||
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));
|
||||
config.time.min = "2015-01-01T04:00:00";
|
||||
config.time.max = "2015-01-05T06:00:00"
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('time');
|
||||
var scale = new Constructor({
|
||||
ctx: mockContext,
|
||||
options: config, // use default config for scale
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
scale.update(400, 50);
|
||||
expect(scale.ticks).toEqual([ 'Jan 1, 2015', 'Jan 5, 2015' ]);
|
||||
});
|
||||
|
||||
it('Should use the isoWeekday option', function() {
|
||||
var scaleID = 'myScale';
|
||||
|
||||
var mockData = {
|
||||
labels: [
|
||||
"2015-01-01T20:00:00", // Thursday
|
||||
"2015-01-02T20:00:00", // Friday
|
||||
"2015-01-03T20:00:00" // Saturday
|
||||
]
|
||||
};
|
||||
|
||||
var mockContext = window.createMockContext();
|
||||
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));
|
||||
config.time.unit = 'week';
|
||||
// Wednesday
|
||||
config.time.isoWeekday = 3;
|
||||
var Constructor = Chart.scaleService.getScaleConstructor('time');
|
||||
var scale = new Constructor({
|
||||
ctx: mockContext,
|
||||
options: config, // use default config for scale
|
||||
chart: {
|
||||
data: mockData
|
||||
},
|
||||
id: scaleID
|
||||
});
|
||||
|
||||
scale.update(400, 50);
|
||||
expect(scale.ticks).toEqual([ 'Dec 31, 2014', 'Jan 7, 2015' ]);
|
||||
});
|
||||
|
||||
it('should get the correct pixel for a value', function() {
|
||||
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
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale0',
|
||||
type: 'time',
|
||||
position: 'bottom'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
position: 'left'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var xScale = chartInstance.scales.xScale0;
|
||||
|
||||
expect(xScale.getPixelForValue('', 0, 0)).toBeCloseToPixel(78);
|
||||
expect(xScale.getPixelForValue('', 6, 0)).toBeCloseToPixel(452);
|
||||
|
||||
expect(xScale.getValueForPixel(78)).toBeCloseToTime({
|
||||
value: moment(chartInstance.data.labels[0]),
|
||||
unit: 'hour',
|
||||
threshold: 0.75
|
||||
});
|
||||
expect(xScale.getValueForPixel(452)).toBeCloseToTime({
|
||||
value: moment(chartInstance.data.labels[6]),
|
||||
unit: 'hour'
|
||||
});
|
||||
});
|
||||
|
||||
it('should get the correct label for a data value', function() {
|
||||
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
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
id: 'xScale0',
|
||||
type: 'time',
|
||||
position: 'bottom'
|
||||
}],
|
||||
yAxes: [{
|
||||
id: 'yScale0',
|
||||
type: 'linear',
|
||||
position: 'left'
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var xScale = chartInstance.scales.xScale0;
|
||||
expect(xScale.getLabelForIndex(0, 0)).toBe('2015-01-01T20:00:00');
|
||||
expect(xScale.getLabelForIndex(6, 0)).toBe('2015-01-10T12:00');
|
||||
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user