Skip to content

Commit

Permalink
Add dark/light mode (#108)
Browse files Browse the repository at this point in the history
Add support for dark/light theme

The browser theme is initially used. A switch in the navbar let the user choose their theme. The selection is saved into localStorage for persistency

Fixes #23
  • Loading branch information
tommyblue authored Apr 30, 2023
1 parent cdd0a4c commit cca6221
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 9 deletions.
13 changes: 13 additions & 0 deletions internal/static/css/statsviz.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ body {
margin: 0;
}

nav.navbar {
background-color: #f8f9fa;
}

body.dark-theme {
color: white;
background-color: #282a2c;
}

body.dark-theme nav.navbar span.action svg {
color: lightgray;
}

#header {
text-align: center;
}
Expand Down
7 changes: 5 additions & 2 deletions internal/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</head>

<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light" style="background-color: #84afce;">
<nav id="navbar" class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-xxl">
<a class="navbar-brand" href="#">Statsviz</a>
<button class="navbar-toggler" type="button">
Expand All @@ -45,9 +45,12 @@
<option value="300">5 minute</option>
<option value="600">10 minutes</option>
</select>
<span title="play/pause">
<span class="action" title="play/pause">
<input id="play_pause" type="checkbox" data-toggle="toggle" data-onstyle="default" data-on="<i class='fa fa-play'></i>" data-off="<i class='fa fa-pause'></i>" data-size="mini" data-bs-toggle="tooltip">
</span>
<span class="action" title="color theme">
<input id="color_theme_sw" type="checkbox" data-toggle="toggle" data-onstyle="default" data-on="<i class='fa fa-circle-half-stroke'></i>" data-off="<i class='fa fa-circle-half-stroke'></i>" data-size="mini" data-bs-toggle="tooltip">
</span>
</div>
</nav>

Expand Down
23 changes: 21 additions & 2 deletions internal/static/js/app.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as stats from './stats.js';
import * as plot from "./plot.js";
import * as theme from "./theme.js";
import PlotsDef from './plotsdef.js';

const buildWebsocketURI = () => {
Expand Down Expand Up @@ -90,7 +91,6 @@ const configurePlots = (plotdefs) => {
}

const attachPlots = () => {
let row = null;
let plotsDiv = $('#plots');
plotsDiv.empty();

Expand Down Expand Up @@ -123,4 +123,23 @@ const updatePlots = () => {
plot.update(xrange, data, shapes);
}
});
}
}

const updatePlotsLayout = () => {
plots.forEach(plot => {
plot.updateTheme();
});
}

theme.updateThemeMode();

/**
* Change color theme when the user presses the theme switch button
*/
$('#color_theme_sw').change(() => {
const themeMode = theme.getThemeMode();
const newTheme = themeMode === "dark" && "light" || "dark";
localStorage.setItem("theme-mode", newTheme);
theme.updateThemeMode();
updatePlotsLayout();
});
48 changes: 43 additions & 5 deletions internal/static/js/plot.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as theme from "./theme.js";

