Skip to content

feat: add light/dark theme toggle for HTML reports#939

Open
Do-yoon wants to merge 4 commits into
bloomberg:mainfrom
Do-yoon:feature/dark-mode
Open

feat: add light/dark theme toggle for HTML reports#939
Do-yoon wants to merge 4 commits into
bloomberg:mainfrom
Do-yoon:feature/dark-mode

Conversation

@Do-yoon

@Do-yoon Do-yoon commented May 19, 2026

Copy link
Copy Markdown

Summary

Adds a light/dark theme toggle to the flamegraph and table HTML reports.
Closes #650.

What's included

  • Toggle button (🌙/☀️) in the navbar
  • Initial theme follows the OS prefers-color-scheme
  • Selection persisted via localStorage
  • data-theme is set before first paint to avoid FOUC
  • CSS variables for light and dark palettes (dark uses a black base)
  • Bootstrap overrides for navbar, modals, forms, tables, DataTables pagination, search input, dropdowns and scrollbars
  • Recolored flame graph bar fills for the dark theme
  • News entry (news/650.feature.rst)

Test plan

  • Generate flamegraph report and verify both themes
  • Generate table report and verify both themes (incl. Previous/Next, search)
  • Verify initial paint follows OS dark/light preference
  • Verify localStorage persistence across reloads

@codecov-commenter

codecov-commenter commented May 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.22%. Comparing base (776fe15) to head (0243fa8).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #939   +/-   ##
=======================================
  Coverage   92.22%   92.22%           
=======================================
  Files          99       99           
  Lines       12556    12556           
  Branches      432      432           
=======================================
  Hits        11580    11580           
  Misses        976      976           
Flag Coverage Δ
cpp 92.22% <ø> (ø)
python_and_cython 92.22% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sarahmonod

sarahmonod commented May 19, 2026

Copy link
Copy Markdown
Contributor

This PR definitely deserves a NEWS entry. @Do-yoon do you know how to use towncrier? bloomberg/pystack#305 has an example if you want one.

@godlygeek

Copy link
Copy Markdown
Contributor

@pradyunsg I'm going to defer to you for reviewing this one, if you don't mind doing it.

@godlygeek
godlygeek requested a review from pradyunsg May 20, 2026 17:42
@Do-yoon

Do-yoon commented Jun 20, 2026

Copy link
Copy Markdown
Author

@sarahmonod

Thanks for pointing me to towncrier — I hadn't used it before, so I really appreciate the pystack#305 example.

Before I push, I just want to make sure I've got the convention right: I'm planning to add a single fragment at news/650.feature.rst containing a one-line description of the feature. Does that look correct to you, or should I use a different filename/category?

@godlygeek

Copy link
Copy Markdown
Contributor

Yes, that's the correct filename

@Do-yoon

Do-yoon commented Jun 20, 2026

Copy link
Copy Markdown
Author

I've added the news fragment at news/650.feature.rst and pushed it as a new commit, so this should be ready for another look whenever you get the chance. Let me know if anything else is needed.

Do-yoon and others added 4 commits July 21, 2026 21:10
Closes bloomberg#650

- Add a theme toggle button (🌙/☀️) to the navbar
- Detect the OS prefers-color-scheme as the initial value
- Persist the selected theme in localStorage
- Set data-theme before first paint to avoid FOUC
- Define light/dark palettes via CSS variables (dark uses a black base)
- Override Bootstrap navbar, modals, forms, tables, DataTables pagination
  (Previous/Next), search input, dropdowns and scrollbars for dark mode
- Applies to both the flamegraph and table reports
- Add getPlotlyTheme() helper that returns Plotly layout colors based on
  the current data-theme value (paper/plot backgrounds, font, gridlines)
- Apply the theme to the main memoryGraph, the navbar smallMemoryGraph,
  and the temporal flamegraph's "plot"
- Re-run Plotly.relayout for all charts on theme toggle so colors switch
  live without needing a page reload
- Rebuild bundled JS assets
- Make colorByExtension and memrayColorMapper theme-aware
- Dark palette tuned to match the report's black-based background:
  * .py            -> #4f8a5e (muted green)
  * .c/.cpp/.h     -> #9a8442 (muted gold)
  * other          -> #5a5f68 (muted gray)
  * builtin/no-loc -> #2a2f36
  * highlight      -> "orange" (unchanged)
- Add applyFlamegraphTheme() that recolors existing rects in place,
  exposed via window.memrayApplyFlamegraphTheme from both the
  flamegraph and temporal_flamegraph entry points
- Theme toggle in base.html now re-applies both the Plotly theme and
  the flame graph fills, so light/dark switches live without reloading
- Rebuild bundled JS assets
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Do-yoon
Do-yoon force-pushed the feature/dark-mode branch from 2aebed9 to 0243fa8 Compare July 21, 2026 12:13
@Do-yoon

Do-yoon commented Jul 21, 2026

Copy link
Copy Markdown
Author

@godlygeek
@pradyunsg

Rebased onto the latest main to resolve a merge conflict.

The conflict was only in src/memray/reporters/templates/assets/table.js, which is a generated webpack bundle — both this PR (dark theme changes in assets/common.js) and #857 (row deduplication in assets/table.js) had regenerated it, so it couldn't be merged textually. There were no conflicts at the source level.

To resolve it, I took main's version of the bundle and regenerated it with npm ci && npm run build on top of the rebased sources, so the new bundle includes both the deduplication change from #857 and the theme support from this PR. The other bundles didn't need regenerating since #857 doesn't touch common.js.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dark Mode for Flame graph reports

4 participants