@@ -12,10 +12,9 @@ import {
1212 getFormatter ,
1313} from "../util/format" ;
1414import { colorBasedOnPackageName , colorGreyscale } from "../util/color" ;
15+ import { deltaDiff } from '../util/flamebearer' ;
1516
16-
17- const PX_PER_LEVEL = 18 ;
18- const COLLAPSE_THRESHOLD = 0 ;
17+ const COLLAPSE_THRESHOLD = 10 ;
1918const LABEL_THRESHOLD = 10 ;
2019const HIGHLIGHT_NODE_COLOR = "#48CE73" ; // green
2120const GAP = 0.5 ;
@@ -66,7 +65,9 @@ class FlameGraphRenderer extends React.Component {
6665 this . rangeMax = 1 ;
6766 this . query = "" ;
6867
69- window . addEventListener ( "resize" , this . resizeHandler ) ;
68+ const panelContainer = document . querySelector ( '.flamegraph-wrapper' ) ?. closest ( '.panel-wrapper' ) ;
69+ const panelContanerResizeObserver = new ResizeObserver ( this . resizeHandler ) ;
70+ panelContanerResizeObserver . observe ( panelContainer ) ;
7071 window . addEventListener ( "focus" , this . focusHandler ) ;
7172
7273 if ( this . props . shortcut ) {
@@ -110,9 +111,11 @@ class FlameGraphRenderer extends React.Component {
110111 }
111112
112113 fetchFlameBearerData ( url ) {
113- this . setState ( { "flamebearer" :{ "names" :[ "total" , "runtime.mstart" , "runtime.mstart1" , "runtime.sysmon" , "runtime.usleep" , "runtime.startm" , "runtime.notewakeup" , "runtime.futexwakeup" , "runtime.futex" , "runtime.notetsleep" , "runtime.notetsleep_internal" , "runtime.futexsleep" , "runtime.nanotime" , "runtime.lockWithRank" , "runtime.lock2" , "runtime.morestack" , "runtime.newstack" , "runtime.gopreempt_m" , "runtime.goschedImpl" , "runtime.schedule" , "runtime.resetspinning" , "runtime.wakep" , "runtime.mcall" , "runtime.park_m" , "runtime.findrunnable" , "runtime.write" , "runtime.write1" , "runtime.stopm" , "runtime.notesleep" , "runtime.runqsteal" , "runtime.runqgrab" , "runtime.pidleput" , "runtime.netpoll" , "runtime.epollwait" , "runtime.checkTimers" , "runtime.runtimer" , "runtime.runOneTimer" , "time.sendTime" , "time.Now" , "runtime.walltime" , "net/http.(*conn).serve" , "net/http.serverHandler.ServeHTTP" , "net/http.(*ServeMux).ServeHTTP" , "net/http.HandlerFunc.ServeHTTP" , "github.com/pyroscope-io/pyroscope/pkg/server.(*Controller).ingestHandler" , "github.com/pyroscope-io/pyroscope/pkg/server.ingestParamsFromRequest" , "runtime.newobject" , "runtime.nextFreeFast" , "github.com/pyroscope-io/pyroscope/pkg/server.(*Controller).Start.func1" , "net/http.(*fileHandler).ServeHTTP" , "net/http.serveFile" , "net/http.serveContent" , "io.Copy" , "io.copyBuffer" , "net/http.(*response).ReadFrom" , "io.CopyBuffer" , "net/http.(*response).Write" , "net/http.(*response).write" , "bufio.(*Writer).Write" , "net/http.(*chunkWriter).Write" , "net/http.checkConnErrorWriter.Write" , "net.(*conn).Write" , "net.(*netFD).Write" , "internal/poll.(*FD).Write" , "internal/poll.ignoringEINTR" , "syscall.Write" , "syscall.write" , "syscall.Syscall" , "net/http.(*conn).readRequest" , "net/http.readRequest" , "net/textproto.(*Reader).ReadMIMEHeader" , "runtime.slicebytetostring" , "runtime.memmove" , "github.com/pyroscope-io/pyroscope/pkg/agent/upstream/direct.(*Direct).uploadLoop" , "github.com/pyroscope-io/pyroscope/pkg/agent/upstream/direct.(*Direct).safeUpload" , "github.com/pyroscope-io/pyroscope/pkg/agent/upstream/direct.(*Direct).uploadProfile" , "github.com/pyroscope-io/pyroscope/pkg/storage.(*Storage).Put" , "github.com/pyroscope-io/pyroscope/pkg/storage/cache.(*Cache).Get" , "github.com/pyroscope-io/pyroscope/pkg/storage/dimension.FromBytes" , "github.com/pyroscope-io/pyroscope/pkg/storage/dimension.Deserialize" , "io.ReadAtLeast" , "github.com/dgraph-io/badger/v2/y.(*WaterMark).process" , "runtime.selectgo" , "github.com/dgraph-io/badger/v2.(*levelsController).runCompactor" , "github.com/dgraph-io/badger/v2.(*levelsController).pickCompactLevels" , "sort.Slice" , "sort.quickSort_func" ] , "levels" :[ [ 0 , 78 , 0 , 0 ] , [ 0 , 2 , 1 , 83 , 0 , 1 , 0 , 81 , 0 , 1 , 0 , 73 , 0 , 3 , 0 , 40 , 0 , 49 , 0 , 22 , 0 , 1 , 0 , 15 , 0 , 21 , 0 , 1 ] , [ 1 , 1 , 0 , 84 , 0 , 1 , 1 , 82 , 0 , 1 , 0 , 74 , 0 , 1 , 0 , 68 , 0 , 2 , 0 , 41 , 0 , 49 , 0 , 23 , 0 , 1 , 0 , 16 , 0 , 21 , 0 , 2 ] , [ 1 , 1 , 0 , 85 , 1 , 1 , 0 , 75 , 0 , 1 , 0 , 69 , 0 , 2 , 0 , 42 , 0 , 49 , 0 , 19 , 0 , 1 , 0 , 17 , 0 , 6 , 6 , 12 , 0 , 15 , 0 , 3 ] , [ 1 , 1 , 1 , 86 , 1 , 1 , 0 , 76 , 0 , 1 , 0 , 70 , 0 , 2 , 0 , 43 , 0 , 36 , 1 , 24 , 0 , 6 , 6 , 12 , 0 , 7 , 0 , 20 , 0 , 1 , 0 , 18 , 6 , 1 , 0 , 13 , 0 , 7 , 0 , 9 , 0 , 4 , 0 , 5 , 0 , 3 , 3 , 4 ] , [ 3 , 1 , 0 , 77 , 0 , 1 , 0 , 71 , 0 , 1 , 0 , 48 , 0 , 1 , 0 , 44 , 1 , 8 , 0 , 34 , 0 , 13 , 13 , 12 , 0 , 8 , 0 , 32 , 0 , 1 , 1 , 31 , 0 , 1 , 0 , 29 , 0 , 3 , 0 , 27 , 0 , 1 , 0 , 25 , 6 , 7 , 0 , 21 , 0 , 1 , 0 , 19 , 6 , 1 , 1 , 14 , 0 , 4 , 4 , 12 , 0 , 3 , 0 , 10 , 0 , 4 , 0 , 6 ] , [ 3 , 1 , 0 , 78 , 0 , 1 , 1 , 72 , 0 , 1 , 0 , 49 , 0 , 1 , 0 , 45 , 1 , 8 , 0 , 35 , 13 , 8 , 8 , 33 , 1 , 1 , 1 , 30 , 0 , 3 , 1 , 28 , 0 , 1 , 1 , 26 , 6 , 7 , 0 , 5 , 0 , 1 , 0 , 20 , 11 , 3 , 0 , 11 , 0 , 4 , 0 , 7 ] , [ 3 , 1 , 0 , 79 , 1 , 1 , 0 , 50 , 0 , 1 , 0 , 46 , 1 , 8 , 0 , 36 , 24 , 2 , 0 , 11 , 7 , 7 , 0 , 6 , 0 , 1 , 0 , 21 , 11 , 3 , 3 , 8 , 0 , 4 , 4 , 8 ] , [ 3 , 1 , 1 , 80 , 1 , 1 , 0 , 51 , 0 , 1 , 1 , 47 , 1 , 8 , 0 , 37 , 24 , 2 , 2 , 8 , 7 , 7 , 0 , 7 , 0 , 1 , 0 , 5 ] , [ 5 , 1 , 0 , 52 , 2 , 8 , 0 , 38 , 33 , 7 , 7 , 8 , 0 , 1 , 0 , 6 ] , [ 5 , 1 , 0 , 53 , 2 , 6 , 6 , 12 , 0 , 2 , 2 , 39 , 40 , 1 , 0 , 7 ] , [ 5 , 1 , 0 , 54 , 50 , 1 , 1 , 8 ] , [ 5 , 1 , 0 , 55 ] , [ 5 , 1 , 0 , 53 ] , [ 5 , 1 , 0 , 56 ] , [ 5 , 1 , 0 , 57 ] , [ 5 , 1 , 0 , 58 ] , [ 5 , 1 , 0 , 59 ] , [ 5 , 1 , 0 , 58 ] , [ 5 , 1 , 0 , 60 ] , [ 5 , 1 , 0 , 61 ] , [ 5 , 1 , 0 , 62 ] , [ 5 , 1 , 0 , 63 ] , [ 5 , 1 , 0 , 64 ] , [ 5 , 1 , 0 , 65 ] , [ 5 , 1 , 0 , 66 ] , [ 5 , 1 , 1 , 67 ] ] , "numTicks" :78 , "maxSelf" :13 , "spyName" :"gospy" , "sampleRate" :100 , "units" :"samples" } , "metadata" :{ "sampleRate" :100 , "spyName" :"gospy" , "units" :"samples" } , "timeline" :{ "startTime" :1621014100 , "samples" :[ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 13 , 16 , 18 , 19 , 17 , 0 ] , "durationDelta" :10 } }
114- , ( ) => {
115- this . updateData ( ) ;
114+ const flamebearer = { names :[ "total" , "runtime.mstart" , "runtime.mstart1" , "runtime.sysmon" , "runtime.usleep" , "runtime.startm" , "runtime.notewakeup" , "runtime.futexwakeup" , "runtime.futex" , "runtime.notetsleep" , "runtime.notetsleep_internal" , "runtime.futexsleep" , "runtime.nanotime" , "runtime.lockWithRank" , "runtime.lock2" , "runtime.morestack" , "runtime.newstack" , "runtime.gopreempt_m" , "runtime.goschedImpl" , "runtime.schedule" , "runtime.resetspinning" , "runtime.wakep" , "runtime.mcall" , "runtime.park_m" , "runtime.findrunnable" , "runtime.write" , "runtime.write1" , "runtime.stopm" , "runtime.notesleep" , "runtime.runqsteal" , "runtime.runqgrab" , "runtime.pidleput" , "runtime.netpoll" , "runtime.epollwait" , "runtime.checkTimers" , "runtime.runtimer" , "runtime.runOneTimer" , "time.sendTime" , "time.Now" , "runtime.walltime" , "net/http.(*conn).serve" , "net/http.serverHandler.ServeHTTP" , "net/http.(*ServeMux).ServeHTTP" , "net/http.HandlerFunc.ServeHTTP" , "github.com/pyroscope-io/pyroscope/pkg/server.(*Controller).ingestHandler" , "github.com/pyroscope-io/pyroscope/pkg/server.ingestParamsFromRequest" , "runtime.newobject" , "runtime.nextFreeFast" , "github.com/pyroscope-io/pyroscope/pkg/server.(*Controller).Start.func1" , "net/http.(*fileHandler).ServeHTTP" , "net/http.serveFile" , "net/http.serveContent" , "io.Copy" , "io.copyBuffer" , "net/http.(*response).ReadFrom" , "io.CopyBuffer" , "net/http.(*response).Write" , "net/http.(*response).write" , "bufio.(*Writer).Write" , "net/http.(*chunkWriter).Write" , "net/http.checkConnErrorWriter.Write" , "net.(*conn).Write" , "net.(*netFD).Write" , "internal/poll.(*FD).Write" , "internal/poll.ignoringEINTR" , "syscall.Write" , "syscall.write" , "syscall.Syscall" , "net/http.(*conn).readRequest" , "net/http.readRequest" , "net/textproto.(*Reader).ReadMIMEHeader" , "runtime.slicebytetostring" , "runtime.memmove" , "github.com/pyroscope-io/pyroscope/pkg/agent/upstream/direct.(*Direct).uploadLoop" , "github.com/pyroscope-io/pyroscope/pkg/agent/upstream/direct.(*Direct).safeUpload" , "github.com/pyroscope-io/pyroscope/pkg/agent/upstream/direct.(*Direct).uploadProfile" , "github.com/pyroscope-io/pyroscope/pkg/storage.(*Storage).Put" , "github.com/pyroscope-io/pyroscope/pkg/storage/cache.(*Cache).Get" , "github.com/pyroscope-io/pyroscope/pkg/storage/dimension.FromBytes" , "github.com/pyroscope-io/pyroscope/pkg/storage/dimension.Deserialize" , "io.ReadAtLeast" , "github.com/dgraph-io/badger/v2/y.(*WaterMark).process" , "runtime.selectgo" , "github.com/dgraph-io/badger/v2.(*levelsController).runCompactor" , "github.com/dgraph-io/badger/v2.(*levelsController).pickCompactLevels" , "sort.Slice" , "sort.quickSort_func" ] , levels :[ [ 0 , 78 , 0 , 0 ] , [ 0 , 2 , 1 , 83 , 0 , 1 , 0 , 81 , 0 , 1 , 0 , 73 , 0 , 3 , 0 , 40 , 0 , 49 , 0 , 22 , 0 , 1 , 0 , 15 , 0 , 21 , 0 , 1 ] , [ 1 , 1 , 0 , 84 , 0 , 1 , 1 , 82 , 0 , 1 , 0 , 74 , 0 , 1 , 0 , 68 , 0 , 2 , 0 , 41 , 0 , 49 , 0 , 23 , 0 , 1 , 0 , 16 , 0 , 21 , 0 , 2 ] , [ 1 , 1 , 0 , 85 , 1 , 1 , 0 , 75 , 0 , 1 , 0 , 69 , 0 , 2 , 0 , 42 , 0 , 49 , 0 , 19 , 0 , 1 , 0 , 17 , 0 , 6 , 6 , 12 , 0 , 15 , 0 , 3 ] , [ 1 , 1 , 1 , 86 , 1 , 1 , 0 , 76 , 0 , 1 , 0 , 70 , 0 , 2 , 0 , 43 , 0 , 36 , 1 , 24 , 0 , 6 , 6 , 12 , 0 , 7 , 0 , 20 , 0 , 1 , 0 , 18 , 6 , 1 , 0 , 13 , 0 , 7 , 0 , 9 , 0 , 4 , 0 , 5 , 0 , 3 , 3 , 4 ] , [ 3 , 1 , 0 , 77 , 0 , 1 , 0 , 71 , 0 , 1 , 0 , 48 , 0 , 1 , 0 , 44 , 1 , 8 , 0 , 34 , 0 , 13 , 13 , 12 , 0 , 8 , 0 , 32 , 0 , 1 , 1 , 31 , 0 , 1 , 0 , 29 , 0 , 3 , 0 , 27 , 0 , 1 , 0 , 25 , 6 , 7 , 0 , 21 , 0 , 1 , 0 , 19 , 6 , 1 , 1 , 14 , 0 , 4 , 4 , 12 , 0 , 3 , 0 , 10 , 0 , 4 , 0 , 6 ] , [ 3 , 1 , 0 , 78 , 0 , 1 , 1 , 72 , 0 , 1 , 0 , 49 , 0 , 1 , 0 , 45 , 1 , 8 , 0 , 35 , 13 , 8 , 8 , 33 , 1 , 1 , 1 , 30 , 0 , 3 , 1 , 28 , 0 , 1 , 1 , 26 , 6 , 7 , 0 , 5 , 0 , 1 , 0 , 20 , 11 , 3 , 0 , 11 , 0 , 4 , 0 , 7 ] , [ 3 , 1 , 0 , 79 , 1 , 1 , 0 , 50 , 0 , 1 , 0 , 46 , 1 , 8 , 0 , 36 , 24 , 2 , 0 , 11 , 7 , 7 , 0 , 6 , 0 , 1 , 0 , 21 , 11 , 3 , 3 , 8 , 0 , 4 , 4 , 8 ] , [ 3 , 1 , 1 , 80 , 1 , 1 , 0 , 51 , 0 , 1 , 1 , 47 , 1 , 8 , 0 , 37 , 24 , 2 , 2 , 8 , 7 , 7 , 0 , 7 , 0 , 1 , 0 , 5 ] , [ 5 , 1 , 0 , 52 , 2 , 8 , 0 , 38 , 33 , 7 , 7 , 8 , 0 , 1 , 0 , 6 ] , [ 5 , 1 , 0 , 53 , 2 , 6 , 6 , 12 , 0 , 2 , 2 , 39 , 40 , 1 , 0 , 7 ] , [ 5 , 1 , 0 , 54 , 50 , 1 , 1 , 8 ] , [ 5 , 1 , 0 , 55 ] , [ 5 , 1 , 0 , 53 ] , [ 5 , 1 , 0 , 56 ] , [ 5 , 1 , 0 , 57 ] , [ 5 , 1 , 0 , 58 ] , [ 5 , 1 , 0 , 59 ] , [ 5 , 1 , 0 , 58 ] , [ 5 , 1 , 0 , 60 ] , [ 5 , 1 , 0 , 61 ] , [ 5 , 1 , 0 , 62 ] , [ 5 , 1 , 0 , 63 ] , [ 5 , 1 , 0 , 64 ] , [ 5 , 1 , 0 , 65 ] , [ 5 , 1 , 0 , 66 ] , [ 5 , 1 , 1 , 67 ] ] , "numTicks" :78 , "maxSelf" :13 , "spyName" :"gospy" , "sampleRate" :100 , "units" :"samples" } , metadata :{ sampleRate :100 , spyName :"gospy" , units :"samples" } , timeline :{ startTime :1621014100 , samples :[ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 13 , 16 , 18 , 19 , 17 , 0 ] , durationDelta :10 } ;
115+ deltaDiff ( flamebearer . levels ) ;
116+ this . setState ( { ...this . state , flamebearer } ,
117+ ( ) => {
118+ this . updateData ( ) ;
116119 } )
117120 }
118121
@@ -225,7 +228,7 @@ class FlameGraphRenderer extends React.Component {
225228 } ;
226229
227230 xyToBar = ( x , y ) => {
228- const i = Math . floor ( y / PX_PER_LEVEL ) + this . topLevel ;
231+ const i = Math . floor ( y / this . pxPerLevel ) + this . topLevel ;
229232 if ( i >= 0 && i < this . state . levels . length ) {
230233 const j = this . binarySearchLevel ( x , this . state . levels [ i ] , this . tickToX ) ;
231234 return { i, j } ;
@@ -242,11 +245,12 @@ class FlameGraphRenderer extends React.Component {
242245 this . mouseOutHandler ( ) ;
243246 } ;
244247
245- resizeHandler = ( ) => {
248+ resizeHandler = ( el ) => {
246249 // this is here to debounce resize events (see: https://css-tricks.com/debouncing-throttling-explained-examples/)
247250 // because rendering is expensive
248251 clearTimeout ( this . resizeFinish ) ;
249- this . resizeFinish = setTimeout ( this . renderCanvas , 100 ) ;
252+ this . pxPerLevel = ( el [ 0 ] . contentRect . height - 60 ) / this . state . flamebearer . levels . length ;
253+ this . resizeFinish = setTimeout ( this . renderCanvas , 50 ) ;
250254 } ;
251255
252256 focusHandler = ( ) => {
@@ -279,13 +283,11 @@ class FlameGraphRenderer extends React.Component {
279283 this . graphWidth = this . canvas . offsetWidth ;
280284 this . pxPerTick =
281285 this . graphWidth / numTicks / ( this . rangeMax - this . rangeMin ) ;
282- this . canvas . height = PX_PER_LEVEL * ( levels . length - this . topLevel ) ;
283-
286+ this . canvas . height = this . pxPerLevel * ( levels . length - this . topLevel ) ;
284287 this . canvas . style . width = '100%' ;
285288 this . canvas . style . height = '100%' ;
286289 this . canvas . width = this . canvas . offsetWidth ;
287290 this . canvas . height = this . canvas . offsetHeight ;
288-
289291 if ( devicePixelRatio > 1 ) {
290292 this . canvas . width *= 2 ;
291293 this . canvas . height *= 2 ;
@@ -294,7 +296,7 @@ class FlameGraphRenderer extends React.Component {
294296
295297 this . ctx . textBaseline = "middle" ;
296298 this . ctx . font =
297- '400 12px system-ui, -apple-system, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"' ;
299+ '400 11px system-ui, -apple-system, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"' ;
298300
299301 const formatter = this . createFormatter ( ) ;
300302 // i = level
@@ -306,17 +308,16 @@ class FlameGraphRenderer extends React.Component {
306308 // j = 2: position in the main index
307309
308310 const barIndex = level [ j ] ;
309- const x = this . tickToX ( barIndex + j * 1.2 ) ;
310- const y = i * PX_PER_LEVEL ;
311+ const x = this . tickToX ( barIndex ) ;
312+ const y = i * this . pxPerLevel ;
311313 let numBarTicks = level [ j + 1 ] ;
312314
313315 // For this particular bar, there is a match
314316 const queryExists = this . query . length > 0 ;
315317 const nodeIsInQuery =
316318 ( this . query && names [ level [ j + 3 ] ] . indexOf ( this . query ) >= 0 ) || false ;
317319 // merge very small blocks into big "collapsed" ones for performance
318- // const collapsed = numBarTicks * this.pxPerTick <= COLLAPSE_THRESHOLD;
319- const collapsed = false ;
320+ const collapsed = numBarTicks * this . pxPerTick <= COLLAPSE_THRESHOLD ;
320321
321322 // const collapsed = false;
322323 if ( collapsed ) {
@@ -334,7 +335,7 @@ class FlameGraphRenderer extends React.Component {
334335 }
335336 // ticks are samples
336337 const sw = numBarTicks * this . pxPerTick - ( collapsed ? 0 : GAP ) ;
337- const sh = PX_PER_LEVEL - GAP ;
338+ const sh = this . pxPerLevel - GAP ;
338339
339340 // if (x < -1 || x + sw > this.graphWidth + 1 || sw < HIDE_THRESHOLD) continue;
340341
@@ -364,7 +365,7 @@ class FlameGraphRenderer extends React.Component {
364365 this . ctx . fillStyle = nodeColor ;
365366 this . ctx . fill ( ) ;
366367
367- if ( ! collapsed /* && sw >= LABEL_THRESHOLD */ ) {
368+ if ( ! collapsed && sw >= LABEL_THRESHOLD ) {
368369 const percent = formatPercent ( ratio ) ;
369370 const name = `${ names [ level [ j + 3 ] ] } (${ percent } , ${ formatter . format ( numBarTicks , sampleRate ) } )` ;
370371
@@ -394,7 +395,7 @@ class FlameGraphRenderer extends React.Component {
394395
395396 const level = this . state . levels [ i ] ;
396397 const x = Math . max ( this . tickToX ( level [ j ] ) , 0 ) ;
397- const y = ( i - this . topLevel ) * PX_PER_LEVEL ;
398+ const y = ( i - this . topLevel ) * this . pxPerLevel ;
398399 const sw = Math . min (
399400 this . tickToX ( level [ j ] + level [ j + 1 ] ) - x ,
400401 this . graphWidth
@@ -417,7 +418,7 @@ class FlameGraphRenderer extends React.Component {
417418 left : `${ this . canvas . offsetLeft + x } px` ,
418419 top : `${ this . canvas . offsetTop + y } px` ,
419420 width : `${ sw } px` ,
420- height : `${ PX_PER_LEVEL } px` ,
421+ height : `${ this . pxPerLevel } px` ,
421422 } ,
422423 tooltipStyle : {
423424 maxWidth : '80%' ,
0 commit comments