core.scale.tests.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. describe('Core.scale', function() {
  2. describe('auto', jasmine.fixture.specs('core.scale'));
  3. it('should provide default scale label options', function() {
  4. expect(Chart.defaults.scale.scaleLabel).toEqual({
  5. // display property
  6. display: false,
  7. // actual label
  8. labelString: '',
  9. // top/bottom padding
  10. padding: {
  11. top: 4,
  12. bottom: 4
  13. }
  14. });
  15. });
  16. describe('displaying xAxis ticks with autoSkip=true', function() {
  17. function getChart(data) {
  18. return window.acquireChart({
  19. type: 'line',
  20. data: data,
  21. options: {
  22. scales: {
  23. xAxes: [{
  24. ticks: {
  25. autoSkip: true
  26. }
  27. }]
  28. }
  29. }
  30. });
  31. }
  32. function lastTick(chart) {
  33. var xAxis = chart.scales['x-axis-0'];
  34. var ticks = xAxis.getTicks();
  35. return ticks[ticks.length - 1];
  36. }
  37. it('should display the last tick if it fits evenly with other ticks', function() {
  38. var chart = getChart({
  39. labels: [
  40. 'January 2018', 'February 2018', 'March 2018', 'April 2018',
  41. 'May 2018', 'June 2018', 'July 2018', 'August 2018',
  42. 'September 2018'
  43. ],
  44. datasets: [{
  45. data: [12, 19, 3, 5, 2, 3, 7, 8, 9]
  46. }]
  47. });
  48. expect(lastTick(chart).label).toEqual('September 2018');
  49. });
  50. it('should not display the last tick if it does not fit evenly', function() {
  51. var chart = getChart({
  52. labels: [
  53. 'January 2018', 'February 2018', 'March 2018', 'April 2018',
  54. 'May 2018', 'June 2018', 'July 2018', 'August 2018',
  55. 'September 2018', 'October 2018', 'November 2018', 'December 2018',
  56. 'January 2019', 'February 2019', 'March 2019', 'April 2019',
  57. 'May 2019', 'June 2019', 'July 2019', 'August 2019',
  58. 'September 2019', 'October 2019', 'November 2019', 'December 2019',
  59. 'January 2020', 'February 2020'
  60. ],
  61. datasets: [{
  62. data: [12, 19, 3, 5, 2, 3, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
  63. }]
  64. });
  65. expect(lastTick(chart).label).toBeUndefined();
  66. });
  67. });
  68. var gridLineTests = [{
  69. labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5'],
  70. offsetGridLines: false,
  71. offset: false,
  72. expected: [0.5, 128.5, 256.5, 384.5, 512.5]
  73. }, {
  74. labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5'],
  75. offsetGridLines: false,
  76. offset: true,
  77. expected: [51.5, 153.5, 256.5, 358.5, 460.5]
  78. }, {
  79. labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5'],
  80. offsetGridLines: true,
  81. offset: false,
  82. expected: [64.5, 192.5, 320.5, 448.5]
  83. }, {
  84. labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5'],
  85. offsetGridLines: true,
  86. offset: true,
  87. expected: [0.5, 102.5, 204.5, 307.5, 409.5, 512.5]
  88. }, {
  89. labels: ['tick1'],
  90. offsetGridLines: false,
  91. offset: false,
  92. expected: [0.5]
  93. }, {
  94. labels: ['tick1'],
  95. offsetGridLines: false,
  96. offset: true,
  97. expected: [256.5]
  98. }, {
  99. labels: ['tick1'],
  100. offsetGridLines: true,
  101. offset: false,
  102. expected: [512.5]
  103. }, {
  104. labels: ['tick1'],
  105. offsetGridLines: true,
  106. offset: true,
  107. expected: [0.5, 512.5]
  108. }];
  109. gridLineTests.forEach(function(test) {
  110. it('should get the correct pixels for gridLine(s) for the horizontal scale when offsetGridLines is ' + test.offsetGridLines + ' and offset is ' + test.offset, function() {
  111. var chart = window.acquireChart({
  112. type: 'line',
  113. data: {
  114. datasets: [{
  115. data: []
  116. }],
  117. labels: test.labels
  118. },
  119. options: {
  120. scales: {
  121. xAxes: [{
  122. id: 'xScale0',
  123. gridLines: {
  124. offsetGridLines: test.offsetGridLines,
  125. drawTicks: false
  126. },
  127. ticks: {
  128. display: false
  129. },
  130. offset: test.offset
  131. }],
  132. yAxes: [{
  133. display: false
  134. }]
  135. },
  136. legend: {
  137. display: false
  138. }
  139. }
  140. });
  141. var xScale = chart.scales.xScale0;
  142. xScale.ctx = window.createMockContext();
  143. chart.draw();
  144. expect(xScale.ctx.getCalls().filter(function(x) {
  145. return x.name === 'moveTo' && x.args[1] === 0;
  146. }).map(function(x) {
  147. return x.args[0];
  148. })).toEqual(test.expected);
  149. });
  150. });
  151. gridLineTests.forEach(function(test) {
  152. it('should get the correct pixels for gridLine(s) for the vertical scale when offsetGridLines is ' + test.offsetGridLines + ' and offset is ' + test.offset, function() {
  153. var chart = window.acquireChart({
  154. type: 'line',
  155. data: {
  156. datasets: [{
  157. data: []
  158. }],
  159. labels: test.labels
  160. },
  161. options: {
  162. scales: {
  163. xAxes: [{
  164. display: false
  165. }],
  166. yAxes: [{
  167. type: 'category',
  168. id: 'yScale0',
  169. gridLines: {
  170. offsetGridLines: test.offsetGridLines,
  171. drawTicks: false
  172. },
  173. ticks: {
  174. display: false
  175. },
  176. offset: test.offset
  177. }]
  178. },
  179. legend: {
  180. display: false
  181. }
  182. }
  183. });
  184. var yScale = chart.scales.yScale0;
  185. yScale.ctx = window.createMockContext();
  186. chart.draw();
  187. expect(yScale.ctx.getCalls().filter(function(x) {
  188. return x.name === 'moveTo' && x.args[0] === 1;
  189. }).map(function(x) {
  190. return x.args[1];
  191. })).toEqual(test.expected);
  192. });
  193. });
  194. it('should add the correct padding for long tick labels', function() {
  195. var chart = window.acquireChart({
  196. type: 'line',
  197. data: {
  198. labels: [
  199. 'This is a very long label',
  200. 'This is a very long label'
  201. ],
  202. datasets: [{
  203. data: [0, 1]
  204. }]
  205. },
  206. options: {
  207. scales: {
  208. xAxes: [{
  209. id: 'foo'
  210. }],
  211. yAxes: [{
  212. display: false
  213. }]
  214. },
  215. legend: {
  216. display: false
  217. }
  218. }
  219. }, {
  220. canvas: {
  221. height: 100,
  222. width: 200
  223. }
  224. });
  225. var scale = chart.scales.foo;
  226. expect(scale.left).toBeGreaterThan(100);
  227. expect(scale.right).toBeGreaterThan(190);
  228. });
  229. describe('given the axes display option is set to auto', function() {
  230. describe('for the x axes', function() {
  231. it('should draw the axes if at least one associated dataset is visible', function() {
  232. var chart = window.acquireChart({
  233. type: 'line',
  234. data: {
  235. datasets: [{
  236. data: [100, 200, 100, 50],
  237. xAxisId: 'foo',
  238. hidden: true,
  239. labels: ['Q1', 'Q2', 'Q3', 'Q4']
  240. }, {
  241. data: [100, 200, 100, 50],
  242. xAxisId: 'foo',
  243. labels: ['Q1', 'Q2', 'Q3', 'Q4']
  244. }]
  245. },
  246. options: {
  247. scales: {
  248. xAxes: [{
  249. id: 'foo',
  250. display: 'auto'
  251. }],
  252. yAxes: [{
  253. type: 'category',
  254. id: 'yScale0'
  255. }]
  256. }
  257. }
  258. });
  259. var scale = chart.scales.foo;
  260. scale.ctx = window.createMockContext();
  261. chart.draw();
  262. expect(scale.ctx.getCalls().length).toBeGreaterThan(0);
  263. expect(scale.height).toBeGreaterThan(0);
  264. });
  265. it('should not draw the axes if no associated datasets are visible', function() {
  266. var chart = window.acquireChart({
  267. type: 'line',
  268. data: {
  269. datasets: [{
  270. data: [100, 200, 100, 50],
  271. xAxisId: 'foo',
  272. hidden: true,
  273. labels: ['Q1', 'Q2', 'Q3', 'Q4']
  274. }]
  275. },
  276. options: {
  277. scales: {
  278. xAxes: [{
  279. id: 'foo',
  280. display: 'auto'
  281. }]
  282. }
  283. }
  284. });
  285. var scale = chart.scales.foo;
  286. scale.ctx = window.createMockContext();
  287. chart.draw();
  288. expect(scale.ctx.getCalls().length).toBe(0);
  289. expect(scale.height).toBe(0);
  290. });
  291. });
  292. describe('for the y axes', function() {
  293. it('should draw the axes if at least one associated dataset is visible', function() {
  294. var chart = window.acquireChart({
  295. type: 'line',
  296. data: {
  297. datasets: [{
  298. data: [100, 200, 100, 50],
  299. yAxisId: 'foo',
  300. hidden: true,
  301. labels: ['Q1', 'Q2', 'Q3', 'Q4']
  302. }, {
  303. data: [100, 200, 100, 50],
  304. yAxisId: 'foo',
  305. labels: ['Q1', 'Q2', 'Q3', 'Q4']
  306. }]
  307. },
  308. options: {
  309. scales: {
  310. yAxes: [{
  311. id: 'foo',
  312. display: 'auto'
  313. }]
  314. }
  315. }
  316. });
  317. var scale = chart.scales.foo;
  318. scale.ctx = window.createMockContext();
  319. chart.draw();
  320. expect(scale.ctx.getCalls().length).toBeGreaterThan(0);
  321. expect(scale.width).toBeGreaterThan(0);
  322. });
  323. it('should not draw the axes if no associated datasets are visible', function() {
  324. var chart = window.acquireChart({
  325. type: 'line',
  326. data: {
  327. datasets: [{
  328. data: [100, 200, 100, 50],
  329. yAxisId: 'foo',
  330. hidden: true,
  331. labels: ['Q1', 'Q2', 'Q3', 'Q4']
  332. }]
  333. },
  334. options: {
  335. scales: {
  336. yAxes: [{
  337. id: 'foo',
  338. display: 'auto'
  339. }]
  340. }
  341. }
  342. });
  343. var scale = chart.scales.foo;
  344. scale.ctx = window.createMockContext();
  345. chart.draw();
  346. expect(scale.ctx.getCalls().length).toBe(0);
  347. expect(scale.width).toBe(0);
  348. });
  349. });
  350. });
  351. describe('afterBuildTicks', function() {
  352. it('should allow filtering of ticks', function() {
  353. var labels = ['tick1', 'tick2', 'tick3', 'tick4', 'tick5'];
  354. var chart = window.acquireChart({
  355. type: 'line',
  356. options: {
  357. scales: {
  358. xAxes: [{
  359. id: 'x',
  360. type: 'category',
  361. labels: labels,
  362. afterBuildTicks: function(axis, ticks) {
  363. return ticks.slice(1);
  364. }
  365. }]
  366. }
  367. }
  368. });
  369. var scale = chart.scales.x;
  370. expect(scale.ticks).toEqual(labels.slice(1));
  371. });
  372. it('should allow filtering of ticks (for new implementation of buildTicks)', function() {
  373. var chart = window.acquireChart({
  374. type: 'line',
  375. data: {
  376. labels: ['2016', '2017', '2018']
  377. },
  378. options: {
  379. scales: {
  380. xAxes: [{
  381. id: 'x',
  382. type: 'time',
  383. time: {
  384. parser: 'YYYY'
  385. },
  386. ticks: {
  387. source: 'labels'
  388. },
  389. afterBuildTicks: function(axis, ticks) {
  390. return ticks.slice(1);
  391. }
  392. }]
  393. }
  394. }
  395. });
  396. var scale = chart.scales.x;
  397. expect(scale.ticks.length).toEqual(2);
  398. });
  399. it('should allow no return value from callback', function() {
  400. var labels = ['tick1', 'tick2', 'tick3', 'tick4', 'tick5'];
  401. var chart = window.acquireChart({
  402. type: 'line',
  403. options: {
  404. scales: {
  405. xAxes: [{
  406. id: 'x',
  407. type: 'category',
  408. labels: labels,
  409. afterBuildTicks: function() { }
  410. }]
  411. }
  412. }
  413. });
  414. var scale = chart.scales.x;
  415. expect(scale.ticks).toEqual(labels);
  416. });
  417. it('should allow empty ticks', function() {
  418. var labels = ['tick1', 'tick2', 'tick3', 'tick4', 'tick5'];
  419. var chart = window.acquireChart({
  420. type: 'line',
  421. options: {
  422. scales: {
  423. xAxes: [{
  424. id: 'x',
  425. type: 'category',
  426. labels: labels,
  427. afterBuildTicks: function() {
  428. return [];
  429. }
  430. }]
  431. }
  432. }
  433. });
  434. var scale = chart.scales.x;
  435. expect(scale.ticks.length).toBe(0);
  436. });
  437. });
  438. describe('_layers', function() {
  439. it('should default to one layer', function() {
  440. var chart = window.acquireChart({
  441. type: 'line',
  442. options: {
  443. scales: {
  444. xAxes: [{
  445. id: 'x',
  446. type: 'linear',
  447. }]
  448. }
  449. }
  450. });
  451. var scale = chart.scales.x;
  452. expect(scale._layers().length).toEqual(1);
  453. });
  454. it('should default to one layer for custom scales', function() {
  455. var customScale = Chart.Scale.extend({
  456. draw: function() {},
  457. convertTicksToLabels: function() {
  458. return ['tick'];
  459. }
  460. });
  461. Chart.scaleService.registerScaleType('customScale', customScale, {});
  462. var chart = window.acquireChart({
  463. type: 'line',
  464. options: {
  465. scales: {
  466. xAxes: [{
  467. id: 'x',
  468. type: 'customScale',
  469. gridLines: {
  470. z: 10
  471. },
  472. ticks: {
  473. z: 20
  474. }
  475. }]
  476. }
  477. }
  478. });
  479. var scale = chart.scales.x;
  480. expect(scale._layers().length).toEqual(1);
  481. expect(scale._layers()[0].z).toEqual(20);
  482. });
  483. it('should default to one layer when z is equal between ticks and grid', function() {
  484. var chart = window.acquireChart({
  485. type: 'line',
  486. options: {
  487. scales: {
  488. xAxes: [{
  489. id: 'x',
  490. type: 'linear',
  491. ticks: {
  492. z: 10
  493. },
  494. gridLines: {
  495. z: 10
  496. }
  497. }]
  498. }
  499. }
  500. });
  501. var scale = chart.scales.x;
  502. expect(scale._layers().length).toEqual(1);
  503. });
  504. it('should return 2 layers when z is not equal between ticks and grid', function() {
  505. var chart = window.acquireChart({
  506. type: 'line',
  507. options: {
  508. scales: {
  509. xAxes: [{
  510. id: 'x',
  511. type: 'linear',
  512. ticks: {
  513. z: 10
  514. }
  515. }]
  516. }
  517. }
  518. });
  519. expect(chart.scales.x._layers().length).toEqual(2);
  520. chart = window.acquireChart({
  521. type: 'line',
  522. options: {
  523. scales: {
  524. xAxes: [{
  525. id: 'x',
  526. type: 'linear',
  527. gridLines: {
  528. z: 11
  529. }
  530. }]
  531. }
  532. }
  533. });
  534. expect(chart.scales.x._layers().length).toEqual(2);
  535. chart = window.acquireChart({
  536. type: 'line',
  537. options: {
  538. scales: {
  539. xAxes: [{
  540. id: 'x',
  541. type: 'linear',
  542. ticks: {
  543. z: 10
  544. },
  545. gridLines: {
  546. z: 11
  547. }
  548. }]
  549. }
  550. }
  551. });
  552. expect(chart.scales.x._layers().length).toEqual(2);
  553. });
  554. });
  555. });