scale.logarithmic.tests.js 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124
  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 generate tick marks', function() {
  444. var chart = window.acquireChart({
  445. type: 'bar',
  446. data: {
  447. datasets: [{
  448. data: [10, 5, 1, 25, 78]
  449. }],
  450. labels: []
  451. },
  452. options: {
  453. scales: {
  454. yAxes: [{
  455. id: 'yScale',
  456. type: 'logarithmic',
  457. ticks: {
  458. callback: function(value) {
  459. return value;
  460. }
  461. }
  462. }]
  463. }
  464. }
  465. });
  466. // Counts down because the lines are drawn top to bottom
  467. expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
  468. ticks: [80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
  469. start: 1,
  470. end: 80
  471. }));
  472. });
  473. it('should generate tick marks when 0 values are present', function() {
  474. var chart = window.acquireChart({
  475. type: 'bar',
  476. data: {
  477. datasets: [{
  478. data: [11, 0.8, 0, 28, 7]
  479. }],
  480. labels: []
  481. },
  482. options: {
  483. scales: {
  484. yAxes: [{
  485. id: 'yScale',
  486. type: 'logarithmic',
  487. ticks: {
  488. callback: function(value) {
  489. return value;
  490. }
  491. }
  492. }]
  493. }
  494. }
  495. });
  496. // Counts down because the lines are drawn top to bottom
  497. expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
  498. ticks: [30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0.9, 0.8, 0],
  499. start: 0,
  500. end: 30
  501. }));
  502. });
  503. it('should generate tick marks in the correct order in reversed mode', function() {
  504. var chart = window.acquireChart({
  505. type: 'line',
  506. data: {
  507. datasets: [{
  508. data: [10, 5, 1, 25, 78]
  509. }],
  510. labels: []
  511. },
  512. options: {
  513. scales: {
  514. yAxes: [{
  515. id: 'yScale',
  516. type: 'logarithmic',
  517. ticks: {
  518. reverse: true,
  519. callback: function(value) {
  520. return value;
  521. }
  522. }
  523. }]
  524. }
  525. }
  526. });
  527. // Counts down because the lines are drawn top to bottom
  528. expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
  529. ticks: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80],
  530. start: 80,
  531. end: 1
  532. }));
  533. });
  534. it('should generate tick marks in the correct order in reversed mode when 0 values are present', function() {
  535. var chart = window.acquireChart({
  536. type: 'line',
  537. data: {
  538. datasets: [{
  539. data: [21, 9, 0, 10, 25]
  540. }],
  541. labels: []
  542. },
  543. options: {
  544. scales: {
  545. yAxes: [{
  546. id: 'yScale',
  547. type: 'logarithmic',
  548. ticks: {
  549. reverse: true,
  550. callback: function(value) {
  551. return value;
  552. }
  553. }
  554. }]
  555. }
  556. }
  557. });
  558. // Counts down because the lines are drawn top to bottom
  559. expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
  560. ticks: [0, 9, 10, 20, 30],
  561. start: 30,
  562. end: 0
  563. }));
  564. });
  565. it('should build labels using the default template', function() {
  566. var chart = window.acquireChart({
  567. type: 'line',
  568. data: {
  569. datasets: [{
  570. data: [10, 5, 1, 25, 0, 78]
  571. }],
  572. labels: []
  573. },
  574. options: {
  575. scales: {
  576. yAxes: [{
  577. id: 'yScale',
  578. type: 'logarithmic'
  579. }]
  580. }
  581. }
  582. });
  583. expect(chart.scales.yScale.ticks).toEqual(['8e+1', '', '', '5e+1', '', '', '2e+1', '1e+1', '', '', '', '', '5e+0', '', '', '2e+0', '1e+0', '0']);
  584. });
  585. it('should build labels using the user supplied callback', function() {
  586. var chart = window.acquireChart({
  587. type: 'bar',
  588. data: {
  589. datasets: [{
  590. data: [10, 5, 1, 25, 78]
  591. }],
  592. labels: []
  593. },
  594. options: {
  595. scales: {
  596. yAxes: [{
  597. id: 'yScale',
  598. type: 'logarithmic',
  599. ticks: {
  600. callback: function(value, index) {
  601. return index.toString();
  602. }
  603. }
  604. }]
  605. }
  606. }
  607. });
  608. // Just the index
  609. expect(chart.scales.yScale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']);
  610. });
  611. it('should correctly get the correct label for a data item', function() {
  612. var chart = window.acquireChart({
  613. type: 'bar',
  614. data: {
  615. datasets: [{
  616. yAxisID: 'yScale0',
  617. data: [10, 5, 5000, 78, 450]
  618. }, {
  619. yAxisID: 'yScale1',
  620. data: [1, 1000, 10, 100],
  621. }, {
  622. yAxisID: 'yScale0',
  623. data: [150]
  624. }],
  625. labels: []
  626. },
  627. options: {
  628. scales: {
  629. yAxes: [{
  630. id: 'yScale0',
  631. type: 'logarithmic'
  632. }, {
  633. id: 'yScale1',
  634. type: 'logarithmic'
  635. }]
  636. }
  637. }
  638. });
  639. expect(chart.scales.yScale1.getLabelForIndex(0, 2)).toBe(150);
  640. });
  641. describe('when', function() {
  642. var data = [
  643. {
  644. data: [1, 39],
  645. stack: 'stack'
  646. },
  647. {
  648. data: [1, 39],
  649. stack: 'stack'
  650. },
  651. ];
  652. var dataWithEmptyStacks = [
  653. {
  654. data: []
  655. },
  656. {
  657. data: []
  658. }
  659. ].concat(data);
  660. var config = [
  661. {
  662. axis: 'y',
  663. firstTick: 1, // start of the axis (minimum)
  664. describe: 'all stacks are defined'
  665. },
  666. {
  667. axis: 'y',
  668. data: dataWithEmptyStacks,
  669. firstTick: 1,
  670. describe: 'not all stacks are defined'
  671. },
  672. {
  673. axis: 'y',
  674. scale: {
  675. yAxes: [{
  676. ticks: {
  677. min: 0
  678. }
  679. }]
  680. },
  681. firstTick: 0,
  682. describe: 'all stacks are defined and ticks.min: 0'
  683. },
  684. {
  685. axis: 'y',
  686. data: dataWithEmptyStacks,
  687. scale: {
  688. yAxes: [{
  689. ticks: {
  690. min: 0
  691. }
  692. }]
  693. },
  694. firstTick: 0,
  695. describe: 'not stacks are defined and ticks.min: 0'
  696. },
  697. {
  698. axis: 'x',
  699. firstTick: 1,
  700. describe: 'all stacks are defined'
  701. },
  702. {
  703. axis: 'x',
  704. data: dataWithEmptyStacks,
  705. firstTick: 1,
  706. describe: 'not all stacks are defined'
  707. },
  708. {
  709. axis: 'x',
  710. scale: {
  711. xAxes: [{
  712. ticks: {
  713. min: 0
  714. }
  715. }]
  716. },
  717. firstTick: 0,
  718. describe: 'all stacks are defined and ticks.min: 0'
  719. },
  720. {
  721. axis: 'x',
  722. data: dataWithEmptyStacks,
  723. scale: {
  724. xAxes: [{
  725. ticks: {
  726. min: 0
  727. }
  728. }]
  729. },
  730. firstTick: 0,
  731. describe: 'not all stacks are defined and ticks.min: 0'
  732. },
  733. ];
  734. config.forEach(function(setup) {
  735. var scaleConfig = {};
  736. var type, chartStart, chartEnd;
  737. if (setup.axis === 'x') {
  738. type = 'horizontalBar';
  739. chartStart = 'left';
  740. chartEnd = 'right';
  741. } else {
  742. type = 'bar';
  743. chartStart = 'bottom';
  744. chartEnd = 'top';
  745. }
  746. scaleConfig[setup.axis + 'Axes'] = [{
  747. type: 'logarithmic'
  748. }];
  749. Chart.helpers.extend(scaleConfig, setup.scale);
  750. var description = 'dataset has stack option and ' + setup.describe
  751. + ' and axis is "' + setup.axis + '";';
  752. describe(description, function() {
  753. it('should define the correct axis limits', function() {
  754. var chart = window.acquireChart({
  755. type: type,
  756. data: {
  757. labels: ['category 1', 'category 2'],
  758. datasets: setup.data || data,
  759. },
  760. options: {
  761. scales: scaleConfig
  762. }
  763. });
  764. var axisID = setup.axis + '-axis-0';
  765. var scale = chart.scales[axisID];
  766. var firstTick = setup.firstTick;
  767. var lastTick = 80; // last tick (should be first available tick after: 2 * 39)
  768. var start = chart.chartArea[chartStart];
  769. var end = chart.chartArea[chartEnd];
  770. expect(scale.getPixelForValue(firstTick, 0, 0)).toBe(start);
  771. expect(scale.getPixelForValue(lastTick, 0, 0)).toBe(end);
  772. expect(scale.getValueForPixel(start)).toBeCloseTo(firstTick, 4);
  773. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  774. chart.scales[axisID].options.ticks.reverse = true; // Reverse mode
  775. chart.update();
  776. // chartArea might have been resized in update
  777. start = chart.chartArea[chartEnd];
  778. end = chart.chartArea[chartStart];
  779. expect(scale.getPixelForValue(firstTick, 0, 0)).toBe(start);
  780. expect(scale.getPixelForValue(lastTick, 0, 0)).toBe(end);
  781. expect(scale.getValueForPixel(start)).toBeCloseTo(firstTick, 4);
  782. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  783. });
  784. });
  785. });
  786. });
  787. describe('when', function() {
  788. var config = [
  789. {
  790. dataset: [],
  791. firstTick: 1, // value of the first tick
  792. lastTick: 10, // value of the last tick
  793. describe: 'empty dataset, without ticks.min/max'
  794. },
  795. {
  796. dataset: [],
  797. scale: {stacked: true},
  798. firstTick: 1,
  799. lastTick: 10,
  800. describe: 'empty dataset, without ticks.min/max, with stacked: true'
  801. },
  802. {
  803. data: {
  804. datasets: [
  805. {data: [], stack: 'stack'},
  806. {data: [], stack: 'stack'},
  807. ],
  808. },
  809. type: 'bar',
  810. firstTick: 1,
  811. lastTick: 10,
  812. describe: 'empty dataset with stack option, without ticks.min/max'
  813. },
  814. {
  815. data: {
  816. datasets: [
  817. {data: [], stack: 'stack'},
  818. {data: [], stack: 'stack'},
  819. ],
  820. },
  821. type: 'horizontalBar',
  822. firstTick: 1,
  823. lastTick: 10,
  824. describe: 'empty dataset with stack option, without ticks.min/max'
  825. },
  826. {
  827. dataset: [],
  828. scale: {ticks: {min: 1}},
  829. firstTick: 1,
  830. lastTick: 10,
  831. describe: 'empty dataset, ticks.min: 1, without ticks.max'
  832. },
  833. {
  834. dataset: [],
  835. scale: {ticks: {max: 80}},
  836. firstTick: 1,
  837. lastTick: 80,
  838. describe: 'empty dataset, ticks.max: 80, without ticks.min'
  839. },
  840. {
  841. dataset: [],
  842. scale: {ticks: {max: 0.8}},
  843. firstTick: 0.01,
  844. lastTick: 0.8,
  845. describe: 'empty dataset, ticks.max: 0.8, without ticks.min'
  846. },
  847. {
  848. dataset: [{x: 10, y: 10}, {x: 5, y: 5}, {x: 1, y: 1}, {x: 25, y: 25}, {x: 78, y: 78}],
  849. firstTick: 1,
  850. lastTick: 80,
  851. describe: 'dataset min point {x: 1, y: 1}, max point {x:78, y:78}'
  852. },
  853. ];
  854. config.forEach(function(setup) {
  855. var axes = [
  856. {
  857. id: 'x', // horizontal scale
  858. start: 'left',
  859. end: 'right'
  860. },
  861. {
  862. id: 'y', // vertical scale
  863. start: 'bottom',
  864. end: 'top'
  865. }
  866. ];
  867. axes.forEach(function(axis) {
  868. var expectation = 'min = ' + setup.firstTick + ', max = ' + setup.lastTick;
  869. describe(setup.describe + ' and axis is "' + axis.id + '"; expect: ' + expectation + ';', function() {
  870. beforeEach(function() {
  871. var xScaleConfig = {
  872. type: 'logarithmic',
  873. };
  874. var yScaleConfig = {
  875. type: 'logarithmic',
  876. };
  877. var data = setup.data || {
  878. datasets: [{
  879. data: setup.dataset
  880. }],
  881. };
  882. Chart.helpers.extend(xScaleConfig, setup.scale);
  883. Chart.helpers.extend(yScaleConfig, setup.scale);
  884. Chart.helpers.extend(data, setup.data || {});
  885. this.chart = window.acquireChart({
  886. type: 'line',
  887. data: data,
  888. options: {
  889. scales: {
  890. xAxes: [xScaleConfig],
  891. yAxes: [yScaleConfig]
  892. }
  893. }
  894. });
  895. });
  896. it('should get the correct pixel value for a point', function() {
  897. var chart = this.chart;
  898. var axisID = axis.id + '-axis-0';
  899. var scale = chart.scales[axisID];
  900. var firstTick = setup.firstTick;
  901. var lastTick = setup.lastTick;
  902. var start = chart.chartArea[axis.start];
  903. var end = chart.chartArea[axis.end];
  904. expect(scale.getPixelForValue(firstTick, 0, 0)).toBe(start);
  905. expect(scale.getPixelForValue(lastTick, 0, 0)).toBe(end);
  906. expect(scale.getPixelForValue(0, 0, 0)).toBe(start); // 0 is invalid, put it at the start.
  907. expect(scale.getValueForPixel(start)).toBeCloseTo(firstTick, 4);
  908. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  909. chart.scales[axisID].options.ticks.reverse = true; // Reverse mode
  910. chart.update();
  911. // chartArea might have been resized in update
  912. start = chart.chartArea[axis.end];
  913. end = chart.chartArea[axis.start];
  914. expect(scale.getPixelForValue(firstTick, 0, 0)).toBe(start);
  915. expect(scale.getPixelForValue(lastTick, 0, 0)).toBe(end);
  916. expect(scale.getValueForPixel(start)).toBeCloseTo(firstTick, 4);
  917. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  918. });
  919. });
  920. });
  921. });
  922. });
  923. describe('when', function() {
  924. var config = [
  925. {
  926. dataset: [],
  927. scale: {ticks: {min: 0}},
  928. firstTick: 1, // value of the first tick
  929. lastTick: 10, // value of the last tick
  930. describe: 'empty dataset, ticks.min: 0, without ticks.max'
  931. },
  932. {
  933. dataset: [],
  934. scale: {ticks: {min: 0, max: 80}},
  935. firstTick: 1,
  936. lastTick: 80,
  937. describe: 'empty dataset, ticks.min: 0, ticks.max: 80'
  938. },
  939. {
  940. dataset: [],
  941. scale: {ticks: {min: 0, max: 0.8}},
  942. firstTick: 0.1,
  943. lastTick: 0.8,
  944. describe: 'empty dataset, ticks.min: 0, ticks.max: 0.8'
  945. },
  946. {
  947. dataset: [{x: 0, y: 0}, {x: 10, y: 10}, {x: 1.2, y: 1.2}, {x: 25, y: 25}, {x: 78, y: 78}],
  948. firstTick: 1,
  949. lastTick: 80,
  950. describe: 'dataset min point {x: 0, y: 0}, max point {x:78, y:78}, minNotZero {x: 1.2, y: 1.2}'
  951. },
  952. {
  953. dataset: [{x: 0, y: 0}, {x: 10, y: 10}, {x: 6.3, y: 6.3}, {x: 25, y: 25}, {x: 78, y: 78}],
  954. firstTick: 6,
  955. lastTick: 80,
  956. describe: 'dataset min point {x: 0, y: 0}, max point {x:78, y:78}, minNotZero {x: 6.3, y: 6.3}'
  957. },
  958. {
  959. dataset: [{x: 10, y: 10}, {x: 1.2, y: 1.2}, {x: 25, y: 25}, {x: 78, y: 78}],
  960. scale: {ticks: {min: 0}},
  961. firstTick: 1,
  962. lastTick: 80,
  963. describe: 'dataset min point {x: 1.2, y: 1.2}, max point {x:78, y:78}, ticks.min: 0'
  964. },
  965. {
  966. dataset: [{x: 10, y: 10}, {x: 6.3, y: 6.3}, {x: 25, y: 25}, {x: 78, y: 78}],
  967. scale: {ticks: {min: 0}},
  968. firstTick: 6,
  969. lastTick: 80,
  970. describe: 'dataset min point {x: 6.3, y: 6.3}, max point {x:78, y:78}, ticks.min: 0'
  971. },
  972. ];
  973. config.forEach(function(setup) {
  974. var axes = [
  975. {
  976. id: 'x', // horizontal scale
  977. start: 'left',
  978. end: 'right'
  979. },
  980. {
  981. id: 'y', // vertical scale
  982. start: 'bottom',
  983. end: 'top'
  984. }
  985. ];
  986. axes.forEach(function(axis) {
  987. var expectation = 'min = 0, max = ' + setup.lastTick + ', first tick = ' + setup.firstTick;
  988. describe(setup.describe + ' and axis is "' + axis.id + '"; expect: ' + expectation + ';', function() {
  989. beforeEach(function() {
  990. var xScaleConfig = {
  991. type: 'logarithmic',
  992. };
  993. var yScaleConfig = {
  994. type: 'logarithmic',
  995. };
  996. var data = setup.data || {
  997. datasets: [{
  998. data: setup.dataset
  999. }],
  1000. };
  1001. Chart.helpers.extend(xScaleConfig, setup.scale);
  1002. Chart.helpers.extend(yScaleConfig, setup.scale);
  1003. Chart.helpers.extend(data, setup.data || {});
  1004. this.chart = window.acquireChart({
  1005. type: 'line',
  1006. data: data,
  1007. options: {
  1008. scales: {
  1009. xAxes: [xScaleConfig],
  1010. yAxes: [yScaleConfig]
  1011. }
  1012. }
  1013. });
  1014. });
  1015. it('should get the correct pixel value for a point', function() {
  1016. var chart = this.chart;
  1017. var axisID = axis.id + '-axis-0';
  1018. var scale = chart.scales[axisID];
  1019. var firstTick = setup.firstTick;
  1020. var lastTick = setup.lastTick;
  1021. var fontSize = chart.options.defaultFontSize;
  1022. var start = chart.chartArea[axis.start];
  1023. var end = chart.chartArea[axis.end];
  1024. var sign = scale.isHorizontal() ? 1 : -1;
  1025. expect(scale.getPixelForValue(0, 0, 0)).toBe(start);
  1026. expect(scale.getPixelForValue(lastTick, 0, 0)).toBe(end);
  1027. expect(scale.getPixelForValue(firstTick, 0, 0)).toBe(start + sign * fontSize);
  1028. expect(scale.getValueForPixel(start)).toBeCloseTo(0, 4);
  1029. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  1030. expect(scale.getValueForPixel(start + sign * fontSize)).toBeCloseTo(firstTick, 4);
  1031. chart.scales[axisID].options.ticks.reverse = true; // Reverse mode
  1032. chart.update();
  1033. // chartArea might have been resized in update
  1034. start = chart.chartArea[axis.end];
  1035. end = chart.chartArea[axis.start];
  1036. expect(scale.getPixelForValue(0, 0, 0)).toBe(start);
  1037. expect(scale.getPixelForValue(lastTick, 0, 0)).toBe(end);
  1038. expect(scale.getPixelForValue(firstTick, 0, 0)).toBe(start - sign * fontSize, 4);
  1039. expect(scale.getValueForPixel(start)).toBeCloseTo(0, 4);
  1040. expect(scale.getValueForPixel(end)).toBeCloseTo(lastTick, 4);
  1041. expect(scale.getValueForPixel(start - sign * fontSize)).toBeCloseTo(firstTick, 4);
  1042. });
  1043. });
  1044. });
  1045. });
  1046. });
  1047. });