Skip to content

Commit 16c3dfb

Browse files
Add hover tooltip descriptions to asset-type legend items in over-time plot (#109)
* Initial plan * Add hover tooltip text to asset-type legend items in over-time plot Agent-Logs-Url: https://github.com/dandi/access-page/sessions/0de9647e-34f4-4012-9273-34e4b9841bf3 Co-authored-by: CodyCBakerPhD <51133164+CodyCBakerPhD@users.noreply.github.com> * Apply suggestion from @CodyCBakerPhD --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: CodyCBakerPhD <51133164+CodyCBakerPhD@users.noreply.github.com>
1 parent 4655160 commit 16c3dfb

1 file changed

Lines changed: 43 additions & 0 deletions

File tree

src/plots.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,15 @@ function aggregate_by_timebin(dates, bytes_sent, aggregation) {
914914
};
915915
}
916916

917+
// Abbreviated descriptions shown as tooltip text on legend items when the
918+
// over-time plot is grouped by asset type.
919+
const ASSET_TYPE_DESCRIPTIONS = {
920+
Neurophysiology: "NWB files",
921+
Microscopy: "OME-Zarr, NIfTI, TIFF",
922+
Video: "AVI, MKV, MP4, MOV, WMV",
923+
Miscellaneous: "TXT, TSV, JSON, code, etc.",
924+
};
925+
917926
// Categorical colour palette for the "group by Dandisets" overlay bars.
918927
// Colours include 0.7 alpha so overlapping bars remain visible.
919928
const DANDISET_BAR_COLORS = [
@@ -973,6 +982,39 @@ function parse_by_asset_type_per_week_tsv(text) {
973982
return { dates, asset_types, series_map };
974983
}
975984

985+
/**
986+
* Adds SVG <title> tooltip elements to Plotly legend items whose display name
987+
* appears in `label_to_tooltip`. Attaches to the plotly_afterplot event so
988+
* tooltips survive redraws (theme switches, resizes, trace toggles, etc.).
989+
*
990+
* @param {string} plot_element_id - ID of the Plotly graph div.
991+
* @param {Object} label_to_tooltip - Map of legend label → tooltip string.
992+
*/
993+
function attach_legend_tooltips(plot_element_id, label_to_tooltip) {
994+
const el = document.getElementById(plot_element_id);
995+
if (!el) return;
996+
997+
function inject_titles() {
998+
el.querySelectorAll(".legendtext").forEach((text_el) => {
999+
const desc = label_to_tooltip[text_el.textContent];
1000+
if (!desc) return;
1001+
const group = text_el.closest(".traces");
1002+
if (!group) return;
1003+
// Replace any stale title so re-renders always have the correct text.
1004+
const existing = group.querySelector("title");
1005+
if (existing) existing.remove();
1006+
const title_el = document.createElementNS("http://www.w3.org/2000/svg", "title");
1007+
title_el.textContent = desc;
1008+
group.appendChild(title_el);
1009+
});
1010+
}
1011+
1012+
inject_titles();
1013+
// `el.on()` is Plotly's own event-emitter API (added to the graph div by
1014+
// Plotly.newPlot); it is the documented way to subscribe to plotly_* events.
1015+
el.on("plotly_afterplot", inject_titles);
1016+
}
1017+
9761018
/**
9771019
* Builds the shared layout options used by both single-series and grouped
9781020
* over-time plots.
@@ -1129,6 +1171,7 @@ function load_over_time_plot(dandiset_id) {
11291171
}
11301172

11311173
Plotly.newPlot(plot_element_id, plot_info, layout);
1174+
attach_legend_tooltips(plot_element_id, ASSET_TYPE_DESCRIPTIONS);
11321175

11331176
// Table: show total bytes per time bin (sum across all asset types)
11341177
const total_bytes = raw_dates.map((_, i) =>

0 commit comments

Comments
 (0)