line_spec.coffee 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. describe 'Morris.Line', ->
  2. it 'should raise an error when the placeholder element is not found', ->
  3. my_data = [{x: 1, y: 1}, {x: 2, y: 2}]
  4. fn = ->
  5. Morris.Line(
  6. element: "thisplacedoesnotexist"
  7. data: my_data
  8. xkey: 'x'
  9. ykeys: ['y']
  10. labels: ['dontcare']
  11. )
  12. fn.should.throw(/Graph container element not found/)
  13. it 'should make point styles customizable', ->
  14. my_data = [{x: 1, y: 1}, {x: 2, y: 2}]
  15. red = '#ff0000'
  16. blue = '#0000ff'
  17. chart = Morris.Line
  18. element: 'graph'
  19. data: my_data
  20. xkey: 'x'
  21. ykeys: ['y']
  22. labels: ['dontcare']
  23. pointStrokeColors: [red, blue]
  24. pointStrokeWidths: [1, 2]
  25. pointFillColors: [null, red]
  26. chart.pointStrokeWidthForSeries(0).should.equal 1
  27. chart.pointStrokeColorForSeries(0).should.equal red
  28. chart.pointStrokeWidthForSeries(1).should.equal 2
  29. chart.pointStrokeColorForSeries(1).should.equal blue
  30. chart.colorFor(chart.data[0], 0, 'point').should.equal chart.colorFor(chart.data[0], 0, 'line')
  31. chart.colorFor(chart.data[1], 1, 'point').should.equal red
  32. describe 'generating column labels', ->
  33. it 'should use user-supplied x value strings by default', ->
  34. chart = Morris.Line
  35. element: 'graph'
  36. data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
  37. xkey: 'x'
  38. ykeys: ['y']
  39. labels: ['dontcare']
  40. chart.data.map((x) -> x.label).should == ['2012 Q1', '2012 Q2']
  41. it 'should use a default format for timestamp x-values', ->
  42. d1 = new Date(2012, 0, 1)
  43. d2 = new Date(2012, 0, 2)
  44. chart = Morris.Line
  45. element: 'graph'
  46. data: [{x: d1.getTime(), y: 1}, {x: d2.getTime(), y: 1}]
  47. xkey: 'x'
  48. ykeys: ['y']
  49. labels: ['dontcare']
  50. chart.data.map((x) -> x.label).should == [d2.toString(), d1.toString()]
  51. it 'should use user-defined formatters', ->
  52. d = new Date(2012, 0, 1)
  53. chart = Morris.Line
  54. element: 'graph'
  55. data: [{x: d.getTime(), y: 1}, {x: '2012-01-02', y: 1}]
  56. xkey: 'x'
  57. ykeys: ['y']
  58. labels: ['dontcare']
  59. dateFormat: (d) ->
  60. x = new Date(d)
  61. "#{x.getYear()}/#{x.getMonth()+1}/#{x.getDay()}"
  62. chart.data.map((x) -> x.label).should == ['2012/1/1', '2012/1/2']
  63. describe 'rendering lines', ->
  64. beforeEach ->
  65. @defaults =
  66. element: 'graph'
  67. data: [{x:0, y:1, z:0}, {x:1, y:0, z:1}, {x:2, y:1, z:0}, {x:3, y:0, z:1}, {x:4, y:1, z:0}]
  68. xkey: 'x'
  69. ykeys: ['y', 'z']
  70. labels: ['y', 'z']
  71. lineColors: ['#abcdef', '#fedcba']
  72. smooth: true
  73. shouldHavePath = (regex, color = '#abcdef') ->
  74. # Matches an SVG path element within the rendered chart.
  75. #
  76. # Sneakily uses line colors to differentiate between paths within
  77. # the chart.
  78. $('#graph').find("path[stroke='#{color}']").attr('d').should.match regex
  79. it 'should generate smooth lines when options.smooth is true', ->
  80. Morris.Line @defaults
  81. shouldHavePath /M[\d\.]+,[\d\.]+(C[\d\.]+(,[\d\.]+){5}){4}/
  82. it 'should generate jagged lines when options.smooth is false', ->
  83. Morris.Line $.extend(@defaults, smooth: false)
  84. shouldHavePath /M[\d\.]+,[\d\.]+(L[\d\.]+,[\d\.]+){4}/
  85. it 'should generate smooth/jagged lines according to the value for each series when options.smooth is an array', ->
  86. Morris.Line $.extend(@defaults, smooth: ['y'])
  87. shouldHavePath /M[\d\.]+,[\d\.]+(C[\d\.]+(,[\d\.]+){5}){4}/, '#abcdef'
  88. shouldHavePath /M[\d\.]+,[\d\.]+(L[\d\.]+,[\d\.]+){4}/, '#fedcba'
  89. it 'should ignore undefined values', ->
  90. @defaults.data[2].y = undefined
  91. Morris.Line @defaults
  92. shouldHavePath /M[\d\.]+,[\d\.]+(C[\d\.]+(,[\d\.]+){5}){3}/
  93. it 'should break the line at null values', ->
  94. @defaults.data[2].y = null
  95. Morris.Line @defaults
  96. shouldHavePath /(M[\d\.]+,[\d\.]+C[\d\.]+(,[\d\.]+){5}){2}/
  97. it 'should make line width customizable', ->
  98. chart = Morris.Line $.extend(@defaults, lineWidth: [1, 2])
  99. chart.lineWidthForSeries(0).should.equal 1
  100. chart.lineWidthForSeries(1).should.equal 2
  101. describe '#createPath', ->
  102. it 'should generate a smooth line', ->
  103. testData = [{x: 0, y: 10}, {x: 10, y: 0}, {x: 20, y: 10}]
  104. path = Morris.Line.createPath(testData, true, 20)
  105. path.should.equal 'M0,10C2.5,7.5,7.5,0,10,0C12.5,0,17.5,7.5,20,10'
  106. it 'should generate a jagged line', ->
  107. testData = [{x: 0, y: 10}, {x: 10, y: 0}, {x: 20, y: 10}]
  108. path = Morris.Line.createPath(testData, false, 20)
  109. path.should.equal 'M0,10L10,0L20,10'
  110. it 'should prevent paths from descending below the bottom of the chart', ->
  111. testData = [{x: 0, y: 20}, {x: 10, y: 30}, {x: 20, y: 10}]
  112. path = Morris.Line.createPath(testData, true, 30)
  113. path.should.equal 'M0,20C2.5,22.5,7.5,30,10,30C12.5,28.75,17.5,15,20,10'
  114. it 'should break the line at null values', ->
  115. testData = [{x: 0, y: 10}, {x: 10, y: 0}, {x: 20, y: null}, {x: 30, y: 10}, {x: 40, y: 0}]
  116. path = Morris.Line.createPath(testData, true, 20)
  117. path.should.equal 'M0,10C2.5,7.5,7.5,2.5,10,0M30,10C32.5,7.5,37.5,2.5,40,0'
  118. it 'should ignore leading and trailing null values', ->
  119. testData = [{x: 0, y: null}, {x: 10, y: 10}, {x: 20, y: 0}, {x: 30, y: 10}, {x: 40, y: null}]
  120. path = Morris.Line.createPath(testData, true, 20)
  121. path.should.equal 'M10,10C12.5,7.5,17.5,0,20,0C22.5,0,27.5,7.5,30,10'
  122. describe 'svg structure', ->
  123. defaults =
  124. element: 'graph'
  125. data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
  126. lineColors: [ '#0b62a4', '#7a92a3']
  127. xkey: 'x'
  128. ykeys: ['y']
  129. labels: ['dontcare']
  130. it 'should contain a path that represents the line', ->
  131. chart = Morris.Line $.extend {}, defaults
  132. $('#graph').find("path[stroke='#0b62a4']").size().should.equal 1
  133. it 'should contain a circle for each data point', ->
  134. chart = Morris.Line $.extend {}, defaults
  135. $('#graph').find("circle").size().should.equal 2
  136. it 'should contain 5 grid lines', ->
  137. chart = Morris.Line $.extend {}, defaults
  138. $('#graph').find("path[stroke='#aaaaaa']").size().should.equal 5
  139. it 'should contain 9 text elements', ->
  140. chart = Morris.Line $.extend {}, defaults
  141. $('#graph').find("text").size().should.equal 9
  142. describe 'svg attributes', ->
  143. defaults =
  144. element: 'graph'
  145. data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
  146. xkey: 'x'
  147. ykeys: ['y', 'z']
  148. labels: ['Y', 'Z']
  149. lineColors: [ '#0b62a4', '#7a92a3']
  150. lineWidth: 3
  151. pointStrokeWidths: [5]
  152. pointStrokeColors: ['#ffffff']
  153. gridLineColor: '#aaa'
  154. gridStrokeWidth: 0.5
  155. gridTextColor: '#888'
  156. gridTextSize: 12
  157. pointSize: [5]
  158. it 'should have circles with configured fill color', ->
  159. chart = Morris.Line $.extend {}, defaults
  160. $('#graph').find("circle[fill='#0b62a4']").size().should.equal 2
  161. it 'should have circles with configured stroke width', ->
  162. chart = Morris.Line $.extend {}, defaults
  163. $('#graph').find("circle[stroke-width='5']").size().should.equal 2
  164. it 'should have circles with configured stroke color', ->
  165. chart = Morris.Line $.extend {}, defaults
  166. $('#graph').find("circle[stroke='#ffffff']").size().should.equal 2
  167. it 'should have line with configured line width', ->
  168. chart = Morris.Line $.extend {}, defaults
  169. $('#graph').find("path[stroke-width='3']").size().should.equal 1
  170. it 'should have text with configured font size', ->
  171. chart = Morris.Line $.extend {}, defaults
  172. $('#graph').find("text[font-size='12px']").size().should.equal 9
  173. it 'should have text with configured font size', ->
  174. chart = Morris.Line $.extend {}, defaults
  175. $('#graph').find("text[fill='#888888']").size().should.equal 9
  176. it 'should have circle with configured size', ->
  177. chart = Morris.Line $.extend {}, defaults
  178. $('#graph').find("circle[r='5']").size().should.equal 2