controller.line.tests.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  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 update elements when modifying data', function() {
  124. var chart = window.acquireChart({
  125. type: 'line',
  126. data: {
  127. datasets: [{
  128. data: [10, 15, 0, -4],
  129. label: 'dataset',
  130. xAxisID: 'firstXScaleID',
  131. yAxisID: 'firstYScaleID'
  132. }],
  133. labels: ['label1', 'label2', 'label3', 'label4']
  134. },
  135. options: {
  136. showLines: true,
  137. elements: {
  138. point: {
  139. backgroundColor: 'red',
  140. borderColor: 'blue',
  141. }
  142. },
  143. scales: {
  144. xAxes: [{
  145. id: 'firstXScaleID'
  146. }],
  147. yAxes: [{
  148. id: 'firstYScaleID'
  149. }]
  150. }
  151. },
  152. });
  153. var meta = chart.getDatasetMeta(0);
  154. expect(meta.data.length).toBe(4);
  155. chart.data.datasets[0].data = [1, 2]; // remove 2 items
  156. chart.data.datasets[0].borderWidth = 1;
  157. chart.update();
  158. expect(meta.data.length).toBe(2);
  159. [ { x: 44, y: 484 },
  160. { x: 193, y: 32 }
  161. ].forEach(function(expected, i) {
  162. expect(meta.data[i]._datasetIndex).toBe(0);
  163. expect(meta.data[i]._index).toBe(i);
  164. expect(meta.data[i]._xScale).toBe(chart.scales.firstXScaleID);
  165. expect(meta.data[i]._yScale).toBe(chart.scales.firstYScaleID);
  166. expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
  167. expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
  168. expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
  169. backgroundColor: 'red',
  170. borderColor: 'blue',
  171. }));
  172. });
  173. chart.data.datasets[0].data = [1, 2, 3]; // add 1 items
  174. chart.update();
  175. expect(meta.data.length).toBe(3); // should add a new meta data item
  176. });
  177. it('should update elements when the y scale is stacked', function() {
  178. var chart = window.acquireChart({
  179. type: 'line',
  180. data: {
  181. datasets: [{
  182. data: [10, -10, 10, -10],
  183. label: 'dataset1'
  184. }, {
  185. data: [10, 15, 0, -4],
  186. label: 'dataset2'
  187. }],
  188. labels: ['label1', 'label2', 'label3', 'label4']
  189. },
  190. options: {
  191. scales: {
  192. yAxes: [{
  193. stacked: true
  194. }]
  195. }
  196. }
  197. });
  198. var meta0 = chart.getDatasetMeta(0);
  199. [ { x: 38, y: 161 },
  200. { x: 189, y: 419 },
  201. { x: 341, y: 161 },
  202. { x: 492, y: 419 }
  203. ].forEach(function(values, i) {
  204. expect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);
  205. expect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);
  206. });
  207. var meta1 = chart.getDatasetMeta(1);
  208. [ { x: 38, y: 32 },
  209. { x: 189, y: 97 },
  210. { x: 341, y: 161 },
  211. { x: 492, y: 471 }
  212. ].forEach(function(values, i) {
  213. expect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);
  214. expect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);
  215. });
  216. });
  217. it('should find the correct scale zero when the data is all positive', function() {
  218. var chart = window.acquireChart({
  219. type: 'line',
  220. data: {
  221. datasets: [{
  222. data: [10, 15, 20, 20],
  223. label: 'dataset1',
  224. }],
  225. labels: ['label1', 'label2', 'label3', 'label4']
  226. },
  227. });
  228. var meta = chart.getDatasetMeta(0);
  229. expect(meta.dataset._model).toEqual(jasmine.objectContaining({
  230. scaleTop: 32,
  231. scaleBottom: 484,
  232. scaleZero: 484,
  233. }));
  234. });
  235. it('should find the correct scale zero when the data is all negative', function() {
  236. var chart = window.acquireChart({
  237. type: 'line',
  238. data: {
  239. datasets: [{
  240. data: [-10, -15, -20, -20],
  241. label: 'dataset1',
  242. }],
  243. labels: ['label1', 'label2', 'label3', 'label4']
  244. },
  245. });
  246. var meta = chart.getDatasetMeta(0);
  247. expect(meta.dataset._model).toEqual(jasmine.objectContaining({
  248. scaleTop: 32,
  249. scaleBottom: 484,
  250. scaleZero: 32,
  251. }));
  252. });
  253. it('should fall back to the line styles for points', function() {
  254. var chart = window.acquireChart({
  255. type: 'line',
  256. data: {
  257. datasets: [{
  258. data: [0, 0],
  259. label: 'dataset1',
  260. // line styles
  261. backgroundColor: 'rgb(98, 98, 98)',
  262. borderColor: 'rgb(8, 8, 8)',
  263. borderWidth: 0.55,
  264. }],
  265. labels: ['label1', 'label2']
  266. }
  267. });
  268. var meta = chart.getDatasetMeta(0);
  269. expect(meta.dataset._model.backgroundColor).toBe('rgb(98, 98, 98)');
  270. expect(meta.dataset._model.borderColor).toBe('rgb(8, 8, 8)');
  271. expect(meta.dataset._model.borderWidth).toBe(0.55);
  272. });
  273. it('should handle number of data point changes in update', function() {
  274. var chart = window.acquireChart({
  275. type: 'line',
  276. data: {
  277. datasets: [{
  278. data: [10, 15, 0, -4],
  279. label: 'dataset1',
  280. }],
  281. labels: ['label1', 'label2', 'label3', 'label4']
  282. }
  283. });
  284. var meta = chart.getDatasetMeta(0);
  285. chart.data.datasets[0].data = [1, 2]; // remove 2 items
  286. chart.update();
  287. expect(meta.data.length).toBe(2);
  288. expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
  289. expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
  290. chart.data.datasets[0].data = [1, 2, 3, 4, 5]; // add 3 items
  291. chart.update();
  292. expect(meta.data.length).toBe(5);
  293. expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
  294. expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
  295. expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
  296. expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
  297. expect(meta.data[4] instanceof Chart.elements.Point).toBe(true);
  298. });
  299. it('should set point hover styles', function() {
  300. var chart = window.acquireChart({
  301. type: 'line',
  302. data: {
  303. datasets: [{
  304. data: [10, 15, 0, -4],
  305. label: 'dataset1',
  306. }],
  307. labels: ['label1', 'label2', 'label3', 'label4']
  308. },
  309. options: {
  310. elements: {
  311. point: {
  312. backgroundColor: 'rgb(255, 255, 0)',
  313. borderWidth: 1,
  314. borderColor: 'rgb(255, 255, 255)',
  315. hitRadius: 1,
  316. hoverRadius: 4,
  317. hoverBorderWidth: 1,
  318. radius: 3,
  319. }
  320. }
  321. }
  322. });
  323. var meta = chart.getDatasetMeta(0);
  324. var point = meta.data[0];
  325. meta.controller.setHoverStyle(point);
  326. expect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');
  327. expect(point._model.borderColor).toBe('rgb(230, 230, 230)');
  328. expect(point._model.borderWidth).toBe(1);
  329. expect(point._model.radius).toBe(4);
  330. // Can set hover style per dataset
  331. chart.data.datasets[0].pointHoverRadius = 3.3;
  332. chart.data.datasets[0].pointHoverBackgroundColor = 'rgb(77, 79, 81)';
  333. chart.data.datasets[0].pointHoverBorderColor = 'rgb(123, 125, 127)';
  334. chart.data.datasets[0].pointHoverBorderWidth = 2.1;
  335. meta.controller.setHoverStyle(point);
  336. expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
  337. expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
  338. expect(point._model.borderWidth).toBe(2.1);
  339. expect(point._model.radius).toBe(3.3);
  340. // Use the consistent name "pointRadius", setting but overwriting
  341. // another value in "radius"
  342. chart.data.datasets[0].pointRadius = 250;
  343. chart.data.datasets[0].radius = 20;
  344. meta.controller.setHoverStyle(point);
  345. expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
  346. expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
  347. expect(point._model.borderWidth).toBe(2.1);
  348. expect(point._model.radius).toBe(3.3);
  349. // Custom style
  350. point.custom = {
  351. hoverRadius: 4.4,
  352. hoverBorderWidth: 5.5,
  353. hoverBackgroundColor: 'rgb(0, 0, 0)',
  354. hoverBorderColor: 'rgb(10, 10, 10)'
  355. };
  356. meta.controller.setHoverStyle(point);
  357. expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
  358. expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
  359. expect(point._model.borderWidth).toBe(5.5);
  360. expect(point._model.radius).toBe(4.4);
  361. });
  362. it('should remove hover styles', function() {
  363. var chart = window.acquireChart({
  364. type: 'line',
  365. data: {
  366. datasets: [{
  367. data: [10, 15, 0, -4],
  368. label: 'dataset1',
  369. }],
  370. labels: ['label1', 'label2', 'label3', 'label4']
  371. },
  372. options: {
  373. elements: {
  374. point: {
  375. backgroundColor: 'rgb(255, 255, 0)',
  376. borderWidth: 1,
  377. borderColor: 'rgb(255, 255, 255)',
  378. hitRadius: 1,
  379. hoverRadius: 4,
  380. hoverBorderWidth: 1,
  381. radius: 3,
  382. }
  383. }
  384. }
  385. });
  386. var meta = chart.getDatasetMeta(0);
  387. var point = meta.data[0];
  388. chart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';
  389. chart.options.elements.point.borderColor = 'rgb(50, 51, 52)';
  390. chart.options.elements.point.borderWidth = 10.1;
  391. chart.options.elements.point.radius = 1.01;
  392. meta.controller.removeHoverStyle(point);
  393. expect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');
  394. expect(point._model.borderColor).toBe('rgb(50, 51, 52)');
  395. expect(point._model.borderWidth).toBe(10.1);
  396. expect(point._model.radius).toBe(1.01);
  397. // Can set hover style per dataset
  398. chart.data.datasets[0].radius = 3.3;
  399. chart.data.datasets[0].pointBackgroundColor = 'rgb(77, 79, 81)';
  400. chart.data.datasets[0].pointBorderColor = 'rgb(123, 125, 127)';
  401. chart.data.datasets[0].pointBorderWidth = 2.1;
  402. meta.controller.removeHoverStyle(point);
  403. expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
  404. expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
  405. expect(point._model.borderWidth).toBe(2.1);
  406. expect(point._model.radius).toBe(3.3);
  407. // Use the consistent name "pointRadius", setting but overwriting
  408. // another value in "radius"
  409. chart.data.datasets[0].pointRadius = 250;
  410. chart.data.datasets[0].radius = 20;
  411. meta.controller.removeHoverStyle(point);
  412. expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
  413. expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
  414. expect(point._model.borderWidth).toBe(2.1);
  415. expect(point._model.radius).toBe(250);
  416. // Custom style
  417. point.custom = {
  418. radius: 4.4,
  419. borderWidth: 5.5,
  420. backgroundColor: 'rgb(0, 0, 0)',
  421. borderColor: 'rgb(10, 10, 10)'
  422. };
  423. meta.controller.removeHoverStyle(point);
  424. expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
  425. expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
  426. expect(point._model.borderWidth).toBe(5.5);
  427. expect(point._model.radius).toBe(4.4);
  428. });
  429. });