]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-138122: Add docs button to Tachyon heatmap and flamegraph (#142614)
authorStan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
Fri, 12 Dec 2025 15:06:28 +0000 (15:06 +0000)
committerGitHub <noreply@github.com>
Fri, 12 Dec 2025 15:06:28 +0000 (15:06 +0000)
Lib/profiling/sampling/_flamegraph_assets/flamegraph.js
Lib/profiling/sampling/_flamegraph_assets/flamegraph_template.html
Lib/profiling/sampling/_heatmap_assets/heatmap.js
Lib/profiling/sampling/_heatmap_assets/heatmap_index.js
Lib/profiling/sampling/_heatmap_assets/heatmap_index_template.html
Lib/profiling/sampling/_heatmap_assets/heatmap_pyfile_template.html
Lib/profiling/sampling/heatmap_collector.py
Lib/profiling/sampling/stack_collector.py

index fb81094521815e0f055c296ed71ddc46adc93cd1..6345320bd2555de8ed3ccace6e0277d8895b9dd0 100644 (file)
@@ -92,7 +92,8 @@ function toggleTheme() {
   // Update theme button icon
   const btn = document.getElementById('theme-btn');
   if (btn) {
-    btn.innerHTML = next === 'dark' ? '&#9788;' : '&#9790;';  // sun or moon
+    btn.querySelector('.icon-moon').style.display = next === 'dark' ? 'none' : '';
+    btn.querySelector('.icon-sun').style.display = next === 'dark' ? '' : 'none';
   }
 
   // Re-render flamegraph with new theme colors
@@ -160,7 +161,8 @@ function restoreUIState() {
     document.documentElement.setAttribute('data-theme', savedTheme);
     const btn = document.getElementById('theme-btn');
     if (btn) {
-      btn.innerHTML = savedTheme === 'dark' ? '&#9788;' : '&#9790;';
+      btn.querySelector('.icon-moon').style.display = savedTheme === 'dark' ? 'none' : '';
+      btn.querySelector('.icon-sun').style.display = savedTheme === 'dark' ? '' : 'none';
     }
   }
 
index 211296a708643fea25de3a8ec8caf9284cf358a2..02855563f83f7cbafdb1639aef3a714f37040b54 100644 (file)
             class="toolbar-btn"
             onclick="resetZoom()"
             title="Reset zoom"
-          >&#8962;</button>
+          >
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
+              <path d="M8.707 1.5a1 1 0 0 0-1.414 0L.646 8.146a.5.5 0 0 0 .708.708L2 8.207V13.5A1.5 1.5 0 0 0 3.5 15h9a1.5 1.5 0 0 0 1.5-1.5V8.207l.646.647a.5.5 0 0 0 .708-.708L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293zM13 7.207V13.5a.5.5 0 0 1-.5.5h-9a.5.5 0 0 1-.5-.5V7.207l5-5z"/>
+            </svg>
+          </button>
           <button
             class="toolbar-btn"
             onclick="exportSVG()"
             title="Export SVG"
-          >&#8595;</button>
+          >
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
+              <path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5"/><path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708z"/>
+            </svg>
+          </button>
+          <a
+            class="toolbar-btn"
+            href="https://docs.python.org/<!-- PYTHON_VERSION -->/library/profiling.sampling.html"
+            target="_blank"
+            title="Documentation"
+          >
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
+              <path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783"/>
+            </svg>
+          </a>
           <button
             class="toolbar-btn theme-toggle"
             onclick="toggleTheme()"
             title="Toggle theme"
             id="theme-btn"
-          >&#9790;</button>
+          >
+            <svg class="icon-moon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
+              <path d="M6 .278a.77.77 0 0 1 .08.858 7.2 7.2 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277q.792-.001 1.533-.16a.79.79 0 0 1 .81.316.73.73 0 0 1-.031.893A8.35 8.35 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.75.75 0 0 1 6 .278M4.858 1.311A7.27 7.27 0 0 0 1.025 7.71c0 4.02 3.279 7.276 7.319 7.276a7.32 7.32 0 0 0 5.205-2.162q-.506.063-1.029.063c-4.61 0-8.343-3.714-8.343-8.29 0-1.167.242-2.278.681-3.286"/>
+            </svg>
+            <svg class="icon-sun" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" style="display:none">
+              <path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6m0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8M8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0m0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13m8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5M3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8m10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0m-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0m9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707M4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708"/>
+            </svg>
+          </button>
         </div>
       </header>
 
index 038aa44b3df6192f977fcfca599b768163bc0edd..8ac4ef43e53b37a7a84cfc0f2a3378174ec3bd08 100644 (file)
@@ -24,7 +24,8 @@ function toggleTheme() {
     // Update theme button icon
     const btn = document.getElementById('theme-btn');
     if (btn) {
-        btn.innerHTML = next === 'dark' ? '&#9788;' : '&#9790;';  // sun or moon
+        btn.querySelector('.icon-moon').style.display = next === 'dark' ? 'none' : '';
+        btn.querySelector('.icon-sun').style.display = next === 'dark' ? '' : 'none';
     }
     applyLineColors();
 
@@ -39,7 +40,8 @@ function restoreUIState() {
         document.documentElement.setAttribute('data-theme', savedTheme);
         const btn = document.getElementById('theme-btn');
         if (btn) {
-            btn.innerHTML = savedTheme === 'dark' ? '&#9788;' : '&#9790;';
+            btn.querySelector('.icon-moon').style.display = savedTheme === 'dark' ? 'none' : '';
+            btn.querySelector('.icon-sun').style.display = savedTheme === 'dark' ? '' : 'none';
         }
     }
 }
index 4ddacca5173d34874c13d4c4cc915a802b4abfe3..8eb6af0db5335e53e2fc85d447a83ec974bbcb4a 100644 (file)
@@ -28,7 +28,8 @@ function toggleTheme() {
     // Update theme button icon
     const btn = document.getElementById('theme-btn');
     if (btn) {
-        btn.innerHTML = next === 'dark' ? '&#9788;' : '&#9790;';  // sun or moon
+        btn.querySelector('.icon-moon').style.display = next === 'dark' ? 'none' : '';
+        btn.querySelector('.icon-sun').style.display = next === 'dark' ? '' : 'none';
     }
 
     applyHeatmapBarColors();
@@ -41,7 +42,8 @@ function restoreUIState() {
         document.documentElement.setAttribute('data-theme', savedTheme);
         const btn = document.getElementById('theme-btn');
         if (btn) {
-            btn.innerHTML = savedTheme === 'dark' ? '&#9788;' : '&#9790;';
+            btn.querySelector('.icon-moon').style.display = savedTheme === 'dark' ? 'none' : '';
+            btn.querySelector('.icon-sun').style.display = savedTheme === 'dark' ? '' : 'none';
         }
     }
 }
index 98996bdbf5ffb1a66f9f01a53497858b77ee908f..3620f8efb8058aecc712eade91036678cdea147d 100644 (file)
                 <span class="brand-subtitle">Heatmap Report</span>
             </div>
             <div class="toolbar">
+                <a
+                    class="toolbar-btn"
+                    href="https://docs.python.org/<!-- PYTHON_VERSION -->/library/profiling.sampling.html"
+                    target="_blank"
+                    title="Documentation"
+                >
+                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
+                    <path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783"/>
+                  </svg>
+                </a>
                 <button
                     class="toolbar-btn theme-toggle"
                     onclick="toggleTheme()"
                     title="Toggle theme"
                     id="theme-btn"
-                >&#9790;</button>
+                >
+                  <svg class="icon-moon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
+                    <path d="M6 .278a.77.77 0 0 1 .08.858 7.2 7.2 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277q.792-.001 1.533-.16a.79.79 0 0 1 .81.316.73.73 0 0 1-.031.893A8.35 8.35 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.75.75 0 0 1 6 .278M4.858 1.311A7.27 7.27 0 0 0 1.025 7.71c0 4.02 3.279 7.276 7.319 7.276a7.32 7.32 0 0 0 5.205-2.162q-.506.063-1.029.063c-4.61 0-8.343-3.714-8.343-8.29 0-1.167.242-2.278.681-3.286"/>
+                  </svg>
+                  <svg class="icon-sun" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" style="display:none">
+                    <path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6m0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8M8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0m0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13m8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5M3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8m10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0m-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0m9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707M4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708"/>
+                  </svg>
+                </button>
             </div>
         </header>
 
index 3fb6d3a6b91dbb25bb90c3a27af27733b3ab4f3e..91b629b262824498e84f811599e516a276206307 100644 (file)
                 <span class="brand-subtitle" style="font-family: var(--font-mono); font-size: 13px;"><!-- FILENAME --></span>
             </div>
             <div class="toolbar">
-                <a href="index.html" class="toolbar-btn" title="Back to Index" aria-label="Back to Index">&#8962;</a>
+                <a href="index.html" class="toolbar-btn" title="Back to Index" aria-label="Back to Index">
+                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
+                    <path d="M8.707 1.5a1 1 0 0 0-1.414 0L.646 8.146a.5.5 0 0 0 .708.708L2 8.207V13.5A1.5 1.5 0 0 0 3.5 15h9a1.5 1.5 0 0 0 1.5-1.5V8.207l.646.647a.5.5 0 0 0 .708-.708L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293zM13 7.207V13.5a.5.5 0 0 1-.5.5h-9a.5.5 0 0 1-.5-.5V7.207l5-5z"/>
+                  </svg>
+                </a>
+                <a
+                    class="toolbar-btn"
+                    href="https://docs.python.org/<!-- PYTHON_VERSION -->/library/profiling.sampling.html"
+                    target="_blank"
+                    title="Documentation"
+                >
+                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
+                    <path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783"/>
+                  </svg>
+                </a>
                 <button
                     class="toolbar-btn theme-toggle"
                     onclick="toggleTheme()"
                     title="Toggle theme"
                     aria-label="Toggle theme"
                     id="theme-btn"
-                >&#9790;</button>
+                >
+                  <svg class="icon-moon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
+                    <path d="M6 .278a.77.77 0 0 1 .08.858 7.2 7.2 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277q.792-.001 1.533-.16a.79.79 0 0 1 .81.316.73.73 0 0 1-.031.893A8.35 8.35 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.75.75 0 0 1 6 .278M4.858 1.311A7.27 7.27 0 0 0 1.025 7.71c0 4.02 3.279 7.276 7.319 7.276a7.32 7.32 0 0 0 5.205-2.162q-.506.063-1.029.063c-4.61 0-8.343-3.714-8.343-8.29 0-1.167.242-2.278.681-3.286"/>
+                  </svg>
+                  <svg class="icon-sun" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" style="display:none">
+                    <path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6m0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8M8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0m0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13m8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5M3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8m10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0m-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0m9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707M4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708"/>
+                  </svg>
+                </button>
             </div>
         </header>
 
index 45649ce2009bb6a3f7ae610c1daaf14ba1c7cbef..5b4c89283be08ccb5a1b4071f11620be61808d2e 100644 (file)
@@ -858,6 +858,7 @@ class HeatmapCollector(StackTraceCollector):
             "<!-- INLINE_CSS -->": f"<style>\n{self._template_loader.index_css}\n</style>",
             "<!-- INLINE_JS -->": f"<script>\n{self._template_loader.index_js}\n</script>",
             "<!-- PYTHON_LOGO -->": self._template_loader.logo_html,
+            "<!-- PYTHON_VERSION -->": f"{sys.version_info.major}.{sys.version_info.minor}",
             "<!-- NUM_FILES -->": str(len(file_stats)),
             "<!-- TOTAL_SAMPLES -->": f"{self._total_samples:,}",
             "<!-- DURATION -->": f"{self.stats.get('duration_sec', 0):.1f}s",
@@ -915,6 +916,7 @@ class HeatmapCollector(StackTraceCollector):
             "<!-- INLINE_CSS -->": f"<style>\n{self._template_loader.file_css}\n</style>",
             "<!-- INLINE_JS -->": f"<script>\n{self._template_loader.file_js}\n</script>",
             "<!-- PYTHON_LOGO -->": self._template_loader.logo_html,
+            "<!-- PYTHON_VERSION -->": f"{sys.version_info.major}.{sys.version_info.minor}",
         }
 
         html_content = self._template_loader.file_template
index b7aa7f5ff82da305f1d27e41daffb4a3ab3d321c..e437facd8bb94b422fa180bedbb6d36384022382 100644 (file)
@@ -5,6 +5,7 @@ import importlib.resources
 import json
 import linecache
 import os
+import sys
 
 from ._css_utils import get_combined_css
 from .collector import Collector, extract_lineno
@@ -393,6 +394,9 @@ class FlamegraphCollector(StackTraceCollector):
         # Let CSS control size; keep markup simple
         logo_html = f'<img src="data:image/png;base64,{b64_logo}" alt="Tachyon logo"/>'
         html_template = html_template.replace("<!-- INLINE_LOGO -->", logo_html)
+        html_template = html_template.replace(
+            "<!-- PYTHON_VERSION -->", f"{sys.version_info.major}.{sys.version_info.minor}"
+        )
 
         d3_js = d3_path.read_text(encoding="utf-8")
         fg_css = fg_css_path.read_text(encoding="utf-8")