@@ -99,13 +99,23 @@ function getDisplayName(moduleName, filename) {
9999 return filename ;
100100}
101101
102- function selectFlamegraphData ( ) {
103- const baseData = isShowingElided ? elidedFlamegraphData : normalData ;
102+ function selectFlamegraphData ( selectedThreadId = null ) {
103+ let baseData = isShowingElided ? elidedFlamegraphData : normalData ;
104+
105+ if ( selectedThreadId !== null ) {
106+ baseData = filterDataByThread ( baseData , selectedThreadId ) ;
107+ }
104108
105109 if ( ! isInverted ) {
106110 return baseData ;
107111 }
108112
113+ // Thread-filtered trees have different values, so invert them after filtering
114+ // instead of using the cached all-thread tree.
115+ if ( selectedThreadId !== null ) {
116+ return generateInvertedFlamegraph ( baseData ) ;
117+ }
118+
109119 if ( isShowingElided ) {
110120 if ( ! invertedElidedData ) {
111121 invertedElidedData = generateInvertedFlamegraph ( baseData ) ;
@@ -120,12 +130,11 @@ function selectFlamegraphData() {
120130}
121131
122132function updateFlamegraphView ( ) {
123- const selectedData = selectFlamegraphData ( ) ;
124133 const selectedThreadId = currentThreadFilter !== 'all' ? parseInt ( currentThreadFilter , 10 ) : null ;
125- const filteredData = selectedThreadId !== null ? filterDataByThread ( selectedData , selectedThreadId ) : selectedData ;
126- const tooltip = createPythonTooltip ( filteredData ) ;
127- const chart = createFlamegraph ( tooltip , filteredData . value , filteredData ) ;
128- renderFlamegraph ( chart , filteredData ) ;
134+ const selectedData = selectFlamegraphData ( selectedThreadId ) ;
135+ const tooltip = createPythonTooltip ( selectedData ) ;
136+ const chart = createFlamegraph ( tooltip , selectedData . value , selectedData ) ;
137+ renderFlamegraph ( chart , selectedData ) ;
129138 populateThreadStats ( selectedData , selectedThreadId ) ;
130139}
131140
@@ -1209,7 +1218,7 @@ function initThreadFilter(data) {
12091218 const threadFilter = document . getElementById ( 'thread-filter' ) ;
12101219 const threadSection = document . getElementById ( 'thread-section' ) ;
12111220
1212- if ( ! threadFilter || ! data . threads ) return ;
1221+ if ( ! threadFilter || ! data . threads || data . stats ?. is_differential ) return ;
12131222
12141223 threadFilter . innerHTML = '<option value="all">All Threads</option>' ;
12151224
@@ -1238,11 +1247,17 @@ function filterByThread() {
12381247
12391248function filterDataByThread ( data , threadId ) {
12401249 function filterNode ( node ) {
1241- if ( ! node . threads || ! node . threads . includes ( threadId ) ) {
1250+ const threadValues = node . thread_values ?. [ threadId ] ;
1251+ if ( ! threadValues ) {
12421252 return null ;
12431253 }
12441254
1245- const filteredNode = { ...node , children : [ ] } ;
1255+ const filteredNode = {
1256+ ...node ,
1257+ value : threadValues [ 0 ] ,
1258+ self : threadValues [ 1 ] ,
1259+ children : [ ]
1260+ } ;
12461261
12471262 if ( node . children && Array . isArray ( node . children ) ) {
12481263 filteredNode . children = node . children
@@ -1253,25 +1268,7 @@ function filterDataByThread(data, threadId) {
12531268 return filteredNode ;
12541269 }
12551270
1256- function recalculateValue ( node ) {
1257- if ( ! node . children || node . children . length === 0 ) {
1258- return node . value || 0 ;
1259- }
1260- const childrenValue = node . children . reduce ( ( sum , child ) => sum + recalculateValue ( child ) , 0 ) ;
1261- node . value = Math . max ( node . value || 0 , childrenValue ) ;
1262- return node . value ;
1263- }
1264-
1265- const filteredRoot = { ...data , children : [ ] } ;
1266-
1267- if ( data . children && Array . isArray ( data . children ) ) {
1268- filteredRoot . children = data . children
1269- . map ( child => filterNode ( child ) )
1270- . filter ( child => child !== null ) ;
1271- }
1272-
1273- recalculateValue ( filteredRoot ) ;
1274- return filteredRoot ;
1271+ return filterNode ( data ) ;
12751272}
12761273
12771274// ============================================================================
0 commit comments