data-spec.ts 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566
  1. import { d3, initChart } from './c3-helper'
  2. describe('load without data', function() {
  3. var chart, args
  4. beforeAll(function() {
  5. args = {
  6. data: {}
  7. }
  8. })
  9. it('throws when data is an empty object', () => {
  10. expect(() => initChart(chart, args, () => {})).toThrowError(
  11. Error,
  12. /url or json or rows or columns is required/
  13. )
  14. })
  15. })
  16. describe('c3 chart data', function() {
  17. 'use strict'
  18. var chart, args
  19. beforeEach(function(done) {
  20. chart = initChart(chart, args, done)
  21. })
  22. describe('load json', function() {
  23. beforeAll(function() {
  24. args = {
  25. data: {
  26. json: {
  27. data1: [30, 20, 50],
  28. data2: [200, 130, 90]
  29. }
  30. }
  31. }
  32. })
  33. it('should draw correctly', function() {
  34. var expectedCx = [6, 299, 593],
  35. expectedCy = [371, 391, 332]
  36. d3.selectAll('.c3-circles-data1 .c3-circle').each(function(d, i) {
  37. var circle = d3.select(this)
  38. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)
  39. expect(+circle.attr('cy')).toBeCloseTo(expectedCy[i], 0)
  40. })
  41. })
  42. describe('more data', function() {
  43. beforeAll(function() {
  44. args = {
  45. data: {
  46. json: [
  47. {
  48. date: '2014-06-03',
  49. '443': '3000',
  50. '995': '500'
  51. },
  52. {
  53. date: '2014-06-04',
  54. '443': '1000'
  55. },
  56. {
  57. date: '2014-06-05',
  58. '443': '5000',
  59. '995': '1000'
  60. }
  61. ],
  62. keys: {
  63. x: 'date',
  64. value: ['443', '995']
  65. }
  66. },
  67. axis: {
  68. x: {
  69. type: 'category'
  70. }
  71. }
  72. }
  73. })
  74. it('should draw correctly', function() {
  75. var expectedCx = { 443: [98, 294, 490], 995: [98, 294, 490] },
  76. expectedCy = { 443: [194, 351, 36], 995: [391, 430, 351] }
  77. d3.selectAll('.c3-circles-443 .c3-circle').each(function(d, i) {
  78. var circle = d3.select(this)
  79. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[443][i], 0)
  80. expect(+circle.attr('cy')).toBeCloseTo(expectedCy[443][i], 0)
  81. })
  82. d3.selectAll('.c3-circles-995 .c3-circle').each(function(d, i) {
  83. var circle = d3.select(this)
  84. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[995][i], 0)
  85. expect(+circle.attr('cy')).toBeCloseTo(expectedCy[995][i], 0)
  86. })
  87. })
  88. })
  89. describe('with nested JSON args', function() {
  90. beforeAll(function() {
  91. args = {
  92. data: {
  93. json: [
  94. {
  95. date: '2014-06-03',
  96. '443': '3000',
  97. '995': { '996': '500' },
  98. '112': ['600'],
  99. '223': [{ '224': '100' }],
  100. '334': [[], [{ '335': '300' }]],
  101. '556': { '557': { '558': ['1000'] } },
  102. '778.889': '700'
  103. },
  104. {
  105. date: '2014-06-04',
  106. '443': '1000',
  107. '112': ['700'],
  108. '223': [{ '224': '200' }],
  109. '556': { '557': { '558': ['2000'] } },
  110. '778.889': '300'
  111. },
  112. {
  113. date: '2014-06-05',
  114. '995': { '996': '1000' },
  115. '112': ['800'],
  116. '223': [{ '224': '300' }],
  117. '443': '5000',
  118. '334': [[], [{ '335': '500' }]],
  119. '556': { '557': { '558': ['3000'] } },
  120. '778.889': '800'
  121. }
  122. ],
  123. keys: {
  124. x: 'date',
  125. value: [
  126. '443',
  127. '995.996',
  128. '112[0]',
  129. '223[0].224',
  130. '334[1][0].335',
  131. '556.557.558[0]',
  132. '778.889'
  133. ]
  134. }
  135. },
  136. axis: {
  137. x: {
  138. type: 'category'
  139. }
  140. }
  141. }
  142. })
  143. it('should draw nested JSON correctly', function() {
  144. var expectedCx = [98, 294, 490],
  145. expectedCy = {
  146. 443: [181, 326, 36],
  147. 995: [362, 398, 326],
  148. 112: [354, 347, 340],
  149. 223: [391, 383, 376],
  150. 334: [376, 398, 362],
  151. 556: [326, 253, 181],
  152. '778.889': [347, 376, 340]
  153. }
  154. d3.selectAll('.c3-circles-443 .c3-circle').each(function(d, i) {
  155. var circle = d3.select(this)
  156. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)
  157. expect(+circle.attr('cy')).toBeCloseTo(expectedCy[443][i], 0)
  158. })
  159. d3.selectAll('.c3-circles-995-996 .c3-circle').each(function(d, i) {
  160. var circle = d3.select(this)
  161. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)
  162. expect(+circle.attr('cy')).toBeCloseTo(expectedCy[995][i], 0)
  163. })
  164. d3.selectAll('.c3-circles-112-0- .c3-circle').each(function(d, i) {
  165. var circle = d3.select(this)
  166. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)
  167. expect(+circle.attr('cy')).toBeCloseTo(expectedCy[112][i], 0)
  168. })
  169. d3.selectAll('.c3-circles-223-0--224 .c3-circle').each(function(d, i) {
  170. var circle = d3.select(this)
  171. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)
  172. expect(+circle.attr('cy')).toBeCloseTo(expectedCy[223][i], 0)
  173. })
  174. d3.selectAll('.c3-circles-334-1--0--335 .c3-circle').each(function(
  175. d,
  176. i
  177. ) {
  178. var circle = d3.select(this)
  179. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)
  180. expect(+circle.attr('cy')).toBeCloseTo(expectedCy[334][i], 0)
  181. })
  182. d3.selectAll('.c3-circles-556-557-558-0- .c3-circle').each(function(
  183. d,
  184. i
  185. ) {
  186. var circle = d3.select(this)
  187. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)
  188. expect(+circle.attr('cy')).toBeCloseTo(expectedCy[556][i], 0)
  189. })
  190. d3.selectAll('.c3-circles-778-889 .c3-circle').each(function(d, i) {
  191. var circle = d3.select(this)
  192. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)
  193. expect(+circle.attr('cy')).toBeCloseTo(expectedCy['778.889'][i], 0)
  194. })
  195. })
  196. })
  197. })
  198. describe('load rows', function() {
  199. beforeAll(function() {
  200. args = {
  201. data: {
  202. rows: [
  203. ['data1', 'data2', 'data3'],
  204. [90, 120, 300],
  205. [40, 160, 240],
  206. [50, 200, 290],
  207. [120, 160, 230],
  208. [80, 130, 300],
  209. [90, 220, 320]
  210. ]
  211. }
  212. }
  213. })
  214. it('should draw correctly', function() {
  215. var expectedCx = [6, 124, 241, 358, 475, 593],
  216. expectedCy = [327, 391, 378, 289, 340, 327]
  217. d3.selectAll('.c3-circles-data1 .c3-circle').each(function(d, i) {
  218. var circle = d3.select(this)
  219. expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)
  220. expect(+circle.attr('cy')).toBeCloseTo(expectedCy[i], 0)
  221. })
  222. })
  223. })
  224. describe('function in data.order', function() {
  225. beforeAll(function() {
  226. args = {
  227. data: {
  228. columns: [
  229. ['data1', 30, 200, 100, 400, 150, 250],
  230. ['data2', 50, 20, 10, 40, 15, 25],
  231. ['data3', 150, 120, 110, 140, 115, 125]
  232. ],
  233. order: function() {
  234. return 0
  235. }
  236. }
  237. }
  238. })
  239. it('should return false in isOrderAsc and isOrderDesc functions', function() {
  240. expect(chart.internal.isOrderAsc() || chart.internal.isOrderDesc()).toBe(
  241. false
  242. )
  243. })
  244. })
  245. describe('addHiddenTargetIds if not already hidden', function() {
  246. it('should update args', function() {
  247. args = {
  248. data: {
  249. columns: [
  250. ['data1', 30, 200, 100, 400, 150, 250],
  251. ['data2', 150, 120, 110, 140, 115, 125]
  252. ]
  253. }
  254. }
  255. expect(true).toBeTruthy()
  256. })
  257. it('length of hiddenTargetIds should not change if same key added twice', function() {
  258. chart.internal.addHiddenTargetIds('data1')
  259. expect(chart.internal.hiddenTargetIds.length).toBe(1)
  260. chart.internal.addHiddenTargetIds('data1')
  261. expect(chart.internal.hiddenTargetIds.length).toBe(1)
  262. chart.hide('data1')
  263. expect(chart.internal.hiddenTargetIds.length).toBe(1)
  264. chart.internal.addHiddenTargetIds('data2')
  265. expect(chart.internal.hiddenTargetIds.length).toBe(2)
  266. chart.show()
  267. chart.hide(['data1', 'data2'])
  268. expect(chart.internal.hiddenTargetIds.length).toBe(2)
  269. chart.show()
  270. chart.hide()
  271. expect(chart.internal.hiddenTargetIds.length).toBe(2)
  272. })
  273. })
  274. describe('addHiddenLegendIds if not already hidden', function() {
  275. it('should update args', function() {
  276. args = {
  277. data: {
  278. columns: [
  279. ['data1', 30, 200, 100, 400, 150, 250],
  280. ['data2', 150, 120, 110, 140, 115, 125]
  281. ]
  282. }
  283. }
  284. expect(true).toBeTruthy()
  285. })
  286. it('length of hiddenLegendIds should not change if same key added twice', function() {
  287. chart.internal.addHiddenLegendIds('data1')
  288. expect(chart.internal.hiddenLegendIds.length).toBe(1)
  289. chart.internal.addHiddenLegendIds('data1')
  290. expect(chart.internal.hiddenLegendIds.length).toBe(1)
  291. chart.hide('data1', { withLegend: true })
  292. expect(chart.internal.hiddenLegendIds.length).toBe(1)
  293. chart.hide('data2', { withLegend: true })
  294. expect(chart.internal.hiddenLegendIds.length).toBe(2)
  295. chart.show(['data1', 'data2'], { withLegend: true })
  296. chart.hide(['data1', 'data2'], { withLegend: true })
  297. expect(chart.internal.hiddenLegendIds.length).toBe(2)
  298. })
  299. })
  300. describe('data.xs', function() {
  301. beforeAll(function() {
  302. args = {
  303. data: {
  304. columns: [
  305. ['data1', 30, 200, 100, 400, 150, 250],
  306. ['data2', 50, 20, 10, 40, 15, 25],
  307. ['data3', 150, 120, 110, 140, 115, 125]
  308. ]
  309. }
  310. }
  311. })
  312. describe('normal x', function() {
  313. it('should have correct number of xs for each', function() {
  314. expect(Object.keys(chart.internal.data.xs).length).toBe(3)
  315. expect(chart.internal.data.xs.data1.length).toBe(6)
  316. expect(chart.internal.data.xs.data2.length).toBe(6)
  317. expect(chart.internal.data.xs.data3.length).toBe(6)
  318. })
  319. it('should have integer index as x', function() {
  320. for (var i = 0; i < chart.internal.data.xs.data3.length; i++) {
  321. expect(chart.internal.data.xs.data1[i]).toBe(i)
  322. expect(chart.internal.data.xs.data2[i]).toBe(i)
  323. expect(chart.internal.data.xs.data3[i]).toBe(i)
  324. }
  325. })
  326. })
  327. describe('timeseries x', function() {
  328. describe('without xFormat', function() {
  329. beforeAll(function() {
  330. args = {
  331. data: {
  332. x: 'date',
  333. columns: [
  334. ['date', '2013-01-01', '2013-01-02', '2013-01-03'],
  335. ['data1', 30, 200, 100],
  336. ['data2', 130, 300, 200]
  337. ]
  338. },
  339. axis: {
  340. x: {
  341. type: 'timeseries'
  342. }
  343. }
  344. }
  345. })
  346. it('should have correct number of xs', function() {
  347. expect(Object.keys(chart.internal.data.xs).length).toBe(2)
  348. expect(chart.internal.data.xs.data1.length).toBe(3)
  349. expect(chart.internal.data.xs.data2.length).toBe(3)
  350. })
  351. it('should have Date object as x', function() {
  352. var xs = chart.internal.data.xs
  353. expect(+xs.data1[0]).toBe(+new Date(2013, 0, 1, 0, 0, 0))
  354. expect(+xs.data1[1]).toBe(+new Date(2013, 0, 2, 0, 0, 0))
  355. expect(+xs.data1[2]).toBe(+new Date(2013, 0, 3, 0, 0, 0))
  356. expect(+xs.data2[0]).toBe(+new Date(2013, 0, 1, 0, 0, 0))
  357. expect(+xs.data2[1]).toBe(+new Date(2013, 0, 2, 0, 0, 0))
  358. expect(+xs.data2[2]).toBe(+new Date(2013, 0, 3, 0, 0, 0))
  359. })
  360. })
  361. describe('with xFormat', function() {
  362. describe('timeseries x with xFormat', function() {
  363. beforeAll(function() {
  364. args = {
  365. data: {
  366. x: 'date',
  367. xFormat: '%Y%m%d',
  368. columns: [
  369. ['date', '20130101', '20130102', '20130103'],
  370. ['data1', 30, 200, 100],
  371. ['data2', 130, 300, 200]
  372. ]
  373. },
  374. axis: {
  375. x: {
  376. type: 'timeseries'
  377. }
  378. }
  379. }
  380. })
  381. it('should have correct number of xs', function() {
  382. expect(Object.keys(chart.internal.data.xs).length).toBe(2)
  383. expect(chart.internal.data.xs.data1.length).toBe(3)
  384. expect(chart.internal.data.xs.data2.length).toBe(3)
  385. })
  386. it('should have Date object as x', function() {
  387. var xs = chart.internal.data.xs
  388. expect(+xs.data1[0]).toBe(+new Date(2013, 0, 1, 0, 0, 0))
  389. expect(+xs.data1[1]).toBe(+new Date(2013, 0, 2, 0, 0, 0))
  390. expect(+xs.data1[2]).toBe(+new Date(2013, 0, 3, 0, 0, 0))
  391. expect(+xs.data2[0]).toBe(+new Date(2013, 0, 1, 0, 0, 0))
  392. expect(+xs.data2[1]).toBe(+new Date(2013, 0, 2, 0, 0, 0))
  393. expect(+xs.data2[2]).toBe(+new Date(2013, 0, 3, 0, 0, 0))
  394. })
  395. })
  396. })
  397. })
  398. describe('milliseconds timeseries x', function() {
  399. describe('as date string', function() {
  400. beforeAll(function() {
  401. args = {
  402. data: {
  403. x: 'date',
  404. xFormat: '%Y-%m-%d %H:%M:%S.%L',
  405. columns: [
  406. ['date', '2014-05-20 17:25:00.123', '2014-05-20 17:30:00.345'],
  407. ['data1', 30, 200],
  408. ['data2', 130, 300]
  409. ]
  410. },
  411. axis: {
  412. x: {
  413. type: 'timeseries',
  414. tick: {
  415. format: '%Y-%m-%d %H:%M:%S.%L',
  416. multiline: false
  417. }
  418. }
  419. }
  420. }
  421. })
  422. it('should have correct number of xs', function() {
  423. expect(Object.keys(chart.internal.data.xs).length).toBe(2)
  424. expect(chart.internal.data.xs.data1.length).toBe(2)
  425. expect(chart.internal.data.xs.data2.length).toBe(2)
  426. })
  427. it('should have Date object as x', function() {
  428. var xs = chart.internal.data.xs
  429. expect(+xs.data1[0]).toBe(+new Date(2014, 4, 20, 17, 25, 0, 123))
  430. expect(+xs.data1[1]).toBe(+new Date(2014, 4, 20, 17, 30, 0, 345))
  431. expect(+xs.data2[0]).toBe(+new Date(2014, 4, 20, 17, 25, 0, 123))
  432. expect(+xs.data2[1]).toBe(+new Date(2014, 4, 20, 17, 30, 0, 345))
  433. })
  434. it('should have milliseconds tick format', function() {
  435. var expected = ['2014-05-20 17:25:00.123', '2014-05-20 17:30:00.345']
  436. chart.internal.main
  437. .selectAll('.c3-axis-x g.tick text')
  438. .each(function(d, i) {
  439. expect(d3.select(this).text()).toBe(expected[i])
  440. })
  441. })
  442. })
  443. describe('as unixtime number', function() {
  444. beforeAll(function() {
  445. args = {
  446. data: {
  447. x: 'date',
  448. columns: [
  449. ['date', 1417622461123, 1417622522345],
  450. ['data1', 30, 200],
  451. ['data2', 130, 300]
  452. ]
  453. },
  454. axis: {
  455. x: {
  456. type: 'timeseries',
  457. tick: {
  458. format: '%Y-%m-%d %H:%M:%S.%L'
  459. }
  460. }
  461. }
  462. }
  463. })
  464. it('should have correct number of xs', function() {
  465. expect(Object.keys(chart.internal.data.xs).length).toBe(2)
  466. expect(chart.internal.data.xs.data1.length).toBe(2)
  467. expect(chart.internal.data.xs.data2.length).toBe(2)
  468. })
  469. it('should have Date object as x', function() {
  470. var xs = chart.internal.data.xs
  471. expect(+xs.data1[0]).toBe(1417622461123)
  472. expect(+xs.data1[1]).toBe(1417622522345)
  473. expect(+xs.data2[0]).toBe(1417622461123)
  474. expect(+xs.data2[1]).toBe(1417622522345)
  475. })
  476. })
  477. })
  478. })
  479. describe('data.label', function() {
  480. describe('on line chart', function() {
  481. beforeAll(function() {
  482. args = {
  483. data: {
  484. columns: [
  485. ['data1', 1030, 2200, 2100],
  486. ['data2', 1150, 2010, 1200],
  487. ['data3', -1150, -2010, -1200],
  488. ['data4', -1030, -2200, -2100]
  489. ],
  490. type: 'line',
  491. labels: true
  492. }
  493. }
  494. })
  495. it('should locate data labels in correct position', function() {
  496. var expectedTextY = {
  497. data1: [128, 38, 46],
  498. data2: [119, 53, 115],
  499. data3: [311, 377, 315],
  500. data4: [302, 392, 384]
  501. }
  502. var expectedTextX = {
  503. data1: [6, 294, 583],
  504. data2: [6, 294, 583],
  505. data3: [6, 294, 583],
  506. data4: [6, 294, 583]
  507. }
  508. Object.keys(expectedTextY).forEach(function(key) {
  509. d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(
  510. d,
  511. i
  512. ) {
  513. var text = d3.select(this)
  514. expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)
  515. expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)
  516. })
  517. })
  518. })
  519. describe('with stacked', function() {
  520. beforeAll(function() {
  521. args.data.groups = [
  522. ['data1', 'data2'],
  523. ['data3', 'data4']
  524. ]
  525. })
  526. it('should locate data labels in correct position', function() {
  527. var expectedTextY = {
  528. data1: [120, 38, 75],
  529. data2: [161, 127, 159],
  530. data3: [269, 303, 271],
  531. data4: [310, 392, 355]
  532. }
  533. var expectedTextX = {
  534. data1: [6, 294, 583],
  535. data2: [6, 294, 583],
  536. data3: [6, 294, 583],
  537. data4: [6, 294, 583]
  538. }
  539. Object.keys(expectedTextY).forEach(function(key) {
  540. d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(
  541. d,
  542. i
  543. ) {
  544. var text = d3.select(this)
  545. expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)
  546. expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)
  547. })
  548. })
  549. })
  550. })
  551. })
  552. describe('on area chart', function() {
  553. beforeAll(function() {
  554. args = {
  555. data: {
  556. columns: [
  557. ['data1', 1030, 2200, 2100],
  558. ['data2', 1150, 2010, 1200],
  559. ['data3', -1150, -2010, -1200],
  560. ['data4', -1030, -2200, -2100]
  561. ],
  562. type: 'area',
  563. labels: true
  564. }
  565. }
  566. })
  567. it('should locate data labels in correct position', function() {
  568. var expectedTextY = {
  569. data1: [128, 38, 46],
  570. data2: [119, 53, 115],
  571. data3: [311, 377, 315],
  572. data4: [302, 392, 384]
  573. }
  574. var expectedTextX = {
  575. data1: [6, 294, 583],
  576. data2: [6, 294, 583],
  577. data3: [6, 294, 583],
  578. data4: [6, 294, 583]
  579. }
  580. Object.keys(expectedTextY).forEach(function(key) {
  581. d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(
  582. d,
  583. i
  584. ) {
  585. var text = d3.select(this)
  586. expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)
  587. expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)
  588. })
  589. })
  590. })
  591. describe('with stacked', function() {
  592. beforeAll(function() {
  593. args.data.groups = [
  594. ['data1', 'data2'],
  595. ['data3', 'data4']
  596. ]
  597. })
  598. it('should locate data labels in correct position', function() {
  599. var expectedTextY = {
  600. data1: [120, 38, 75],
  601. data2: [161, 127, 159],
  602. data3: [269, 303, 271],
  603. data4: [310, 392, 355]
  604. }
  605. var expectedTextX = {
  606. data1: [6, 294, 583],
  607. data2: [6, 294, 583],
  608. data3: [6, 294, 583],
  609. data4: [6, 294, 583]
  610. }
  611. Object.keys(expectedTextY).forEach(function(key) {
  612. d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(
  613. d,
  614. i
  615. ) {
  616. var text = d3.select(this)
  617. expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)
  618. expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)
  619. })
  620. })
  621. })
  622. })
  623. })
  624. describe('on bar chart', function() {
  625. beforeAll(function() {
  626. args = {
  627. data: {
  628. columns: [
  629. ['data1', 1030, 2200, 2100],
  630. ['data2', 1150, 2010, 1200],
  631. ['data3', -1150, -2010, -1200],
  632. ['data4', -1030, -2200, -2100]
  633. ],
  634. type: 'bar',
  635. labels: true
  636. }
  637. }
  638. })
  639. it('should locate data labels in correct position', function() {
  640. var expectedTextY = {
  641. data1: [128, 38, 46],
  642. data2: [119, 53, 115],
  643. data3: [311, 377, 315],
  644. data4: [302, 392, 384]
  645. }
  646. var expectedTextX = {
  647. data1: [53, 249, 445],
  648. data2: [83, 279, 475],
  649. data3: [112, 308, 504],
  650. data4: [142, 338, 534]
  651. }
  652. Object.keys(expectedTextY).forEach(function(key) {
  653. d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(
  654. d,
  655. i
  656. ) {
  657. var text = d3.select(this)
  658. expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)
  659. expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)
  660. })
  661. })
  662. })
  663. describe('with stacked', function() {
  664. beforeAll(function() {
  665. args.data.groups = [
  666. ['data1', 'data2'],
  667. ['data3', 'data4']
  668. ]
  669. })
  670. it('should locate data labels in correct position', function() {
  671. var expectedTextY = {
  672. data1: [120, 38, 75],
  673. data2: [161, 127, 159],
  674. data3: [269, 303, 271],
  675. data4: [310, 392, 355]
  676. }
  677. var expectedTextX = {
  678. data1: [68.6, 264, 460],
  679. data2: [68.6, 264, 460],
  680. data3: [127, 323, 519],
  681. data4: [127, 323, 519]
  682. }
  683. Object.keys(expectedTextY).forEach(function(key) {
  684. d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(
  685. d,
  686. i
  687. ) {
  688. var text = d3.select(this)
  689. expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)
  690. expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)
  691. })
  692. })
  693. })
  694. })
  695. })
  696. describe('for all targets', function() {
  697. describe('with data label for all data', function() {
  698. beforeAll(function() {
  699. args = {
  700. data: {
  701. columns: [
  702. ['data1', 100, 200, 100, 400, 150, 250],
  703. ['data2', 10, 20, 10, 40, 15, 25],
  704. ['data3', 1000, 2000, 1000, 4000, 1500, 2500]
  705. ],
  706. labels: true
  707. }
  708. }
  709. })
  710. it('should have data labels on all data', function() {
  711. d3.selectAll('.c3-texts-data1 text').each(function(d, i) {
  712. expect(d3.select(this).text()).toBe(
  713. args.data.columns[0][i + 1] + ''
  714. )
  715. })
  716. d3.selectAll('.c3-texts-data2 text').each(function(d, i) {
  717. expect(d3.select(this).text()).toBe(
  718. args.data.columns[1][i + 1] + ''
  719. )
  720. })
  721. d3.selectAll('.c3-texts-data3 text').each(function(d, i) {
  722. expect(d3.select(this).text()).toBe(
  723. args.data.columns[2][i + 1] + ''
  724. )
  725. })
  726. })
  727. })
  728. })
  729. describe('for each target', function() {
  730. describe('as true', function() {
  731. describe('with data label for only data1', function() {
  732. beforeAll(function() {
  733. args = {
  734. data: {
  735. columns: [
  736. ['data1', 100, 200, 100, 400, 150, 250],
  737. ['data2', 10, 20, 10, 40, 15, 25],
  738. ['data3', 1000, 2000, 1000, 4000, 1500, 2500]
  739. ],
  740. labels: {
  741. format: {
  742. data1: true
  743. }
  744. }
  745. }
  746. }
  747. })
  748. it('should have data labels on all data', function() {
  749. d3.selectAll('.c3-texts-data1 text').each(function(d, i) {
  750. expect(d3.select(this).text()).toBe(
  751. args.data.columns[0][i + 1] + ''
  752. )
  753. })
  754. d3.selectAll('.c3-texts-data2 text').each(function() {
  755. expect(d3.select(this).text()).toBe('')
  756. })
  757. d3.selectAll('.c3-texts-data3 text').each(function() {
  758. expect(d3.select(this).text()).toBe('')
  759. })
  760. })
  761. })
  762. })
  763. describe('as function', function() {
  764. describe('with data label for only data1', function() {
  765. beforeAll(function() {
  766. args = {
  767. data: {
  768. columns: [
  769. ['data1', 100, 200, 100, 400, 150, 250],
  770. ['data2', 10, 20, 10, 40, 15, 25],
  771. ['data3', 1000, 2000, 1000, 4000, 1500, 2500]
  772. ],
  773. labels: {
  774. format: {
  775. data1: d3.format('$')
  776. }
  777. }
  778. }
  779. }
  780. })
  781. it('should have data labels on all data', function() {
  782. d3.selectAll('.c3-texts-data1 text').each(function(d, i) {
  783. expect(d3.select(this).text()).toBe(
  784. '$' + args.data.columns[0][i + 1]
  785. )
  786. })
  787. d3.selectAll('.c3-texts-data2 text').each(function() {
  788. expect(d3.select(this).text()).toBe('')
  789. })
  790. d3.selectAll('.c3-texts-data3 text').each(function() {
  791. expect(d3.select(this).text()).toBe('')
  792. })
  793. })
  794. })
  795. })
  796. })
  797. describe('with small values', function() {
  798. describe('with data label', function() {
  799. beforeAll(function() {
  800. args = {
  801. data: {
  802. columns: [['data1', 0.03, 0.2, 0.1, 0.4, 0.15, 0.25]],
  803. labels: true
  804. }
  805. }
  806. })
  807. it('should have proper y domain', function() {
  808. var domain = chart.internal.y.domain()
  809. expect(domain[0]).toBeCloseTo(-0.02)
  810. expect(domain[1]).toBeCloseTo(0.45)
  811. })
  812. })
  813. })
  814. describe('with positive values and null', function() {
  815. describe('on not rotated axis', function() {
  816. beforeAll(function() {
  817. args = {
  818. data: {
  819. columns: [['data1', 190, 200, 190, null]],
  820. type: 'bar',
  821. labels: {
  822. format: function(v) {
  823. if (v === null) {
  824. return 'Not Applicable'
  825. }
  826. return d3.format('$')(v)
  827. }
  828. }
  829. }
  830. }
  831. })
  832. it('should have y domain with proper padding', function() {
  833. var domain = chart.internal.y.domain()
  834. expect(domain[0]).toBeCloseTo(0, -1)
  835. expect(domain[1]).toBeCloseTo(227, -1)
  836. })
  837. it('should locate labels above each data point', function() {
  838. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  839. expectedYs = [67, 49, 67, 423],
  840. expectedXs = [74, 221, 368, 515]
  841. texts.each(function(d, i) {
  842. var text = d3.select(this)
  843. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  844. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  845. })
  846. })
  847. describe('data type line', function() {
  848. beforeAll(function() {
  849. args.data.type = 'line'
  850. })
  851. it('should have y domain with proper padding', function() {
  852. var domain = chart.internal.y.domain()
  853. expect(domain[0]).toBeCloseTo(189, -1)
  854. expect(domain[1]).toBeCloseTo(201, -1)
  855. })
  856. it('should locate labels above each data point', function() {
  857. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  858. expectedYs = [375, 40, 375, 422],
  859. expectedXs = [6, 198, 391, 583]
  860. texts.each(function(d, i) {
  861. var text = d3.select(this)
  862. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  863. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  864. })
  865. })
  866. })
  867. })
  868. describe('on rotated axis', function() {
  869. describe('data type bar', function() {
  870. beforeAll(function() {
  871. args.data.type = 'bar'
  872. args.axis = {
  873. rotated: true
  874. }
  875. })
  876. it('should have y domain with proper padding', function() {
  877. var domain = chart.internal.y.domain()
  878. expect(domain[0]).toBeCloseTo(0, -1)
  879. expect(domain[1]).toBeCloseTo(231, -1)
  880. })
  881. it('should locate labels above each data point', function() {
  882. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  883. expectedYs = [57, 163, 269, 375],
  884. expectedXs = [490, 516, 490, 4]
  885. texts.each(function(d, i) {
  886. var text = d3.select(this)
  887. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  888. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  889. })
  890. })
  891. })
  892. describe('data type line', function() {
  893. beforeAll(function() {
  894. args.data.type = 'line'
  895. })
  896. it('should have y domain with proper padding', function() {
  897. var domain = chart.internal.y.domain()
  898. expect(domain[0]).toBeCloseTo(188, -1)
  899. expect(domain[1]).toBeCloseTo(202, -1)
  900. })
  901. it('should locate labels above each data point', function() {
  902. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  903. expectedYs = [9, 147, 286, 424],
  904. expectedXs = [76, 526, 76, 4]
  905. texts.each(function(d, i) {
  906. var text = d3.select(this)
  907. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  908. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  909. })
  910. })
  911. })
  912. })
  913. })
  914. describe('with negative values and null', function() {
  915. describe('on not rotated axis', function() {
  916. describe('type bar', function() {
  917. beforeAll(function() {
  918. args = {
  919. data: {
  920. columns: [['data1', -190, 0, -190, null]],
  921. type: 'bar',
  922. labels: {
  923. format: function(v) {
  924. if (v === null) {
  925. return 'Not Applicable'
  926. }
  927. return d3.format('$')(v)
  928. }
  929. }
  930. }
  931. }
  932. })
  933. it('should have y domain with proper padding', function() {
  934. var domain = chart.internal.y.domain()
  935. expect(domain[0]).toBeCloseTo(-215, -1)
  936. expect(domain[1]).toBeCloseTo(0, -1)
  937. })
  938. it('should locate labels above each data point', function() {
  939. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  940. expectedYs = [368, 12, 368, 12],
  941. expectedXs = [74, 221, 368, 515]
  942. texts.each(function(d, i) {
  943. var text = d3.select(this)
  944. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  945. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  946. })
  947. })
  948. })
  949. describe('data type line', function() {
  950. beforeAll(function() {
  951. args.data.type = 'line'
  952. })
  953. it('should have y domain with proper padding', function() {
  954. var domain = chart.internal.y.domain()
  955. expect(domain[0]).toBeCloseTo(-215, -1)
  956. expect(domain[1]).toBeCloseTo(25, -1)
  957. })
  958. it('should locate labels above each data point', function() {
  959. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  960. expectedYs = [395, 60, 395, 12],
  961. expectedXs = [6, 198, 391, 583]
  962. texts.each(function(d, i) {
  963. var text = d3.select(this)
  964. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  965. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  966. })
  967. })
  968. })
  969. })
  970. describe('on rotated axis', function() {
  971. describe('data type bar', function() {
  972. beforeAll(function() {
  973. args.data.type = 'bar'
  974. args.axis = {
  975. rotated: true
  976. }
  977. })
  978. it('should have y domain with proper padding', function() {
  979. var domain = chart.internal.y.domain()
  980. expect(domain[0]).toBeCloseTo(-220, -1)
  981. expect(domain[1]).toBeCloseTo(0, -1)
  982. })
  983. it('should locate labels above each data point', function() {
  984. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  985. expectedYs = [57, 163, 269, 375],
  986. expectedXs = [103, 594, 103, 526]
  987. texts.each(function(d, i) {
  988. var text = d3.select(this)
  989. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  990. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  991. })
  992. })
  993. })
  994. describe('data type line', function() {
  995. beforeAll(function() {
  996. args.data.type = 'line'
  997. })
  998. it('should have y domain with proper padding', function() {
  999. var domain = chart.internal.y.domain()
  1000. expect(domain[0]).toBeCloseTo(-220, -1)
  1001. expect(domain[1]).toBeCloseTo(24, -1)
  1002. })
  1003. it('should locate labels above each data point', function() {
  1004. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1005. expectedYs = [9, 147, 286, 424],
  1006. expectedXs = [67, 537, 67, 526]
  1007. texts.each(function(d, i) {
  1008. var text = d3.select(this)
  1009. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1010. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1011. })
  1012. })
  1013. })
  1014. })
  1015. })
  1016. describe('with positive and negative values and null', function() {
  1017. describe('on non rotated axis', function() {
  1018. describe('data type bar', function() {
  1019. beforeAll(function() {
  1020. args = {
  1021. data: {
  1022. columns: [['data1', -190, 200, 190, null]],
  1023. type: 'bar',
  1024. labels: {
  1025. format: function(v) {
  1026. if (v === null) {
  1027. return 'Not Applicable'
  1028. }
  1029. return d3.format('$')(v)
  1030. }
  1031. }
  1032. }
  1033. }
  1034. })
  1035. it('should have y domain with proper padding', function() {
  1036. var domain = chart.internal.y.domain()
  1037. expect(domain[0]).toBeCloseTo(-243, -1)
  1038. expect(domain[1]).toBeCloseTo(253, -1)
  1039. })
  1040. it('should locate labels above each data point', function() {
  1041. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1042. expectedYs = [392, 43, 52, 215],
  1043. expectedXs = [74, 221, 368, 515]
  1044. texts.each(function(d, i) {
  1045. var text = d3.select(this)
  1046. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1047. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1048. })
  1049. })
  1050. })
  1051. describe('data type line', function() {
  1052. beforeAll(function() {
  1053. args.data.type = 'line'
  1054. })
  1055. it('should have y domain with proper padding', function() {
  1056. var domain = chart.internal.y.domain()
  1057. expect(domain[0]).toBeCloseTo(-243, -1)
  1058. expect(domain[1]).toBeCloseTo(253, -1)
  1059. })
  1060. it('should locate labels above each data point', function() {
  1061. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1062. expectedYs = [392, 40, 49, 212],
  1063. expectedXs = [6, 198, 391, 583]
  1064. texts.each(function(d, i) {
  1065. var text = d3.select(this)
  1066. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1067. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1068. })
  1069. })
  1070. })
  1071. })
  1072. describe('on rotated axis', function() {
  1073. describe('data type bar', function() {
  1074. beforeAll(function() {
  1075. args.data.type = 'bar'
  1076. args.axis = {
  1077. rotated: true
  1078. }
  1079. })
  1080. it('should have y domain with proper padding', function() {
  1081. var domain = chart.internal.y.domain()
  1082. expect(domain[0]).toBeCloseTo(-253, -1)
  1083. expect(domain[1]).toBeCloseTo(260, -1)
  1084. })
  1085. it('should locate labels above each data point', function() {
  1086. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1087. expectedYs = [57, 163, 269, 375],
  1088. expectedXs = [69, 525, 513, 295]
  1089. texts.each(function(d, i) {
  1090. var text = d3.select(this)
  1091. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1092. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1093. })
  1094. })
  1095. })
  1096. describe('data type line', function() {
  1097. beforeAll(function() {
  1098. args.data.type = 'line'
  1099. })
  1100. it('should have y domain with proper padding', function() {
  1101. var domain = chart.internal.y.domain()
  1102. expect(domain[0]).toBeCloseTo(-253, -1)
  1103. expect(domain[1]).toBeCloseTo(260, -1)
  1104. })
  1105. it('should locate labels above each data point', function() {
  1106. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1107. expectedYs = [9, 147, 286, 424],
  1108. expectedXs = [67, 527, 515, 297]
  1109. texts.each(function(d, i) {
  1110. var text = d3.select(this)
  1111. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1112. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1113. })
  1114. })
  1115. })
  1116. })
  1117. })
  1118. describe('with positive grouped values', function() {
  1119. describe('on non rotated axis', function() {
  1120. describe('data type bar', function() {
  1121. beforeAll(function() {
  1122. args = {
  1123. data: {
  1124. columns: [
  1125. ['data1', 30, 200, 100, 500],
  1126. ['data2', 50, 20, 10, 40],
  1127. ['data3', 250, 220, 210, 240]
  1128. ],
  1129. groups: [['data1', 'data2', 'data3']],
  1130. labels: true,
  1131. type: 'bar'
  1132. }
  1133. }
  1134. })
  1135. it('should have y domain with proper padding', function() {
  1136. var domain = chart.internal.y.domain()
  1137. expect(domain[0]).toBeCloseTo(0, -1)
  1138. expect(domain[1]).toBeCloseTo(885, -1)
  1139. })
  1140. it('should locate labels above each data point', function() {
  1141. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1142. expectedYs = [385, 317, 370, 164],
  1143. expectedXs = [74, 221, 368, 515]
  1144. texts.each(function(d, i) {
  1145. var text = d3.select(this)
  1146. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1147. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1148. })
  1149. })
  1150. })
  1151. describe('data type line', function() {
  1152. beforeAll(function() {
  1153. args.data.type = 'line'
  1154. })
  1155. it('should have y domain with proper padding', function() {
  1156. var domain = chart.internal.y.domain()
  1157. expect(domain[0]).toBeCloseTo(-94, -1)
  1158. expect(domain[1]).toBeCloseTo(884, -1)
  1159. })
  1160. it('should locate labels above each data point', function() {
  1161. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1162. expectedYs = [344, 284, 331, 144],
  1163. expectedXs = [6, 198, 391, 583]
  1164. texts.each(function(d, i) {
  1165. var text = d3.select(this)
  1166. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1167. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1168. })
  1169. })
  1170. })
  1171. })
  1172. describe('on rotated axis', function() {
  1173. describe('data type bar', function() {
  1174. beforeAll(function() {
  1175. args.data.type = 'bar'
  1176. args.axis = {
  1177. rotated: true
  1178. }
  1179. })
  1180. it('should have y domain with proper padding', function() {
  1181. var domain = chart.internal.y.domain()
  1182. expect(domain[0]).toBeCloseTo(0, -1)
  1183. expect(domain[1]).toBeCloseTo(888, -1.2)
  1184. })
  1185. it('should locate labels above each data point', function() {
  1186. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1187. expectedYs = [57, 163, 269, 375],
  1188. expectedXs = [57, 150, 77, 363]
  1189. texts.each(function(d, i) {
  1190. var text = d3.select(this)
  1191. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1192. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1193. })
  1194. })
  1195. })
  1196. describe('data type line', function() {
  1197. beforeAll(function() {
  1198. args.data.type = 'line'
  1199. })
  1200. it('should have y domain with proper padding', function() {
  1201. var domain = chart.internal.y.domain()
  1202. expect(domain[0]).toBeCloseTo(-87, -1)
  1203. expect(domain[1]).toBeCloseTo(887, -1.2)
  1204. })
  1205. it('should locate labels above each data point', function() {
  1206. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1207. expectedYs = [9, 147, 286, 424],
  1208. expectedXs = [107, 192, 125, 386]
  1209. texts.each(function(d, i) {
  1210. var text = d3.select(this)
  1211. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1212. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1213. })
  1214. })
  1215. })
  1216. })
  1217. })
  1218. describe('with negative grouped values', function() {
  1219. describe('on non rotated axis', function() {
  1220. describe('data type bar', function() {
  1221. beforeAll(function() {
  1222. args = {
  1223. data: {
  1224. columns: [
  1225. ['data1', -30, -200, -100, -500],
  1226. ['data2', -50, -20, -10, -40],
  1227. ['data3', -250, -220, -210, -240]
  1228. ],
  1229. groups: [['data1', 'data2', 'data3']],
  1230. labels: true,
  1231. type: 'bar'
  1232. }
  1233. }
  1234. })
  1235. it('should have y domain with proper padding', function() {
  1236. var domain = chart.internal.y.domain()
  1237. expect(domain[0]).toBeCloseTo(-885, -1)
  1238. expect(domain[1]).toBeCloseTo(0, -1)
  1239. })
  1240. it('should locate labels above each data point', function() {
  1241. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1242. expectedYs = [51, 118, 65, 272],
  1243. expectedXs = [74, 221, 368, 515]
  1244. texts.each(function(d, i) {
  1245. var text = d3.select(this)
  1246. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1247. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1248. })
  1249. })
  1250. })
  1251. describe('data type line', function() {
  1252. beforeAll(function() {
  1253. args.data.type = 'line'
  1254. })
  1255. it('should have y domain with proper padding', function() {
  1256. var domain = chart.internal.y.domain()
  1257. expect(domain[0]).toBeCloseTo(-884, -1)
  1258. expect(domain[1]).toBeCloseTo(94, -1)
  1259. })
  1260. it('should locate labels above each data point', function() {
  1261. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1262. expectedYs = [88, 149, 101, 288],
  1263. expectedXs = [6, 198, 391, 583]
  1264. texts.each(function(d, i) {
  1265. var text = d3.select(this)
  1266. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1267. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1268. })
  1269. })
  1270. })
  1271. })
  1272. describe('on rotated axis', function() {
  1273. describe('data type bar', function() {
  1274. beforeAll(function() {
  1275. args.data.type = 'bar'
  1276. args.axis = {
  1277. rotated: true
  1278. }
  1279. })
  1280. it('should have y domain with proper padding', function() {
  1281. var domain = chart.internal.y.domain()
  1282. expect(domain[0]).toBeCloseTo(-899, -1)
  1283. expect(domain[1]).toBeCloseTo(0, -1)
  1284. })
  1285. it('should locate labels above each data point', function() {
  1286. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1287. expectedYs = [57, 163, 269, 375],
  1288. expectedXs = [533, 440, 513, 230]
  1289. texts.each(function(d, i) {
  1290. var text = d3.select(this)
  1291. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1292. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1293. })
  1294. })
  1295. })
  1296. describe('data type line', function() {
  1297. beforeAll(function() {
  1298. args.data.type = 'line'
  1299. })
  1300. it('should have y domain with proper padding', function() {
  1301. var domain = chart.internal.y.domain()
  1302. expect(domain[0]).toBeCloseTo(-893, -1)
  1303. expect(domain[1]).toBeCloseTo(93, -1)
  1304. })
  1305. it('should locate labels above each data point', function() {
  1306. var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),
  1307. expectedYs = [9, 147, 286, 424],
  1308. expectedXs = [480, 397, 462, 205]
  1309. texts.each(function(d, i) {
  1310. var text = d3.select(this)
  1311. expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)
  1312. expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)
  1313. })
  1314. })
  1315. })
  1316. })
  1317. })
  1318. })
  1319. describe('data.stack', function() {
  1320. beforeAll(() => {
  1321. args = {
  1322. data: {
  1323. columns: [
  1324. ['data1', 230, 50, 300],
  1325. ['data2', 198, 87, 580]
  1326. ],
  1327. type: 'bar',
  1328. groups: [['data1', 'data2']],
  1329. stack: {
  1330. normalize: true
  1331. }
  1332. }
  1333. }
  1334. })
  1335. const getChartHeight = () =>
  1336. +chart.internal.main.select(`.c3-event-rect`).attr('height') - 1
  1337. it('check for the normalized y axis tick in percentage', () => {
  1338. const tick = chart.internal.main.selectAll(`.c3-axis-y .tick tspan`)
  1339. // check for the y axis to be in percentage
  1340. tick.each(function(v, i) {
  1341. expect(this.textContent).toEqual(`${i * 10}%`)
  1342. })
  1343. })
  1344. it("check for the normalized bar's height", () => {
  1345. const chartHeight = getChartHeight()
  1346. const bars = chart.internal.main.selectAll('.c3-bar').nodes()
  1347. bars.splice(0, 3).forEach((v, i) => {
  1348. expect(v.getBBox().height + bars[i].getBBox().height).toEqual(
  1349. chartHeight
  1350. )
  1351. })
  1352. })
  1353. it('check when hiding data', done => {
  1354. const chartHeight = getChartHeight()
  1355. // when
  1356. chart.hide('data1')
  1357. setTimeout(() => {
  1358. chart.internal.main.selectAll(`.c3-target-data2 path`).each(function() {
  1359. expect(this.getBBox().height).toBe(chartHeight)
  1360. })
  1361. done()
  1362. }, 500)
  1363. })
  1364. describe('timeseries chart', () => {
  1365. beforeAll(function() {
  1366. args = {
  1367. data: {
  1368. x: 'date',
  1369. columns: [
  1370. ['date', '2012-12-24', '2012-12-25', '2012-12-26'],
  1371. ['data1', 30, 200, 400],
  1372. ['data2', 50, 60, 50]
  1373. ],
  1374. groups: [['data1', 'data2']],
  1375. type: 'bar',
  1376. stack: {
  1377. normalize: true
  1378. }
  1379. },
  1380. axis: {
  1381. x: {
  1382. type: 'timeseries'
  1383. }
  1384. }
  1385. }
  1386. })
  1387. it("check for the normalized bar's height", () => {
  1388. const chartHeight = getChartHeight()
  1389. const bars = chart.internal.main.selectAll('.c3-bar').nodes()
  1390. expect(document.hidden).toBeFalsy()
  1391. bars.splice(0, 3).forEach((v, i) => {
  1392. expect(v.getBBox().height + bars[i].getBBox().height).toEqual(
  1393. chartHeight
  1394. )
  1395. })
  1396. })
  1397. })
  1398. describe('area chart', () => {
  1399. beforeAll(() => {
  1400. args = {
  1401. data: {
  1402. columns: [
  1403. ['data1', 200, 387, 123],
  1404. ['data2', 200, 387, 123]
  1405. ],
  1406. type: 'area',
  1407. groups: [['data1', 'data2']],
  1408. stack: {
  1409. normalize: true
  1410. }
  1411. }
  1412. }
  1413. })
  1414. it("check for the normalized area's height", () => {
  1415. const chartHeight = getChartHeight()
  1416. let areaHeight = 0
  1417. chart.internal.main.selectAll('.c3-area').each(function() {
  1418. areaHeight += this.getBBox().height
  1419. })
  1420. expect(document.hidden).toBeFalsy()
  1421. expect(areaHeight).toEqual(chartHeight)
  1422. })
  1423. })
  1424. })
  1425. })