@@ -131,6 +131,7 @@ function transformAppVersion(inpVersion) {
131131 var realSession = state . realSession ;
132132 var realTotalSession = ( realSession . usage && realSession . usage [ 'total-sessions' ] . total ) || 0 ;
133133 var dashboard = { } ;
134+ var wholeUsers = { } ;
134135
135136 if ( "data" in state . rawData ) {
136137 dashboard = countlyCommon . getDashboardData ( state . filteredData . data , [ "cr" , "crnf" , "crf" , "cru" , "cruf" , "crunf" , "crru" , "crau" , "crauf" , "craunf" , "crses" , "crfses" , "crnfses" , "cr_s" , "cr_u" ] , [ "cru" , "crau" , "cruf" , "crunf" , "crauf" , "craunf" , "cr_u" ] , null , countlyCrashes . clearObject ) ;
@@ -139,6 +140,12 @@ function transformAppVersion(inpVersion) {
139140 return dashboard ;
140141 }
141142
143+ if ( 'users' in state . rawData ) {
144+ wholeUsers . total = state . rawData . users . total ;
145+ wholeUsers . fatal = state . rawData . users . fatal ;
146+ wholeUsers . nonfatal = state . rawData . users . nonfatal ;
147+ }
148+
142149 /**
143150 * Populates the metric's change and trend properties according to its total and prev-total.
144151 * @param {string } metric - A metric name e.g. "cr"
@@ -173,7 +180,7 @@ function transformAppVersion(inpVersion) {
173180 } ) ;
174181 }
175182
176- if ( isPercent && [ "crses" , "crnfses" , "crfses" , "crau" , "craunf" , "crauf" ] . includes ( metric ) ) {
183+ if ( isPercent && [ "crses" , "crnfses" , "crfses" , "crau" , "craunf" , "crauf" , 'crinv' , 'crfinv' , 'crnfinv' , 'crauinv' , 'craufinv' , 'craunfinv' ] . includes ( metric ) ) {
177184 [ "total" , "prev-total" ] . forEach ( function ( prop ) {
178185 dashboard [ metric ] [ prop ] = dashboard [ metric ] [ prop ] . toFixed ( 2 ) + '%' ;
179186 } ) ;
@@ -195,7 +202,7 @@ function transformAppVersion(inpVersion) {
195202 } ) ;
196203 } ) ;
197204
198- [ "cr-session" , "crtf" , "crtnf" , "crau" , "crses" ] . forEach ( function ( metric ) {
205+ [ "cr-session" , "crtf" , "crtnf" , "crau" , "crses" , 'crinv' , 'crfinv' , 'crnfinv' , 'crauinv' , 'craufinv' , 'craunfinv' ] . forEach ( function ( metric ) {
199206 dashboard [ metric ] = { } ;
200207 } ) ;
201208
@@ -211,9 +218,16 @@ function transformAppVersion(inpVersion) {
211218 dashboard . cr_s [ prop ] += dashboard . crfses [ prop ] + dashboard . crnfses [ prop ] ;
212219 }
213220
214- if ( dashboard . cr_u [ prop ] < ( dashboard . crauf [ prop ] + dashboard . craunf [ prop ] ) ) {
215- dashboard . cr_u [ prop ] += dashboard . crauf [ prop ] + dashboard . craunf [ prop ] ;
221+ // derive user count from whole users
222+ if ( dashboard . crau [ prop ] > dashboard . cr_u [ prop ] && 'users' in state . rawData ) {
223+ dashboard . crauf [ prop ] = dashboard . cr_u [ prop ] * ( ( wholeUsers . fatal / wholeUsers . total ) - ( dashboard . crf [ prop ] / dashboard . cr_s [ prop ] ) ) ;
224+ dashboard . craunf [ prop ] = dashboard . cr_u [ prop ] * ( ( wholeUsers . nonfatal / wholeUsers . total ) - ( dashboard . crnf [ prop ] / dashboard . cr_s [ prop ] ) ) ;
225+ dashboard . crau [ prop ] = dashboard . crauf [ prop ] + dashboard . craunf [ prop ] ;
216226 }
227+
228+ dashboard . crinv [ prop ] = Math . max ( 0 , dashboard . cr_s [ prop ] - dashboard . cr [ prop ] ) ;
229+ dashboard . crfinv [ prop ] = Math . max ( 0 , dashboard . cr_s [ prop ] - dashboard . crf [ prop ] ) ;
230+ dashboard . crnfinv [ prop ] = Math . max ( 0 , dashboard . cr_s [ prop ] - dashboard . crnf [ prop ] ) ;
217231 } ) ;
218232
219233 [ "cr-session" , "crtf" , "crtnf" ] . forEach ( function ( metric ) {
@@ -222,7 +236,7 @@ function transformAppVersion(inpVersion) {
222236
223237 [ "crau" , "craunf" , "crauf" ] . forEach ( function ( name ) {
224238 [ "total" , "prev-total" ] . forEach ( function ( prop ) {
225- dashboard [ name ] [ prop ] = Math . min ( 100 , ( dashboard . cr_u [ prop ] === 0 || dashboard [ name ] [ prop ] === 0 ) ? 100 : ( ( dashboard . cr_u [ prop ] - dashboard [ name ] [ prop ] ) / dashboard . cr_u [ prop ] * 100 ) ) ;
239+ dashboard [ name ] [ prop ] = Math . min ( 100 , ( dashboard . cr_u [ prop ] === 0 || dashboard [ name ] [ prop ] === 0 ) ? 100 : ( Math . abs ( dashboard . cr_u [ prop ] - dashboard [ name ] [ prop ] ) / dashboard . cr_u [ prop ] * 100 ) ) ;
226240 } ) ;
227241 populateMetric ( name , true ) ;
228242 } ) ;
@@ -249,6 +263,22 @@ function transformAppVersion(inpVersion) {
249263 populateMetric ( name , true ) ;
250264 } ) ;
251265
266+ [ 'crinv' , 'crfinv' , 'crnfinv' ] . forEach ( function ( name ) {
267+ [ "total" , "prev-total" ] . forEach ( function ( prop ) {
268+ var propValue = 0 ;
269+
270+ if ( dashboard . cr_s [ prop ] === 0 ) {
271+ propValue = 100 ;
272+ }
273+ else {
274+ propValue = dashboard [ name ] [ prop ] / dashboard . cr_s [ prop ] * 100 ;
275+ }
276+
277+ dashboard [ name ] [ prop ] = Math . min ( 100 , propValue ) ;
278+ } ) ;
279+ populateMetric ( name , true ) ;
280+ } ) ;
281+
252282 return dashboard ;
253283 } ;
254284
@@ -270,14 +300,22 @@ function transformAppVersion(inpVersion) {
270300 return { } ;
271301 }
272302
303+ var wholeUsers = { } ;
304+ if ( 'users' in state . rawData ) {
305+ wholeUsers . total = state . rawData . users . total ;
306+ wholeUsers . fatal = state . rawData . users . fatal ;
307+ wholeUsers . nonfatal = state . rawData . users . nonfatal ;
308+ }
309+
273310 var chartData , dataProps ;
274311
275312 var metricChartConfig = {
276313 "cr-session" : { labelKey : "crashes.total-per-session" , colorIndex : 1 } ,
277314 "crses" : { labelKey : "crashes.free-sessions" , colorIndex : 1 } ,
278315 "crau" : { labelKey : "crashes.free-users" , colorIndex : 1 } ,
279316 "cr" : { labelKey : "crashes.total" , colorIndex : 1 } ,
280- "cru" : { labelKey : "crashes.unique" , colorIndex : 1 }
317+ "cru" : { labelKey : "crashes.unique" , colorIndex : 1 } ,
318+ "crinv" : { labelKey : "crashes.free-sessions" , colorIndex : 1 } ,
281319 } [ metric ] ;
282320
283321 if ( typeof metricChartConfig !== "undefined" ) {
@@ -298,7 +336,8 @@ function transformAppVersion(inpVersion) {
298336 "crses" : { "fatal" : "crfses" , "nonfatal" : "crnfses" } ,
299337 "crau" : { "fatal" : "crauf" , "nonfatal" : "craunf" } ,
300338 "cr" : { "fatal" : "crf" , "nonfatal" : "crnf" } ,
301- "cru" : { "fatal" : "cruf" , "nonfatal" : "crunf" }
339+ "cru" : { "fatal" : "cruf" , "nonfatal" : "crunf" } ,
340+ "crinv" : { "fatal" : "crfinv" , "nonfatal" : "crnfinv" } ,
302341 } ;
303342
304343 name = name || ( ( metric in metricNames && state . activeFilter . fatality !== "both" ) ? metricNames [ metric ] [ state . activeFilter . fatality ] : metric ) ;
@@ -311,7 +350,15 @@ function transformAppVersion(inpVersion) {
311350 return ( obj . cr_s === 0 || obj . crfses + obj . crnfses === 0 ) ? 100 : Math . round ( Math . min ( Math . max ( ( obj . crfses + obj . crnfses - obj . cr_s ) / obj . cr_s , 0 ) , 1 ) * 10000 ) / 100 ;
312351 } ,
313352 "^crau$" : function ( obj ) {
314- return ( obj . cr_u === 0 || obj . crauf + obj . craunf === 0 ) ? 100 : Math . round ( Math . min ( Math . max ( ( obj . crauf + obj . craunf - obj . cr_u ) / obj . cr_u , 0 ) , 1 ) * 10000 ) / 100 ;
353+ if ( obj . cr_u === 0 || obj . crauf + obj . craunf === 0 ) {
354+ return 100 ;
355+ }
356+ else if ( obj . crauf + obj . craunf > obj . cr_u && obj . cr_s !== 0 && 'users' in state . rawData ) {
357+ var value = ( obj . cr_u - ( obj . cr_u * ( ( wholeUsers . fatal / wholeUsers . total ) - ( obj . crf / obj . cr_s ) ) ) - ( obj . cr_u * ( ( wholeUsers . nonfatal / wholeUsers . total ) - ( obj . crnf / obj . cr_s ) ) ) ) / obj . cr_u * 100 ;
358+ return Math . round ( value * 100 ) / 100 ;
359+ }
360+
361+ return Math . round ( Math . min ( Math . max ( ( obj . crauf + obj . craunf - obj . cr_u ) / obj . cr_u , 0 ) , 1 ) * 10000 ) / 100 ;
315362 } ,
316363 "^cr$" : function ( obj ) {
317364 return obj . crf + obj . crnf ;
@@ -325,9 +372,40 @@ function transformAppVersion(inpVersion) {
325372 "^crn?fses$" : function ( obj ) {
326373 return ( obj . cr_s === 0 || obj [ name ] === 0 ) ? 100 : Math . round ( Math . min ( obj [ name ] / obj . cr_s , 1 ) * 10000 ) / 100 ;
327374 } ,
328- "^craun?f$" : function ( obj ) {
329- return ( obj . cr_s === 0 || obj [ name ] === 0 ) ? 100 : Math . round ( Math . min ( obj [ name ] / obj . cr_u , 1 ) * 10000 ) / 100 ;
330- }
375+ "^crauf$" : function ( obj ) {
376+ if ( obj . cr_u === 0 || obj [ name ] === 0 ) {
377+ return 100 ;
378+ }
379+ else if ( obj . crauf + obj . craunf > obj . cr_u && obj . cr_s !== 0 && 'users' in state . rawData ) {
380+ var value = ( obj . cr_u - ( obj . cr_u * ( ( wholeUsers . fatal / wholeUsers . total ) - ( obj . crf / obj . cr_s ) ) ) ) / obj . cr_u * 100 ;
381+ return Math . round ( value * 100 ) / 100 ;
382+ }
383+
384+ return Math . round ( Math . min ( obj [ name ] / obj . cr_u , 1 ) * 10000 ) / 100 ;
385+ } ,
386+ "^craunf$" : function ( obj ) {
387+ if ( obj . cr_u === 0 || obj [ name ] === 0 ) {
388+ return 100 ;
389+ }
390+ else if ( obj . crauf + obj . craunf > obj . cr_u && obj . cr_s !== 0 && 'users' in state . rawData ) {
391+ var value = ( obj . cr_u - ( obj . cr_u * ( ( wholeUsers . nonfatal / wholeUsers . total ) - ( obj . crnf / obj . cr_s ) ) ) ) / obj . cr_u * 100 ;
392+ return Math . round ( value * 100 ) / 100 ;
393+ }
394+
395+ return Math . round ( Math . min ( obj [ name ] / obj . cr_u , 1 ) * 10000 ) / 100 ;
396+ } ,
397+ '^crinv$' : function ( obj ) {
398+ var value = ( obj . cr_s === 0 ) ? 100 : ( obj . cr_s - ( obj . crf + obj . crnf ) ) / obj . cr_s * 100 ;
399+ return Math . round ( value * 100 ) / 100 ;
400+ } ,
401+ '^crfinv$' : function ( obj ) {
402+ var value = ( obj . cr_s === 0 ) ? 100 : ( obj . cr_s - obj . crf ) / obj . cr_s * 100 ;
403+ return Math . round ( value * 100 ) / 100 ;
404+ } ,
405+ '^crnfinv$' : function ( obj ) {
406+ var value = ( obj . cr_s === 0 ) ? 100 : ( obj . cr_s - obj . crnf ) / obj . cr_s * 100 ;
407+ return Math . round ( value * 100 ) / 100 ;
408+ } ,
331409 } ;
332410
333411 dataProps = [
@@ -370,6 +448,7 @@ function transformAppVersion(inpVersion) {
370448 state . isLoading = false ;
371449 return chartOptions ;
372450 } ;
451+
373452 } ;
374453
375454 _overviewSubmodule . getters . statistics = function ( state ) {
0 commit comments