scale.logarithmic.tests.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. describe('Logarithmic Scale tests', function() {
  2. it('should register the constructor with the scale service', function() {
  3. var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
  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('logarithmic');
  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,
  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 nicer, then check explicitly below
  39. autoSkip: true,
  40. autoSkipPadding: 0,
  41. labelOffset: 0,
  42. minor: {},
  43. major: {},
  44. },
  45. });
  46. // Is this actually a function
  47. expect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));
  48. });
  49. it('should correctly determine the max & min data values', function() {
  50. var chart = window.acquireChart({
  51. type: 'bar',
  52. data: {
  53. datasets: [{
  54. yAxisID: 'yScale0',
  55. data: [42, 1000, 64, 100],
  56. }, {
  57. yAxisID: 'yScale1',
  58. data: [10, 5, 5000, 78, 450]
  59. }, {
  60. yAxisID: 'yScale1',
  61. data: [150]
  62. }, {
  63. yAxisID: 'yScale2',
  64. data: [20, 0, 150, 1800, 3040]
  65. }, {
  66. yAxisID: 'yScale3',
  67. data: [67, 0.0004, 0, 820, 0.001]
  68. }],
  69. labels: ['a', 'b', 'c', 'd', 'e']
  70. },
  71. options: {
  72. scales: {
  73. yAxes: [{
  74. id: 'yScale0',
  75. type: 'logarithmic'
  76. }, {
  77. id: 'yScale1',
  78. type: 'logarithmic'
  79. }, {
  80. id: 'yScale2',
  81. type: 'logarithmic'
  82. }, {
  83. id: 'yScale3',
  84. type: 'logarithmic'
  85. }]
  86. }
  87. }
  88. });
  89. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  90. expect(chart.scales.yScale0.min).toBe(10);
  91. expect(chart.scales.yScale0.max).toBe(1000);
  92. expect(chart.scales.yScale1).not.toEqual(undefined); // must construct
  93. expect(chart.scales.yScale1.min).toBe(1);
  94. expect(chart.scales.yScale1.max).toBe(5000);
  95. expect(chart.scales.yScale2).not.toEqual(undefined); // must construct
  96. expect(chart.scales.yScale2.min).toBe(0);
  97. expect(chart.scales.yScale2.max).toBe(4000);
  98. expect(chart.scales.yScale3).not.toEqual(undefined); // must construct
  99. expect(chart.scales.yScale3.min).toBe(0);
  100. expect(chart.scales.yScale3.max).toBe(900);
  101. });
  102. it('should correctly determine the max & min of string data values', function() {
  103. var chart = window.acquireChart({
  104. type: 'line',
  105. data: {
  106. datasets: [{
  107. yAxisID: 'yScale0',
  108. data: ['42', '1000', '64', '100'],
  109. }, {
  110. yAxisID: 'yScale1',
  111. data: ['10', '5', '5000', '78', '450']
  112. }, {
  113. yAxisID: 'yScale1',
  114. data: ['150']
  115. }, {
  116. yAxisID: 'yScale2',
  117. data: ['20', '0', '150', '1800', '3040']
  118. }, {
  119. yAxisID: 'yScale3',
  120. data: ['67', '0.0004', '0', '820', '0.001']
  121. }],
  122. labels: ['a', 'b', 'c', 'd', 'e']
  123. },
  124. options: {
  125. scales: {
  126. yAxes: [{
  127. id: 'yScale0',
  128. type: 'logarithmic'
  129. }, {
  130. id: 'yScale1',
  131. type: 'logarithmic'
  132. }, {
  133. id: 'yScale2',
  134. type: 'logarithmic'
  135. }, {
  136. id: 'yScale3',
  137. type: 'logarithmic'
  138. }]
  139. }
  140. }
  141. });
  142. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  143. expect(chart.scales.yScale0.min).toBe(10);
  144. expect(chart.scales.yScale0.max).toBe(1000);
  145. expect(chart.scales.yScale1).not.toEqual(undefined); // must construct
  146. expect(chart.scales.yScale1.min).toBe(1);
  147. expect(chart.scales.yScale1.max).toBe(5000);
  148. expect(chart.scales.yScale2).not.toEqual(undefined); // must construct
  149. expect(chart.scales.yScale2.min).toBe(0);
  150. expect(chart.scales.yScale2.max).toBe(4000);
  151. expect(chart.scales.yScale3).not.toEqual(undefined); // must construct
  152. expect(chart.scales.yScale3.min).toBe(0);
  153. expect(chart.scales.yScale3.max).toBe(900);
  154. });
  155. it('should correctly determine the max & min data values when there are hidden datasets', function() {
  156. var chart = window.acquireChart({
  157. type: 'line',
  158. data: {
  159. datasets: [{
  160. yAxisID: 'yScale1',
  161. data: [10, 5, 5000, 78, 450]
  162. }, {
  163. yAxisID: 'yScale0',
  164. data: [42, 1000, 64, 100],
  165. }, {
  166. yAxisID: 'yScale1',
  167. data: [50000],
  168. hidden: true
  169. }, {
  170. yAxisID: 'yScale2',
  171. data: [20, 0, 7400, 14, 291]
  172. }, {
  173. yAxisID: 'yScale2',
  174. data: [6, 0.0007, 9, 890, 60000],
  175. hidden: true
  176. }],
  177. labels: ['a', 'b', 'c', 'd', 'e']
  178. },
  179. options: {
  180. scales: {
  181. yAxes: [{
  182. id: 'yScale0',
  183. type: 'logarithmic'
  184. }, {
  185. id: 'yScale1',
  186. type: 'logarithmic'
  187. }, {
  188. id: 'yScale2',
  189. type: 'logarithmic'
  190. }]
  191. }
  192. }
  193. });
  194. expect(chart.scales.yScale1).not.toEqual(undefined); // must construct
  195. expect(chart.scales.yScale1.min).toBe(1);
  196. expect(chart.scales.yScale1.max).toBe(5000);
  197. expect(chart.scales.yScale2).not.toEqual(undefined); // must construct
  198. expect(chart.scales.yScale2.min).toBe(0);
  199. expect(chart.scales.yScale2.max).toBe(8000);
  200. });
  201. it('should correctly determine the max & min data values when there is NaN data', function() {
  202. var chart = window.acquireChart({
  203. type: 'bar',
  204. data: {
  205. datasets: [{
  206. yAxisID: 'yScale0',
  207. data: [undefined, 10, null, 5, 5000, NaN, 78, 450]
  208. }, {
  209. yAxisID: 'yScale0',
  210. data: [undefined, 28, null, 1000, 500, NaN, 50, 42, Infinity, -Infinity]
  211. }, {
  212. yAxisID: 'yScale1',
  213. data: [undefined, 30, null, 9400, 0, NaN, 54, 836]
  214. }, {
  215. yAxisID: 'yScale1',
  216. data: [undefined, 0, null, 800, 9, NaN, 894, 21]
  217. }],
  218. labels: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
  219. },
  220. options: {
  221. scales: {
  222. yAxes: [{
  223. id: 'yScale0',
  224. type: 'logarithmic'
  225. }, {
  226. id: 'yScale1',
  227. type: 'logarithmic'
  228. }]
  229. }
  230. }
  231. });
  232. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  233. expect(chart.scales.yScale0.min).toBe(1);
  234. expect(chart.scales.yScale0.max).toBe(5000);
  235. // Turn on stacked mode since it uses it's own
  236. chart.options.scales.yAxes[0].stacked = true;
  237. chart.update();
  238. expect(chart.scales.yScale0.min).toBe(10);
  239. expect(chart.scales.yScale0.max).toBe(6000);
  240. expect(chart.scales.yScale1).not.toEqual(undefined); // must construct
  241. expect(chart.scales.yScale1.min).toBe(0);
  242. expect(chart.scales.yScale1.max).toBe(10000);
  243. });
  244. it('should correctly determine the max & min for scatter data', function() {
  245. var chart = window.acquireChart({
  246. type: 'line',
  247. data: {
  248. datasets: [{
  249. data: [
  250. {x: 10, y: 100},
  251. {x: 2, y: 6},
  252. {x: 65, y: 121},
  253. {x: 99, y: 7}
  254. ]
  255. }]
  256. },
  257. options: {
  258. scales: {
  259. xAxes: [{
  260. id: 'xScale',
  261. type: 'logarithmic',
  262. position: 'bottom'
  263. }],
  264. yAxes: [{
  265. id: 'yScale',
  266. type: 'logarithmic'
  267. }]
  268. }
  269. }
  270. });
  271. expect(chart.scales.xScale.min).toBe(1);
  272. expect(chart.scales.xScale.max).toBe(100);
  273. expect(chart.scales.yScale.min).toBe(1);
  274. expect(chart.scales.yScale.max).toBe(200);
  275. });
  276. it('should correctly determine the max & min for scatter data when 0 values are present', function() {
  277. var chart = window.acquireChart({
  278. type: 'line',
  279. data: {
  280. datasets: [{
  281. data: [
  282. {x: 7, y: 950},
  283. {x: 289, y: 0},
  284. {x: 0, y: 8},
  285. {x: 23, y: 0.04}
  286. ]
  287. }]
  288. },
  289. options: {
  290. scales: {
  291. xAxes: [{
  292. id: 'xScale',
  293. type: 'logarithmic',
  294. position: 'bottom'
  295. }],
  296. yAxes: [{
  297. id: 'yScale',
  298. type: 'logarithmic'
  299. }]
  300. }
  301. }
  302. });
  303. expect(chart.scales.xScale.min).toBe(0);
  304. expect(chart.scales.xScale.max).toBe(300);
  305. expect(chart.scales.yScale.min).toBe(0);
  306. expect(chart.scales.yScale.max).toBe(1000);
  307. });
  308. it('should correctly determine the min and max data values when stacked mode is turned on', function() {
  309. var chart = window.acquireChart({
  310. type: 'bar',
  311. data: {
  312. datasets: [{
  313. type: 'bar',
  314. yAxisID: 'yScale0',
  315. data: [10, 5, 1, 5, 78, 100]
  316. }, {
  317. yAxisID: 'yScale1',
  318. data: [0, 1000],
  319. }, {
  320. type: 'bar',
  321. yAxisID: 'yScale0',
  322. data: [150, 10, 10, 100, 10, 9]
  323. }, {
  324. type: 'line',
  325. yAxisID: 'yScale0',
  326. data: [100, 100, 100, 100, 100, 100]
  327. }],
  328. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  329. },
  330. options: {
  331. scales: {
  332. yAxes: [{
  333. id: 'yScale0',
  334. type: 'logarithmic',
  335. stacked: true
  336. }, {
  337. id: 'yScale1',
  338. type: 'logarithmic'
  339. }]
  340. }
  341. }
  342. });
  343. expect(chart.scales.yScale0.min).toBe(10);
  344. expect(chart.scales.yScale0.max).toBe(200);
  345. });
  346. it('should correctly determine the min and max data values when stacked mode is turned on ignoring hidden datasets', function() {
  347. var chart = window.acquireChart({
  348. type: 'bar',
  349. data: {
  350. datasets: [{
  351. yAxisID: 'yScale0',
  352. data: [10, 5, 1, 5, 78, 100],
  353. type: 'bar'
  354. }, {
  355. yAxisID: 'yScale1',
  356. data: [0, 1000],
  357. type: 'bar'
  358. }, {
  359. yAxisID: 'yScale0',
  360. data: [150, 10, 10, 100, 10, 9],
  361. type: 'bar'
  362. }, {
  363. yAxisID: 'yScale0',
  364. data: [10000, 10000, 10000, 10000, 10000, 10000],
  365. hidden: true,
  366. type: 'bar'
  367. }],
  368. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  369. },
  370. options: {
  371. scales: {
  372. yAxes: [{
  373. id: 'yScale0',
  374. type: 'logarithmic',
  375. stacked: true
  376. }, {
  377. id: 'yScale1',
  378. type: 'logarithmic'
  379. }]
  380. }
  381. }
  382. });
  383. expect(chart.scales.yScale0.min).toBe(10);
  384. expect(chart.scales.yScale0.max).toBe(200);
  385. });
  386. it('should ensure that the scale has a max and min that are not equal', function() {
  387. var chart = window.acquireChart({
  388. type: 'bar',
  389. data: {
  390. datasets: [{
  391. data: []
  392. }],
  393. labels: []
  394. },
  395. options: {
  396. scales: {
  397. yAxes: [{
  398. id: 'yScale',
  399. type: 'logarithmic'
  400. }]
  401. }
  402. }
  403. });
  404. expect(chart.scales.yScale.min).toBe(1);
  405. expect(chart.scales.yScale.max).toBe(10);
  406. chart.data.datasets[0].data = [0.15, 0.15];
  407. chart.update();
  408. expect(chart.scales.yScale.min).toBe(0.01);
  409. expect(chart.scales.yScale.max).toBe(1);
  410. });
  411. it('should use the min and max options', function() {
  412. var chart = window.acquireChart({
  413. type: 'bar',
  414. data: {
  415. datasets: [{
  416. data: [1, 1, 1, 2, 1, 0]
  417. }],
  418. labels: []
  419. },
  420. options: {
  421. scales: {
  422. yAxes: [{
  423. id: 'yScale',
  424. type: 'logarithmic',
  425. ticks: {
  426. min: 10,
  427. max: 1010,
  428. callback: function(value) {
  429. return value;
  430. }
  431. }
  432. }]
  433. }
  434. }
  435. });
  436. var yScale = chart.scales.yScale;
  437. var tickCount = yScale.ticks.length;
  438. expect(yScale.min).toBe(10);
  439. expect(yScale.max).toBe(1010);
  440. expect(yScale.ticks[0]).toBe(1010);
  441. expect(yScale.ticks[tickCount - 1]).toBe(10);
  442. });
  443. it('should ignore negative min and max options', function() {
  444. var chart = window.acquireChart({
  445. type: 'bar',
  446. data: {
  447. datasets: [{
  448. data: [1, 1, 1, 2, 1, 0]
  449. }],
  450. labels: []
  451. },
  452. options: {
  453. scales: {
  454. yAxes: [{
  455. id: 'yScale',
  456. type: 'logarithmic',
  457. ticks: {
  458. min: -10,
  459. max: -1010,
  460. callback: function(value) {
  461. return value;
  462. }
  463. }
  464. }]
  465. }
  466. }
  467. });
  468. var yScale = chart.scales.yScale;
  469. expect(yScale.min).toBe(0);
  470. expect(yScale.max).toBe(2);
  471. });
  472. it('should ignore invalid min and max options', function() {
  473. var chart = window.acquireChart({
  474. type: 'bar',
  475. data: {
  476. datasets: [{
  477. data: [1, 1, 1, 2, 1, 0]
  478. }],
  479. labels: []
  480. },
  481. options: {
  482. scales: {
  483. yAxes: [{
  484. id: 'yScale',
  485. type: 'logarithmic',
  486. ticks: {
  487. min: '',
  488. max: false,
  489. callback: function(value) {
  490. return value;
  491. }
  492. }
  493. }]
  494. }
  495. }
  496. });
  497. var yScale = chart.scales.yScale;
  498. expect(yScale.min).toBe(0);
  499. expect(yScale.max).toBe(2);
  500. });
  501. it('should generate tick marks', function() {
  502. var chart = window.acquireChart({
  503. type: 'bar',
  504. data: {
  505. datasets: [{
  506. data: [10, 5, 1, 25, 78]
  507. }],
  508. labels: []
  509. },
  510. options: {
  511. scales: {
  512. yAxes: [{
  513. id: 'yScale',
  514. type: 'logarithmic',
  515. ticks: {
  516. callback: function(value) {
  517. return value;
  518. }
  519. }
  520. }]
  521. }
  522. }
  523. });
  524. // Counts down because the lines are drawn top to bottom
  525. expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
  526. ticks: [80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
  527. start: 1,
  528. end: 80
  529. }));
  530. });
  531. it('should generate tick marks when 0 values are present', function() {
  532. var chart = window.acquireChart({
  533. type: 'bar',
  534. data: {
  535. datasets: [{
  536. data: [11, 0.8, 0, 28, 7]
  537. }],
  538. labels: []
  539. },
  540. options: {
  541. scales: {
  542. yAxes: [{
  543. id: 'yScale',
  544. type: 'logarithmic',
  545. ticks: {
  546. callback: function(value) {
  547. return value;
  548. }
  549. }
  550. }]
  551. }
  552. }
  553. });
  554. // Counts down because the lines are drawn top to bottom
  555. expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
  556. ticks: [30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0.9, 0.8, 0],
  557. start: 0,
  558. end: 30
  559. }));
  560. });
  561. it('should generate tick marks in the correct order in reversed mode', function() {
  562. var chart = window.acquireChart({
  563. type: 'line',
  564. data: {
  565. datasets: [{
  566. data: [10, 5, 1, 25, 78]
  567. }],
  568. labels: []
  569. },
  570. options: {
  571. scales: {
  572. yAxes: [{
  573. id: 'yScale',
  574. type: 'logarithmic',
  575. ticks: {
  576. reverse: true,
  577. callback: function(value) {
  578. return value;
  579. }
  580. }
  581. }]
  582. }
  583. }
  584. });
  585. // Counts down because the lines are drawn top to bottom
  586. expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
  587. ticks: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80],
  588. start: 80,
  589. end: 1
  590. }));
  591. });
  592. it('should generate tick marks in the correct order in reversed mode when 0 values are present', function() {
  593. var chart = window.acquireChart({
  594. type: 'line',
  595. data: {
  596. datasets: [{
  597. data: [21, 9, 0, 10, 25]
  598. }],
  599. labels: []
  600. },
  601. options: {
  602. scales: {
  603. yAxes: [{
  604. id: 'yScale',
  605. type: 'logarithmic',
  606. ticks: {
  607. reverse: true,
  608. callback: function(value) {
  609. return value;
  610. }
  611. }
  612. }]
  613. }
  614. }
  615. });
  616. // Counts down because the lines are drawn top to bottom
  617. expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
  618. ticks: [0, 9, 10, 20, 30],
  619. start: 30,
  620. end: 0
  621. }));
  622. });
  623. it('should build labels using the default template', function() {
  624. var chart = window.acquireChart({
  625. type: 'line',
  626. data: {
  627. datasets: [{
  628. data: [10, 5, 1, 25, 0, 78]
  629. }],
  630. labels: []
  631. },
  632. options: {
  633. scales: {
  634. yAxes: [{
  635. id: 'yScale',
  636. type: 'logarithmic'
  637. }]
  638. }
  639. }
  640. });
  641. expect(chart.scales.yScale.ticks).toEqual(['8e+1', '', '', '5e+1', '', '', '2e+1', '1e+1', '', '', '', '', '5e+0', '', '', '2e+0', '1e+0', '0']);
  642. });
  643. it('should build labels using the user supplied callback', function() {
  644. var chart = window.acquireChart({
  645. type: 'bar',
  646. data: {
  647. datasets: [{
  648. data: [10, 5, 1, 25, 78]
  649. }],
  650. labels: []
  651. },
  652. options: {
  653. scales: {
  654. yAxes: [{
  655. id: 'yScale',
  656. type: 'logarithmic',
  657. ticks: {
  658. callback: function(value, index) {
  659. return index.toString();
  660. }
  661. }
  662. }]
  663. }
  664. }
  665. });
  666. // Just the index
  667. expect(chart.scales.yScale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']);
  668. });
  669. it('should correctly get the correct label for a data item', function() {
  670. var chart = window.acquireChart({
  671. type: 'bar',
  672. data: {
  673. datasets: [{
  674. yAxisID: 'yScale0',
  675. data: [10, 5, 5000, 78, 450]
  676. }, {
  677. yAxisID: 'yScale1',
  678. data: [1, 1000, 10, 100],
  679. }, {
  680. yAxisID: 'yScale0',
  681. data: [150]
  682. }],
  683. labels: []
  684. },
  685. options: {
  686. scales: {
  687. yAxes: [{
  688. id: 'yScale0',
  689. type: 'logarithmic'
  690. }, {
  691. id: 'yScale1',
  692. type: 'logarithmic'
  693. }]
  694. }
  695. }
  696. });
  697. expect(chart.scales.yScale1.getLabelForIndex(0, 2)).toBe(150);
  698. });
  699. describe('when', function() {
  700. var data = [
  701. {
  702. data: [1, 39],
  703. stack: 'stack'
  704. },
  705. {
  706. data: [1, 39],
  707. stack: 'stack'
  708. },
  709. ];
  710. var dataWithEmptyStacks = [
  711. {
  712. data: []
  713. },
  714. {
  715. data: []
  716. }
  717. ].concat(data);
  718. var config = [
  719. {
  720. axis: 'y',
  721. firstTick: 1, // start of the axis (minimum)
  722. describe: 'all stacks are defined'
  723. },
  724. {
  725. axis: 'y',
  726. data: dataWithEmptyStacks,
  727. firstTick: 1,
  728. describe: 'not all stacks are defined'
  729. },
  730. {
  731. axis: 'y',
  732. scale: {
  733. yAxes: [{
  734. ticks: {
  735. min: 0
  736. }
  737. }]
  738. },
  739. firstTick: 0,
  740. describe: 'all stacks are defined and ticks.min: 0'
  741. },
  742. {
  743. axis: 'y',
  744. data: dataWithEmptyStacks,
  745. scale: {
  746. yAxes: [{
  747. ticks: {
  748. min: 0
  749. }
  750. }]
  751. },
  752. firstTick: 0,
  753. describe: 'not stacks are defined and ticks.min: 0'
  754. },
  755. {
  756. axis: 'x',
  757. firstTick: 1,
  758. describe: 'all stacks are defined'
  759. },
  760. {
  761. axis: 'x',
  762. data: dataWithEmptyStacks,
  763. firstTick: 1,
  764. describe: 'not all stacks are defined'
  765. },
  766. {
  767. axis: 'x',
  768. scale: {
  769. xAxes: [{
  770. ticks: {
  771. min: 0
  772. }
  773. }]
  774. },
  775. firstTick: 0,
  776. describe: 'all stacks are defined and ticks.min: 0'
  777. },
  778. {
  779. axis: 'x',
  780. data: dataWithEmptyStacks,
  781. scale: {
  782. xAxes: [{
  783. ticks: {
  784. min: 0
  785. }
  786. }]
  787. },
  788. firstTick: 0,
  789. describe: 'not all stacks are defined and ticks.min: 0'
  790. },
  791. ];
  792. config.forEach(function(setup) {
  793. var scaleConfig = {};
  794. var type, chartStart, chartEnd;
  795. if (setup.axis === 'x') {
  796. type = 'horizontalBar';
  797. chartStart = 'left';
  798. chartEnd = 'right';
  799. } else {
  800. type = 'bar';
  801. chartStart = 'bottom';
  802. chartEnd = 'top';
  803. }
  804. scaleConfig[setup.axis + 'Axes'] = [{
  805. type: 'logarithmic'
  806. }];
  807. Chart.helpers.extend(scaleConfig, setup.scale);
  808. scaleConfig[setup.axis + 'Axes'][0].type = 'logarithmic';
  809. var description = 'dataset has stack option and ' + setup.describe
  810. + ' and axis is "' + setup.axis + '";';
  811. describe(description, function() {
  812. it('should define the correct axis limits', function() {
  813. var chart = window.acquireChart({
  814. type: type,
  815. data: {
  816. labels: ['category 1', 'category 2'],
  817. datasets: setup.data || data,
  818. },
  819. options: {
  820. scales: scaleConfig
  821. }
  822. });
  823. var axisID = setup.axis + '-axis-0';
  824. var scale = chart.scales[axisID];
  825. var firstTick = setup.firstTick;
  826. var lastTick = 80; // last tick (should be first available tick after: 2 * 39)
  827. var start = chart.chartArea[chartStart];
  828. var end = chart.chartArea[chartEnd];
  829. expect(scale.getPixelForValue(firstTick, 0, 0)).toBeCloseToPixel(start);
  830. expect(scale.getPixelForValue(lastTick, 0, 0)).toBeCloseToPixel(end);
  831. expect(scale.getValueForPixel(start)).toBeCloseTo(firstTick, 4);
  832. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  833. chart.scales[axisID].options.ticks.reverse = true; // Reverse mode
  834. chart.update();
  835. // chartArea might have been resized in update
  836. start = chart.chartArea[chartEnd];
  837. end = chart.chartArea[chartStart];
  838. expect(scale.getPixelForValue(firstTick, 0, 0)).toBeCloseToPixel(start);
  839. expect(scale.getPixelForValue(lastTick, 0, 0)).toBeCloseToPixel(end);
  840. expect(scale.getValueForPixel(start)).toBeCloseTo(firstTick, 4);
  841. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  842. });
  843. });
  844. });
  845. });
  846. describe('when', function() {
  847. var config = [
  848. {
  849. dataset: [],
  850. firstTick: 1, // value of the first tick
  851. lastTick: 10, // value of the last tick
  852. describe: 'empty dataset, without ticks.min/max'
  853. },
  854. {
  855. dataset: [],
  856. scale: {stacked: true},
  857. firstTick: 1,
  858. lastTick: 10,
  859. describe: 'empty dataset, without ticks.min/max, with stacked: true'
  860. },
  861. {
  862. data: {
  863. datasets: [
  864. {data: [], stack: 'stack'},
  865. {data: [], stack: 'stack'},
  866. ],
  867. },
  868. type: 'bar',
  869. firstTick: 1,
  870. lastTick: 10,
  871. describe: 'empty dataset with stack option, without ticks.min/max'
  872. },
  873. {
  874. data: {
  875. datasets: [
  876. {data: [], stack: 'stack'},
  877. {data: [], stack: 'stack'},
  878. ],
  879. },
  880. type: 'horizontalBar',
  881. firstTick: 1,
  882. lastTick: 10,
  883. describe: 'empty dataset with stack option, without ticks.min/max'
  884. },
  885. {
  886. dataset: [],
  887. scale: {ticks: {min: 1}},
  888. firstTick: 1,
  889. lastTick: 10,
  890. describe: 'empty dataset, ticks.min: 1, without ticks.max'
  891. },
  892. {
  893. dataset: [],
  894. scale: {ticks: {max: 80}},
  895. firstTick: 1,
  896. lastTick: 80,
  897. describe: 'empty dataset, ticks.max: 80, without ticks.min'
  898. },
  899. {
  900. dataset: [],
  901. scale: {ticks: {max: 0.8}},
  902. firstTick: 0.01,
  903. lastTick: 0.8,
  904. describe: 'empty dataset, ticks.max: 0.8, without ticks.min'
  905. },
  906. {
  907. dataset: [{x: 10, y: 10}, {x: 5, y: 5}, {x: 1, y: 1}, {x: 25, y: 25}, {x: 78, y: 78}],
  908. firstTick: 1,
  909. lastTick: 80,
  910. describe: 'dataset min point {x: 1, y: 1}, max point {x:78, y:78}'
  911. },
  912. ];
  913. config.forEach(function(setup) {
  914. var axes = [
  915. {
  916. id: 'x', // horizontal scale
  917. start: 'left',
  918. end: 'right'
  919. },
  920. {
  921. id: 'y', // vertical scale
  922. start: 'bottom',
  923. end: 'top'
  924. }
  925. ];
  926. axes.forEach(function(axis) {
  927. var expectation = 'min = ' + setup.firstTick + ', max = ' + setup.lastTick;
  928. describe(setup.describe + ' and axis is "' + axis.id + '"; expect: ' + expectation + ';', function() {
  929. beforeEach(function() {
  930. var xScaleConfig = {
  931. type: 'logarithmic',
  932. };
  933. var yScaleConfig = {
  934. type: 'logarithmic',
  935. };
  936. var data = setup.data || {
  937. datasets: [{
  938. data: setup.dataset
  939. }],
  940. };
  941. Chart.helpers.extend(xScaleConfig, setup.scale);
  942. Chart.helpers.extend(yScaleConfig, setup.scale);
  943. Chart.helpers.extend(data, setup.data || {});
  944. this.chart = window.acquireChart({
  945. type: 'line',
  946. data: data,
  947. options: {
  948. scales: {
  949. xAxes: [xScaleConfig],
  950. yAxes: [yScaleConfig]
  951. }
  952. }
  953. });
  954. });
  955. it('should get the correct pixel value for a point', function() {
  956. var chart = this.chart;
  957. var axisID = axis.id + '-axis-0';
  958. var scale = chart.scales[axisID];
  959. var firstTick = setup.firstTick;
  960. var lastTick = setup.lastTick;
  961. var start = chart.chartArea[axis.start];
  962. var end = chart.chartArea[axis.end];
  963. expect(scale.getPixelForValue(firstTick, 0, 0)).toBeCloseToPixel(start);
  964. expect(scale.getPixelForValue(lastTick, 0, 0)).toBeCloseToPixel(end);
  965. expect(scale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(start); // 0 is invalid, put it at the start.
  966. expect(scale.getValueForPixel(start)).toBeCloseTo(firstTick, 4);
  967. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  968. chart.scales[axisID].options.ticks.reverse = true; // Reverse mode
  969. chart.update();
  970. // chartArea might have been resized in update
  971. start = chart.chartArea[axis.end];
  972. end = chart.chartArea[axis.start];
  973. expect(scale.getPixelForValue(firstTick, 0, 0)).toBeCloseToPixel(start);
  974. expect(scale.getPixelForValue(lastTick, 0, 0)).toBeCloseToPixel(end);
  975. expect(scale.getValueForPixel(start)).toBeCloseTo(firstTick, 4);
  976. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  977. });
  978. });
  979. });
  980. });
  981. });
  982. describe('when', function() {
  983. var config = [
  984. {
  985. dataset: [],
  986. scale: {ticks: {min: 0}},
  987. firstTick: 1, // value of the first tick
  988. lastTick: 10, // value of the last tick
  989. describe: 'empty dataset, ticks.min: 0, without ticks.max'
  990. },
  991. {
  992. dataset: [],
  993. scale: {ticks: {min: 0, max: 80}},
  994. firstTick: 1,
  995. lastTick: 80,
  996. describe: 'empty dataset, ticks.min: 0, ticks.max: 80'
  997. },
  998. {
  999. dataset: [],
  1000. scale: {ticks: {min: 0, max: 0.8}},
  1001. firstTick: 0.1,
  1002. lastTick: 0.8,
  1003. describe: 'empty dataset, ticks.min: 0, ticks.max: 0.8'
  1004. },
  1005. {
  1006. dataset: [{x: 0, y: 0}, {x: 10, y: 10}, {x: 1.2, y: 1.2}, {x: 25, y: 25}, {x: 78, y: 78}],
  1007. firstTick: 1,
  1008. lastTick: 80,
  1009. describe: 'dataset min point {x: 0, y: 0}, max point {x:78, y:78}, minNotZero {x: 1.2, y: 1.2}'
  1010. },
  1011. {
  1012. dataset: [{x: 0, y: 0}, {x: 10, y: 10}, {x: 6.3, y: 6.3}, {x: 25, y: 25}, {x: 78, y: 78}],
  1013. firstTick: 6,
  1014. lastTick: 80,
  1015. describe: 'dataset min point {x: 0, y: 0}, max point {x:78, y:78}, minNotZero {x: 6.3, y: 6.3}'
  1016. },
  1017. {
  1018. dataset: [{x: 10, y: 10}, {x: 1.2, y: 1.2}, {x: 25, y: 25}, {x: 78, y: 78}],
  1019. scale: {ticks: {min: 0}},
  1020. firstTick: 1,
  1021. lastTick: 80,
  1022. describe: 'dataset min point {x: 1.2, y: 1.2}, max point {x:78, y:78}, ticks.min: 0'
  1023. },
  1024. {
  1025. dataset: [{x: 10, y: 10}, {x: 6.3, y: 6.3}, {x: 25, y: 25}, {x: 78, y: 78}],
  1026. scale: {ticks: {min: 0}},
  1027. firstTick: 6,
  1028. lastTick: 80,
  1029. describe: 'dataset min point {x: 6.3, y: 6.3}, max point {x:78, y:78}, ticks.min: 0'
  1030. },
  1031. ];
  1032. config.forEach(function(setup) {
  1033. var axes = [
  1034. {
  1035. id: 'x', // horizontal scale
  1036. start: 'left',
  1037. end: 'right'
  1038. },
  1039. {
  1040. id: 'y', // vertical scale
  1041. start: 'bottom',
  1042. end: 'top'
  1043. }
  1044. ];
  1045. axes.forEach(function(axis) {
  1046. var expectation = 'min = 0, max = ' + setup.lastTick + ', first tick = ' + setup.firstTick;
  1047. describe(setup.describe + ' and axis is "' + axis.id + '"; expect: ' + expectation + ';', function() {
  1048. beforeEach(function() {
  1049. var xScaleConfig = {
  1050. type: 'logarithmic',
  1051. };
  1052. var yScaleConfig = {
  1053. type: 'logarithmic',
  1054. };
  1055. var data = setup.data || {
  1056. datasets: [{
  1057. data: setup.dataset
  1058. }],
  1059. };
  1060. Chart.helpers.extend(xScaleConfig, setup.scale);
  1061. Chart.helpers.extend(yScaleConfig, setup.scale);
  1062. Chart.helpers.extend(data, setup.data || {});
  1063. this.chart = window.acquireChart({
  1064. type: 'line',
  1065. data: data,
  1066. options: {
  1067. scales: {
  1068. xAxes: [xScaleConfig],
  1069. yAxes: [yScaleConfig]
  1070. }
  1071. }
  1072. });
  1073. });
  1074. it('should get the correct pixel value for a point', function() {
  1075. var chart = this.chart;
  1076. var axisID = axis.id + '-axis-0';
  1077. var scale = chart.scales[axisID];
  1078. var firstTick = setup.firstTick;
  1079. var lastTick = setup.lastTick;
  1080. var fontSize = chart.options.defaultFontSize;
  1081. var start = chart.chartArea[axis.start];
  1082. var end = chart.chartArea[axis.end];
  1083. var sign = scale.isHorizontal() ? 1 : -1;
  1084. expect(scale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(start);
  1085. expect(scale.getPixelForValue(lastTick, 0, 0)).toBeCloseToPixel(end);
  1086. expect(scale.getPixelForValue(firstTick, 0, 0)).toBeCloseToPixel(start + sign * fontSize);
  1087. expect(scale.getValueForPixel(start)).toBeCloseTo(0, 4);
  1088. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  1089. expect(scale.getValueForPixel(start + sign * fontSize)).toBeCloseTo(firstTick, 4);
  1090. chart.scales[axisID].options.ticks.reverse = true; // Reverse mode
  1091. chart.update();
  1092. // chartArea might have been resized in update
  1093. start = chart.chartArea[axis.end];
  1094. end = chart.chartArea[axis.start];
  1095. expect(scale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(start);
  1096. expect(scale.getPixelForValue(lastTick, 0, 0)).toBeCloseToPixel(end);
  1097. expect(scale.getPixelForValue(firstTick, 0, 0)).toBeCloseToPixel(start - sign * fontSize, 4);
  1098. expect(scale.getValueForPixel(start)).toBeCloseTo(0, 4);
  1099. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  1100. expect(scale.getValueForPixel(start - sign * fontSize)).toBeCloseTo(firstTick, 4);
  1101. });
  1102. });
  1103. });
  1104. });
  1105. });
  1106. });