22
22
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
23
* THE POSSIBILITY OF SUCH DAMAGE.
24
24
*/
25
+
26
+ const msPerSecond = 1000 ;
27
+
25
28
Utilities . extendObject ( window . benchmarkController , {
26
29
updateGraphData : function ( testResult , testData , options )
27
30
{
@@ -30,10 +33,11 @@ Utilities.extendObject(window.benchmarkController, {
30
33
element . _testResult = testResult ;
31
34
element . _options = options ;
32
35
33
- var margins = new Insets ( 30 , 30 , 30 , 40 ) ;
36
+ // top, right, bottom, left.
37
+ var margins = new Insets ( 30 , 30 , 50 , 40 ) ;
38
+ // Note that changes to header content (in onGraphTypeChanged()) can change the available size, so we prepopulate
39
+ // "score" and "confidence" elements with non-breaking spaces in the HTML.
34
40
var size = Point . elementClientSize ( element ) ;
35
- size . y = window . innerHeight - element . offsetTop ;
36
- size = size . subtract ( margins . size ) ;
37
41
38
42
// Convert from compact JSON output to propertied data
39
43
var samplesWithProperties = { } ;
@@ -98,14 +102,43 @@ Utilities.extendObject(window.benchmarkController, {
98
102
this . _addRegressionLine ( svg , xScale , yScale , data . segment1 , data . stdev ) ;
99
103
this . _addRegressionLine ( svg , xScale , yScale , data . segment2 , data . stdev ) ;
100
104
} ,
105
+
106
+ _tickValuesForFrameRate : function ( frameRate , minValue , maxValue )
107
+ {
108
+ // Tick labels go up to 1.5x frame rate
109
+ const buildInFrameRates = {
110
+ 15 : [ 5 , 10 , 15 , 20 ] ,
111
+ 30 : [ 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 ] ,
112
+ 45 : [ 30 , 35 , 40 , 45 , 50 , 55 , 60 ] ,
113
+ 60 : [ 30 , 35 , 40 , 45 , 50 , 55 , 60 , 90 ] ,
114
+ 90 : [ 30 , 35 , 40 , 45 , 50 , 55 , 60 , 90 , 120 ] ,
115
+ 120 : [ 30 , 40 , 50 , 60 , 70 , 80 , 100 , 120 , 150 ] ,
116
+ 144 : [ 40 , 50 , 60 , 70 , 80 , 90 , 100 , 110 , 120 , 130 , 140 , 150 , 200 ] ,
117
+ } ;
118
+
119
+ let tickValues = buildInFrameRates [ frameRate ] ;
120
+ if ( ! tickValues ) {
121
+ const minLabel = Math . round ( minValue / 10 ) * 10 ;
122
+ const maxLabel = Math . round ( maxValue / 10 ) * 10 ;
123
+ tickValues = [ ] ;
124
+ let curValue = minLabel ;
125
+ while ( curValue <= maxLabel ) {
126
+ tickValues . push ( curValue ) ;
127
+ curValue += 20 ;
128
+ }
129
+ }
130
+
131
+ tickValues = tickValues . map ( ( x ) => msPerSecond / x ) ;
132
+ return tickValues ;
133
+ } ,
101
134
102
135
createComplexityGraph : function ( result , timeRegressions , data , options , margins , size )
103
136
{
104
137
var svg = d3 . select ( "#test-graph-data" ) . append ( "svg" )
105
138
. attr ( "id" , "complexity-graph" )
106
139
. attr ( "class" , "hidden" )
107
- . attr ( "width" , size . width + margins . left + margins . right )
108
- . attr ( "height" , size . height + margins . top + margins . bottom )
140
+ . attr ( "width" , size . width )
141
+ . attr ( "height" , size . height )
109
142
. append ( "g" )
110
143
. attr ( "transform" , "translate(" + margins . left + "," + margins . top + ")" ) ;
111
144
@@ -124,38 +157,47 @@ Utilities.extendObject(window.benchmarkController, {
124
157
xMax = d3 . max ( timeSamples , function ( s ) { return s . complexity ; } ) ;
125
158
}
126
159
160
+ const axisWidth = size . width - margins . left - margins . right ;
161
+ const axisHeight = size . height - margins . top - margins . bottom ;
162
+
163
+ // The y axis is frameLength in ms, inverted with the axis labels showing fps.
164
+ const minFrameRate = this . _targetFrameRate / 4 ;
165
+ const maxFrameRate = this . _targetFrameRate * 1.5 ;
166
+
167
+ const yMin = msPerSecond / minFrameRate ;
168
+ const yMax = msPerSecond / maxFrameRate ;
169
+
127
170
var xScale = d3 . scale . linear ( )
128
- . range ( [ 0 , size . width ] )
171
+ . range ( [ 0 , axisWidth ] )
129
172
. domain ( [ xMin , xMax ] ) ;
130
173
var yScale = d3 . scale . linear ( )
131
- . range ( [ size . height , 0 ] )
132
- . domain ( [ 1000 / ( this . _targetFrameRate / 3 ) , 1000 / this . _targetFrameRate ] ) ;
174
+ . range ( [ axisHeight , 0 ] )
175
+ . domain ( [ yMin , yMax ] ) ;
133
176
134
177
var xAxis = d3 . svg . axis ( )
135
178
. scale ( xScale )
136
179
. orient ( "bottom" ) ;
137
180
var yAxis = d3 . svg . axis ( )
138
181
. scale ( yScale )
139
- . tickValues ( [ 1000 / 20 , 1000 / 25 , 1000 / 30 , 1000 / 35 , 1000 / 40 , 1000 / 45 , 1000 / 50 , 1000 / 55 , 1000 / 60 , 1000 / 90 , 1000 / 120 ] )
140
- . tickFormat ( function ( d ) { return ( 1000 / d ) . toFixed ( 0 ) ; } )
182
+ . tickValues ( this . _tickValuesForFrameRate ( this . _targetFrameRate , minFrameRate , maxFrameRate ) )
183
+ . tickFormat ( function ( d ) { return ( msPerSecond / d ) . toFixed ( 0 ) ; } )
141
184
. orient ( "left" ) ;
142
185
143
186
// x-axis
144
187
svg . append ( "g" )
145
188
. attr ( "class" , "x axis" )
146
- . attr ( "transform" , "translate(0," + size . height + ")" )
189
+ . attr ( "transform" , "translate(0," + axisHeight + ")" )
147
190
. call ( xAxis ) ;
148
191
149
192
// y-axis
150
- svg . append ( "g" )
193
+ var yAxisGroup = svg . append ( "g" )
151
194
. attr ( "class" , "y axis" )
152
195
. call ( yAxis ) ;
153
196
154
197
// time result
155
198
var mean = svg . append ( "g" )
156
199
. attr ( "class" , "mean complexity" ) ;
157
200
var timeResult = result [ Strings . json . controller ] ;
158
- var yMin = yScale . domain ( ) [ 0 ] , yMax = yScale . domain ( ) [ 1 ] ;
159
201
this . _addRegressionLine ( mean , xScale , yScale , [ [ timeResult . average , yMin ] , [ timeResult . average , yMax ] ] , timeResult . stdev , true ) ;
160
202
161
203
// regression
@@ -166,7 +208,7 @@ Utilities.extendObject(window.benchmarkController, {
166
208
var histogram = d3 . layout . histogram ( )
167
209
. bins ( xScale . ticks ( 100 ) ) ( bootstrapResult . data ) ;
168
210
var yBootstrapScale = d3 . scale . linear ( )
169
- . range ( [ size . height / 2 , 0 ] )
211
+ . range ( [ axisHeight / 2 , 0 ] )
170
212
. domain ( [ 0 , d3 . max ( histogram , function ( d ) { return d . y ; } ) ] ) ;
171
213
group = svg . append ( "g" ) . attr ( "class" , "bootstrap" ) ;
172
214
var bar = group . selectAll ( ".bar" )
@@ -176,14 +218,14 @@ Utilities.extendObject(window.benchmarkController, {
176
218
. attr ( "transform" , function ( d ) { return "translate(" + xScale ( d . x ) + "," + yBootstrapScale ( d . y ) + ")" ; } ) ;
177
219
bar . append ( "rect" )
178
220
. attr ( "x" , 1 )
179
- . attr ( "y" , size . height / 2 )
221
+ . attr ( "y" , axisHeight / 2 )
180
222
. attr ( "width" , xScale ( histogram [ 1 ] . x ) - xScale ( histogram [ 0 ] . x ) - 1 )
181
- . attr ( "height" , function ( d ) { return size . height / 2 - yBootstrapScale ( d . y ) ; } ) ;
223
+ . attr ( "height" , function ( d ) { return axisHeight / 2 - yBootstrapScale ( d . y ) ; } ) ;
182
224
group = group . append ( "g" ) . attr ( "class" , "median" ) ;
183
225
this . _addRegressionLine ( group , xScale , yScale , [ [ bootstrapResult . median , yMin ] , [ bootstrapResult . median , yMax ] ] , [ bootstrapResult . confidenceLow , bootstrapResult . confidenceHigh ] , true ) ;
184
226
group . append ( "circle" )
185
227
. attr ( "cx" , xScale ( bootstrapResult . median ) )
186
- . attr ( "cy" , yScale ( 1000 / 60 ) )
228
+ . attr ( "cy" , yScale ( msPerSecond / 60 ) )
187
229
. attr ( "r" , 5 ) ;
188
230
}
189
231
@@ -193,7 +235,8 @@ Utilities.extendObject(window.benchmarkController, {
193
235
. selectAll ( "line" )
194
236
. data ( data [ Strings . json . complexity ] )
195
237
. enter ( ) ;
196
- group . append ( "line" )
238
+
239
+ group . append ( "line" )
197
240
. attr ( "x1" , function ( d ) { return xScale ( d . complexity ) - 3 ; } )
198
241
. attr ( "x2" , function ( d ) { return xScale ( d . complexity ) + 3 ; } )
199
242
. attr ( "y1" , function ( d ) { return yScale ( d . frameLength ) - 3 ; } )
@@ -236,7 +279,7 @@ Utilities.extendObject(window.benchmarkController, {
236
279
. attr ( "x" , 0 )
237
280
. attr ( "y" , 0 )
238
281
. attr ( "width" , size . width )
239
- . attr ( "height" , size . height ) ;
282
+ . attr ( "height" , axisHeight ) ;
240
283
241
284
area . on ( "mouseover" , function ( ) {
242
285
document . querySelector ( "#complexity-graph .cursor" ) . classList . remove ( "hidden" ) ;
@@ -256,22 +299,25 @@ Utilities.extendObject(window.benchmarkController, {
256
299
. attr ( "y2" , location [ 1 ] ) ;
257
300
cursorGroup . select ( "text.y" )
258
301
. attr ( "y" , location [ 1 ] )
259
- . text ( ( 1000 / location_domain [ 1 ] ) . toFixed ( 1 ) ) ;
302
+ . text ( ( msPerSecond / location_domain [ 1 ] ) . toFixed ( 1 ) ) ;
260
303
} ) ;
261
304
} ,
262
305
263
306
createTimeGraph : function ( result , samples , marks , regressions , options , margins , size )
264
307
{
308
+ const axisWidth = size . width - margins . left - margins . right ;
309
+ const axisHeight = size . height - margins . top - margins . bottom ;
310
+
265
311
var svg = d3 . select ( "#test-graph-data" ) . append ( "svg" )
266
312
. attr ( "id" , "time-graph" )
267
- . attr ( "width" , size . width + margins . left + margins . right )
268
- . attr ( "height" , size . height + margins . top + margins . bottom )
313
+ . attr ( "width" , size . width )
314
+ . attr ( "height" , size . height )
269
315
. append ( "g" )
270
316
. attr ( "transform" , "translate(" + margins . left + "," + margins . top + ")" ) ;
271
317
272
318
// Axis scales
273
319
var x = d3 . scale . linear ( )
274
- . range ( [ 0 , size . width ] )
320
+ . range ( [ 0 , axisWidth ] )
275
321
. domain ( [
276
322
Math . min ( d3 . min ( samples , function ( s ) { return s . time ; } ) , 0 ) ,
277
323
d3 . max ( samples , function ( s ) { return s . time ; } ) ] ) ;
@@ -280,37 +326,47 @@ Utilities.extendObject(window.benchmarkController, {
280
326
return s . complexity ;
281
327
return 0 ;
282
328
} ) ;
329
+ complexityMax *= 1.2 ;
283
330
331
+ const graphTop = 10 ;
284
332
var yLeft = d3 . scale . linear ( )
285
- . range ( [ size . height , 0 ] )
333
+ . range ( [ axisHeight , graphTop ] )
286
334
. domain ( [ 0 , complexityMax ] ) ;
335
+
336
+
337
+ const minFrameRate = this . _targetFrameRate / 2 ;
338
+ const maxFrameRate = this . _targetFrameRate * 1.5 ;
339
+ const yRightMin = msPerSecond / minFrameRate ;
340
+ const yRightMax = msPerSecond / maxFrameRate ;
341
+
287
342
var yRight = d3 . scale . linear ( )
288
- . range ( [ size . height , 0 ] )
289
- . domain ( [ 1000 / ( this . _targetFrameRate / 3 ) , 1000 / this . _targetFrameRate ] ) ;
343
+ . range ( [ axisHeight , graphTop ] )
344
+ . domain ( [ yRightMin , yRightMax ] ) ;
290
345
291
346
// Axes
292
347
var xAxis = d3 . svg . axis ( )
293
348
. scale ( x )
294
349
. orient ( "bottom" )
295
- . tickFormat ( function ( d ) { return ( d / 1000 ) . toFixed ( 0 ) ; } ) ;
350
+ . tickFormat ( function ( d ) { return ( d / msPerSecond ) . toFixed ( 0 ) ; } ) ;
296
351
var yAxisLeft = d3 . svg . axis ( )
297
352
. scale ( yLeft )
298
353
. orient ( "left" ) ;
354
+
299
355
var yAxisRight = d3 . svg . axis ( )
300
356
. scale ( yRight )
301
- . tickValues ( [ 1000 / 20 , 1000 / 25 , 1000 / 30 , 1000 / 35 , 1000 / 40 , 1000 / 45 , 1000 / 50 , 1000 / 55 , 1000 / 60 , 1000 / 90 , 1000 / 120 ] )
302
- . tickFormat ( function ( d ) { return ( 1000 / d ) . toFixed ( 0 ) ; } )
357
+ . tickValues ( this . _tickValuesForFrameRate ( this . _targetFrameRate , minFrameRate , maxFrameRate ) )
358
+ . tickFormat ( function ( d ) { return ( msPerSecond / d ) . toFixed ( 0 ) ; } )
303
359
. orient ( "right" ) ;
304
360
305
361
// x-axis
306
362
svg . append ( "g" )
307
363
. attr ( "class" , "x axis" )
308
364
. attr ( "fill" , "rgb(235, 235, 235)" )
309
- . attr ( "transform" , "translate(0," + size . height + ")" )
365
+ . attr ( "transform" , "translate(0," + axisHeight + ")" )
310
366
. call ( xAxis )
311
367
. append ( "text" )
312
368
. attr ( "class" , "label" )
313
- . attr ( "x" , size . width )
369
+ . attr ( "x" , axisWidth )
314
370
. attr ( "y" , - 6 )
315
371
. attr ( "fill" , "rgb(235, 235, 235)" )
316
372
. style ( "text-anchor" , "end" )
@@ -334,7 +390,7 @@ Utilities.extendObject(window.benchmarkController, {
334
390
svg . append ( "g" )
335
391
. attr ( "class" , "yRight axis" )
336
392
. attr ( "fill" , "#FA4925" )
337
- . attr ( "transform" , "translate(" + size . width + ", 0)" )
393
+ . attr ( "transform" , "translate(" + axisWidth + ", 0)" )
338
394
. call ( yAxisRight )
339
395
. append ( "text" )
340
396
. attr ( "class" , "label" )
@@ -376,15 +432,15 @@ Utilities.extendObject(window.benchmarkController, {
376
432
var frameLength = result [ Strings . json . frameLength ] ;
377
433
var regression = svg . append ( "g" )
378
434
. attr ( "class" , "fps mean" ) ;
379
- this . _addRegressionLine ( regression , x , yRight , [ [ samples [ 0 ] . time , 1000 / frameLength . average ] , [ samples [ samples . length - 1 ] . time , 1000 / frameLength . average ] ] , frameLength . stdev ) ;
435
+ this . _addRegressionLine ( regression , x , yRight , [ [ samples [ 0 ] . time , msPerSecond / frameLength . average ] , [ samples [ samples . length - 1 ] . time , msPerSecond / frameLength . average ] ] , frameLength . stdev ) ;
380
436
}
381
437
382
438
// right-target
383
439
if ( options [ "controller" ] == "adaptive" ) {
384
- var targetFrameLength = 1000 / options [ "frame-rate" ] ;
440
+ var targetFrameLength = msPerSecond / options [ "frame-rate" ] ;
385
441
svg . append ( "line" )
386
442
. attr ( "x1" , x ( 0 ) )
387
- . attr ( "x2" , size . width )
443
+ . attr ( "x2" , axisWidth )
388
444
. attr ( "y1" , yRight ( targetFrameLength ) )
389
445
. attr ( "y2" , yRight ( targetFrameLength ) )
390
446
. attr ( "class" , "target-fps marker" ) ;
@@ -485,8 +541,8 @@ Utilities.extendObject(window.benchmarkController, {
485
541
. attr ( "fill" , "transparent" )
486
542
. attr ( "x" , 0 )
487
543
. attr ( "y" , 0 )
488
- . attr ( "width" , size . width )
489
- . attr ( "height" , size . height ) ;
544
+ . attr ( "width" , axisWidth )
545
+ . attr ( "height" , axisHeight ) ;
490
546
491
547
var timeBisect = d3 . bisector ( function ( d ) { return d . time ; } ) . right ;
492
548
var statsToHighlight = [ "complexity" , "rawFPS" , "filteredFPS" ] ;
@@ -506,7 +562,7 @@ Utilities.extendObject(window.benchmarkController, {
506
562
var cursor_y = yAxisRight . scale ( ) . domain ( ) [ 1 ] ;
507
563
var ys = [ yRight ( yAxisRight . scale ( ) . domain ( ) [ 0 ] ) , yRight ( yAxisRight . scale ( ) . domain ( ) [ 1 ] ) ] ;
508
564
509
- document . querySelector ( "#test-graph nav .time" ) . textContent = ( data . time / 1000 ) . toFixed ( 4 ) + "s (" + index + ")" ;
565
+ document . querySelector ( "#test-graph nav .time" ) . textContent = ( data . time / msPerSecond ) . toFixed ( 4 ) + "s (" + index + ")" ;
510
566
statsToHighlight . forEach ( function ( name ) {
511
567
var element = document . querySelector ( "#test-graph nav ." + name ) ;
512
568
var content = "" ;
@@ -517,12 +573,12 @@ Utilities.extendObject(window.benchmarkController, {
517
573
data_y = yLeft ( data . complexity ) ;
518
574
break ;
519
575
case "rawFPS" :
520
- content = ( 1000 / data . frameLength ) . toFixed ( 2 ) ;
576
+ content = ( msPerSecond / data . frameLength ) . toFixed ( 2 ) ;
521
577
data_y = yRight ( data . frameLength ) ;
522
578
break ;
523
579
case "filteredFPS" :
524
580
if ( "smoothedFrameLength" in data ) {
525
- content = ( 1000 / data . smoothedFrameLength ) . toFixed ( 2 ) ;
581
+ content = ( msPerSecond / data . smoothedFrameLength ) . toFixed ( 2 ) ;
526
582
data_y = yRight ( data . smoothedFrameLength ) ;
527
583
}
528
584
break ;
0 commit comments