Skip to content

Instantly share code, notes, and snippets.

@J08nY
Last active July 28, 2025 12:26
Show Gist options
  • Save J08nY/7333026beaa08c00afe8cd08910ed49c to your computer and use it in GitHub Desktop.
Save J08nY/7333026beaa08c00afe8cd08910ed49c to your computer and use it in GitHub Desktop.
Makes the past workout skyline flat and look like the normal one.
// ==UserScript==
// @name Skyline Chart Gradient Flattener
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Sets all gradient stops in #skyline-chart-gradients to constant opacity (stop-opacity: 0.8) and adds a stroke.
// @author You
// @match https://intervals.icu/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
function flattenSkylineGradients() {
const svg = document.getElementById("skyline-chart-gradients");
if (!svg) return;
// Query all <stop> elements under the gradients
const stops = svg.querySelectorAll("linearGradient > stop");
stops.forEach(stop => {
// Set stop-opacity to 1.0
stop.setAttribute("style", stop.getAttribute("style") // overwrite only stop-opacity, keep color
? stop.getAttribute("style").replace(/stop-opacity\s*:\s*[^;]+(;?)/, "stop-opacity: 0.7;")
: "stop-opacity: 0.7;");
// If the style didn't have stop-opacity, ensure it's appended
if (!stop.getAttribute("style").includes("stop-opacity")) {
stop.setAttribute("style", stop.getAttribute("style") + " stop-opacity: 0.7;");
}
});
}
// Utility to parse the color from fill="url(#skyline-chart-gradients-hexcode)"
function extractHexFromFill(fill) {
// fill is expected as: url(#skyline-chart-gradients-ffcb0e)
const match = fill && fill.match(/url\(#skyline-chart-gradients-([0-9a-fA-F]{6})\)/);
return match ? `#${match[1]}` : null;
}
function highlightSkylineRects() {
const skylineDivs = document.querySelectorAll('div.activity-skyline');
skylineDivs.forEach(skylineDiv => {
const svg = skylineDiv.querySelector('svg');
if (!svg) return;
svg.querySelectorAll('rect[fill^="url(#skyline-chart-gradients-"]').forEach(rect => {
const fill = rect.getAttribute('fill');
const color = extractHexFromFill(fill);
if (color) {
rect.setAttribute('stroke', color);
rect.setAttribute('stroke-width', '1.5');
}
});
});
}
// Try on DOMContentLoaded and again if chart loads dynamically
document.addEventListener("DOMContentLoaded", flattenSkylineGradients);
document.addEventListener("DOMContentLoaded", highlightSkylineRects);
// Mutation observer to handle dynamically inserted SVG
const observer = new MutationObserver((mutations) => {
for (const m of mutations) {
if (m.addedNodes.length) {
for (const node of m.addedNodes) {
if (node.nodeType === 1) { // ELEMENT_NODE
if (node.id === "skyline-chart-gradients" || node.querySelector?.("#skyline-chart-gradients")) {
flattenSkylineGradients();
highlightSkylineRects();
break;
}
}
}
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment