controller.bar.tests.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. // Test the bar controller
  2. describe('Bar 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: 'bar',
  12. data: {
  13. datasets: [
  14. { data: [] },
  15. { data: [] }
  16. ],
  17. labels: []
  18. }
  19. });
  20. var meta = chart.getDatasetMeta(1);
  21. expect(meta.type).toEqual('bar');
  22. expect(meta.data).toEqual([]);
  23. expect(meta.hidden).toBe(null);
  24. expect(meta.controller).not.toBe(undefined);
  25. expect(meta.controller.index).toBe(1);
  26. expect(meta.xAxisID).not.toBe(null);
  27. expect(meta.yAxisID).not.toBe(null);
  28. meta.controller.updateIndex(0);
  29. expect(meta.controller.index).toBe(0);
  30. });
  31. it('should use the first scale IDs if the dataset does not specify them', function() {
  32. var chart = window.acquireChart({
  33. type: 'bar',
  34. data: {
  35. datasets: [
  36. { data: [] },
  37. { data: [] }
  38. ],
  39. labels: []
  40. },
  41. options: {
  42. scales: {
  43. xAxes: [{
  44. id: 'firstXScaleID'
  45. }],
  46. yAxes: [{
  47. id: 'firstYScaleID'
  48. }]
  49. }
  50. }
  51. });
  52. var meta = chart.getDatasetMeta(1);
  53. expect(meta.xAxisID).toBe('firstXScaleID');
  54. expect(meta.yAxisID).toBe('firstYScaleID');
  55. });
  56. it('should correctly count the number of bar datasets', function() {
  57. var chart = window.acquireChart({
  58. type: 'bar',
  59. data: {
  60. datasets: [
  61. { data: [], type: 'line' },
  62. { data: [], hidden: true },
  63. { data: [] },
  64. { data: [] }
  65. ],
  66. labels: []
  67. }
  68. });
  69. var meta = chart.getDatasetMeta(1);
  70. expect(meta.controller.getBarCount()).toBe(2);
  71. });
  72. it('should correctly get the bar index accounting for hidden datasets', function() {
  73. var chart = window.acquireChart({
  74. type: 'bar',
  75. data: {
  76. datasets: [
  77. { data: [] },
  78. { data: [], hidden: true },
  79. { data: [], type: 'line' },
  80. { data: [] }
  81. ],
  82. labels: []
  83. }
  84. });
  85. var meta = chart.getDatasetMeta(1);
  86. expect(meta.controller.getBarIndex(0)).toBe(0);
  87. expect(meta.controller.getBarIndex(3)).toBe(1);
  88. });
  89. it('should create rectangle elements for each data item during initialization', function() {
  90. var chart = window.acquireChart({
  91. type: 'bar',
  92. data: {
  93. datasets: [
  94. { data: [] },
  95. { data: [10, 15, 0, -4] }
  96. ],
  97. labels: []
  98. }
  99. });
  100. var meta = chart.getDatasetMeta(1);
  101. expect(meta.data.length).toBe(4); // 4 rectangles created
  102. expect(meta.data[0] instanceof Chart.elements.Rectangle).toBe(true);
  103. expect(meta.data[1] instanceof Chart.elements.Rectangle).toBe(true);
  104. expect(meta.data[2] instanceof Chart.elements.Rectangle).toBe(true);
  105. expect(meta.data[3] instanceof Chart.elements.Rectangle).toBe(true);
  106. });
  107. it('should update elements when modifying data', function() {
  108. var chart = window.acquireChart({
  109. type: 'bar',
  110. data: {
  111. datasets: [{
  112. data: [1, 2],
  113. label: 'dataset1'
  114. }, {
  115. data: [10, 15, 0, -4],
  116. label: 'dataset2',
  117. borderColor: 'blue'
  118. }],
  119. labels: ['label1', 'label2', 'label3', 'label4']
  120. },
  121. options: {
  122. elements: {
  123. rectangle: {
  124. backgroundColor: 'red',
  125. borderSkipped: 'top',
  126. borderColor: 'green',
  127. borderWidth: 2,
  128. }
  129. },
  130. scales: {
  131. xAxes: [{
  132. id: 'firstXScaleID',
  133. type: 'category'
  134. }],
  135. yAxes: [{
  136. id: 'firstYScaleID',
  137. type: 'linear'
  138. }]
  139. }
  140. }
  141. });
  142. var meta = chart.getDatasetMeta(1);
  143. expect(meta.data.length).toBe(4);
  144. chart.data.datasets[1].data = [1, 2]; // remove 2 items
  145. chart.data.datasets[1].borderWidth = 1;
  146. chart.update();
  147. expect(meta.data.length).toBe(2);
  148. [ { x: 122, y: 484 },
  149. { x: 234, y: 32 }
  150. ].forEach(function(expected, i) {
  151. expect(meta.data[i]._datasetIndex).toBe(1);
  152. expect(meta.data[i]._index).toBe(i);
  153. expect(meta.data[i]._xScale).toBe(chart.scales.firstXScaleID);
  154. expect(meta.data[i]._yScale).toBe(chart.scales.firstYScaleID);
  155. expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
  156. expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
  157. expect(meta.data[i]._model.base).toBeCloseToPixel(484);
  158. expect(meta.data[i]._model.width).toBeCloseToPixel(40);
  159. expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
  160. datasetLabel: chart.config.data.datasets[1].label,
  161. label: chart.config.data.labels[i],
  162. backgroundColor: 'red',
  163. borderSkipped: 'top',
  164. borderColor: 'blue',
  165. borderWidth: 1
  166. }));
  167. });
  168. chart.data.datasets[1].data = [1, 2, 3]; // add 1 items
  169. chart.update();
  170. expect(meta.data.length).toBe(3); // should add a new meta data item
  171. });
  172. it('should get the correct bar points when datasets of different types exist', function() {
  173. var chart = window.acquireChart({
  174. type: 'bar',
  175. data: {
  176. datasets: [{
  177. data: [1, 2],
  178. label: 'dataset1'
  179. }, {
  180. type: 'line',
  181. data: [4, 6],
  182. label: 'dataset2'
  183. }, {
  184. data: [8, 10],
  185. label: 'dataset3'
  186. }],
  187. labels: ['label1', 'label2']
  188. },
  189. options: {
  190. scales: {
  191. xAxes: [{
  192. type: 'category'
  193. }],
  194. yAxes: [{
  195. type: 'linear'
  196. }]
  197. }
  198. }
  199. });
  200. var meta = chart.getDatasetMeta(2);
  201. expect(meta.data.length).toBe(2);
  202. var bar1 = meta.data[0];
  203. var bar2 = meta.data[1];
  204. expect(bar1._model.x).toBeCloseToPixel(194);
  205. expect(bar1._model.y).toBeCloseToPixel(132);
  206. expect(bar2._model.x).toBeCloseToPixel(424);
  207. expect(bar2._model.y).toBeCloseToPixel(32);
  208. });
  209. it('should update elements when the scales are stacked', function() {
  210. var chart = window.acquireChart({
  211. type: 'bar',
  212. data: {
  213. datasets: [{
  214. data: [10, -10, 10, -10],
  215. label: 'dataset1'
  216. }, {
  217. data: [10, 15, 0, -4],
  218. label: 'dataset2'
  219. }],
  220. labels: ['label1', 'label2', 'label3', 'label4']
  221. },
  222. options: {
  223. scales: {
  224. xAxes: [{
  225. type: 'category',
  226. stacked: true
  227. }],
  228. yAxes: [{
  229. type: 'linear',
  230. stacked: true
  231. }]
  232. }
  233. }
  234. });
  235. var meta0 = chart.getDatasetMeta(0);
  236. [ { b: 290, w: 91, x: 95, y: 161 },
  237. { b: 290, w: 91, x: 209, y: 419 },
  238. { b: 290, w: 91, x: 322, y: 161 },
  239. { b: 290, w: 91, x: 436, y: 419 }
  240. ].forEach(function(values, i) {
  241. expect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);
  242. expect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);
  243. expect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);
  244. expect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);
  245. });
  246. var meta1 = chart.getDatasetMeta(1);
  247. [ { b: 161, w: 91, x: 95, y: 32 },
  248. { b: 290, w: 91, x: 209, y: 97 },
  249. { b: 161, w: 91, x: 322, y: 161 },
  250. { b: 419, w: 91, x: 436, y: 471 }
  251. ].forEach(function(values, i) {
  252. expect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);
  253. expect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);
  254. expect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);
  255. expect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);
  256. });
  257. });
  258. it('should draw all bars', function() {
  259. var chart = window.acquireChart({
  260. type: 'bar',
  261. data: {
  262. datasets: [{
  263. data: [],
  264. }, {
  265. data: [10, 15, 0, -4],
  266. label: 'dataset2'
  267. }],
  268. labels: ['label1', 'label2', 'label3', 'label4']
  269. }
  270. });
  271. var meta = chart.getDatasetMeta(1);
  272. spyOn(meta.data[0], 'draw');
  273. spyOn(meta.data[1], 'draw');
  274. spyOn(meta.data[2], 'draw');
  275. spyOn(meta.data[3], 'draw');
  276. chart.update();
  277. expect(meta.data[0].draw.calls.count()).toBe(1);
  278. expect(meta.data[1].draw.calls.count()).toBe(1);
  279. expect(meta.data[2].draw.calls.count()).toBe(1);
  280. expect(meta.data[3].draw.calls.count()).toBe(1);
  281. });
  282. it('should set hover styles on rectangles', function() {
  283. var chart = window.acquireChart({
  284. type: 'bar',
  285. data: {
  286. datasets: [{
  287. data: [],
  288. }, {
  289. data: [10, 15, 0, -4],
  290. label: 'dataset2'
  291. }],
  292. labels: ['label1', 'label2', 'label3', 'label4']
  293. },
  294. options: {
  295. elements: {
  296. rectangle: {
  297. backgroundColor: 'rgb(255, 0, 0)',
  298. borderColor: 'rgb(0, 0, 255)',
  299. borderWidth: 2,
  300. }
  301. }
  302. }
  303. });
  304. var meta = chart.getDatasetMeta(1);
  305. var bar = meta.data[0];
  306. meta.controller.setHoverStyle(bar);
  307. expect(bar._model.backgroundColor).toBe('rgb(230, 0, 0)');
  308. expect(bar._model.borderColor).toBe('rgb(0, 0, 230)');
  309. expect(bar._model.borderWidth).toBe(2);
  310. // Set a dataset style
  311. chart.data.datasets[1].hoverBackgroundColor = 'rgb(128, 128, 128)';
  312. chart.data.datasets[1].hoverBorderColor = 'rgb(0, 0, 0)';
  313. chart.data.datasets[1].hoverBorderWidth = 5;
  314. meta.controller.setHoverStyle(bar);
  315. expect(bar._model.backgroundColor).toBe('rgb(128, 128, 128)');
  316. expect(bar._model.borderColor).toBe('rgb(0, 0, 0)');
  317. expect(bar._model.borderWidth).toBe(5);
  318. // Should work with array styles so that we can set per bar
  319. chart.data.datasets[1].hoverBackgroundColor = ['rgb(255, 255, 255)', 'rgb(128, 128, 128)'];
  320. chart.data.datasets[1].hoverBorderColor = ['rgb(9, 9, 9)', 'rgb(0, 0, 0)'];
  321. chart.data.datasets[1].hoverBorderWidth = [2.5, 5];
  322. meta.controller.setHoverStyle(bar);
  323. expect(bar._model.backgroundColor).toBe('rgb(255, 255, 255)');
  324. expect(bar._model.borderColor).toBe('rgb(9, 9, 9)');
  325. expect(bar._model.borderWidth).toBe(2.5);
  326. // Should allow a custom style
  327. bar.custom = {
  328. hoverBackgroundColor: 'rgb(255, 0, 0)',
  329. hoverBorderColor: 'rgb(0, 255, 0)',
  330. hoverBorderWidth: 1.5
  331. };
  332. meta.controller.setHoverStyle(bar);
  333. expect(bar._model.backgroundColor).toBe('rgb(255, 0, 0)');
  334. expect(bar._model.borderColor).toBe('rgb(0, 255, 0)');
  335. expect(bar._model.borderWidth).toBe(1.5);
  336. });
  337. it('should remove a hover style from a bar', function() {
  338. var chart = window.acquireChart({
  339. type: 'bar',
  340. data: {
  341. datasets: [{
  342. data: [],
  343. }, {
  344. data: [10, 15, 0, -4],
  345. label: 'dataset2'
  346. }],
  347. labels: ['label1', 'label2', 'label3', 'label4']
  348. },
  349. options: {
  350. elements: {
  351. rectangle: {
  352. backgroundColor: 'rgb(255, 0, 0)',
  353. borderColor: 'rgb(0, 0, 255)',
  354. borderWidth: 2,
  355. }
  356. }
  357. }
  358. });
  359. var meta = chart.getDatasetMeta(1);
  360. var bar = meta.data[0];
  361. // Change default
  362. chart.options.elements.rectangle.backgroundColor = 'rgb(128, 128, 128)';
  363. chart.options.elements.rectangle.borderColor = 'rgb(15, 15, 15)';
  364. chart.options.elements.rectangle.borderWidth = 3.14;
  365. // Remove to defaults
  366. meta.controller.removeHoverStyle(bar);
  367. expect(bar._model.backgroundColor).toBe('rgb(128, 128, 128)');
  368. expect(bar._model.borderColor).toBe('rgb(15, 15, 15)');
  369. expect(bar._model.borderWidth).toBe(3.14);
  370. // Should work with array styles so that we can set per bar
  371. chart.data.datasets[1].backgroundColor = ['rgb(255, 255, 255)', 'rgb(128, 128, 128)'];
  372. chart.data.datasets[1].borderColor = ['rgb(9, 9, 9)', 'rgb(0, 0, 0)'];
  373. chart.data.datasets[1].borderWidth = [2.5, 5];
  374. meta.controller.removeHoverStyle(bar);
  375. expect(bar._model.backgroundColor).toBe('rgb(255, 255, 255)');
  376. expect(bar._model.borderColor).toBe('rgb(9, 9, 9)');
  377. expect(bar._model.borderWidth).toBe(2.5);
  378. // Should allow a custom style
  379. bar.custom = {
  380. backgroundColor: 'rgb(255, 0, 0)',
  381. borderColor: 'rgb(0, 255, 0)',
  382. borderWidth: 1.5
  383. };
  384. meta.controller.removeHoverStyle(bar);
  385. expect(bar._model.backgroundColor).toBe('rgb(255, 0, 0)');
  386. expect(bar._model.borderColor).toBe('rgb(0, 255, 0)');
  387. expect(bar._model.borderWidth).toBe(1.5);
  388. });
  389. });