return;
}
+ /** @type {{date: string; max_id: number; total_changes: number}[]} */
const heatmapData = heatmapElement.dataset.heatmap ? JSON.parse(heatmapElement.dataset.heatmap) : [];
+ const displayName = heatmapElement.dataset.displayName;
const colorScheme = document.documentElement.getAttribute("data-bs-theme") ?? "auto";
- const rangeColors = ["#14432a", "#166b34", "#37a446", "#4dd05a"];
+ const rangeColorsDark = ["#14432a", "#4dd05a"];
+ const rangeColorsLight = ["#4dd05a", "#14432a"];
const startDate = new Date(Date.now() - (365 * 24 * 60 * 60 * 1000));
- const monthNames = I18n.t("date.abbr_month_names");
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
type: "month",
gutter: 4,
label: {
- text: (timestamp) => monthNames[new Date(timestamp).getMonth() + 1],
+ text: (timestamp) => new Date(timestamp).toLocaleString(OSM.i18n.locale, { timeZone: "UTC", month: "short" }),
position: "top",
textAlign: "middle"
},
},
scale: {
color: {
- type: "threshold",
- range: currentTheme === "dark" ? rangeColors : Array.from(rangeColors).reverse(),
- domain: [10, 20, 30, 40]
+ type: "sqrt",
+ range: currentTheme === "dark" ? rangeColorsDark : rangeColorsLight,
+ domain: [0, Math.max(0, ...heatmapData.map(d => d.total_changes))]
}
}
}, [
text: (date, value) => getTooltipText(date, value)
}]
]);
+
+ cal.on("mouseover", (event, timestamp, value) => {
+ if (!displayName || !value) return;
+ if (event.target.parentElement.nodeName === "a") return;
+
+ for (const { date, max_id } of heatmapData) {
+ if (!max_id) continue;
+ if (timestamp !== Date.parse(date)) continue;
+
+ const params = new URLSearchParams({ before: max_id + 1 });
+ const a = document.createElementNS("http://www.w3.org/2000/svg", "a");
+ a.setAttribute("href", `/user/${encodeURIComponent(displayName)}/history?${params}`);
+ $(event.target).wrap(a);
+ break;
+ }
+ });
}
function getTooltipText(date, value) {
- const localizedDate = I18n.l("date.formats.long", date);
+ const localizedDate = OSM.i18n.l("date.formats.long", date);
if (value > 0) {
- return I18n.t("javascripts.heatmap.tooltip.contributions", { count: value, date: localizedDate });
+ return OSM.i18n.t("javascripts.heatmap.tooltip.contributions", { count: value, date: localizedDate });
}
- return I18n.t("javascripts.heatmap.tooltip.no_contributions", { date: localizedDate });
+ return OSM.i18n.t("javascripts.heatmap.tooltip.no_contributions", { date: localizedDate });
}
function getTheme() {