SpriteLegend.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. /* global Ext, expect */
  2. topSuite("Ext.chart.legend.SpriteLegend", ['Ext.chart.*', 'Ext.data.ArrayStore'], function() {
  3. function generateStoreData(pointCount) {
  4. var data = [
  5. { month: 'Jan' },
  6. { month: 'Feb' },
  7. { month: 'Mar' },
  8. { month: 'Apr' },
  9. { month: 'May' },
  10. { month: 'Jun' },
  11. { month: 'Jul' },
  12. { month: 'Aug' },
  13. { month: 'Sep' },
  14. { month: 'Oct' },
  15. { month: 'Nov' },
  16. { month: 'Dec' }
  17. ],
  18. i = 0,
  19. j = 0,
  20. ln = data.length,
  21. entry;
  22. for (; i < ln; i++) {
  23. entry = data[i];
  24. for (j = 0; j < pointCount; j++) {
  25. entry['data' + (j + 1).toString()] = Math.random() * 10;
  26. }
  27. }
  28. return data;
  29. }
  30. beforeEach(function() {
  31. // Silence Sencha download server warnings
  32. spyOn(Ext.log, 'warn');
  33. });
  34. describe('markers', function () {
  35. var chart;
  36. afterEach(function () {
  37. Ext.destroy(chart);
  38. });
  39. it('should be visible even if the series markers are hidden', function () {
  40. var layoutDone;
  41. runs(function () {
  42. chart = new Ext.chart.CartesianChart({
  43. renderTo: Ext.getBody(),
  44. width: 300,
  45. height: 300,
  46. store: {
  47. data: [
  48. { x: 1, y: 1 },
  49. { x: 2, y: 3 },
  50. { x: 3, y: 1 }
  51. ]
  52. },
  53. axes: [
  54. {
  55. type: 'numeric',
  56. position: 'left'
  57. },
  58. {
  59. type: 'numeric',
  60. position: 'bottom'
  61. }
  62. ],
  63. series: [{
  64. showMarkers: false,
  65. marker: {
  66. type: 'square'
  67. },
  68. type: 'line',
  69. xField: 'x',
  70. yField: 'y'
  71. }],
  72. legend: true,
  73. listeners: {
  74. layout: function () {
  75. layoutDone = true;
  76. }
  77. }
  78. });
  79. });
  80. waitsFor(function () {
  81. return layoutDone;
  82. });
  83. runs(function () {
  84. var sprite = chart.getLegend().getSprites()[0];
  85. expect(sprite.getMarker().attr.hidden).toBe(false);
  86. });
  87. });
  88. });
  89. describe('docked', function () {
  90. var chart;
  91. afterEach(function () {
  92. Ext.destroy(chart);
  93. });
  94. it('should position the sprite legend properly', function () {
  95. var side = 400,
  96. layoutDone,
  97. legendSpriteCount,
  98. legendSpriteIds;
  99. chart = new Ext.chart.CartesianChart({
  100. renderTo: Ext.getBody(),
  101. width: side,
  102. height: side,
  103. store: {
  104. data: [
  105. { x: 1, y: 1 },
  106. { x: 2, y: 3 },
  107. { x: 3, y: 1 }
  108. ]
  109. },
  110. axes: [
  111. {
  112. type: 'numeric',
  113. position: 'left'
  114. },
  115. {
  116. type: 'category',
  117. position: 'bottom'
  118. }
  119. ],
  120. series: {
  121. type: 'bar',
  122. xField: 'x',
  123. yField: 'y'
  124. },
  125. listeners: {
  126. layout: function () {
  127. layoutDone = true;
  128. }
  129. }
  130. });
  131. waitsFor(function () {
  132. return layoutDone;
  133. });
  134. runs(function () {
  135. chart.setLegend({
  136. type: 'sprite',
  137. docked: 'top'
  138. });
  139. layoutDone = false;
  140. });
  141. waitsFor(function () {
  142. return layoutDone;
  143. });
  144. runs(function () {
  145. // docked: 'top'
  146. var chartRect = chart.getChartRect(),
  147. legend = chart.getLegend(),
  148. legendSize = legend.getSize(),
  149. legendSurface = legend.getSurface(),
  150. legendSprites = legendSurface.getItems(),
  151. legendRect = legendSurface.getRect();
  152. expect(chartRect[0]).toBe(0);
  153. expect(chartRect[1]).toBe(legendSize.height);
  154. expect(chartRect[2]).toBe(side);
  155. expect(chartRect[3]).toBe(side - legendSize.height);
  156. expect(legendRect[0]).toBe(0);
  157. expect(legendRect[1]).toBe(0);
  158. expect(legendRect[2]).toBe(side);
  159. expect(legendRect[3]).toBe(legendSize.height);
  160. legendSpriteCount = legendSprites.length;
  161. // Don't want to be too specific here, as the number of sprites may change
  162. // in the future, but there must be something there.
  163. expect(legendSpriteCount).toBeGreaterThan(0);
  164. legendSpriteIds = {};
  165. for (var i = 0; i < legendSpriteCount; i++) {
  166. legendSpriteIds[legendSprites[i].getId()] = true;
  167. }
  168. chart.setLegend({
  169. type: 'sprite',
  170. docked: 'top' // that's not a mistake, setting again to 'top'
  171. });
  172. layoutDone = false;
  173. });
  174. waitsFor(function () {
  175. return layoutDone;
  176. });
  177. runs(function () {
  178. // docked: 'top'
  179. var chartRect = chart.getChartRect(),
  180. legend = chart.getLegend(),
  181. legendSize = legend.getSize(),
  182. legendSurface = legend.getSurface(),
  183. legendSprites = legendSurface.getItems(),
  184. legendRect = legendSurface.getRect();
  185. // Sprites from the previous legend should not remain in the chart's
  186. // 'legend' surface. We should get the same number of sprites, not double
  187. // the sprites ...
  188. expect(legendSprites.length).toBe(legendSpriteCount);
  189. // ... and those sprites should be all different.
  190. for (var i = 0; i < legendSpriteCount; i++) {
  191. expect(legendSprites[i].getId() in legendSpriteIds).toBe(false);
  192. }
  193. expect(chartRect[0]).toBe(0);
  194. expect(chartRect[1]).toBe(legendSize.height);
  195. expect(chartRect[2]).toBe(side);
  196. expect(chartRect[3]).toBe(side - legendSize.height);
  197. expect(legendRect[0]).toBe(0);
  198. expect(legendRect[1]).toBe(0);
  199. expect(legendRect[2]).toBe(side);
  200. expect(legendRect[3]).toBe(legendSize.height);
  201. chart.setLegend({
  202. type: 'sprite',
  203. docked: 'right'
  204. });
  205. layoutDone = false;
  206. });
  207. waitsFor(function () {
  208. return layoutDone;
  209. });
  210. runs(function () {
  211. // docked: 'right'
  212. var chartRect = chart.getChartRect(),
  213. legend = chart.getLegend(),
  214. legendSize = legend.getSize(),
  215. legendRect = legend.getSurface().getRect();
  216. expect(chartRect[0]).toBe(0);
  217. expect(chartRect[1]).toBe(0);
  218. expect(chartRect[2]).toBe(side - legendSize.width);
  219. expect(chartRect[3]).toBe(side);
  220. expect(legendRect[0]).toBe(side - legendSize.width);
  221. expect(legendRect[1]).toBe(0);
  222. expect(legendRect[2]).toBe(legendSize.width);
  223. expect(legendRect[3]).toBe(side);
  224. chart.setLegend({
  225. type: 'sprite',
  226. docked: 'bottom'
  227. });
  228. layoutDone = false;
  229. });
  230. waitsFor(function () {
  231. return layoutDone;
  232. });
  233. runs(function () {
  234. // docked: 'bottom'
  235. var chartRect = chart.getChartRect(),
  236. legend = chart.getLegend(),
  237. legendSize = legend.getSize(),
  238. legendRect = legend.getSurface().getRect();
  239. expect(chartRect[0]).toBe(0);
  240. expect(chartRect[1]).toBe(0);
  241. expect(chartRect[2]).toBe(side);
  242. expect(chartRect[3]).toBe(side - legendSize.height);
  243. expect(legendRect[0]).toBe(0);
  244. expect(legendRect[1]).toBe(side - legendSize.height);
  245. expect(legendRect[2]).toBe(side);
  246. expect(legendRect[3]).toBe(legendSize.height);
  247. chart.setLegend({
  248. type: 'sprite',
  249. docked: 'left'
  250. });
  251. layoutDone = false;
  252. });
  253. waitsFor(function () {
  254. return layoutDone;
  255. });
  256. runs(function () {
  257. // docked: 'left'
  258. var chartRect = chart.getChartRect(),
  259. legend = chart.getLegend(),
  260. legendSize = legend.getSize(),
  261. legendRect = legend.getSurface().getRect();
  262. expect(chartRect[0]).toBe(legendSize.width);
  263. expect(chartRect[1]).toBe(0);
  264. expect(chartRect[2]).toBe(side - legendSize.width);
  265. expect(chartRect[3]).toBe(side);
  266. expect(legendRect[0]).toBe(0);
  267. expect(legendRect[1]).toBe(0);
  268. expect(legendRect[2]).toBe(legendSize.width);
  269. expect(legendRect[3]).toBe(side);
  270. chart.setLegend(null);
  271. layoutDone = false;
  272. });
  273. waitsFor(function () {
  274. return layoutDone;
  275. });
  276. runs(function () {
  277. // legend: null
  278. var chartRect = chart.getChartRect();
  279. expect(chartRect[0]).toBe(0);
  280. expect(chartRect[1]).toBe(0);
  281. expect(chartRect[2]).toBe(side);
  282. expect(chartRect[3]).toBe(side);
  283. chart.setLegend({
  284. type: 'sprite',
  285. docked: 'right' // creating ...
  286. });
  287. layoutDone = false;
  288. });
  289. waitsFor(function () {
  290. return layoutDone;
  291. });
  292. runs(function () {
  293. var legend = chart.getLegend(),
  294. legendSurface = legend.getSurface();
  295. expect(legendSurface.getHidden()).toBe(false);
  296. chart.getLegend().setHidden(true); // ... and hiding
  297. layoutDone = false;
  298. });
  299. waitsFor(function () {
  300. return layoutDone;
  301. });
  302. runs(function () {
  303. // docked: 'right',
  304. // hidden: true
  305. var chartRect = chart.getChartRect(),
  306. legend = chart.getLegend(),
  307. legendSurface = legend.getSurface();
  308. expect(chartRect[0]).toBe(0);
  309. expect(chartRect[1]).toBe(0);
  310. expect(chartRect[2]).toBe(side);
  311. expect(chartRect[3]).toBe(side);
  312. expect(legendSurface.getHidden()).toBe(true);
  313. chart.getLegend().setHidden(false);
  314. layoutDone = false;
  315. });
  316. waitsFor(function () {
  317. return layoutDone;
  318. });
  319. runs(function () {
  320. // docked: 'right',
  321. // hidden: false
  322. var chartRect = chart.getChartRect(),
  323. legend = chart.getLegend(),
  324. legendSize = legend.getSize(),
  325. legendSurface = legend.getSurface();
  326. expect(chartRect[0]).toBe(0);
  327. expect(chartRect[1]).toBe(0);
  328. expect(chartRect[2]).toBe(side - legendSize.width);
  329. expect(chartRect[3]).toBe(side);
  330. expect(legendSurface.getHidden()).toBe(false);
  331. chart.setLegend({
  332. type: 'sprite',
  333. docked: 'right',
  334. hidden: true // creating already hidden
  335. });
  336. layoutDone = false;
  337. });
  338. waitsFor(function () {
  339. return layoutDone;
  340. });
  341. runs(function () {
  342. // docked: 'right',
  343. // hidden: true
  344. var chartRect = chart.getChartRect(),
  345. legend = chart.getLegend(),
  346. legendSurface = legend.getSurface();
  347. expect(chartRect[0]).toBe(0);
  348. expect(chartRect[1]).toBe(0);
  349. expect(chartRect[2]).toBe(side);
  350. expect(chartRect[3]).toBe(side);
  351. expect(legendSurface.getHidden()).toBe(true);
  352. });
  353. });
  354. });
  355. describe("updateTheme", function () {
  356. var storeData = generateStoreData(2);
  357. var chartConfig = {
  358. animation: false,
  359. width: 400,
  360. height: 300,
  361. renderTo: document.body,
  362. axes: [{
  363. type: 'numeric',
  364. position: 'left',
  365. adjustByMajorUnit: true,
  366. grid: true,
  367. fields: ['data1'],
  368. minimum: 0
  369. }, {
  370. type: 'category',
  371. position: 'bottom',
  372. grid: true,
  373. fields: ['month'],
  374. label: {
  375. rotate: {
  376. degrees: -45
  377. }
  378. }
  379. }],
  380. series: [{
  381. type: 'bar',
  382. title: [ 'IE', 'Firefox' ],
  383. xField: 'month',
  384. yField: [ 'data1', 'data2' ],
  385. stacked: true,
  386. style: {
  387. opacity: 0.80
  388. },
  389. highlight: {
  390. fillStyle: 'yellow'
  391. }
  392. }]
  393. };
  394. var store, chart;
  395. beforeEach(function () {
  396. store = new Ext.data.Store({
  397. fields: [ 'month', 'data1', 'data2' ],
  398. data: storeData
  399. });
  400. });
  401. afterEach(function () {
  402. Ext.destroy(chart, store);
  403. });
  404. it("should use the style from the theme, " +
  405. "if the user hasn't provided their own config", function () {
  406. var CustomTheme = Ext.define(null, {
  407. extend: 'Ext.chart.theme.Base',
  408. singleton: true,
  409. config: {
  410. legend: {
  411. label: {
  412. fontSize: 15,
  413. fontWeight: 'bold',
  414. fontFamily: 'Tahoma',
  415. fillStyle: '#ff0000'
  416. },
  417. border: {
  418. lineWidth: 2,
  419. radius: 5,
  420. fillStyle: '#ffff00',
  421. strokeStyle: '#ff0000'
  422. }
  423. }
  424. }
  425. });
  426. var config = Ext.merge({
  427. theme: new CustomTheme,
  428. store: store,
  429. legend: {
  430. type: 'sprite',
  431. docked: 'top'
  432. }
  433. }, chartConfig);
  434. chart = new Ext.chart.CartesianChart(config);
  435. var legend = chart.getLegend();
  436. var borderSprite = legend.getBorder();
  437. var itemSprites = legend.getSprites();
  438. expect(borderSprite.attr.lineWidth).toBe(2);
  439. expect(borderSprite.attr.radius).toBe(5);
  440. expect(borderSprite.attr.fillStyle).toBe('#ffff00');
  441. expect(borderSprite.attr.strokeStyle).toBe('#ff0000');
  442. for (var i = 0, ln = itemSprites.length; i < ln; i++) {
  443. var label = itemSprites[i].getLabel();
  444. expect(label.attr.fontSize).toBe('15px');
  445. expect(label.attr.fontWeight).toBe('bold');
  446. expect(label.attr.fontFamily).toBe('Tahoma');
  447. expect(label.attr.fillStyle).toBe('#ff0000');
  448. }
  449. });
  450. it("should should use the style from the user config, if it was provided", function () {
  451. var config = Ext.merge({
  452. store: store,
  453. legend: {
  454. type: 'sprite',
  455. docked: 'top',
  456. label: {
  457. fontSize: 15,
  458. fontWeight: 'bold',
  459. fontFamily: 'Tahoma',
  460. fillStyle: '#ff0000'
  461. },
  462. border: {
  463. lineWidth: 2,
  464. radius: 5,
  465. fillStyle: '#ffff00',
  466. strokeStyle: '#ff0000'
  467. }
  468. }
  469. }, chartConfig);
  470. chart = new Ext.chart.CartesianChart(config);
  471. var legend = chart.getLegend();
  472. var borderSprite = legend.getBorder();
  473. var itemSprites = legend.getSprites();
  474. expect(borderSprite.attr.lineWidth).toBe(2);
  475. expect(borderSprite.attr.radius).toBe(5);
  476. expect(borderSprite.attr.fillStyle).toBe('#ffff00');
  477. expect(borderSprite.attr.strokeStyle).toBe('#ff0000');
  478. for (var i = 0, ln = itemSprites.length; i < ln; i++) {
  479. var label = itemSprites[i].getLabel();
  480. expect(label.attr.fontSize).toBe('15px');
  481. expect(label.attr.fontWeight).toBe('bold');
  482. expect(label.attr.fontFamily).toBe('Tahoma');
  483. expect(label.attr.fillStyle).toBe('#ff0000');
  484. }
  485. });
  486. });
  487. // Safari 7 times out here in Modern for unknown reason in TeamCity only.
  488. // Works fine locally (tested in Safari 7.0 (9537.71).
  489. TODO(Ext.isSafari7).
  490. describe("store", function () {
  491. var storeData = generateStoreData(4),
  492. store, chart, legend;
  493. beforeEach(function () {
  494. var layoutEndSpy;
  495. store = new Ext.data.Store({
  496. fields: [ 'month', 'data1', 'data2', 'data3', 'data4' ],
  497. data: storeData
  498. });
  499. chart = new Ext.chart.CartesianChart({
  500. animation: false,
  501. width: 400,
  502. height: 300,
  503. renderTo: document.body,
  504. store: store,
  505. legend: {
  506. type: 'sprite',
  507. docked: 'top'
  508. },
  509. axes: [{
  510. type: 'numeric',
  511. position: 'left',
  512. adjustByMajorUnit: true,
  513. grid: true,
  514. fields: ['data1'],
  515. minimum: 0
  516. }, {
  517. type: 'category',
  518. position: 'bottom',
  519. grid: true,
  520. fields: ['month'],
  521. label: {
  522. rotate: {
  523. degrees: -45
  524. }
  525. }
  526. }],
  527. series: [{
  528. type: 'bar',
  529. title: [ 'IE', 'Firefox', 'Chrome', 'Safari' ],
  530. xField: 'month',
  531. yField: [ 'data1', 'data2', 'data3', 'data4' ],
  532. stacked: true,
  533. style: {
  534. opacity: 0.80
  535. },
  536. highlight: {
  537. fillStyle: 'yellow'
  538. }
  539. }]
  540. });
  541. legend = chart.getLegend();
  542. layoutEndSpy = spyOn(chart, 'onLayoutEnd').andCallThrough();
  543. waitsForSpy(layoutEndSpy, "chart layout to finish");
  544. });
  545. afterEach(function () {
  546. Ext.destroy(chart, store);
  547. });
  548. it("should trigger sprite/layout update on data update", function () {
  549. var series = chart.getSeries()[0],
  550. oldBorderWidth, newBorderWidth,
  551. oldSecondItem, oldSecondItemX, newSecondItem, newSecondItemX;
  552. runs(function () {
  553. oldBorderWidth = legend.borderSprite.getBBox().width;
  554. oldSecondItem = legend.getSprites()[1];
  555. oldSecondItemX = oldSecondItem.getBBox().x;
  556. expect(oldSecondItemX > 0).toBe(true);
  557. series.setTitle([ 'Edge', 'Firewall', 'Cross', 'Savanna' ]);
  558. });
  559. // Wait for the required test conditions to become true
  560. waitsFor(function () {
  561. newBorderWidth = legend.borderSprite.getBBox().width;
  562. newSecondItem = legend.getSprites()[1];
  563. newSecondItemX = newSecondItem.getBBox().x;
  564. return newBorderWidth > oldBorderWidth &&
  565. newSecondItem === oldSecondItem &&
  566. newSecondItem.getLabel().attr.text === 'Firewall' &&
  567. newSecondItemX > oldSecondItemX;
  568. });
  569. });
  570. it("should trigger sprite/layout update on data change", function () {
  571. var series = chart.getSeries()[0],
  572. oldBorderWidth, newBorderWidth,
  573. oldSecondItem, oldSecondItemX, newSecondItem, newSecondItemX;
  574. runs(function () {
  575. oldBorderWidth = legend.borderSprite.getBBox().width;
  576. oldSecondItem = legend.getSprites()[1];
  577. oldSecondItemX = oldSecondItem.getBBox().x;
  578. expect(oldSecondItemX > 0).toBe(true);
  579. series.setTitle([ 'IE', 'Chrome', 'Safari' ]);
  580. });
  581. // Wait for the required test conditions to become true
  582. waitsFor(function () {
  583. newBorderWidth = legend.borderSprite.getBBox().width;
  584. newSecondItem = legend.getSprites()[1];
  585. newSecondItemX = newSecondItem.getBBox().x;
  586. return newBorderWidth < oldBorderWidth &&
  587. // The sprite should be reused.
  588. newSecondItem === oldSecondItem &&
  589. newSecondItem.getLabel().attr.text === 'Chrome' &&
  590. legend.getSprites().length === 4 &&
  591. // The second sprite now displays the third title ('Chrome'),
  592. // but because the whole legend is centered, it should actually
  593. // move to the right, as there is now one less item.
  594. newSecondItemX > oldSecondItemX &&
  595. legend.getSprites()[3].getLabel().attr.text === 'data4';
  596. });
  597. });
  598. it("should trigger sprite/layout update on data sort", function () {
  599. var oldBorderWidth, newBorderWidth,
  600. performLayoutSpy = spyOn(legend, 'performLayout').andCallThrough(),
  601. sprites = legend.getSprites();
  602. function checkPositions(sprites) {
  603. expect(sprites[0].getBBox().x < sprites[1].getBBox().x).toBe(true);
  604. expect(sprites[1].getBBox().x < sprites[2].getBBox().x).toBe(true);
  605. expect(sprites[2].getBBox().x < sprites[3].getBBox().x).toBe(true);
  606. }
  607. runs(function () {
  608. // Initial positions:
  609. // IE - Firefox - Chrome - Safari
  610. checkPositions(sprites);
  611. oldBorderWidth = legend.borderSprite.getBBox().width;
  612. chart.legendStore.sort('name', 'DESC');
  613. performLayoutSpy.reset();
  614. });
  615. waitsForSpy(performLayoutSpy, "legend layout to finish after DESC sort");
  616. runs(function () {
  617. newBorderWidth = legend.borderSprite.getBBox().width;
  618. // Relative positions of the sprites should stay the same.
  619. checkPositions(sprites);
  620. // The sum of all sprite widths should stay the same,
  621. // and thus the legend border width too.
  622. // Safari - IE - Firefox - Chrome
  623. expect(sprites[0].getLabel().attr.text).toBe('Safari');
  624. expect(sprites[1].getLabel().attr.text).toBe('IE');
  625. expect(sprites[2].getLabel().attr.text).toBe('Firefox');
  626. expect(sprites[3].getLabel().attr.text).toBe('Chrome');
  627. chart.legendStore.sort('name', 'ASC');
  628. performLayoutSpy.reset();
  629. });
  630. waitsForSpy(performLayoutSpy, "legend layout to finish after ASC sort");
  631. runs(function() {
  632. // Relative positions of the sprites should stay the same.
  633. checkPositions(sprites);
  634. // Chrome - Firefox - IE - Safari
  635. expect(sprites[0].getLabel().attr.text).toBe('Chrome');
  636. expect(sprites[1].getLabel().attr.text).toBe('Firefox');
  637. expect(sprites[2].getLabel().attr.text).toBe('IE');
  638. expect(sprites[3].getLabel().attr.text).toBe('Safari');
  639. });
  640. });
  641. });
  642. describe('series colors', function () {
  643. var chart, layoutEnd;
  644. var colors1 = ['red', 'blue', 'green', 'orange', 'yellow'];
  645. var colors2 = ['gold', 'cyan', 'magenta', 'lime', 'navy'];
  646. var n = colors1.length;
  647. var data = (function () {
  648. var data = [];
  649. for (var i = 0; i < n; i++) {
  650. var point = {
  651. x: 'cat' + (i+1)
  652. };
  653. for (var j = 0; j < n; j++) {
  654. point['y' + (j+1)] = j+1;
  655. }
  656. data.push(point);
  657. }
  658. return data;
  659. })();
  660. afterEach(function () {
  661. chart = Ext.destroy(chart);
  662. layoutEnd = false;
  663. });
  664. it('should use theme colors in a cartesian (bar) chart', function () {
  665. runs(function () {
  666. chart = Ext.create({
  667. xtype: 'cartesian',
  668. animation: false,
  669. renderTo: document.body,
  670. width: 400,
  671. height: 400,
  672. store: {
  673. data: data.slice()
  674. },
  675. legend: {
  676. type: 'sprite',
  677. docked: 'right'
  678. },
  679. series: [{
  680. type: 'bar',
  681. xField: 'x',
  682. yField: ['y1', 'y2', 'y3', 'y4', 'y5']
  683. }],
  684. listeners: {
  685. layout: function () {
  686. layoutEnd = true;
  687. }
  688. }
  689. });
  690. });
  691. waitsFor(function () {
  692. return layoutEnd;
  693. });
  694. runs(function () {
  695. var series = chart.getSeries()[0],
  696. seriesSprites = series.getSprites(),
  697. legendSprites = chart.getLegend().getSprites(),
  698. themeColors = chart.getTheme().getColors();
  699. for (var i = 0; i < n; i++) {
  700. expect(seriesSprites[i].attr.fillStyle).toBe(themeColors[i]);
  701. expect(legendSprites[i].getMarker().attr.fillStyle).toBe(themeColors[i]);
  702. }
  703. });
  704. });
  705. it('should use theme colors in a polar (pie3d) chart', function () {
  706. runs(function () {
  707. chart = Ext.create({
  708. xtype: 'polar',
  709. animation: false,
  710. renderTo: document.body,
  711. width: 400,
  712. height: 400,
  713. store: {
  714. data: data.slice()
  715. },
  716. legend: {
  717. type: 'sprite',
  718. docked: 'right'
  719. },
  720. series: [{
  721. type: 'pie3d',
  722. angleField: 'y1',
  723. label: {
  724. field: 'x'
  725. }
  726. }],
  727. listeners: {
  728. layout: function () {
  729. layoutEnd = true;
  730. }
  731. }
  732. });
  733. });
  734. waitsFor(function () {
  735. return layoutEnd;
  736. });
  737. runs(function () {
  738. var series = chart.getSeries()[0],
  739. seriesSprites = series.getSprites(),
  740. legendSprites = chart.getLegend().getSprites(),
  741. themeColors = chart.getTheme().getColors();
  742. for (var i = 0; i < n; i++) {
  743. expect(seriesSprites[i * series.spritesPerSlice].attr.baseColor).toBe(themeColors[i]);
  744. expect(legendSprites[i].getMarker().attr.fillStyle).toBe(themeColors[i]);
  745. }
  746. });
  747. });
  748. it('should use colors from the series "colors" config (cartesian, bar)', function () {
  749. runs(function () {
  750. chart = Ext.create({
  751. xtype: 'cartesian',
  752. animation: false,
  753. renderTo: document.body,
  754. width: 400,
  755. height: 400,
  756. store: {
  757. data: data.slice()
  758. },
  759. legend: {
  760. type: 'sprite',
  761. docked: 'right'
  762. },
  763. series: [{
  764. type: 'bar',
  765. xField: 'x',
  766. yField: ['y1', 'y2', 'y3', 'y4', 'y5'],
  767. colors: colors1.slice()
  768. }],
  769. listeners: {
  770. layout: function () {
  771. layoutEnd = true;
  772. }
  773. }
  774. });
  775. });
  776. waitsFor(function () {
  777. return layoutEnd;
  778. });
  779. runs(function () {
  780. var series = chart.getSeries()[0],
  781. seriesSprites = series.getSprites(),
  782. legendSprites = chart.getLegend().getSprites();
  783. for (var i = 0; i < n; i++) {
  784. var hexColor = Ext.util.Color.fly(colors1[i]).toString();
  785. expect(seriesSprites[i].attr.fillStyle).toBe(hexColor);
  786. expect(legendSprites[i].getMarker().attr.fillStyle).toBe(hexColor);
  787. }
  788. });
  789. });
  790. it('should use colors from the series "colors" config (polar, pie3d)', function () {
  791. runs(function () {
  792. chart = Ext.create({
  793. xtype: 'polar',
  794. animation: false,
  795. renderTo: document.body,
  796. width: 400,
  797. height: 400,
  798. store: {
  799. data: data.slice()
  800. },
  801. legend: {
  802. type: 'sprite',
  803. docked: 'right'
  804. },
  805. series: [{
  806. type: 'pie3d',
  807. angleField: 'y1',
  808. label: {
  809. field: 'x'
  810. },
  811. colors: colors1.slice()
  812. }],
  813. listeners: {
  814. layout: function () {
  815. layoutEnd = true;
  816. }
  817. }
  818. });
  819. });
  820. waitsFor(function () {
  821. return layoutEnd;
  822. });
  823. runs(function () {
  824. var series = chart.getSeries()[0],
  825. seriesSprites = series.getSprites(),
  826. legendSprites = chart.getLegend().getSprites();
  827. for (var i = 0; i < n; i++) {
  828. var hexColor = Ext.util.Color.fly(colors1[i]).toString();
  829. expect(seriesSprites[i * series.spritesPerSlice].attr.baseColor).toBe(hexColor);
  830. expect(legendSprites[i].getMarker().attr.fillStyle).toBe(hexColor);
  831. }
  832. });
  833. });
  834. it('should reflect dynamic changes to the series "colors" config (cartesian, bar)', function () {
  835. runs(function () {
  836. chart = Ext.create({
  837. xtype: 'cartesian',
  838. animation: false,
  839. renderTo: document.body,
  840. width: 400,
  841. height: 400,
  842. store: {
  843. data: data.slice()
  844. },
  845. legend: {
  846. type: 'sprite',
  847. docked: 'right'
  848. },
  849. series: [{
  850. type: 'bar',
  851. xField: 'x',
  852. yField: ['y1', 'y2', 'y3', 'y4', 'y5'],
  853. colors: colors1.slice()
  854. }],
  855. listeners: {
  856. layout: function () {
  857. layoutEnd = true;
  858. }
  859. }
  860. });
  861. });
  862. waitsFor(function () {
  863. return layoutEnd;
  864. });
  865. runs(function () {
  866. layoutEnd = false;
  867. chart.getSeries()[0].setColors(colors2.slice());
  868. });
  869. waits(1);
  870. runs(function () {
  871. var series = chart.getSeries()[0],
  872. seriesSprites = series.getSprites(),
  873. legendSprites = chart.getLegend().getSprites();
  874. for (var i = 0; i < n; i++) {
  875. var hexColor = Ext.util.Color.fly(colors2[i]).toString();
  876. expect(seriesSprites[i].attr.fillStyle).toBe(hexColor);
  877. expect(legendSprites[i].getMarker().attr.fillStyle).toBe(hexColor);
  878. }
  879. });
  880. });
  881. it('should reflect dynamic changes to the series "colors" config (polar, pie3d)', function () {
  882. runs(function () {
  883. chart = Ext.create({
  884. xtype: 'polar',
  885. animation: false,
  886. renderTo: document.body,
  887. width: 400,
  888. height: 400,
  889. store: {
  890. data: data.slice()
  891. },
  892. legend: {
  893. type: 'sprite',
  894. docked: 'right'
  895. },
  896. series: [{
  897. type: 'pie3d',
  898. angleField: 'y1',
  899. label: {
  900. field: 'x'
  901. },
  902. colors: colors1.slice()
  903. }],
  904. listeners: {
  905. layout: function () {
  906. layoutEnd = true;
  907. }
  908. }
  909. });
  910. });
  911. waitsFor(function () {
  912. return layoutEnd;
  913. });
  914. runs(function () {
  915. layoutEnd = false;
  916. chart.getSeries()[0].setColors(colors2.slice());
  917. });
  918. waits(1);
  919. runs(function () {
  920. var series = chart.getSeries()[0],
  921. seriesSprites = series.getSprites(),
  922. legendSprites = chart.getLegend().getSprites();
  923. for (var i = 0; i < n; i++) {
  924. var hexColor = Ext.util.Color.fly(colors2[i]).toString();
  925. expect(seriesSprites[i * series.spritesPerSlice].attr.baseColor).toBe(hexColor);
  926. expect(legendSprites[i].getMarker().attr.fillStyle).toBe(hexColor);
  927. }
  928. });
  929. });
  930. });
  931. });