shape.bar-spec.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. import { d3, initChart } from './c3-helper'
  2. describe('c3 chart shape bar', function() {
  3. 'use strict'
  4. var chart, args
  5. beforeEach(function(done) {
  6. chart = initChart(chart, args, done)
  7. })
  8. describe('Path boxes', function() {
  9. beforeAll(function() {
  10. args = {
  11. data: {
  12. columns: [['data1', 30]],
  13. type: 'bar'
  14. },
  15. bar: {
  16. width: {
  17. max: 40
  18. }
  19. }
  20. }
  21. })
  22. it('bars should have expected Path Box', function() {
  23. var expected = {
  24. x: 279,
  25. y: 40,
  26. width: 40,
  27. height: 387
  28. }
  29. var shapes = chart.internal.main
  30. .selectAll('.' + chart.internal.CLASS.shapes)
  31. .selectAll('.' + chart.internal.CLASS.shape)
  32. shapes.each(function() {
  33. var pathBox = chart.internal.getPathBox(this)
  34. expect(pathBox.x).toBeCloseTo(expected.x, -1)
  35. expect(pathBox.y).toBeCloseTo(expected.y, -1)
  36. expect(pathBox.width).toBeCloseTo(expected.width, -1)
  37. expect(pathBox.height).toBeCloseTo(expected.height, -1)
  38. })
  39. })
  40. })
  41. describe('with groups', function() {
  42. describe('with indexed data', function() {
  43. beforeAll(function() {
  44. args = {
  45. data: {
  46. columns: [
  47. ['data1', 30, 200, -100, 400, -150, 250],
  48. ['data2', 50, 20, 10, 40, 15, 25]
  49. ],
  50. groups: [['data1', 'data2']],
  51. type: 'bar'
  52. }
  53. }
  54. })
  55. it('should be stacked', function() {
  56. var expectedBottom = [275, 293, 365, 281, 395, 290]
  57. chart.internal.main
  58. .selectAll('.c3-bars-data1 .c3-bar')
  59. .each(function(d, i) {
  60. var rect = d3
  61. .select(this)
  62. .node()
  63. .getBoundingClientRect()
  64. expect(rect.bottom).toBeCloseTo(expectedBottom[i], -1)
  65. })
  66. })
  67. })
  68. describe('with timeseries data', function() {
  69. beforeAll(function() {
  70. args = {
  71. data: {
  72. x: 'date',
  73. columns: [
  74. [
  75. 'date',
  76. '2012-12-24',
  77. '2012-12-25',
  78. '2012-12-26',
  79. '2012-12-27',
  80. '2012-12-28',
  81. '2012-12-29'
  82. ],
  83. ['data1', 30, 200, -100, 400, -150, 250],
  84. ['data2', 50, 20, 10, 40, 15, 25]
  85. ],
  86. groups: [['data1', 'data2']],
  87. type: 'bar'
  88. },
  89. axis: {
  90. x: {
  91. type: 'timeseries'
  92. }
  93. }
  94. }
  95. })
  96. it('should be stacked', function() {
  97. var expectedBottom = [275, 293, 365, 281, 395, 290]
  98. chart.internal.main
  99. .selectAll('.c3-bars-data1 .c3-bar')
  100. .each(function(d, i) {
  101. var rect = d3
  102. .select(this)
  103. .node()
  104. .getBoundingClientRect()
  105. expect(rect.bottom).toBeCloseTo(expectedBottom[i], -1)
  106. })
  107. })
  108. })
  109. describe('with category data', function() {
  110. beforeAll(function() {
  111. args = {
  112. data: {
  113. x: 'date',
  114. columns: [
  115. [
  116. 'date',
  117. '2012-12-24',
  118. '2012-12-25',
  119. '2012-12-26',
  120. '2012-12-27',
  121. '2012-12-28',
  122. '2012-12-29'
  123. ],
  124. ['data1', 30, 200, -100, 400, -150, 250],
  125. ['data2', 50, 20, 10, 40, 15, 25]
  126. ],
  127. groups: [['data1', 'data2']],
  128. type: 'bar'
  129. },
  130. axis: {
  131. x: {
  132. type: 'category'
  133. }
  134. }
  135. }
  136. })
  137. it('should be stacked', function() {
  138. var expectedBottom = [275, 293, 365, 281, 395, 290]
  139. chart.internal.main
  140. .selectAll('.c3-bars-data1 .c3-bar')
  141. .each(function(d, i) {
  142. var rect = d3
  143. .select(this)
  144. .node()
  145. .getBoundingClientRect()
  146. expect(rect.bottom).toBeCloseTo(expectedBottom[i], -1)
  147. })
  148. })
  149. })
  150. })
  151. describe('internal.isWithinBar', function() {
  152. describe('with normal axis', function() {
  153. beforeAll(function() {
  154. args = {
  155. data: {
  156. columns: [
  157. ['data1', 30, 200, 100, 400, -150, 250],
  158. ['data2', 50, 20, 10, 40, 15, 25],
  159. ['data3', -150, 120, 110, 140, 115, 125]
  160. ],
  161. type: 'bar'
  162. },
  163. axis: {
  164. rotated: false
  165. }
  166. }
  167. })
  168. it('should not be within bar', function() {
  169. var bar = d3.select('.c3-target-data1 .c3-bar-0').node()
  170. expect(chart.internal.isWithinBar([0, 0], bar)).toBeFalsy()
  171. })
  172. it('should be within bar', function() {
  173. var bar = d3.select('.c3-target-data1 .c3-bar-0').node()
  174. expect(chart.internal.isWithinBar([31, 280], bar)).toBeTruthy()
  175. })
  176. it('should not be within bar of negative value', function() {
  177. var bar = d3.select('.c3-target-data3 .c3-bar-0').node()
  178. expect(chart.internal.isWithinBar([68, 280], bar)).toBeFalsy()
  179. })
  180. it('should be within bar of negative value', function() {
  181. var bar = d3.select('.c3-target-data3 .c3-bar-0').node()
  182. expect(chart.internal.isWithinBar([68, 350], bar)).toBeTruthy()
  183. })
  184. })
  185. describe('with rotated axis', function() {
  186. beforeAll(function() {
  187. args.axis.rotated = true
  188. })
  189. it('should not be within bar', function() {
  190. var bar = d3.select('.c3-target-data1 .c3-bar-0').node()
  191. expect(chart.internal.isWithinBar([0, 0], bar)).toBeFalsy()
  192. })
  193. it('should be within bar', function() {
  194. var bar = d3.select('.c3-target-data1 .c3-bar-0').node()
  195. expect(chart.internal.isWithinBar([190, 20], bar)).toBeTruthy()
  196. })
  197. it('should be within bar of negative value', function() {
  198. var bar = d3.select('.c3-target-data3 .c3-bar-0').node()
  199. expect(chart.internal.isWithinBar([68, 50], bar)).toBeTruthy()
  200. })
  201. })
  202. })
  203. describe('bar spacing', function() {
  204. var createArgs = function(spacing) {
  205. return {
  206. size: {
  207. width: 500
  208. },
  209. data: {
  210. columns: [
  211. ['data1', 30, 200, 100],
  212. ['data2', 50, 20, 10],
  213. ['data3', 150, 120, 110],
  214. ['data4', 12, 24, 20]
  215. ],
  216. type: 'bar',
  217. groups: [['data1', 'data4']]
  218. },
  219. bar: {
  220. space: spacing
  221. }
  222. }
  223. }
  224. var getBBox = function(selector) {
  225. return d3
  226. .select(selector)
  227. .node()
  228. .getBBox()
  229. }
  230. var getBarContainerWidth = function() {
  231. return parseInt(getBBox('.c3-chart-bars').width)
  232. }
  233. var getBarContainerOffset = function() {
  234. return parseInt(getBBox('.c3-chart-bars').x)
  235. }
  236. var getBarBBox = function(name, idx) {
  237. return getBBox('.c3-target-' + name + ' .c3-bar-' + (idx || 0))
  238. }
  239. var getBarWidth = function(name, idx) {
  240. return parseInt(getBarBBox(name, idx).width)
  241. }
  242. var getBarOffset = function(name1, name2, idx) {
  243. var bbox1 = getBarBBox(name1, idx)
  244. var bbox2 = getBarBBox(name2, idx)
  245. return Math.floor(bbox2.x - (bbox1.x + bbox1.width))
  246. }
  247. it('should set bar spacing to 0', function() {
  248. args = createArgs(0)
  249. expect(true).toBeTruthy()
  250. })
  251. it('should display the bars without any spacing', function() {
  252. // all bars should have the same width
  253. expect(getBarWidth('data1', 0)).toEqual(30)
  254. expect(getBarWidth('data2', 0)).toEqual(30)
  255. expect(getBarWidth('data3', 0)).toEqual(30)
  256. expect(getBarWidth('data1', 1)).toEqual(30)
  257. expect(getBarWidth('data2', 1)).toEqual(30)
  258. expect(getBarWidth('data3', 1)).toEqual(30)
  259. expect(getBarWidth('data1', 2)).toEqual(30)
  260. expect(getBarWidth('data2', 2)).toEqual(30)
  261. expect(getBarWidth('data3', 2)).toEqual(30)
  262. // all offsets should be the same
  263. expect(getBarOffset('data1', 'data2', 0)).toEqual(0)
  264. expect(getBarOffset('data2', 'data3', 0)).toEqual(0)
  265. expect(getBarOffset('data1', 'data2', 1)).toEqual(0)
  266. expect(getBarOffset('data2', 'data3', 1)).toEqual(0)
  267. expect(getBarOffset('data1', 'data2', 2)).toEqual(0)
  268. expect(getBarOffset('data2', 'data3', 2)).toEqual(0)
  269. // default width/offset of the container for this chart
  270. expect(getBarContainerWidth()).toEqual(396)
  271. expect(getBarContainerOffset()).toEqual(31)
  272. })
  273. it('should set bar spacing to 0.25', function() {
  274. args = createArgs(0.25)
  275. expect(true).toBeTruthy()
  276. })
  277. it('should display the bars with a spacing ratio of 0.25', function() {
  278. // with bar_space of 0.25, the space between bars is
  279. // expected to be 25% of the original bar's width
  280. // which is ~7
  281. // expect all bars to be the same width
  282. expect(getBarWidth('data1', 0)).toEqual(22)
  283. expect(getBarWidth('data2', 0)).toEqual(22)
  284. expect(getBarWidth('data3', 0)).toEqual(22)
  285. expect(getBarWidth('data1', 1)).toEqual(22)
  286. expect(getBarWidth('data2', 1)).toEqual(22)
  287. expect(getBarWidth('data3', 1)).toEqual(22)
  288. expect(getBarWidth('data1', 2)).toEqual(22)
  289. expect(getBarWidth('data2', 2)).toEqual(22)
  290. expect(getBarWidth('data3', 2)).toEqual(22)
  291. // all offsets should be the same
  292. expect(getBarOffset('data1', 'data2', 0)).toEqual(7)
  293. expect(getBarOffset('data2', 'data3', 0)).toEqual(7)
  294. expect(getBarOffset('data1', 'data2', 1)).toEqual(7)
  295. expect(getBarOffset('data2', 'data3', 1)).toEqual(7)
  296. expect(getBarOffset('data1', 'data2', 2)).toEqual(7)
  297. expect(getBarOffset('data2', 'data3', 2)).toEqual(7)
  298. // expect the container to shrink a little because of
  299. // the offsets from the first/last chart
  300. // we add/subtract 1 because of approximation due to rounded values
  301. expect(getBarContainerWidth()).toEqual(396 - 7 - 1)
  302. expect(getBarContainerOffset()).toEqual(31 + (Math.floor(7 / 2) + 1))
  303. })
  304. it('should set bar spacing to 0.5', function() {
  305. args = createArgs(0.5)
  306. expect(true).toBeTruthy()
  307. })
  308. it('should display the bars with a spacing ratio of 0.5', function() {
  309. // with bar_space of 0.5, the space between bars is
  310. // expected to be 50% of the original bar's width
  311. // which is ~15
  312. // expect all bars to be the same width
  313. expect(getBarWidth('data1', 0)).toEqual(15)
  314. expect(getBarWidth('data2', 0)).toEqual(15)
  315. expect(getBarWidth('data3', 0)).toEqual(15)
  316. expect(getBarWidth('data1', 1)).toEqual(15)
  317. expect(getBarWidth('data2', 1)).toEqual(15)
  318. expect(getBarWidth('data3', 1)).toEqual(15)
  319. expect(getBarWidth('data1', 2)).toEqual(15)
  320. expect(getBarWidth('data2', 2)).toEqual(15)
  321. expect(getBarWidth('data3', 2)).toEqual(15)
  322. // all offsets should be the same
  323. expect(getBarOffset('data1', 'data2', 0)).toEqual(15)
  324. expect(getBarOffset('data2', 'data3', 0)).toEqual(15)
  325. expect(getBarOffset('data1', 'data2', 1)).toEqual(15)
  326. expect(getBarOffset('data2', 'data3', 1)).toEqual(15)
  327. expect(getBarOffset('data1', 'data2', 2)).toEqual(15)
  328. expect(getBarOffset('data2', 'data3', 2)).toEqual(15)
  329. // expect the container to shrink a little because of
  330. // the offsets from the first/last chart
  331. expect(getBarContainerWidth()).toEqual(396 - 15)
  332. expect(getBarContainerOffset()).toEqual(31 + Math.floor(15 / 2))
  333. })
  334. })
  335. })