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