controller.doughnut.tests.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. describe('Chart.controllers.doughnut', function() {
  2. it('should be constructed', function() {
  3. var chart = window.acquireChart({
  4. type: 'doughnut',
  5. data: {
  6. datasets: [{
  7. data: []
  8. }],
  9. labels: []
  10. }
  11. });
  12. var meta = chart.getDatasetMeta(0);
  13. expect(meta.type).toBe('doughnut');
  14. expect(meta.controller).not.toBe(undefined);
  15. expect(meta.controller.index).toBe(0);
  16. expect(meta.data).toEqual([]);
  17. meta.controller.updateIndex(1);
  18. expect(meta.controller.index).toBe(1);
  19. });
  20. it('should create arc elements for each data item during initialization', function() {
  21. var chart = window.acquireChart({
  22. type: 'doughnut',
  23. data: {
  24. datasets: [{
  25. data: [10, 15, 0, 4]
  26. }],
  27. labels: []
  28. }
  29. });
  30. var meta = chart.getDatasetMeta(0);
  31. expect(meta.data.length).toBe(4); // 4 rectangles created
  32. expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
  33. expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
  34. expect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);
  35. expect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);
  36. });
  37. it('should set the innerRadius to 0 if the config option is 0', function() {
  38. var chart = window.acquireChart({
  39. type: 'pie',
  40. data: {
  41. datasets: [{
  42. data: [10, 15, 0, 4]
  43. }],
  44. labels: []
  45. }
  46. });
  47. expect(chart.innerRadius).toBe(0);
  48. });
  49. it ('should reset and update elements', function() {
  50. var chart = window.acquireChart({
  51. type: 'doughnut',
  52. data: {
  53. datasets: [{
  54. data: [1, 2, 3, 4],
  55. hidden: true
  56. }, {
  57. data: [5, 6, 0, 7]
  58. }, {
  59. data: [8, 9, 10, 11]
  60. }],
  61. labels: ['label0', 'label1', 'label2', 'label3']
  62. },
  63. options: {
  64. legend: false,
  65. title: false,
  66. animation: {
  67. animateRotate: true,
  68. animateScale: false
  69. },
  70. cutoutPercentage: 50,
  71. rotation: Math.PI * -0.5,
  72. circumference: Math.PI * 2.0,
  73. elements: {
  74. arc: {
  75. backgroundColor: 'rgb(255, 0, 0)',
  76. borderColor: 'rgb(0, 0, 255)',
  77. borderWidth: 2
  78. }
  79. }
  80. }
  81. });
  82. var meta = chart.getDatasetMeta(1);
  83. meta.controller.reset(); // reset first
  84. expect(meta.data.length).toBe(4);
  85. [
  86. {c: 0},
  87. {c: 0},
  88. {c: 0},
  89. {c: 0}
  90. ].forEach(function(expected, i) {
  91. expect(meta.data[i]._model.x).toBeCloseToPixel(256);
  92. expect(meta.data[i]._model.y).toBeCloseToPixel(256);
  93. expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(254);
  94. expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(190);
  95. expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
  96. expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
  97. startAngle: Math.PI * -0.5,
  98. endAngle: Math.PI * -0.5,
  99. label: chart.data.labels[i],
  100. backgroundColor: 'rgb(255, 0, 0)',
  101. borderColor: 'rgb(0, 0, 255)',
  102. borderWidth: 2
  103. }));
  104. });
  105. chart.update();
  106. [
  107. {c: 1.7453292519, s: -1.5707963267, e: 0.1745329251},
  108. {c: 2.0943951023, s: 0.1745329251, e: 2.2689280275},
  109. {c: 0, s: 2.2689280275, e: 2.2689280275},
  110. {c: 2.4434609527, s: 2.2689280275, e: 4.7123889803}
  111. ].forEach(function(expected, i) {
  112. expect(meta.data[i]._model.x).toBeCloseToPixel(256);
  113. expect(meta.data[i]._model.y).toBeCloseToPixel(256);
  114. expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(254);
  115. expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(190);
  116. expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
  117. expect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);
  118. expect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);
  119. expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
  120. label: chart.data.labels[i],
  121. backgroundColor: 'rgb(255, 0, 0)',
  122. borderColor: 'rgb(0, 0, 255)',
  123. borderWidth: 2
  124. }));
  125. });
  126. // Change the amount of data and ensure that arcs are updated accordingly
  127. chart.data.datasets[1].data = [1, 2]; // remove 2 elements from dataset 0
  128. chart.update();
  129. expect(meta.data.length).toBe(2);
  130. expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
  131. expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
  132. // Add data
  133. chart.data.datasets[1].data = [1, 2, 3, 4];
  134. chart.update();
  135. expect(meta.data.length).toBe(4);
  136. expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
  137. expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
  138. expect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);
  139. expect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);
  140. });
  141. it ('should rotate and limit circumference', function() {
  142. var chart = window.acquireChart({
  143. type: 'doughnut',
  144. data: {
  145. datasets: [{
  146. data: [2, 4],
  147. hidden: true
  148. }, {
  149. data: [1, 3]
  150. }, {
  151. data: [1, 0]
  152. }],
  153. labels: ['label0', 'label1']
  154. },
  155. options: {
  156. legend: false,
  157. title: false,
  158. cutoutPercentage: 50,
  159. rotation: Math.PI,
  160. circumference: Math.PI * 0.5,
  161. elements: {
  162. arc: {
  163. backgroundColor: 'rgb(255, 0, 0)',
  164. borderColor: 'rgb(0, 0, 255)',
  165. borderWidth: 2
  166. }
  167. }
  168. }
  169. });
  170. var meta = chart.getDatasetMeta(1);
  171. expect(meta.data.length).toBe(2);
  172. // Only startAngle, endAngle and circumference should be different.
  173. [
  174. {c: Math.PI / 8, s: Math.PI, e: Math.PI + Math.PI / 8},
  175. {c: 3 * Math.PI / 8, s: Math.PI + Math.PI / 8, e: Math.PI + Math.PI / 2}
  176. ].forEach(function(expected, i) {
  177. expect(meta.data[i]._model.x).toBeCloseToPixel(510);
  178. expect(meta.data[i]._model.y).toBeCloseToPixel(510);
  179. expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(509);
  180. expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(381);
  181. expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
  182. expect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);
  183. expect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);
  184. });
  185. });
  186. it('should treat negative values as positive', function() {
  187. var chart = window.acquireChart({
  188. type: 'doughnut',
  189. data: {
  190. datasets: [{
  191. data: [-1, -3]
  192. }],
  193. labels: ['label0', 'label1']
  194. },
  195. options: {
  196. legend: false,
  197. title: false,
  198. cutoutPercentage: 50,
  199. rotation: Math.PI,
  200. circumference: Math.PI * 0.5,
  201. elements: {
  202. arc: {
  203. backgroundColor: 'rgb(255, 0, 0)',
  204. borderColor: 'rgb(0, 0, 255)',
  205. borderWidth: 2
  206. }
  207. }
  208. }
  209. });
  210. var meta = chart.getDatasetMeta(0);
  211. expect(meta.data.length).toBe(2);
  212. // Only startAngle, endAngle and circumference should be different.
  213. [
  214. {c: Math.PI / 8, s: Math.PI, e: Math.PI + Math.PI / 8},
  215. {c: 3 * Math.PI / 8, s: Math.PI + Math.PI / 8, e: Math.PI + Math.PI / 2}
  216. ].forEach(function(expected, i) {
  217. expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
  218. expect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);
  219. expect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);
  220. });
  221. });
  222. it ('should draw all arcs', function() {
  223. var chart = window.acquireChart({
  224. type: 'doughnut',
  225. data: {
  226. datasets: [{
  227. data: [10, 15, 0, 4]
  228. }],
  229. labels: ['label0', 'label1', 'label2', 'label3']
  230. }
  231. });
  232. var meta = chart.getDatasetMeta(0);
  233. spyOn(meta.data[0], 'draw');
  234. spyOn(meta.data[1], 'draw');
  235. spyOn(meta.data[2], 'draw');
  236. spyOn(meta.data[3], 'draw');
  237. chart.update();
  238. expect(meta.data[0].draw.calls.count()).toBe(1);
  239. expect(meta.data[1].draw.calls.count()).toBe(1);
  240. expect(meta.data[2].draw.calls.count()).toBe(1);
  241. expect(meta.data[3].draw.calls.count()).toBe(1);
  242. });
  243. it ('should set the hover style of an arc', function() {
  244. var chart = window.acquireChart({
  245. type: 'doughnut',
  246. data: {
  247. datasets: [{
  248. data: [10, 15, 0, 4]
  249. }],
  250. labels: ['label0', 'label1', 'label2', 'label3']
  251. },
  252. options: {
  253. elements: {
  254. arc: {
  255. backgroundColor: 'rgb(255, 0, 0)',
  256. borderColor: 'rgb(0, 0, 255)',
  257. borderWidth: 2,
  258. }
  259. }
  260. }
  261. });
  262. var meta = chart.getDatasetMeta(0);
  263. var arc = meta.data[0];
  264. meta.controller.setHoverStyle(arc);
  265. expect(arc._model.backgroundColor).toBe('rgb(230, 0, 0)');
  266. expect(arc._model.borderColor).toBe('rgb(0, 0, 230)');
  267. expect(arc._model.borderWidth).toBe(2);
  268. // Set a dataset style to take precedence
  269. chart.data.datasets[0].hoverBackgroundColor = 'rgb(9, 9, 9)';
  270. chart.data.datasets[0].hoverBorderColor = 'rgb(18, 18, 18)';
  271. chart.data.datasets[0].hoverBorderWidth = 1.56;
  272. meta.controller.setHoverStyle(arc);
  273. expect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)');
  274. expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
  275. expect(arc._model.borderWidth).toBe(1.56);
  276. // Dataset styles can be an array
  277. chart.data.datasets[0].hoverBackgroundColor = ['rgb(255, 255, 255)', 'rgb(9, 9, 9)'];
  278. chart.data.datasets[0].hoverBorderColor = ['rgb(18, 18, 18)'];
  279. chart.data.datasets[0].hoverBorderWidth = [0.1, 1.56];
  280. meta.controller.setHoverStyle(arc);
  281. expect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)');
  282. expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
  283. expect(arc._model.borderWidth).toBe(0.1);
  284. // Element custom styles also work
  285. arc.custom = {
  286. hoverBackgroundColor: 'rgb(7, 7, 7)',
  287. hoverBorderColor: 'rgb(17, 17, 17)',
  288. hoverBorderWidth: 3.14159,
  289. };
  290. meta.controller.setHoverStyle(arc);
  291. expect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)');
  292. expect(arc._model.borderColor).toBe('rgb(17, 17, 17)');
  293. expect(arc._model.borderWidth).toBe(3.14159);
  294. });
  295. it ('should unset the hover style of an arc', function() {
  296. var chart = window.acquireChart({
  297. type: 'doughnut',
  298. data: {
  299. datasets: [{
  300. data: [10, 15, 0, 4]
  301. }],
  302. labels: ['label0', 'label1', 'label2', 'label3']
  303. },
  304. options: {
  305. elements: {
  306. arc: {
  307. backgroundColor: 'rgb(255, 0, 0)',
  308. borderColor: 'rgb(0, 0, 255)',
  309. borderWidth: 2,
  310. }
  311. }
  312. }
  313. });
  314. var meta = chart.getDatasetMeta(0);
  315. var arc = meta.data[0];
  316. meta.controller.removeHoverStyle(arc);
  317. expect(arc._model.backgroundColor).toBe('rgb(255, 0, 0)');
  318. expect(arc._model.borderColor).toBe('rgb(0, 0, 255)');
  319. expect(arc._model.borderWidth).toBe(2);
  320. // Set a dataset style to take precedence
  321. chart.data.datasets[0].backgroundColor = 'rgb(9, 9, 9)';
  322. chart.data.datasets[0].borderColor = 'rgb(18, 18, 18)';
  323. chart.data.datasets[0].borderWidth = 1.56;
  324. meta.controller.removeHoverStyle(arc);
  325. expect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)');
  326. expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
  327. expect(arc._model.borderWidth).toBe(1.56);
  328. // Dataset styles can be an array
  329. chart.data.datasets[0].backgroundColor = ['rgb(255, 255, 255)', 'rgb(9, 9, 9)'];
  330. chart.data.datasets[0].borderColor = ['rgb(18, 18, 18)'];
  331. chart.data.datasets[0].borderWidth = [0.1, 1.56];
  332. meta.controller.removeHoverStyle(arc);
  333. expect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)');
  334. expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
  335. expect(arc._model.borderWidth).toBe(0.1);
  336. // Element custom styles also work
  337. arc.custom = {
  338. backgroundColor: 'rgb(7, 7, 7)',
  339. borderColor: 'rgb(17, 17, 17)',
  340. borderWidth: 3.14159,
  341. };
  342. meta.controller.removeHoverStyle(arc);
  343. expect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)');
  344. expect(arc._model.borderColor).toBe('rgb(17, 17, 17)');
  345. expect(arc._model.borderWidth).toBe(3.14159);
  346. });
  347. });