Skip to content

Commit e34d607

Browse files
committed
Simplify sampling profiler visualization code
Moved function colors to a lookup map and easing definitions to a module constant so they aren't recreated on each call. Cached the background element reference in DOMStackFrame instead of querying it on every hover. Chained the regex replacements in syntax highlighting into one expression. Removed the CSS color rules for specific functions since colors are now set in JS, along with a duplicate color variable and two methods that were never called.
1 parent 65048f0 commit e34d607

File tree

2 files changed

+55
-177
lines changed

2 files changed

+55
-177
lines changed

Doc/_static/profiling-sampling-visualization.css

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@
1919
--text-muted: #6e6e6e;
2020
--text-code: #333333;
2121

22-
/* Accent colors - matching Tachyon logo */
22+
/* Accent colors */
2323
--color-python-blue: #306998;
24-
--color-tachyon-gold: #d4a910;
2524
--color-green: #388e3c;
2625
--color-orange: #e65100;
2726
--color-purple: #7b1fa2;
@@ -229,26 +228,6 @@
229228
transition: opacity 0.15s;
230229
}
231230

232-
.sampling-profiler-viz .stack-frame[data-function="main"] .stack-frame-bg {
233-
background: var(--color-python-blue);
234-
}
235-
236-
.sampling-profiler-viz .stack-frame[data-function="fibonacci"] .stack-frame-bg {
237-
background: var(--color-tachyon-gold);
238-
}
239-
240-
.sampling-profiler-viz .stack-frame[data-function="add"] .stack-frame-bg {
241-
background: var(--color-orange);
242-
}
243-
244-
.sampling-profiler-viz .stack-frame[data-function="multiply"] .stack-frame-bg {
245-
background: var(--color-purple);
246-
}
247-
248-
.sampling-profiler-viz .stack-frame[data-function="calculate"] .stack-frame-bg {
249-
background: var(--color-tachyon-gold);
250-
}
251-
252231
.sampling-profiler-viz .stack-frame-text {
253232
position: absolute;
254233
left: 10px;

Doc/_static/profiling-sampling-visualization.js

Lines changed: 54 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -8,78 +8,35 @@
88
// Configuration
99
// ============================================================================
1010

11-
const COLORS = {
12-
// Tachyon logo-inspired colors
13-
tachyonBlue: 0x306998,
14-
tachyonGold: 0xd4a910,
15-
// Docs-matching colors
16-
background: 0xffffff,
17-
panelBg: 0xffffff,
18-
borderLight: 0xe1e4e8,
19-
borderHighlight: 0x306998,
20-
textPrimary: 0x0d0d0d,
21-
textSecondary: 0x505050,
22-
textDim: 0x6e6e6e,
23-
// Function colors - blue/gold theme
24-
funcMain: 0x306998,
25-
funcFibonacci: 0xd4a910,
26-
active: 0xfff9e6,
27-
activeText: 0x856404,
28-
success: 0x388e3c,
29-
warning: 0xe65100,
30-
error: 0xc62828,
31-
info: 0x306998,
32-
samplingAccent: 0x00897b,
33-
tracingAccent: 0xd4a910,
34-
overheadLow: 0x388e3c,
35-
overheadMedium: 0xe65100,
36-
overheadHigh: 0xc62828,
37-
};
38-
3911
const TIMINGS = {
40-
frameSlideIn: 500,
41-
frameSlideOut: 300,
42-
frameFadeOut: 200,
43-
sampleFlash: 200,
4412
sampleIntervalMin: 100,
4513
sampleIntervalMax: 500,
4614
sampleIntervalDefault: 200,
4715
sampleToFlame: 600,
48-
flameGrowth: 300,
49-
hookDelay: 10,
50-
eventLightDuration: 150,
51-
speeds: [0.1, 0.25, 0.5, 1, 2, 5],
5216
defaultSpeed: 0.05,
5317
};
5418

55-
const LAYOUT = {
56-
frameWidth: 200,
57-
frameHeight: 40,
58-
frameSpacing: 6,
59-
frameRadius: 4,
60-
codePanelWidth: 0.3,
61-
stackPanelWidth: 0.4,
62-
timelinePanelWidth: 0.3,
63-
flameNodeHeight: 30,
64-
flameMaxDepth: 20,
65-
};
19+
const LAYOUT = { frameSpacing: 6 };
6620

67-
// ============================================================================
68-
// Color Utilities
69-
// ============================================================================
21+
// Function name to color mapping
22+
const FUNCTION_COLORS = {
23+
main: "#306998",
24+
fibonacci: "#D4A910",
25+
add: "#E65100",
26+
multiply: "#7B1FA2",
27+
calculate: "#D4A910",
28+
};
29+
const DEFAULT_FUNCTION_COLOR = "#306998";
7030

71-
function hexToCSS(hex) {
72-
return "#" + hex.toString(16).padStart(6, "0").toUpperCase();
73-
}
31+
// Easing functions - cubic-bezier approximations
32+
const EASING_MAP = {
33+
linear: "linear",
34+
easeOutQuad: "cubic-bezier(0.25, 0.46, 0.45, 0.94)",
35+
easeOutCubic: "cubic-bezier(0.215, 0.61, 0.355, 1)",
36+
};
7437

7538
function getFunctionColor(funcName) {
76-
// Blue for main, gold for other functions - matching Tachyon logo
77-
if (funcName === "main") return hexToCSS(COLORS.tachyonBlue);
78-
if (funcName === "fibonacci") return hexToCSS(COLORS.tachyonGold);
79-
if (funcName === "add") return "#E65100"; // Orange
80-
if (funcName === "multiply") return "#7B1FA2"; // Purple
81-
if (funcName === "calculate") return hexToCSS(COLORS.tachyonGold);
82-
return hexToCSS(COLORS.tachyonBlue);
39+
return FUNCTION_COLORS[funcName] || DEFAULT_FUNCTION_COLOR;
8340
}
8441

8542
// ============================================================================
@@ -94,37 +51,17 @@
9451
to(element, props, duration, easing = "easeOutQuad", onComplete = null) {
9552
this.killAnimationsOf(element);
9653

97-
// Cubic-bezier approximations of Robert Penner's easing equations.
98-
// See: https://easings.net/ for visual references.
99-
// Format: cubic-bezier(x1, y1, x2, y2) defines control points for the curve.
100-
const easingMap = {
101-
linear: "linear",
102-
easeInQuad: "cubic-bezier(0.55, 0.085, 0.68, 0.53)",
103-
easeOutQuad: "cubic-bezier(0.25, 0.46, 0.45, 0.94)",
104-
easeInOutQuad: "cubic-bezier(0.455, 0.03, 0.515, 0.955)",
105-
easeInCubic: "cubic-bezier(0.55, 0.055, 0.675, 0.19)",
106-
easeOutCubic: "cubic-bezier(0.215, 0.61, 0.355, 1)",
107-
easeInOutCubic: "cubic-bezier(0.645, 0.045, 0.355, 1)",
108-
easeOutElastic: "cubic-bezier(0.68, -0.55, 0.265, 1.55)",
109-
easeOutBack: "cubic-bezier(0.175, 0.885, 0.32, 1.275)",
110-
easeOutBounce: "cubic-bezier(0.68, -0.25, 0.265, 1.25)",
111-
};
112-
113-
const cssEasing = easingMap[easing] || easingMap.easeOutQuad;
54+
const cssEasing = EASING_MAP[easing] || EASING_MAP.easeOutQuad;
11455

11556
const transformProps = {};
11657
const otherProps = {};
11758

11859
for (const [key, value] of Object.entries(props)) {
119-
if (key === "position" || key === "x" || key === "y") {
120-
if (key === "position") {
121-
if (typeof value.x === "number") transformProps.x = value.x;
122-
if (typeof value.y === "number") transformProps.y = value.y;
123-
} else if (key === "x") {
124-
transformProps.x = value;
125-
} else if (key === "y") {
126-
transformProps.y = value;
127-
}
60+
if (key === "position") {
61+
if (typeof value.x === "number") transformProps.x = value.x;
62+
if (typeof value.y === "number") transformProps.y = value.y;
63+
} else if (key === "x" || key === "y") {
64+
transformProps[key] = value;
12865
} else if (key === "scale") {
12966
transformProps.scale = value;
13067
} else if (key === "alpha" || key === "opacity") {
@@ -136,25 +73,24 @@
13673

13774
const computedStyle = getComputedStyle(element);
13875
const matrix = new DOMMatrix(computedStyle.transform);
76+
const currentScale = Math.sqrt(
77+
matrix.m11 * matrix.m11 + matrix.m21 * matrix.m21,
78+
);
13979

140-
if (transformProps.x === undefined) transformProps.x = matrix.m41;
141-
if (transformProps.y === undefined) transformProps.y = matrix.m42;
142-
if (transformProps.scale === undefined) {
143-
transformProps.scale = Math.sqrt(
144-
matrix.m11 * matrix.m11 + matrix.m21 * matrix.m21,
145-
);
146-
}
80+
transformProps.x ??= matrix.m41;
81+
transformProps.y ??= matrix.m42;
82+
transformProps.scale ??= currentScale;
14783

14884
const initialTransform = this._buildTransformString(
14985
matrix.m41,
15086
matrix.m42,
151-
Math.sqrt(matrix.m11 * matrix.m11 + matrix.m21 * matrix.m21),
87+
currentScale,
15288
);
15389

15490
const finalTransform = this._buildTransformString(
155-
transformProps.x !== undefined ? transformProps.x : matrix.m41,
156-
transformProps.y !== undefined ? transformProps.y : matrix.m42,
157-
transformProps.scale !== undefined ? transformProps.scale : 1,
91+
transformProps.x,
92+
transformProps.y,
93+
transformProps.scale,
15894
);
15995

16096
const initialKeyframe = { transform: initialTransform };
@@ -337,33 +273,21 @@
337273
}
338274

339275
_highlightSyntax(line) {
340-
let highlighted = line
276+
return line
341277
.replace(/&/g, "&")
342278
.replace(/</g, "&lt;")
343-
.replace(/>/g, "&gt;");
344-
highlighted = highlighted.replace(
345-
/(f?"[^"]*"|f?'[^']*')/g,
346-
'<span class="string">$1</span>',
347-
);
348-
highlighted = highlighted.replace(
349-
/(#.*$)/g,
350-
'<span class="comment">$1</span>',
351-
);
352-
const keywords =
353-
/\b(def|if|elif|else|return|for|in|range|print|__name__|__main__)\b/g;
354-
highlighted = highlighted.replace(
355-
keywords,
356-
'<span class="keyword">$1</span>',
357-
);
358-
highlighted = highlighted.replace(
359-
/<span class="keyword">def<\/span>\s+(\w+)/g,
360-
'<span class="keyword">def</span> <span class="function">$1</span>',
361-
);
362-
highlighted = highlighted.replace(
363-
/\b(\d+)\b/g,
364-
'<span class="number">$1</span>',
365-
);
366-
return highlighted;
279+
.replace(/>/g, "&gt;")
280+
.replace(/(f?"[^"]*"|f?'[^']*')/g, '<span class="string">$1</span>')
281+
.replace(/(#.*$)/g, '<span class="comment">$1</span>')
282+
.replace(
283+
/\b(def|if|elif|else|return|for|in|range|print|__name__|__main__)\b/g,
284+
'<span class="keyword">$1</span>',
285+
)
286+
.replace(
287+
/<span class="keyword">def<\/span>\s+(\w+)/g,
288+
'<span class="keyword">def</span> <span class="function">$1</span>',
289+
)
290+
.replace(/\b(\d+)\b/g, '<span class="number">$1</span>');
367291
}
368292

369293
highlightLine(lineNumber) {
@@ -390,22 +314,6 @@
390314
}
391315
}
392316

393-
_scrollToLine(lineElement) {
394-
const containerRect = this.codeContainer.getBoundingClientRect();
395-
const lineRect = lineElement.getBoundingClientRect();
396-
const isAbove = lineRect.top < containerRect.top + 50;
397-
const isBelow = lineRect.bottom > containerRect.bottom - 50;
398-
399-
if (isAbove || isBelow) {
400-
// Scroll within the container only, not the page
401-
const lineTop = lineElement.offsetTop;
402-
const containerHeight = this.codeContainer.clientHeight;
403-
const targetScroll =
404-
lineTop - containerHeight / 2 + lineElement.offsetHeight / 2;
405-
this.codeContainer.scrollTop = Math.max(0, targetScroll);
406-
}
407-
}
408-
409317
reset() {
410318
this.highlightLine(null);
411319
this.codeContainer.scrollTop = 0;
@@ -432,10 +340,10 @@
432340
this.element.className = "stack-frame";
433341
this.element.dataset.function = functionName;
434342

435-
const bg = document.createElement("div");
436-
bg.className = "stack-frame-bg";
437-
bg.style.backgroundColor = this.color;
438-
this.element.appendChild(bg);
343+
this.bgElement = document.createElement("div");
344+
this.bgElement.className = "stack-frame-bg";
345+
this.bgElement.style.backgroundColor = this.color;
346+
this.element.appendChild(this.bgElement);
439347

440348
this.textElement = document.createElement("span");
441349
this.textElement.className = "stack-frame-text";
@@ -451,9 +359,7 @@
451359
}
452360

453361
destroy() {
454-
if (this.element.parentNode) {
455-
this.element.parentNode.removeChild(this.element);
456-
}
362+
this.element.parentNode?.removeChild(this.element);
457363
}
458364

459365
updateLine(lineno) {
@@ -464,18 +370,15 @@
464370
setActive(isActive) {
465371
if (this.isActive === isActive) return;
466372
this.isActive = isActive;
467-
const bg = this.element.querySelector(".stack-frame-bg");
468-
bg.style.opacity = isActive ? "1.0" : "0.9";
373+
this.bgElement.style.opacity = isActive ? "1.0" : "0.9";
469374
}
470375

471376
_onHover() {
472-
const bg = this.element.querySelector(".stack-frame-bg");
473-
bg.style.opacity = "0.8";
377+
this.bgElement.style.opacity = "0.8";
474378
}
475379

476380
_onHoverOut() {
477-
const bg = this.element.querySelector(".stack-frame-bg");
478-
bg.style.opacity = this.isActive ? "1.0" : "0.9";
381+
this.bgElement.style.opacity = this.isActive ? "1.0" : "0.9";
479382
}
480383

481384
flash(duration = 150) {
@@ -960,10 +863,6 @@
960863
this.container.appendChild(this.flashOverlay);
961864
}
962865

963-
isAnimating() {
964-
return this.flyingAnimationInProgress;
965-
}
966-
967866
triggerSamplingEffect(stackViz, samplingPanel, currentTime, trace) {
968867
if (this.flyingAnimationInProgress) return;
969868

0 commit comments

Comments
 (0)