controller.line.tests.js 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. // Test the line controller
  2. describe('Line controller tests', function() {
  3. beforeEach(function() {
  4. window.addDefaultMatchers(jasmine);
  5. });
  6. afterEach(function() {
  7. window.releaseAllCharts();
  8. });
  9. it('should be constructed', function() {
  10. var chart = window.acquireChart({
  11. type: 'line',
  12. data: {
  13. datasets: [{
  14. data: []
  15. }],
  16. labels: []
  17. }
  18. });
  19. var meta = chart.getDatasetMeta(0);
  20. expect(meta.type).toBe('line');
  21. expect(meta.controller).not.toBe(undefined);
  22. expect(meta.controller.index).toBe(0);
  23. expect(meta.data).toEqual([]);
  24. meta.controller.updateIndex(1);
  25. expect(meta.controller.index).toBe(1);
  26. });
  27. it('Should use the first scale IDs if the dataset does not specify them', function() {
  28. var chart = window.acquireChart({
  29. type: 'line',
  30. data: {
  31. datasets: [{
  32. data: []
  33. }],
  34. labels: []
  35. },
  36. options: {
  37. scales: {
  38. xAxes: [{
  39. id: 'firstXScaleID'
  40. }],
  41. yAxes: [{
  42. id: 'firstYScaleID'
  43. }]
  44. }
  45. }
  46. });
  47. var meta = chart.getDatasetMeta(0);
  48. expect(meta.xAxisID).toBe('firstXScaleID');
  49. expect(meta.yAxisID).toBe('firstYScaleID');
  50. });
  51. it('Should create line elements and point elements for each data item during initialization', function() {
  52. var chart = window.acquireChart({
  53. type: 'line',
  54. data: {
  55. datasets: [{
  56. data: [10, 15, 0, -4],
  57. label: 'dataset1'
  58. }],
  59. labels: ['label1', 'label2', 'label3', 'label4']
  60. }
  61. });
  62. var meta = chart.getDatasetMeta(0);
  63. expect(meta.data.length).toBe(4); // 4 points created
  64. expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
  65. expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
  66. expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
  67. expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
  68. expect(meta.dataset instanceof Chart.elements.Line).toBe(true); // 1 line element
  69. });
  70. it('should draw all elements', function() {
  71. var chart = window.acquireChart({
  72. type: 'line',
  73. data: {
  74. datasets: [{
  75. data: [10, 15, 0, -4],
  76. label: 'dataset1'
  77. }],
  78. labels: ['label1', 'label2', 'label3', 'label4']
  79. },
  80. options: {
  81. showLines: true
  82. }
  83. });
  84. var meta = chart.getDatasetMeta(0);
  85. spyOn(meta.dataset, 'draw');
  86. spyOn(meta.data[0], 'draw');
  87. spyOn(meta.data[1], 'draw');
  88. spyOn(meta.data[2], 'draw');
  89. spyOn(meta.data[3], 'draw');
  90. chart.update();
  91. expect(meta.data[0].draw.calls.count()).toBe(1);
  92. expect(meta.data[1].draw.calls.count()).toBe(1);
  93. expect(meta.data[2].draw.calls.count()).toBe(1);
  94. expect(meta.data[3].draw.calls.count()).toBe(1);
  95. });
  96. it('should draw all elements except lines', function() {
  97. var chart = window.acquireChart({
  98. type: 'line',
  99. data: {
  100. datasets: [{
  101. data: [10, 15, 0, -4],
  102. label: 'dataset1'
  103. }],
  104. labels: ['label1', 'label2', 'label3', 'label4']
  105. },
  106. options: {
  107. showLines: false
  108. }
  109. });
  110. var meta = chart.getDatasetMeta(0);
  111. spyOn(meta.dataset, 'draw');
  112. spyOn(meta.data[0], 'draw');
  113. spyOn(meta.data[1], 'draw');
  114. spyOn(meta.data[2], 'draw');
  115. spyOn(meta.data[3], 'draw');
  116. chart.update();
  117. expect(meta.dataset.draw.calls.count()).toBe(0);
  118. expect(meta.data[0].draw.calls.count()).toBe(1);
  119. expect(meta.data[1].draw.calls.count()).toBe(1);
  120. expect(meta.data[2].draw.calls.count()).toBe(1);
  121. expect(meta.data[3].draw.calls.count()).toBe(1);
  122. });
  123. it('should draw all elements except lines turned off per dataset', function() {
  124. var chart = window.acquireChart({
  125. type: 'line',
  126. data: {
  127. datasets: [{
  128. data: [10, 15, 0, -4],
  129. label: 'dataset1',
  130. showLine: false
  131. }],
  132. labels: ['label1', 'label2', 'label3', 'label4']
  133. },
  134. options: {
  135. showLines: true
  136. }
  137. });
  138. var meta = chart.getDatasetMeta(0);
  139. spyOn(meta.dataset, 'draw');
  140. spyOn(meta.data[0], 'draw');
  141. spyOn(meta.data[1], 'draw');
  142. spyOn(meta.data[2], 'draw');
  143. spyOn(meta.data[3], 'draw');
  144. chart.update();
  145. expect(meta.dataset.draw.calls.count()).toBe(0);
  146. expect(meta.data[0].draw.calls.count()).toBe(1);
  147. expect(meta.data[1].draw.calls.count()).toBe(1);
  148. expect(meta.data[2].draw.calls.count()).toBe(1);
  149. expect(meta.data[3].draw.calls.count()).toBe(1);
  150. });
  151. it('should update elements when modifying data', function() {
  152. var chart = window.acquireChart({
  153. type: 'line',
  154. data: {
  155. datasets: [{
  156. data: [10, 15, 0, -4],
  157. label: 'dataset',
  158. xAxisID: 'firstXScaleID',
  159. yAxisID: 'firstYScaleID'
  160. }],
  161. labels: ['label1', 'label2', 'label3', 'label4']
  162. },
  163. options: {
  164. showLines: true,
  165. elements: {
  166. point: {
  167. backgroundColor: 'red',
  168. borderColor: 'blue',
  169. }
  170. },
  171. scales: {
  172. xAxes: [{
  173. id: 'firstXScaleID'
  174. }],
  175. yAxes: [{
  176. id: 'firstYScaleID'
  177. }]
  178. }
  179. },
  180. });
  181. var meta = chart.getDatasetMeta(0);
  182. expect(meta.data.length).toBe(4);
  183. chart.data.datasets[0].data = [1, 2]; // remove 2 items
  184. chart.data.datasets[0].borderWidth = 1;
  185. chart.update();
  186. expect(meta.data.length).toBe(2);
  187. [ { x: 44, y: 484 },
  188. { x: 193, y: 32 }
  189. ].forEach(function(expected, i) {
  190. expect(meta.data[i]._datasetIndex).toBe(0);
  191. expect(meta.data[i]._index).toBe(i);
  192. expect(meta.data[i]._xScale).toBe(chart.scales.firstXScaleID);
  193. expect(meta.data[i]._yScale).toBe(chart.scales.firstYScaleID);
  194. expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
  195. expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
  196. expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
  197. backgroundColor: 'red',
  198. borderColor: 'blue',
  199. }));
  200. });
  201. chart.data.datasets[0].data = [1, 2, 3]; // add 1 items
  202. chart.update();
  203. expect(meta.data.length).toBe(3); // should add a new meta data item
  204. });
  205. it('should update elements when the y scale is stacked', function() {
  206. var chart = window.acquireChart({
  207. type: 'line',
  208. data: {
  209. datasets: [{
  210. data: [10, -10, 10, -10],
  211. label: 'dataset1'
  212. }, {
  213. data: [10, 15, 0, -4],
  214. label: 'dataset2'
  215. }],
  216. labels: ['label1', 'label2', 'label3', 'label4']
  217. },
  218. options: {
  219. scales: {
  220. yAxes: [{
  221. stacked: true
  222. }]
  223. }
  224. }
  225. });
  226. var meta0 = chart.getDatasetMeta(0);
  227. [ { x: 38, y: 161 },
  228. { x: 189, y: 419 },
  229. { x: 341, y: 161 },
  230. { x: 492, y: 419 }
  231. ].forEach(function(values, i) {
  232. expect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);
  233. expect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);
  234. });
  235. var meta1 = chart.getDatasetMeta(1);
  236. [ { x: 38, y: 32 },
  237. { x: 189, y: 97 },
  238. { x: 341, y: 161 },
  239. { x: 492, y: 471 }
  240. ].forEach(function(values, i) {
  241. expect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);
  242. expect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);
  243. });
  244. });
  245. it('should find the correct scale zero when the data is all positive', function() {
  246. var chart = window.acquireChart({
  247. type: 'line',
  248. data: {
  249. datasets: [{
  250. data: [10, 15, 20, 20],
  251. label: 'dataset1',
  252. }],
  253. labels: ['label1', 'label2', 'label3', 'label4']
  254. },
  255. });
  256. var meta = chart.getDatasetMeta(0);
  257. expect(meta.dataset._model).toEqual(jasmine.objectContaining({
  258. scaleTop: 32,
  259. scaleBottom: 484,
  260. scaleZero: 484,
  261. }));
  262. });
  263. it('should find the correct scale zero when the data is all negative', function() {
  264. var chart = window.acquireChart({
  265. type: 'line',
  266. data: {
  267. datasets: [{
  268. data: [-10, -15, -20, -20],
  269. label: 'dataset1',
  270. }],
  271. labels: ['label1', 'label2', 'label3', 'label4']
  272. },
  273. });
  274. var meta = chart.getDatasetMeta(0);
  275. expect(meta.dataset._model).toEqual(jasmine.objectContaining({
  276. scaleTop: 32,
  277. scaleBottom: 484,
  278. scaleZero: 32,
  279. }));
  280. });
  281. it('should fall back to the line styles for points', function() {
  282. var chart = window.acquireChart({
  283. type: 'line',
  284. data: {
  285. datasets: [{
  286. data: [0, 0],
  287. label: 'dataset1',
  288. // line styles
  289. backgroundColor: 'rgb(98, 98, 98)',
  290. borderColor: 'rgb(8, 8, 8)',
  291. borderWidth: 0.55,
  292. }],
  293. labels: ['label1', 'label2']
  294. }
  295. });
  296. var meta = chart.getDatasetMeta(0);
  297. expect(meta.dataset._model.backgroundColor).toBe('rgb(98, 98, 98)');
  298. expect(meta.dataset._model.borderColor).toBe('rgb(8, 8, 8)');
  299. expect(meta.dataset._model.borderWidth).toBe(0.55);
  300. });
  301. it('should handle number of data point changes in update', function() {
  302. var chart = window.acquireChart({
  303. type: 'line',
  304. data: {
  305. datasets: [{
  306. data: [10, 15, 0, -4],
  307. label: 'dataset1',
  308. }],
  309. labels: ['label1', 'label2', 'label3', 'label4']
  310. }
  311. });
  312. var meta = chart.getDatasetMeta(0);
  313. chart.data.datasets[0].data = [1, 2]; // remove 2 items
  314. chart.update();
  315. expect(meta.data.length).toBe(2);
  316. expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
  317. expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
  318. chart.data.datasets[0].data = [1, 2, 3, 4, 5]; // add 3 items
  319. chart.update();
  320. expect(meta.data.length).toBe(5);
  321. expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
  322. expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
  323. expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
  324. expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
  325. expect(meta.data[4] instanceof Chart.elements.Point).toBe(true);
  326. });
  327. it('should set point hover styles', function() {
  328. var chart = window.acquireChart({
  329. type: 'line',
  330. data: {
  331. datasets: [{
  332. data: [10, 15, 0, -4],
  333. label: 'dataset1',
  334. }],
  335. labels: ['label1', 'label2', 'label3', 'label4']
  336. },
  337. options: {
  338. elements: {
  339. point: {
  340. backgroundColor: 'rgb(255, 255, 0)',
  341. borderWidth: 1,
  342. borderColor: 'rgb(255, 255, 255)',
  343. hitRadius: 1,
  344. hoverRadius: 4,
  345. hoverBorderWidth: 1,
  346. radius: 3,
  347. }
  348. }
  349. }
  350. });
  351. var meta = chart.getDatasetMeta(0);
  352. var point = meta.data[0];
  353. meta.controller.setHoverStyle(point);
  354. expect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');
  355. expect(point._model.borderColor).toBe('rgb(230, 230, 230)');
  356. expect(point._model.borderWidth).toBe(1);
  357. expect(point._model.radius).toBe(4);
  358. // Can set hover style per dataset
  359. chart.data.datasets[0].pointHoverRadius = 3.3;
  360. chart.data.datasets[0].pointHoverBackgroundColor = 'rgb(77, 79, 81)';
  361. chart.data.datasets[0].pointHoverBorderColor = 'rgb(123, 125, 127)';
  362. chart.data.datasets[0].pointHoverBorderWidth = 2.1;
  363. meta.controller.setHoverStyle(point);
  364. expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
  365. expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
  366. expect(point._model.borderWidth).toBe(2.1);
  367. expect(point._model.radius).toBe(3.3);
  368. // Use the consistent name "pointRadius", setting but overwriting
  369. // another value in "radius"
  370. chart.data.datasets[0].pointRadius = 250;
  371. chart.data.datasets[0].radius = 20;
  372. meta.controller.setHoverStyle(point);
  373. expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
  374. expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
  375. expect(point._model.borderWidth).toBe(2.1);
  376. expect(point._model.radius).toBe(3.3);
  377. // Custom style
  378. point.custom = {
  379. hoverRadius: 4.4,
  380. hoverBorderWidth: 5.5,
  381. hoverBackgroundColor: 'rgb(0, 0, 0)',
  382. hoverBorderColor: 'rgb(10, 10, 10)'
  383. };
  384. meta.controller.setHoverStyle(point);
  385. expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
  386. expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
  387. expect(point._model.borderWidth).toBe(5.5);
  388. expect(point._model.radius).toBe(4.4);
  389. });
  390. it('should remove hover styles', function() {
  391. var chart = window.acquireChart({
  392. type: 'line',
  393. data: {
  394. datasets: [{
  395. data: [10, 15, 0, -4],
  396. label: 'dataset1',
  397. }],
  398. labels: ['label1', 'label2', 'label3', 'label4']
  399. },
  400. options: {
  401. elements: {
  402. point: {
  403. backgroundColor: 'rgb(255, 255, 0)',
  404. borderWidth: 1,
  405. borderColor: 'rgb(255, 255, 255)',
  406. hitRadius: 1,
  407. hoverRadius: 4,
  408. hoverBorderWidth: 1,
  409. radius: 3,
  410. }
  411. }
  412. }
  413. });
  414. var meta = chart.getDatasetMeta(0);
  415. var point = meta.data[0];
  416. chart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';
  417. chart.options.elements.point.borderColor = 'rgb(50, 51, 52)';
  418. chart.options.elements.point.borderWidth = 10.1;
  419. chart.options.elements.point.radius = 1.01;
  420. meta.controller.removeHoverStyle(point);
  421. expect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');
  422. expect(point._model.borderColor).toBe('rgb(50, 51, 52)');
  423. expect(point._model.borderWidth).toBe(10.1);
  424. expect(point._model.radius).toBe(1.01);
  425. // Can set hover style per dataset
  426. chart.data.datasets[0].radius = 3.3;
  427. chart.data.datasets[0].pointBackgroundColor = 'rgb(77, 79, 81)';
  428. chart.data.datasets[0].pointBorderColor = 'rgb(123, 125, 127)';
  429. chart.data.datasets[0].pointBorderWidth = 2.1;
  430. meta.controller.removeHoverStyle(point);
  431. expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
  432. expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
  433. expect(point._model.borderWidth).toBe(2.1);
  434. expect(point._model.radius).toBe(3.3);
  435. // Use the consistent name "pointRadius", setting but overwriting
  436. // another value in "radius"
  437. chart.data.datasets[0].pointRadius = 250;
  438. chart.data.datasets[0].radius = 20;
  439. meta.controller.removeHoverStyle(point);
  440. expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
  441. expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
  442. expect(point._model.borderWidth).toBe(2.1);
  443. expect(point._model.radius).toBe(250);
  444. // Custom style
  445. point.custom = {
  446. radius: 4.4,
  447. borderWidth: 5.5,
  448. backgroundColor: 'rgb(0, 0, 0)',
  449. borderColor: 'rgb(10, 10, 10)'
  450. };
  451. meta.controller.removeHoverStyle(point);
  452. expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
  453. expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
  454. expect(point._model.borderWidth).toBe(5.5);
  455. expect(point._model.radius).toBe(4.4);
  456. });
  457. });