scale.linear.tests.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281
  1. describe('Linear Scale', function() {
  2. it('Should register the constructor with the scale service', function() {
  3. var Constructor = Chart.scaleService.getScaleConstructor('linear');
  4. expect(Constructor).not.toBe(undefined);
  5. expect(typeof Constructor).toBe('function');
  6. });
  7. it('Should have the correct default config', function() {
  8. var defaultConfig = Chart.scaleService.getScaleDefaults('linear');
  9. expect(defaultConfig).toEqual({
  10. display: true,
  11. gridLines: {
  12. color: 'rgba(0,0,0,0.1)',
  13. drawBorder: true,
  14. drawOnChartArea: true,
  15. drawTicks: true, // draw ticks extending towards the label
  16. tickMarkLength: 10,
  17. lineWidth: 1,
  18. offsetGridLines: false,
  19. display: true,
  20. zeroLineColor: 'rgba(0,0,0,0.25)',
  21. zeroLineWidth: 1,
  22. zeroLineBorderDash: [],
  23. zeroLineBorderDashOffset: 0.0,
  24. borderDash: [],
  25. borderDashOffset: 0.0
  26. },
  27. position: 'left',
  28. offset: false,
  29. scaleLabel: Chart.defaults.scale.scaleLabel,
  30. ticks: {
  31. beginAtZero: false,
  32. minRotation: 0,
  33. maxRotation: 50,
  34. mirror: false,
  35. padding: 0,
  36. reverse: false,
  37. display: true,
  38. callback: defaultConfig.ticks.callback, // make this work nicer, then check below
  39. autoSkip: true,
  40. autoSkipPadding: 0,
  41. labelOffset: 0,
  42. minor: {},
  43. major: {},
  44. }
  45. });
  46. expect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));
  47. });
  48. it('Should correctly determine the max & min data values', function() {
  49. var chart = window.acquireChart({
  50. type: 'bar',
  51. data: {
  52. datasets: [{
  53. yAxisID: 'yScale0',
  54. data: [10, 5, 0, -5, 78, -100]
  55. }, {
  56. yAxisID: 'yScale1',
  57. data: [-1000, 1000],
  58. }, {
  59. yAxisID: 'yScale0',
  60. data: [150]
  61. }],
  62. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  63. },
  64. options: {
  65. scales: {
  66. yAxes: [{
  67. id: 'yScale0',
  68. type: 'linear'
  69. }, {
  70. id: 'yScale1',
  71. type: 'linear'
  72. }]
  73. }
  74. }
  75. });
  76. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  77. expect(chart.scales.yScale0.min).toBe(-100);
  78. expect(chart.scales.yScale0.max).toBe(150);
  79. });
  80. it('Should correctly determine the max & min of string data values', function() {
  81. var chart = window.acquireChart({
  82. type: 'bar',
  83. data: {
  84. datasets: [{
  85. yAxisID: 'yScale0',
  86. data: ['10', '5', '0', '-5', '78', '-100']
  87. }, {
  88. yAxisID: 'yScale1',
  89. data: ['-1000', '1000'],
  90. }, {
  91. yAxisID: 'yScale0',
  92. data: ['150']
  93. }],
  94. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  95. },
  96. options: {
  97. scales: {
  98. yAxes: [{
  99. id: 'yScale0',
  100. type: 'linear'
  101. }, {
  102. id: 'yScale1',
  103. type: 'linear'
  104. }]
  105. }
  106. }
  107. });
  108. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  109. expect(chart.scales.yScale0.min).toBe(-100);
  110. expect(chart.scales.yScale0.max).toBe(150);
  111. });
  112. it('Should correctly determine the max & min when no values provided and suggested minimum and maximum are set', function() {
  113. var chart = window.acquireChart({
  114. type: 'bar',
  115. data: {
  116. datasets: [{
  117. yAxisID: 'yScale0',
  118. data: []
  119. }],
  120. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  121. },
  122. options: {
  123. scales: {
  124. yAxes: [{
  125. id: 'yScale0',
  126. type: 'linear',
  127. ticks: {
  128. suggestedMin: -10,
  129. suggestedMax: 15
  130. }
  131. }]
  132. }
  133. }
  134. });
  135. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  136. expect(chart.scales.yScale0.min).toBe(-10);
  137. expect(chart.scales.yScale0.max).toBe(15);
  138. });
  139. it('Should correctly determine the max & min data values ignoring hidden datasets', function() {
  140. var chart = window.acquireChart({
  141. type: 'bar',
  142. data: {
  143. datasets: [{
  144. yAxisID: 'yScale0',
  145. data: ['10', '5', '0', '-5', '78', '-100']
  146. }, {
  147. yAxisID: 'yScale1',
  148. data: ['-1000', '1000'],
  149. }, {
  150. yAxisID: 'yScale0',
  151. data: ['150'],
  152. hidden: true
  153. }],
  154. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  155. },
  156. options: {
  157. scales: {
  158. yAxes: [{
  159. id: 'yScale0',
  160. type: 'linear'
  161. }, {
  162. id: 'yScale1',
  163. type: 'linear'
  164. }]
  165. }
  166. }
  167. });
  168. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  169. expect(chart.scales.yScale0.min).toBe(-100);
  170. expect(chart.scales.yScale0.max).toBe(80);
  171. });
  172. it('Should correctly determine the max & min data values ignoring data that is NaN', function() {
  173. var chart = window.acquireChart({
  174. type: 'bar',
  175. data: {
  176. datasets: [{
  177. yAxisID: 'yScale0',
  178. data: [null, 90, NaN, undefined, 45, 30, Infinity, -Infinity]
  179. }],
  180. labels: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
  181. },
  182. options: {
  183. scales: {
  184. yAxes: [{
  185. id: 'yScale0',
  186. type: 'linear'
  187. }]
  188. }
  189. }
  190. });
  191. expect(chart.scales.yScale0.min).toBe(30);
  192. expect(chart.scales.yScale0.max).toBe(90);
  193. // Scale is now stacked
  194. chart.scales.yScale0.options.stacked = true;
  195. chart.update();
  196. expect(chart.scales.yScale0.min).toBe(0);
  197. expect(chart.scales.yScale0.max).toBe(90);
  198. });
  199. it('Should correctly determine the max & min data values for small numbers', function() {
  200. var chart = window.acquireChart({
  201. type: 'bar',
  202. data: {
  203. datasets: [{
  204. yAxisID: 'yScale0',
  205. data: [-1e-8, 3e-8, -4e-8, 6e-8]
  206. }],
  207. labels: ['a', 'b', 'c', 'd']
  208. },
  209. options: {
  210. scales: {
  211. yAxes: [{
  212. id: 'yScale0',
  213. type: 'linear'
  214. }]
  215. }
  216. }
  217. });
  218. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  219. expect(chart.scales.yScale0.min * 1e8).toBeCloseTo(-4);
  220. expect(chart.scales.yScale0.max * 1e8).toBeCloseTo(6);
  221. });
  222. it('Should correctly determine the max & min for scatter data', function() {
  223. var chart = window.acquireChart({
  224. type: 'line',
  225. data: {
  226. datasets: [{
  227. xAxisID: 'xScale0',
  228. yAxisID: 'yScale0',
  229. data: [{
  230. x: 10,
  231. y: 100
  232. }, {
  233. x: -10,
  234. y: 0
  235. }, {
  236. x: 0,
  237. y: 0
  238. }, {
  239. x: 99,
  240. y: 7
  241. }]
  242. }],
  243. },
  244. options: {
  245. scales: {
  246. xAxes: [{
  247. id: 'xScale0',
  248. type: 'linear',
  249. position: 'bottom'
  250. }],
  251. yAxes: [{
  252. id: 'yScale0',
  253. type: 'linear'
  254. }]
  255. }
  256. }
  257. });
  258. chart.update();
  259. expect(chart.scales.xScale0.min).toBe(-20);
  260. expect(chart.scales.xScale0.max).toBe(100);
  261. expect(chart.scales.yScale0.min).toBe(0);
  262. expect(chart.scales.yScale0.max).toBe(100);
  263. });
  264. it('Should correctly get the label for the given index', function() {
  265. var chart = window.acquireChart({
  266. type: 'line',
  267. data: {
  268. datasets: [{
  269. xAxisID: 'xScale0',
  270. yAxisID: 'yScale0',
  271. data: [{
  272. x: 10,
  273. y: 100
  274. }, {
  275. x: -10,
  276. y: 0
  277. }, {
  278. x: 0,
  279. y: 0
  280. }, {
  281. x: 99,
  282. y: 7
  283. }]
  284. }],
  285. },
  286. options: {
  287. scales: {
  288. xAxes: [{
  289. id: 'xScale0',
  290. type: 'linear',
  291. position: 'bottom'
  292. }],
  293. yAxes: [{
  294. id: 'yScale0',
  295. type: 'linear'
  296. }]
  297. }
  298. }
  299. });
  300. chart.update();
  301. expect(chart.scales.yScale0.getLabelForIndex(3, 0)).toBe(7);
  302. });
  303. it('Should correctly determine the min and max data values when stacked mode is turned on', function() {
  304. var chart = window.acquireChart({
  305. type: 'line',
  306. data: {
  307. datasets: [{
  308. yAxisID: 'yScale0',
  309. data: [10, 5, 0, -5, 78, -100],
  310. type: 'bar'
  311. }, {
  312. yAxisID: 'yScale1',
  313. data: [-1000, 1000],
  314. }, {
  315. yAxisID: 'yScale0',
  316. data: [150, 0, 0, -100, -10, 9],
  317. type: 'bar'
  318. }, {
  319. yAxisID: 'yScale0',
  320. data: [10, 10, 10, 10, 10, 10],
  321. type: 'line'
  322. }],
  323. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  324. },
  325. options: {
  326. scales: {
  327. yAxes: [{
  328. id: 'yScale0',
  329. type: 'linear',
  330. stacked: true
  331. }, {
  332. id: 'yScale1',
  333. type: 'linear'
  334. }]
  335. }
  336. }
  337. });
  338. chart.update();
  339. expect(chart.scales.yScale0.min).toBe(-150);
  340. expect(chart.scales.yScale0.max).toBe(200);
  341. });
  342. it('Should correctly determine the min and max data values when stacked mode is turned on and there are hidden datasets', function() {
  343. var chart = window.acquireChart({
  344. type: 'bar',
  345. data: {
  346. datasets: [{
  347. yAxisID: 'yScale0',
  348. data: [10, 5, 0, -5, 78, -100],
  349. }, {
  350. yAxisID: 'yScale1',
  351. data: [-1000, 1000],
  352. }, {
  353. yAxisID: 'yScale0',
  354. data: [150, 0, 0, -100, -10, 9],
  355. }, {
  356. yAxisID: 'yScale0',
  357. data: [10, 20, 30, 40, 50, 60],
  358. hidden: true
  359. }],
  360. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  361. },
  362. options: {
  363. scales: {
  364. yAxes: [{
  365. id: 'yScale0',
  366. type: 'linear',
  367. stacked: true
  368. }, {
  369. id: 'yScale1',
  370. type: 'linear'
  371. }]
  372. }
  373. }
  374. });
  375. chart.update();
  376. expect(chart.scales.yScale0.min).toBe(-150);
  377. expect(chart.scales.yScale0.max).toBe(200);
  378. });
  379. it('Should correctly determine the min and max data values when stacked mode is turned on there are multiple types of datasets', function() {
  380. var chart = window.acquireChart({
  381. type: 'bar',
  382. data: {
  383. datasets: [{
  384. yAxisID: 'yScale0',
  385. type: 'bar',
  386. data: [10, 5, 0, -5, 78, -100]
  387. }, {
  388. type: 'line',
  389. data: [10, 10, 10, 10, 10, 10],
  390. }, {
  391. type: 'bar',
  392. data: [150, 0, 0, -100, -10, 9]
  393. }],
  394. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  395. },
  396. options: {
  397. scales: {
  398. yAxes: [{
  399. id: 'yScale0',
  400. type: 'linear',
  401. stacked: true
  402. }]
  403. }
  404. }
  405. });
  406. chart.scales.yScale0.determineDataLimits();
  407. expect(chart.scales.yScale0.min).toBe(-105);
  408. expect(chart.scales.yScale0.max).toBe(160);
  409. });
  410. it('Should ensure that the scale has a max and min that are not equal', function() {
  411. var chart = window.acquireChart({
  412. type: 'bar',
  413. data: {
  414. datasets: [],
  415. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  416. },
  417. options: {
  418. scales: {
  419. yAxes: [{
  420. id: 'yScale0',
  421. type: 'linear'
  422. }]
  423. }
  424. }
  425. });
  426. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  427. expect(chart.scales.yScale0.min).toBe(0);
  428. expect(chart.scales.yScale0.max).toBe(1);
  429. });
  430. it('Should ensure that the scale has a max and min that are not equal when beginAtZero is set', function() {
  431. var chart = window.acquireChart({
  432. type: 'bar',
  433. data: {
  434. datasets: [],
  435. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  436. },
  437. options: {
  438. scales: {
  439. yAxes: [{
  440. id: 'yScale0',
  441. type: 'linear',
  442. ticks: {
  443. beginAtZero: true
  444. }
  445. }]
  446. }
  447. }
  448. });
  449. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  450. expect(chart.scales.yScale0.min).toBe(0);
  451. expect(chart.scales.yScale0.max).toBe(1);
  452. });
  453. it('Should use the suggestedMin and suggestedMax options', function() {
  454. var chart = window.acquireChart({
  455. type: 'bar',
  456. data: {
  457. datasets: [{
  458. yAxisID: 'yScale0',
  459. data: [1, 1, 1, 2, 1, 0]
  460. }],
  461. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  462. },
  463. options: {
  464. scales: {
  465. yAxes: [{
  466. id: 'yScale0',
  467. type: 'linear',
  468. ticks: {
  469. suggestedMax: 10,
  470. suggestedMin: -10
  471. }
  472. }]
  473. }
  474. }
  475. });
  476. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  477. expect(chart.scales.yScale0.min).toBe(-10);
  478. expect(chart.scales.yScale0.max).toBe(10);
  479. });
  480. it('Should use the min and max options', function() {
  481. var chart = window.acquireChart({
  482. type: 'bar',
  483. data: {
  484. datasets: [{
  485. yAxisID: 'yScale0',
  486. data: [1, 1, 1, 2, 1, 0]
  487. }],
  488. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  489. },
  490. options: {
  491. scales: {
  492. yAxes: [{
  493. id: 'yScale0',
  494. type: 'linear',
  495. ticks: {
  496. max: 1010,
  497. min: -1010
  498. }
  499. }]
  500. }
  501. }
  502. });
  503. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  504. expect(chart.scales.yScale0.min).toBe(-1010);
  505. expect(chart.scales.yScale0.max).toBe(1010);
  506. expect(chart.scales.yScale0.ticks[0]).toBe('1010');
  507. expect(chart.scales.yScale0.ticks[chart.scales.yScale0.ticks.length - 1]).toBe('-1010');
  508. });
  509. it('Should use min, max and stepSize to create fixed spaced ticks', function() {
  510. var chart = window.acquireChart({
  511. type: 'bar',
  512. data: {
  513. datasets: [{
  514. yAxisID: 'yScale0',
  515. data: [10, 3, 6, 8, 3, 1]
  516. }],
  517. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  518. },
  519. options: {
  520. scales: {
  521. yAxes: [{
  522. id: 'yScale0',
  523. type: 'linear',
  524. ticks: {
  525. min: 1,
  526. max: 11,
  527. stepSize: 2
  528. }
  529. }]
  530. }
  531. }
  532. });
  533. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  534. expect(chart.scales.yScale0.min).toBe(1);
  535. expect(chart.scales.yScale0.max).toBe(11);
  536. expect(chart.scales.yScale0.ticks).toEqual(['11', '10', '8', '6', '4', '2', '1']);
  537. });
  538. it('Should create decimal steps if stepSize is a decimal number', function() {
  539. var chart = window.acquireChart({
  540. type: 'bar',
  541. data: {
  542. datasets: [{
  543. yAxisID: 'yScale0',
  544. data: [10, 3, 6, 8, 3, 1]
  545. }],
  546. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  547. },
  548. options: {
  549. scales: {
  550. yAxes: [{
  551. id: 'yScale0',
  552. type: 'linear',
  553. ticks: {
  554. stepSize: 2.5
  555. }
  556. }]
  557. }
  558. }
  559. });
  560. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  561. expect(chart.scales.yScale0.min).toBe(0);
  562. expect(chart.scales.yScale0.max).toBe(10);
  563. expect(chart.scales.yScale0.ticks).toEqual(['10', '7.5', '5', '2.5', '0']);
  564. });
  565. describe('precision', function() {
  566. it('Should create integer steps if precision is 0', function() {
  567. var chart = window.acquireChart({
  568. type: 'bar',
  569. data: {
  570. datasets: [{
  571. yAxisID: 'yScale0',
  572. data: [0, 1, 2, 1, 0, 1]
  573. }],
  574. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  575. },
  576. options: {
  577. scales: {
  578. yAxes: [{
  579. id: 'yScale0',
  580. type: 'linear',
  581. ticks: {
  582. precision: 0
  583. }
  584. }]
  585. }
  586. }
  587. });
  588. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  589. expect(chart.scales.yScale0.min).toBe(0);
  590. expect(chart.scales.yScale0.max).toBe(2);
  591. expect(chart.scales.yScale0.ticks).toEqual(['2', '1', '0']);
  592. });
  593. it('Should round the step size to the given number of decimal places', function() {
  594. var chart = window.acquireChart({
  595. type: 'bar',
  596. data: {
  597. datasets: [{
  598. yAxisID: 'yScale0',
  599. data: [0, 0.001, 0.002, 0.003, 0, 0.001]
  600. }],
  601. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  602. },
  603. options: {
  604. scales: {
  605. yAxes: [{
  606. id: 'yScale0',
  607. type: 'linear',
  608. ticks: {
  609. precision: 2
  610. }
  611. }]
  612. }
  613. }
  614. });
  615. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  616. expect(chart.scales.yScale0.min).toBe(0);
  617. expect(chart.scales.yScale0.max).toBe(0.01);
  618. expect(chart.scales.yScale0.ticks).toEqual(['0.01', '0']);
  619. });
  620. });
  621. it('should forcibly include 0 in the range if the beginAtZero option is used', function() {
  622. var chart = window.acquireChart({
  623. type: 'bar',
  624. data: {
  625. datasets: [{
  626. yAxisID: 'yScale0',
  627. data: [20, 30, 40, 50]
  628. }],
  629. labels: ['a', 'b', 'c', 'd']
  630. },
  631. options: {
  632. scales: {
  633. yAxes: [{
  634. id: 'yScale0',
  635. type: 'linear',
  636. }]
  637. }
  638. }
  639. });
  640. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  641. expect(chart.scales.yScale0.ticks).toEqual(['50', '45', '40', '35', '30', '25', '20']);
  642. chart.scales.yScale0.options.ticks.beginAtZero = true;
  643. chart.update();
  644. expect(chart.scales.yScale0.ticks).toEqual(['50', '45', '40', '35', '30', '25', '20', '15', '10', '5', '0']);
  645. chart.data.datasets[0].data = [-20, -30, -40, -50];
  646. chart.update();
  647. expect(chart.scales.yScale0.ticks).toEqual(['0', '-5', '-10', '-15', '-20', '-25', '-30', '-35', '-40', '-45', '-50']);
  648. chart.scales.yScale0.options.ticks.beginAtZero = false;
  649. chart.update();
  650. expect(chart.scales.yScale0.ticks).toEqual(['-20', '-25', '-30', '-35', '-40', '-45', '-50']);
  651. });
  652. it('Should generate tick marks in the correct order in reversed mode', function() {
  653. var chart = window.acquireChart({
  654. type: 'bar',
  655. data: {
  656. datasets: [{
  657. yAxisID: 'yScale0',
  658. data: [10, 5, 0, 25, 78]
  659. }],
  660. labels: ['a', 'b', 'c', 'd']
  661. },
  662. options: {
  663. scales: {
  664. yAxes: [{
  665. id: 'yScale0',
  666. type: 'linear',
  667. ticks: {
  668. reverse: true
  669. }
  670. }]
  671. }
  672. }
  673. });
  674. expect(chart.scales.yScale0.ticks).toEqual(['0', '10', '20', '30', '40', '50', '60', '70', '80']);
  675. expect(chart.scales.yScale0.start).toBe(80);
  676. expect(chart.scales.yScale0.end).toBe(0);
  677. });
  678. it('should use the correct number of decimal places in the default format function', function() {
  679. var chart = window.acquireChart({
  680. type: 'bar',
  681. data: {
  682. datasets: [{
  683. yAxisID: 'yScale0',
  684. data: [0.06, 0.005, 0, 0.025, 0.0078]
  685. }],
  686. labels: ['a', 'b', 'c', 'd']
  687. },
  688. options: {
  689. scales: {
  690. yAxes: [{
  691. id: 'yScale0',
  692. type: 'linear',
  693. }]
  694. }
  695. }
  696. });
  697. expect(chart.scales.yScale0.ticks).toEqual(['0.06', '0.05', '0.04', '0.03', '0.02', '0.01', '0']);
  698. });
  699. it('Should correctly limit the maximum number of ticks', function() {
  700. var chart = window.acquireChart({
  701. type: 'bar',
  702. data: {
  703. labels: ['a', 'b'],
  704. datasets: [{
  705. data: [0.5, 2.5]
  706. }]
  707. },
  708. options: {
  709. scales: {
  710. yAxes: [{
  711. id: 'yScale'
  712. }]
  713. }
  714. }
  715. });
  716. expect(chart.scales.yScale.ticks).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5']);
  717. chart.options.scales.yAxes[0].ticks.maxTicksLimit = 11;
  718. chart.update();
  719. expect(chart.scales.yScale.ticks).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5']);
  720. chart.options.scales.yAxes[0].ticks.maxTicksLimit = 21;
  721. chart.update();
  722. expect(chart.scales.yScale.ticks).toEqual([
  723. '2.5', '2.4', '2.3', '2.2', '2.1', '2.0', '1.9', '1.8', '1.7', '1.6',
  724. '1.5', '1.4', '1.3', '1.2', '1.1', '1.0', '0.9', '0.8', '0.7', '0.6',
  725. '0.5'
  726. ]);
  727. chart.options.scales.yAxes[0].ticks.maxTicksLimit = 11;
  728. chart.options.scales.yAxes[0].ticks.stepSize = 0.01;
  729. chart.update();
  730. expect(chart.scales.yScale.ticks).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5']);
  731. chart.options.scales.yAxes[0].ticks.min = 0.3;
  732. chart.options.scales.yAxes[0].ticks.max = 2.8;
  733. chart.update();
  734. expect(chart.scales.yScale.ticks).toEqual(['2.8', '2.5', '2.0', '1.5', '1.0', '0.5', '0.3']);
  735. });
  736. it('Should build labels using the user supplied callback', function() {
  737. var chart = window.acquireChart({
  738. type: 'bar',
  739. data: {
  740. datasets: [{
  741. yAxisID: 'yScale0',
  742. data: [10, 5, 0, 25, 78]
  743. }],
  744. labels: ['a', 'b', 'c', 'd']
  745. },
  746. options: {
  747. scales: {
  748. yAxes: [{
  749. id: 'yScale0',
  750. type: 'linear',
  751. ticks: {
  752. callback: function(value, index) {
  753. return index.toString();
  754. }
  755. }
  756. }]
  757. }
  758. }
  759. });
  760. // Just the index
  761. expect(chart.scales.yScale0.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8']);
  762. });
  763. it('Should get the correct pixel value for a point', function() {
  764. var chart = window.acquireChart({
  765. type: 'line',
  766. data: {
  767. labels: [-1, 1],
  768. datasets: [{
  769. xAxisID: 'xScale0',
  770. yAxisID: 'yScale0',
  771. data: [-1, 1]
  772. }],
  773. },
  774. options: {
  775. scales: {
  776. xAxes: [{
  777. id: 'xScale0',
  778. type: 'linear',
  779. position: 'bottom'
  780. }],
  781. yAxes: [{
  782. id: 'yScale0',
  783. type: 'linear'
  784. }]
  785. }
  786. }
  787. });
  788. var xScale = chart.scales.xScale0;
  789. expect(xScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(501); // right - paddingRight
  790. expect(xScale.getPixelForValue(-1, 0, 0)).toBeCloseToPixel(31 + 6); // left + paddingLeft + lineSpace
  791. expect(xScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(266 + 6 / 2); // halfway*/
  792. expect(xScale.getValueForPixel(501)).toBeCloseTo(1, 1e-2);
  793. expect(xScale.getValueForPixel(31)).toBeCloseTo(-1, 1e-2);
  794. expect(xScale.getValueForPixel(266)).toBeCloseTo(0, 1e-2);
  795. var yScale = chart.scales.yScale0;
  796. expect(yScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(32); // right - paddingRight
  797. expect(yScale.getPixelForValue(-1, 0, 0)).toBeCloseToPixel(484); // left + paddingLeft
  798. expect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(258); // halfway*/
  799. expect(yScale.getValueForPixel(32)).toBeCloseTo(1, 1e-2);
  800. expect(yScale.getValueForPixel(484)).toBeCloseTo(-1, 1e-2);
  801. expect(yScale.getValueForPixel(258)).toBeCloseTo(0, 1e-2);
  802. });
  803. it('should fit correctly', function() {
  804. var chart = window.acquireChart({
  805. type: 'line',
  806. data: {
  807. datasets: [{
  808. xAxisID: 'xScale0',
  809. yAxisID: 'yScale0',
  810. data: [{
  811. x: 10,
  812. y: 100
  813. }, {
  814. x: -10,
  815. y: 0
  816. }, {
  817. x: 0,
  818. y: 0
  819. }, {
  820. x: 99,
  821. y: 7
  822. }]
  823. }],
  824. },
  825. options: {
  826. scales: {
  827. xAxes: [{
  828. id: 'xScale0',
  829. type: 'linear',
  830. position: 'bottom'
  831. }],
  832. yAxes: [{
  833. id: 'yScale0',
  834. type: 'linear'
  835. }]
  836. }
  837. }
  838. });
  839. var xScale = chart.scales.xScale0;
  840. var yScale = chart.scales.yScale0;
  841. expect(xScale.paddingTop).toBeCloseToPixel(0);
  842. expect(xScale.paddingBottom).toBeCloseToPixel(0);
  843. expect(xScale.paddingLeft).toBeCloseToPixel(12);
  844. expect(xScale.paddingRight).toBeCloseToPixel(13.5);
  845. expect(xScale.width).toBeCloseToPixel(468 - 6); // minus lineSpace
  846. expect(xScale.height).toBeCloseToPixel(30);
  847. expect(yScale.paddingTop).toBeCloseToPixel(7);
  848. expect(yScale.paddingBottom).toBeCloseToPixel(7);
  849. expect(yScale.paddingLeft).toBeCloseToPixel(0);
  850. expect(yScale.paddingRight).toBeCloseToPixel(0);
  851. expect(yScale.width).toBeCloseToPixel(30 + 6); // plus lineSpace
  852. expect(yScale.height).toBeCloseToPixel(450);
  853. // Extra size when scale label showing
  854. xScale.options.scaleLabel.display = true;
  855. yScale.options.scaleLabel.display = true;
  856. chart.update();
  857. expect(xScale.paddingTop).toBeCloseToPixel(0);
  858. expect(xScale.paddingBottom).toBeCloseToPixel(0);
  859. expect(xScale.paddingLeft).toBeCloseToPixel(12);
  860. expect(xScale.paddingRight).toBeCloseToPixel(13.5);
  861. expect(xScale.width).toBeCloseToPixel(440);
  862. expect(xScale.height).toBeCloseToPixel(53);
  863. expect(yScale.paddingTop).toBeCloseToPixel(7);
  864. expect(yScale.paddingBottom).toBeCloseToPixel(7);
  865. expect(yScale.paddingLeft).toBeCloseToPixel(0);
  866. expect(yScale.paddingRight).toBeCloseToPixel(0);
  867. expect(yScale.width).toBeCloseToPixel(58);
  868. expect(yScale.height).toBeCloseToPixel(427);
  869. });
  870. it('should fit correctly when display is turned off', function() {
  871. var chart = window.acquireChart({
  872. type: 'line',
  873. data: {
  874. datasets: [{
  875. xAxisID: 'xScale0',
  876. yAxisID: 'yScale0',
  877. data: [{
  878. x: 10,
  879. y: 100
  880. }, {
  881. x: -10,
  882. y: 0
  883. }, {
  884. x: 0,
  885. y: 0
  886. }, {
  887. x: 99,
  888. y: 7
  889. }]
  890. }],
  891. },
  892. options: {
  893. scales: {
  894. xAxes: [{
  895. id: 'xScale0',
  896. type: 'linear',
  897. position: 'bottom'
  898. }],
  899. yAxes: [{
  900. id: 'yScale0',
  901. type: 'linear',
  902. gridLines: {
  903. drawTicks: false,
  904. drawBorder: false
  905. },
  906. scaleLabel: {
  907. display: false,
  908. lineHeight: 1.2
  909. },
  910. ticks: {
  911. display: false,
  912. padding: 0
  913. }
  914. }]
  915. }
  916. }
  917. });
  918. var yScale = chart.scales.yScale0;
  919. expect(yScale.width).toBeCloseToPixel(0);
  920. });
  921. it('max and min value should be valid and finite when charts datasets are hidden', function() {
  922. var barData = {
  923. labels: ['S1', 'S2', 'S3'],
  924. datasets: [{
  925. label: 'Closed',
  926. backgroundColor: '#382765',
  927. data: [2500, 2000, 1500]
  928. }, {
  929. label: 'In Progress',
  930. backgroundColor: '#7BC225',
  931. data: [1000, 2000, 1500]
  932. }, {
  933. label: 'Assigned',
  934. backgroundColor: '#ffC225',
  935. data: [1000, 2000, 1500]
  936. }]
  937. };
  938. var chart = window.acquireChart({
  939. type: 'horizontalBar',
  940. data: barData,
  941. options: {
  942. scales: {
  943. xAxes: [{
  944. stacked: true
  945. }],
  946. yAxes: [{
  947. stacked: true
  948. }]
  949. }
  950. }
  951. });
  952. barData.datasets.forEach(function(data, index) {
  953. var meta = chart.getDatasetMeta(index);
  954. meta.hidden = true;
  955. chart.update();
  956. });
  957. expect(chart.scales['x-axis-0'].min).toEqual(0);
  958. expect(chart.scales['x-axis-0'].max).toEqual(1);
  959. });
  960. it('max and min value should be valid when min is set and all datasets are hidden', function() {
  961. var barData = {
  962. labels: ['S1', 'S2', 'S3'],
  963. datasets: [{
  964. label: 'dataset 1',
  965. backgroundColor: '#382765',
  966. data: [2500, 2000, 1500],
  967. hidden: true,
  968. }]
  969. };
  970. var chart = window.acquireChart({
  971. type: 'horizontalBar',
  972. data: barData,
  973. options: {
  974. scales: {
  975. xAxes: [{
  976. ticks: {
  977. min: 20
  978. }
  979. }]
  980. }
  981. }
  982. });
  983. expect(chart.scales['x-axis-0'].min).toEqual(20);
  984. expect(chart.scales['x-axis-0'].max).toEqual(21);
  985. });
  986. it('min settings should be used if set to zero', function() {
  987. var barData = {
  988. labels: ['S1', 'S2', 'S3'],
  989. datasets: [{
  990. label: 'dataset 1',
  991. backgroundColor: '#382765',
  992. data: [2500, 2000, 1500]
  993. }]
  994. };
  995. var chart = window.acquireChart({
  996. type: 'horizontalBar',
  997. data: barData,
  998. options: {
  999. scales: {
  1000. xAxes: [{
  1001. ticks: {
  1002. min: 0,
  1003. max: 3000
  1004. }
  1005. }]
  1006. }
  1007. }
  1008. });
  1009. expect(chart.scales['x-axis-0'].min).toEqual(0);
  1010. });
  1011. it('max settings should be used if set to zero', function() {
  1012. var barData = {
  1013. labels: ['S1', 'S2', 'S3'],
  1014. datasets: [{
  1015. label: 'dataset 1',
  1016. backgroundColor: '#382765',
  1017. data: [-2500, -2000, -1500]
  1018. }]
  1019. };
  1020. var chart = window.acquireChart({
  1021. type: 'horizontalBar',
  1022. data: barData,
  1023. options: {
  1024. scales: {
  1025. xAxes: [{
  1026. ticks: {
  1027. min: -3000,
  1028. max: 0
  1029. }
  1030. }]
  1031. }
  1032. }
  1033. });
  1034. expect(chart.scales['x-axis-0'].max).toEqual(0);
  1035. });
  1036. it('minBarLength settings should be used on Y axis on bar chart', function() {
  1037. var minBarLength = 4;
  1038. var chart = window.acquireChart({
  1039. type: 'bar',
  1040. data: {
  1041. datasets: [{
  1042. data: [0.05, -0.05, 10, 15, 20, 25, 30, 35]
  1043. }]
  1044. },
  1045. options: {
  1046. scales: {
  1047. yAxes: [{
  1048. minBarLength: minBarLength
  1049. }]
  1050. }
  1051. }
  1052. });
  1053. var data = chart.getDatasetMeta(0).data;
  1054. expect(data[0]._model.base - minBarLength).toEqual(data[0]._model.y);
  1055. expect(data[1]._model.base + minBarLength).toEqual(data[1]._model.y);
  1056. });
  1057. it('minBarLength settings should be used on X axis on horizontalBar chart', function() {
  1058. var minBarLength = 4;
  1059. var chart = window.acquireChart({
  1060. type: 'horizontalBar',
  1061. data: {
  1062. datasets: [{
  1063. data: [0.05, -0.05, 10, 15, 20, 25, 30, 35]
  1064. }]
  1065. },
  1066. options: {
  1067. scales: {
  1068. xAxes: [{
  1069. minBarLength: minBarLength
  1070. }]
  1071. }
  1072. }
  1073. });
  1074. var data = chart.getDatasetMeta(0).data;
  1075. expect(data[0]._model.base + minBarLength).toEqual(data[0]._model.x);
  1076. expect(data[1]._model.base - minBarLength).toEqual(data[1]._model.x);
  1077. });
  1078. it('Should generate max and min that are not equal when data contains values that are very close to each other', function() {
  1079. var chart = window.acquireChart({
  1080. type: 'scatter',
  1081. data: {
  1082. datasets: [{
  1083. data: [
  1084. {x: 1, y: 1.8548483304974972},
  1085. {x: 2, y: 1.8548483304974974},
  1086. ]
  1087. }],
  1088. },
  1089. options: {
  1090. scales: {
  1091. yAxes: [{
  1092. id: 'yScale0',
  1093. type: 'linear',
  1094. }]
  1095. }
  1096. }
  1097. });
  1098. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  1099. expect(chart.scales.yScale0.max).toBeGreaterThan(chart.scales.yScale0.min);
  1100. });
  1101. it('Should get correct pixel values when horizontal', function() {
  1102. var chart = window.acquireChart({
  1103. type: 'horizontalBar',
  1104. data: {
  1105. datasets: [{
  1106. data: [0.05, -25, 10, 15, 20, 25, 30, 35]
  1107. }]
  1108. },
  1109. options: {
  1110. scales: {
  1111. xAxes: [{
  1112. id: 'x',
  1113. type: 'linear',
  1114. }]
  1115. }
  1116. }
  1117. });
  1118. var start = chart.chartArea.left;
  1119. var end = chart.chartArea.right;
  1120. var min = -30;
  1121. var max = 40;
  1122. var scale = chart.scales.x;
  1123. expect(scale.getPixelForValue(max)).toBeCloseToPixel(end);
  1124. expect(scale.getPixelForValue(min)).toBeCloseToPixel(start);
  1125. expect(scale.getValueForPixel(end)).toBeCloseTo(max, 4);
  1126. expect(scale.getValueForPixel(start)).toBeCloseTo(min, 4);
  1127. scale.options.ticks.reverse = true;
  1128. chart.update();
  1129. start = chart.chartArea.left;
  1130. end = chart.chartArea.right;
  1131. expect(scale.getPixelForValue(max)).toBeCloseToPixel(start);
  1132. expect(scale.getPixelForValue(min)).toBeCloseToPixel(end);
  1133. expect(scale.getValueForPixel(end)).toBeCloseTo(min, 4);
  1134. expect(scale.getValueForPixel(start)).toBeCloseTo(max, 4);
  1135. });
  1136. it('Should get correct pixel values when vertical', function() {
  1137. var chart = window.acquireChart({
  1138. type: 'bar',
  1139. data: {
  1140. datasets: [{
  1141. data: [0.05, -25, 10, 15, 20, 25, 30, 35]
  1142. }]
  1143. },
  1144. options: {
  1145. scales: {
  1146. yAxes: [{
  1147. id: 'y',
  1148. type: 'linear',
  1149. }]
  1150. }
  1151. }
  1152. });
  1153. var start = chart.chartArea.bottom;
  1154. var end = chart.chartArea.top;
  1155. var min = -30;
  1156. var max = 40;
  1157. var scale = chart.scales.y;
  1158. expect(scale.getPixelForValue(max)).toBeCloseToPixel(end);
  1159. expect(scale.getPixelForValue(min)).toBeCloseToPixel(start);
  1160. expect(scale.getValueForPixel(end)).toBeCloseTo(max, 4);
  1161. expect(scale.getValueForPixel(start)).toBeCloseTo(min, 4);
  1162. scale.options.ticks.reverse = true;
  1163. chart.update();
  1164. start = chart.chartArea.bottom;
  1165. end = chart.chartArea.top;
  1166. expect(scale.getPixelForValue(max)).toBeCloseToPixel(start);
  1167. expect(scale.getPixelForValue(min)).toBeCloseToPixel(end);
  1168. expect(scale.getValueForPixel(end)).toBeCloseTo(min, 4);
  1169. expect(scale.getValueForPixel(start)).toBeCloseTo(max, 4);
  1170. });
  1171. });