var infoIcon = {
'width': 470,
'height': 530,
Expand Down Expand Up @@ -39,8 +41,11 @@ const newLayoutObject = (cfg) => {
margin: {
t: 80,
},
paper_bgcolor: '#f8f8f8',
plot_bgcolor: '#ffffdd',
paper_bgcolor: cfg.layout.paper_bgcolor,
plot_bgcolor: cfg.layout.plot_bgcolor,
font: {
color: cfg.layout.font_color
},
width: 630,
height: 450,
hovermode: 'x',
Expand All @@ -61,7 +66,7 @@ const newLayoutObject = (cfg) => {
showlegend: true,
legend: {
"orientation": "h"
},
}
};

if (layout.yaxis.tickmode == "array") {
Expand Down Expand Up @@ -94,6 +99,19 @@ const handleInfoButton = (gd, ev) => {
button.setAttribute('data-val', !val);
}

const themeColors = {
light: {
paper_bgcolor: '#f8f8f8',
plot_bgcolor: '#ffffdd',
font_color: '#434343'
},
dark: {
paper_bgcolor: '#181a1c',
plot_bgcolor: '#282a2c',
font_color: '#fff'
}
};

/*
Plot configuration object:
{
Expand Down Expand Up @@ -159,9 +177,14 @@ class Plot {
*/

constructor(cfg) {
cfg.layout.paper_bgcolor = themeColors[theme.getThemeMode()].paper_bgcolor;
cfg.layout.plot_bgcolor = themeColors[theme.getThemeMode()].plot_bgcolor;
cfg.layout.font_color = themeColors[theme.getThemeMode()].font_color;

this._cfg = cfg;
this._updateCount = 0;
this._dataTemplate = [];
this._lastData = [{ x: new Date() }];

if (['scatter', 'bar'].includes(this._cfg.type)) {
this._cfg.subplots.forEach(subplot => {
Expand Down Expand Up @@ -198,7 +221,7 @@ class Plot {
this._plotIdx = idx;
// Pass a single data with no data to create an empty plot, this removes
// the 'bad time formatting' warning at startup.
Plotly.newPlot(this._htmlElt, [{ x: new Date() }], this._plotlyLayout, this._plotlyConfig);
Plotly.newPlot(this._htmlElt, this._lastData, this._plotlyLayout, this._plotlyConfig);
if (this._cfg.type == 'heatmap') {
this._installHeatmapTooltip();
}
Expand Down Expand Up @@ -275,6 +298,7 @@ class Plot {
}

update(xrange, data, shapes) {
this._lastData = this._extractData(data);
this._updateCount++;
if (this._cfg.updateFreq == 0 || (this._updateCount % this._cfg.updateFreq == 0)) {
// Update layout with vertical shapes if necessary.
Expand All @@ -285,9 +309,23 @@ class Plot {
// Move the xaxis time range.
this._plotlyLayout.xaxis.range = xrange;

Plotly.react(this._htmlElt, this._extractData(data), this._plotlyLayout, this._plotlyConfig);
Plotly.react(this._htmlElt, this._lastData, this._plotlyLayout, this._plotlyConfig);
}
}

/**
* update theme color and immediately force plot redraw to apply the new theme
*/
updateTheme() {
this._cfg.layout.paper_bgcolor = themeColors[theme.getThemeMode()].paper_bgcolor;
this._cfg.layout.plot_bgcolor = themeColors[theme.getThemeMode()].plot_bgcolor;
this._cfg.layout.font_color = themeColors[theme.getThemeMode()].font_color;

this._plotlyLayout = newLayoutObject(this._cfg);
this._plotlyConfig = newConfigObject(this._cfg);

Plotly.react(this._htmlElt, this._lastData, this._plotlyLayout);
}
};

// Create 'vertical lines' shapes for each of the given timestamps.
Expand Down
36 changes: 36 additions & 0 deletions internal/static/js/theme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Get color theme based on previous user choice or browser theme
*/
export const getThemeMode = () => {
let themeMode = localStorage.getItem("theme-mode");

if (themeMode === null) {
const isDark =
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches;
themeMode = (isDark && "dark") || "light";

localStorage.setItem("theme-mode", themeMode);
}

return themeMode;
};

/**
* Set light or dark theme
*/
export const updateThemeMode = () => {
if (getThemeMode() === "dark") {
document.body.classList.add("dark-theme");
document
.getElementById("navbar")
.classList.replace("navbar-light", "navbar-dark");
document.getElementById("navbar").classList.replace("bg-light", "bg-dark");
} else {
document.body.classList.remove("dark-theme");
document
.getElementById("navbar")
.classList.replace("navbar-dark", "navbar-light");
document.getElementById("navbar").classList.replace("bg-dark", "bg-light");
}
};

0 comments on commit cca6221

Please sign in to comment.