scale.logarithmic.tests.js 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. describe('Logarithmic Scale tests', function() {
  2. beforeEach(function() {
  3. window.addDefaultMatchers(jasmine);
  4. });
  5. afterEach(function() {
  6. window.releaseAllCharts();
  7. });
  8. it('should register the constructor with the scale service', function() {
  9. var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
  10. expect(Constructor).not.toBe(undefined);
  11. expect(typeof Constructor).toBe('function');
  12. });
  13. it('should have the correct default config', function() {
  14. var defaultConfig = Chart.scaleService.getScaleDefaults('logarithmic');
  15. expect(defaultConfig).toEqual({
  16. display: true,
  17. gridLines: {
  18. color: "rgba(0, 0, 0, 0.1)",
  19. drawBorder: true,
  20. drawOnChartArea: true,
  21. drawTicks: true,
  22. tickMarkLength: 10,
  23. lineWidth: 1,
  24. offsetGridLines: false,
  25. display: true,
  26. zeroLineColor: "rgba(0,0,0,0.25)",
  27. zeroLineWidth: 1,
  28. },
  29. position: "left",
  30. scaleLabel: {
  31. labelString: '',
  32. display: false,
  33. },
  34. ticks: {
  35. beginAtZero: false,
  36. minRotation: 0,
  37. maxRotation: 50,
  38. mirror: false,
  39. padding: 10,
  40. reverse: false,
  41. display: true,
  42. callback: defaultConfig.ticks.callback, // make this nicer, then check explicitly below
  43. autoSkip: true,
  44. autoSkipPadding: 0,
  45. labelOffset: 0
  46. },
  47. });
  48. // Is this actually a function
  49. expect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));
  50. });
  51. it('should correctly determine the max & min data values', function() {
  52. var chart = window.acquireChart({
  53. type: 'bar',
  54. data: {
  55. datasets: [{
  56. yAxisID: 'yScale0',
  57. data: [42, 1000, 64, 100],
  58. }, {
  59. yAxisID: 'yScale1',
  60. data: [10, 5, 5000, 78, 450]
  61. }, {
  62. yAxisID: 'yScale1',
  63. data: [150]
  64. }],
  65. labels: ['a', 'b', 'c', 'd', 'e']
  66. },
  67. options: {
  68. scales: {
  69. yAxes: [{
  70. id: 'yScale0',
  71. type: 'logarithmic'
  72. }, {
  73. id: 'yScale1',
  74. type: 'logarithmic'
  75. }]
  76. }
  77. }
  78. });
  79. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  80. expect(chart.scales.yScale0.min).toBe(10);
  81. expect(chart.scales.yScale0.max).toBe(1000);
  82. expect(chart.scales.yScale1).not.toEqual(undefined); // must construct
  83. expect(chart.scales.yScale1.min).toBe(1);
  84. expect(chart.scales.yScale1.max).toBe(5000);
  85. });
  86. it('should correctly determine the max & min of string data values', function() {
  87. var chart = window.acquireChart({
  88. type: 'line',
  89. data: {
  90. datasets: [{
  91. yAxisID: 'yScale0',
  92. data: ['42', '1000', '64', '100'],
  93. }, {
  94. yAxisID: 'yScale1',
  95. data: ['10', '5', '5000', '78', '450']
  96. }, {
  97. yAxisID: 'yScale1',
  98. data: ['150']
  99. }],
  100. labels: ['a', 'b', 'c', 'd', 'e']
  101. },
  102. options: {
  103. scales: {
  104. yAxes: [{
  105. id: 'yScale0',
  106. type: 'logarithmic'
  107. }, {
  108. id: 'yScale1',
  109. type: 'logarithmic'
  110. }]
  111. }
  112. }
  113. });
  114. expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
  115. expect(chart.scales.yScale0.min).toBe(10);
  116. expect(chart.scales.yScale0.max).toBe(1000);
  117. expect(chart.scales.yScale1).not.toEqual(undefined); // must construct
  118. expect(chart.scales.yScale1.min).toBe(1);
  119. expect(chart.scales.yScale1.max).toBe(5000);
  120. });
  121. it('should correctly determine the max & min data values when there are hidden datasets', function() {
  122. var chart = window.acquireChart({
  123. type: 'line',
  124. data: {
  125. datasets: [{
  126. yAxisID: 'yScale1',
  127. data: [10, 5, 5000, 78, 450]
  128. }, {
  129. yAxisID: 'yScale0',
  130. data: [42, 1000, 64, 100],
  131. }, {
  132. yAxisID: 'yScale1',
  133. data: [50000],
  134. hidden: true
  135. }],
  136. labels: ['a', 'b', 'c', 'd', 'e']
  137. },
  138. options: {
  139. scales: {
  140. yAxes: [{
  141. id: 'yScale0',
  142. type: 'logarithmic'
  143. }, {
  144. id: 'yScale1',
  145. type: 'logarithmic'
  146. }]
  147. }
  148. }
  149. });
  150. expect(chart.scales.yScale1).not.toEqual(undefined); // must construct
  151. expect(chart.scales.yScale1.min).toBe(1);
  152. expect(chart.scales.yScale1.max).toBe(5000);
  153. });
  154. it('should correctly determine the max & min data values when there is NaN data', function() {
  155. var chart = window.acquireChart({
  156. type: 'bar',
  157. data: {
  158. datasets: [{
  159. data: [undefined, 10, null, 5, 5000, NaN, 78, 450]
  160. }, {
  161. data: [undefined, 28, null, 1000, 500, NaN, 50, 42]
  162. }],
  163. labels: ['a', 'b', 'c', 'd', 'e', 'f' ,'g']
  164. },
  165. options: {
  166. scales: {
  167. yAxes: [{
  168. id: 'yScale',
  169. type: 'logarithmic'
  170. }]
  171. }
  172. }
  173. });
  174. expect(chart.scales.yScale).not.toEqual(undefined); // must construct
  175. expect(chart.scales.yScale.min).toBe(1);
  176. expect(chart.scales.yScale.max).toBe(5000);
  177. // Turn on stacked mode since it uses it's own
  178. chart.options.scales.yAxes[0].stacked = true;
  179. chart.update();
  180. expect(chart.scales.yScale.min).toBe(10);
  181. expect(chart.scales.yScale.max).toBe(6000);
  182. });
  183. it('should correctly determine the max & min for scatter data', function() {
  184. var chart = window.acquireChart({
  185. type: 'line',
  186. data: {
  187. datasets: [{
  188. data: [
  189. { x: 10, y: 100 },
  190. { x: 2, y: 6 },
  191. { x: 65, y: 121 },
  192. { x: 99, y: 7 }
  193. ]
  194. }]
  195. },
  196. options: {
  197. scales: {
  198. xAxes: [{
  199. id: 'xScale',
  200. type: 'logarithmic',
  201. position: 'bottom'
  202. }],
  203. yAxes: [{
  204. id: 'yScale',
  205. type: 'logarithmic'
  206. }]
  207. }
  208. }
  209. });
  210. expect(chart.scales.xScale.min).toBe(1);
  211. expect(chart.scales.xScale.max).toBe(100);
  212. expect(chart.scales.yScale.min).toBe(1);
  213. expect(chart.scales.yScale.max).toBe(200);
  214. });
  215. it('should correctly determine the min and max data values when stacked mode is turned on', function() {
  216. var chart = window.acquireChart({
  217. type: 'bar',
  218. data: {
  219. datasets: [{
  220. type: 'bar',
  221. yAxisID: 'yScale0',
  222. data: [10, 5, 1, 5, 78, 100]
  223. }, {
  224. yAxisID: 'yScale1',
  225. data: [-1000, 1000],
  226. }, {
  227. type: 'bar',
  228. yAxisID: 'yScale0',
  229. data: [150, 10, 10, 100, 10, 9]
  230. }, {
  231. type: 'line',
  232. yAxisID: 'yScale0',
  233. data: [100, 100, 100, 100, 100, 100]
  234. }],
  235. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  236. },
  237. options: {
  238. scales: {
  239. yAxes: [{
  240. id: 'yScale0',
  241. type: 'logarithmic',
  242. stacked: true
  243. }, {
  244. id: 'yScale1',
  245. type: 'logarithmic'
  246. }]
  247. }
  248. }
  249. });
  250. expect(chart.scales.yScale0.min).toBe(10);
  251. expect(chart.scales.yScale0.max).toBe(200);
  252. });
  253. it('should correctly determine the min and max data values when stacked mode is turned on ignoring hidden datasets', function() {
  254. var chart = window.acquireChart({
  255. type: 'bar',
  256. data: {
  257. datasets: [{
  258. yAxisID: 'yScale0',
  259. data: [10, 5, 1, 5, 78, 100],
  260. type: 'bar'
  261. }, {
  262. yAxisID: 'yScale1',
  263. data: [-1000, 1000],
  264. type: 'bar'
  265. }, {
  266. yAxisID: 'yScale0',
  267. data: [150, 10, 10, 100, 10, 9],
  268. type: 'bar'
  269. }, {
  270. yAxisID: 'yScale0',
  271. data: [10000, 10000, 10000, 10000, 10000, 10000],
  272. hidden: true,
  273. type: 'bar'
  274. }],
  275. labels: ['a', 'b', 'c', 'd', 'e', 'f']
  276. },
  277. options: {
  278. scales: {
  279. yAxes: [{
  280. id: 'yScale0',
  281. type: 'logarithmic',
  282. stacked: true
  283. }, {
  284. id: 'yScale1',
  285. type: 'logarithmic'
  286. }]
  287. }
  288. }
  289. });
  290. expect(chart.scales.yScale0.min).toBe(10);
  291. expect(chart.scales.yScale0.max).toBe(200);
  292. });
  293. it('should ensure that the scale has a max and min that are not equal', function() {
  294. var chart = window.acquireChart({
  295. type: 'bar',
  296. data: {
  297. datasets: [{
  298. data: []
  299. }],
  300. labels: []
  301. },
  302. options: {
  303. scales: {
  304. yAxes: [{
  305. id: 'yScale',
  306. type: 'logarithmic'
  307. }]
  308. }
  309. }
  310. });
  311. expect(chart.scales.yScale.min).toBe(1);
  312. expect(chart.scales.yScale.max).toBe(10);
  313. chart.data.datasets[0].data = [0.15, 0.15];
  314. chart.update();
  315. expect(chart.scales.yScale.min).toBe(0.01);
  316. expect(chart.scales.yScale.max).toBe(1);
  317. });
  318. it('should use the min and max options', function() {
  319. var chart = window.acquireChart({
  320. type: 'bar',
  321. data: {
  322. datasets: [{
  323. data: [1, 1, 1, 2, 1, 0]
  324. }],
  325. labels: []
  326. },
  327. options: {
  328. scales: {
  329. yAxes: [{
  330. id: 'yScale',
  331. type: 'logarithmic',
  332. ticks: {
  333. min: 10,
  334. max: 1010,
  335. callback: function(value) {
  336. return value;
  337. }
  338. }
  339. }]
  340. }
  341. }
  342. });
  343. var yScale = chart.scales.yScale;
  344. var tickCount = yScale.ticks.length;
  345. expect(yScale.min).toBe(10);
  346. expect(yScale.max).toBe(1010);
  347. expect(yScale.ticks[0]).toBe(1010);
  348. expect(yScale.ticks[tickCount - 1]).toBe(10);
  349. });
  350. it('should generate tick marks', function() {
  351. var chart = window.acquireChart({
  352. type: 'bar',
  353. data: {
  354. datasets: [{
  355. data: [10, 5, 1, 25, 78]
  356. }],
  357. labels: []
  358. },
  359. options: {
  360. scales: {
  361. yAxes: [{
  362. id: 'yScale',
  363. type: 'logarithmic',
  364. ticks: {
  365. callback: function(value) {
  366. return value;
  367. }
  368. }
  369. }]
  370. }
  371. }
  372. });
  373. // Counts down because the lines are drawn top to bottom
  374. expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
  375. ticks: [80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
  376. start: 1,
  377. end: 80
  378. }));
  379. });
  380. it('should generate tick marks in the correct order in reversed mode', function() {
  381. var chart = window.acquireChart({
  382. type: 'line',
  383. data: {
  384. datasets: [{
  385. data: [10, 5, 1, 25, 78]
  386. }],
  387. labels: []
  388. },
  389. options: {
  390. scales: {
  391. yAxes: [{
  392. id: 'yScale',
  393. type: 'logarithmic',
  394. ticks: {
  395. reverse: true,
  396. callback: function(value) {
  397. return value;
  398. }
  399. }
  400. }]
  401. }
  402. }
  403. });
  404. // Counts down because the lines are drawn top to bottom
  405. expect(chart.scales.yScale).toEqual(jasmine.objectContaining({
  406. ticks: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80],
  407. start: 80,
  408. end: 1
  409. }));
  410. });
  411. it('should build labels using the default template', function() {
  412. var chart = window.acquireChart({
  413. type: 'line',
  414. data: {
  415. datasets: [{
  416. data: [10, 5, 1, 25, 78]
  417. }],
  418. labels: []
  419. },
  420. options: {
  421. scales: {
  422. yAxes: [{
  423. id: 'yScale',
  424. type: 'logarithmic'
  425. }]
  426. }
  427. }
  428. });
  429. expect(chart.scales.yScale.ticks).toEqual(['8e+1', '', '', '5e+1', '', '', '2e+1', '1e+1', '', '', '', '', '5e+0', '', '', '2e+0', '1e+0']);
  430. });
  431. it('should build labels using the user supplied callback', function() {
  432. var chart = window.acquireChart({
  433. type: 'bar',
  434. data: {
  435. datasets: [{
  436. data: [10, 5, 1, 25, 78]
  437. }],
  438. labels: []
  439. },
  440. options: {
  441. scales: {
  442. yAxes: [{
  443. id: 'yScale',
  444. type: 'logarithmic',
  445. ticks: {
  446. callback: function(value, index) {
  447. return index.toString();
  448. }
  449. }
  450. }]
  451. }
  452. }
  453. });
  454. // Just the index
  455. expect(chart.scales.yScale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']);
  456. });
  457. it('should correctly get the correct label for a data item', function() {
  458. var chart = window.acquireChart({
  459. type: 'bar',
  460. data: {
  461. datasets: [{
  462. yAxisID: 'yScale0',
  463. data: [10, 5, 5000, 78, 450]
  464. }, {
  465. yAxisID: 'yScale1',
  466. data: [1, 1000, 10, 100],
  467. }, {
  468. yAxisID: 'yScale0',
  469. data: [150]
  470. }],
  471. labels: []
  472. },
  473. options: {
  474. scales: {
  475. yAxes: [{
  476. id: 'yScale0',
  477. type: 'logarithmic'
  478. }, {
  479. id: 'yScale1',
  480. type: 'logarithmic'
  481. }]
  482. }
  483. }
  484. });
  485. expect(chart.scales.yScale1.getLabelForIndex(0, 2)).toBe(150);
  486. });
  487. it('should get the correct pixel value for a point', function() {
  488. var chart = window.acquireChart({
  489. type: 'bar',
  490. data: {
  491. datasets: [{
  492. xAxisID: 'xScale', // for the horizontal scale
  493. yAxisID: 'yScale',
  494. data: [10, 5, 1, 25, 78]
  495. }],
  496. labels: []
  497. },
  498. options: {
  499. scales: {
  500. yAxes: [{
  501. id: 'xScale',
  502. type: 'logarithmic',
  503. position: 'bottom'
  504. }, {
  505. id: 'yScale',
  506. type: 'logarithmic'
  507. }]
  508. }
  509. }
  510. });
  511. var xScale = chart.scales.xScale;
  512. expect(xScale.getPixelForValue(80, 0, 0)).toBeCloseToPixel(495); // right - paddingRight
  513. expect(xScale.getPixelForValue( 1, 0, 0)).toBeCloseToPixel(48); // left + paddingLeft
  514. expect(xScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(283); // halfway
  515. expect(xScale.getPixelForValue( 0, 0, 0)).toBeCloseToPixel(48); // 0 is invalid, put it on the left.
  516. expect(xScale.getValueForPixel(495)).toBeCloseTo(80, 1e-4);
  517. expect(xScale.getValueForPixel(48)).toBeCloseTo(1, 1e-4);
  518. expect(xScale.getValueForPixel(283)).toBeCloseTo(10, 1e-4);
  519. var yScale = chart.scales.yScale;
  520. expect(yScale.getPixelForValue(80, 0, 0)).toBeCloseToPixel(32); // top + paddingTop
  521. expect(yScale.getPixelForValue( 1, 0, 0)).toBeCloseToPixel(456); // bottom - paddingBottom
  522. expect(yScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(234); // halfway
  523. expect(yScale.getPixelForValue( 0, 0, 0)).toBeCloseToPixel(32); // 0 is invalid. force it on top
  524. expect(yScale.getValueForPixel(32)).toBeCloseTo(80, 1e-4);
  525. expect(yScale.getValueForPixel(456)).toBeCloseTo(1, 1e-4);
  526. expect(yScale.getValueForPixel(234)).toBeCloseTo(10, 1e-4);
  527. });
  528. });