Spaces:
Running
Running
Amber Tanaka
commited on
Fix the table legend and tooltips (#84)
Browse files- app.py +61 -1
- content.py +5 -30
- ui_components.py +3 -3
app.py
CHANGED
|
@@ -40,7 +40,67 @@ redirect_script = """
|
|
| 40 |
if (window.location.pathname === '/') { window.location.replace('/home'); }
|
| 41 |
</script>
|
| 42 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
# --- Theme Definition ---
|
| 45 |
theme = gr.themes.Base(
|
| 46 |
primary_hue=gr.themes.Color(c100="#CFF5E8", c200="#B7EFDD", c300="#9FEAD1", c400="#87E5C5", c50="#E7FAF3", c500="#6FE0BA", c600="#57DBAF", c700="#3FD5A3", c800="#27D09C", c900="#0FCB8C", c950="#0fcb8c"),
|
|
@@ -133,7 +193,7 @@ final_css = css + f"""
|
|
| 133 |
}}
|
| 134 |
"""
|
| 135 |
# --- Gradio App Definition ---
|
| 136 |
-
demo = gr.Blocks(theme=theme, css=final_css, head=scroll_script + redirect_script)
|
| 137 |
with demo.route("Home", "/home"):
|
| 138 |
build_main_page()
|
| 139 |
|
|
|
|
| 40 |
if (window.location.pathname === '/') { window.location.replace('/home'); }
|
| 41 |
</script>
|
| 42 |
"""
|
| 43 |
+
tooltip_script = """
|
| 44 |
+
<script>
|
| 45 |
+
function initializeSmartTooltips() {
|
| 46 |
+
// Find all tooltip trigger icons
|
| 47 |
+
const tooltipIcons = document.querySelectorAll('.tooltip-icon-legend');
|
| 48 |
+
|
| 49 |
+
tooltipIcons.forEach(icon => {
|
| 50 |
+
// Find the tooltip card associated with this icon
|
| 51 |
+
const tooltipCard = icon.querySelector('.tooltip-card');
|
| 52 |
+
if (!tooltipCard) return;
|
| 53 |
+
|
| 54 |
+
// Move the card to the end of the <body>. This is the KEY to escaping
|
| 55 |
+
// any parent containers that might clip it.
|
| 56 |
+
document.body.appendChild(tooltipCard);
|
| 57 |
+
|
| 58 |
+
// --- MOUSE HOVER EVENT ---
|
| 59 |
+
icon.addEventListener('mouseenter', () => {
|
| 60 |
+
// Get the exact position of the icon on the screen
|
| 61 |
+
const iconRect = icon.getBoundingClientRect();
|
| 62 |
+
// Get the dimensions of the tooltip card
|
| 63 |
+
const cardRect = tooltipCard.getBoundingClientRect();
|
| 64 |
+
|
| 65 |
+
// Calculate the ideal top position (above the icon with a 10px gap)
|
| 66 |
+
const top = iconRect.top - cardRect.height - 10;
|
| 67 |
+
|
| 68 |
+
// --- Smart Centering Logic ---
|
| 69 |
+
// Start by calculating the perfect center
|
| 70 |
+
let left = iconRect.left + (iconRect.width / 2) - (cardRect.width / 2);
|
| 71 |
+
|
| 72 |
+
// Check if it's going off the left edge of the screen
|
| 73 |
+
if (left < 10) {
|
| 74 |
+
left = 10; // Pin it to the left with a 10px margin
|
| 75 |
+
}
|
| 76 |
+
// Check if it's going off the right edge of the screen
|
| 77 |
+
if (left + cardRect.width > window.innerWidth) {
|
| 78 |
+
left = window.innerWidth - cardRect.width - 10; // Pin it to the right
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
// Apply the calculated position and show the card
|
| 82 |
+
tooltipCard.style.top = `${top}px`;
|
| 83 |
+
tooltipCard.style.left = `${left}px`;
|
| 84 |
+
tooltipCard.classList.add('visible');
|
| 85 |
+
});
|
| 86 |
+
|
| 87 |
+
// --- MOUSE LEAVE EVENT ---
|
| 88 |
+
icon.addEventListener('mouseleave', () => {
|
| 89 |
+
// Hide the card
|
| 90 |
+
tooltipCard.classList.remove('visible');
|
| 91 |
+
});
|
| 92 |
+
});
|
| 93 |
+
}
|
| 94 |
|
| 95 |
+
// Poll the page until the tooltips exist, then run the initialization.
|
| 96 |
+
const tooltipInterval = setInterval(() => {
|
| 97 |
+
if (document.querySelector('.tooltip-icon-legend')) {
|
| 98 |
+
clearInterval(tooltipInterval);
|
| 99 |
+
initializeSmartTooltips();
|
| 100 |
+
}
|
| 101 |
+
}, 200);
|
| 102 |
+
</script>
|
| 103 |
+
"""
|
| 104 |
# --- Theme Definition ---
|
| 105 |
theme = gr.themes.Base(
|
| 106 |
primary_hue=gr.themes.Color(c100="#CFF5E8", c200="#B7EFDD", c300="#9FEAD1", c400="#87E5C5", c50="#E7FAF3", c500="#6FE0BA", c600="#57DBAF", c700="#3FD5A3", c800="#27D09C", c900="#0FCB8C", c950="#0fcb8c"),
|
|
|
|
| 193 |
}}
|
| 194 |
"""
|
| 195 |
# --- Gradio App Definition ---
|
| 196 |
+
demo = gr.Blocks(theme=theme, css=final_css, head=scroll_script + redirect_script + tooltip_script)
|
| 197 |
with demo.route("Home", "/home"):
|
| 198 |
build_main_page()
|
| 199 |
|
content.py
CHANGED
|
@@ -615,19 +615,15 @@ span.wrap[tabindex="0"][role="button"][data-editable="false"] {
|
|
| 615 |
display: inline-block;
|
| 616 |
}
|
| 617 |
|
| 618 |
-
/* The HTML pop-up card.*/
|
| 619 |
.tooltip-card {
|
| 620 |
/* Hiding mechanism */
|
| 621 |
opacity: 0;
|
| 622 |
visibility: hidden;
|
| 623 |
transition: opacity 0.2s;
|
| 624 |
pointer-events: none;
|
| 625 |
-
|
| 626 |
/* Card appearance */
|
| 627 |
-
position:
|
| 628 |
-
bottom: 125%;
|
| 629 |
-
left: 50%;
|
| 630 |
-
transform: translateX(-50%);
|
| 631 |
z-index: 1000;
|
| 632 |
background-color: #083c40;
|
| 633 |
color: #e5e7eb;
|
|
@@ -637,12 +633,10 @@ span.wrap[tabindex="0"][role="button"][data-editable="false"] {
|
|
| 637 |
max-width: 400px;
|
| 638 |
text-align: left;
|
| 639 |
}
|
| 640 |
-
|
| 641 |
-
.tooltip-icon-legend:hover .tooltip-card {
|
| 642 |
opacity: 1;
|
| 643 |
visibility: visible;
|
| 644 |
-
}
|
| 645 |
-
|
| 646 |
.tooltip-card h3 {
|
| 647 |
font-size: 18px;
|
| 648 |
color: #fff;
|
|
@@ -689,26 +683,6 @@ span.wrap[tabindex="0"][role="button"][data-editable="false"] {
|
|
| 689 |
display: flex;
|
| 690 |
flex-direction: column;
|
| 691 |
}
|
| 692 |
-
@media (max-width: 800px) {
|
| 693 |
-
.tooltip-card {
|
| 694 |
-
transform: none;
|
| 695 |
-
left: 10px;
|
| 696 |
-
max-width: calc(100vw - 100px);
|
| 697 |
-
}
|
| 698 |
-
.tooltip-icon-legend:hover::before {
|
| 699 |
-
left: 50%;
|
| 700 |
-
transform: translateX(-50%);
|
| 701 |
-
}
|
| 702 |
-
}
|
| 703 |
-
.tooltip-pin-left .tooltip-card {
|
| 704 |
-
left: 0;
|
| 705 |
-
transform: none;
|
| 706 |
-
}
|
| 707 |
-
.tooltip-pin-right .tooltip-card {
|
| 708 |
-
right: 0;
|
| 709 |
-
left: auto;
|
| 710 |
-
transform: none;
|
| 711 |
-
}
|
| 712 |
.table-legend-item {
|
| 713 |
display: flex;
|
| 714 |
align-items: center;
|
|
@@ -716,6 +690,7 @@ span.wrap[tabindex="0"][role="button"][data-editable="false"] {
|
|
| 716 |
margin-top: 8px;
|
| 717 |
flex-wrap: wrap;
|
| 718 |
}
|
|
|
|
| 719 |
/* About Page CSS */
|
| 720 |
#about-page-content-wrapper {
|
| 721 |
margin-left: auto;
|
|
|
|
| 615 |
display: inline-block;
|
| 616 |
}
|
| 617 |
|
| 618 |
+
/* The HTML pop-up card tooltips.*/
|
| 619 |
.tooltip-card {
|
| 620 |
/* Hiding mechanism */
|
| 621 |
opacity: 0;
|
| 622 |
visibility: hidden;
|
| 623 |
transition: opacity 0.2s;
|
| 624 |
pointer-events: none;
|
|
|
|
| 625 |
/* Card appearance */
|
| 626 |
+
position: fixed;
|
|
|
|
|
|
|
|
|
|
| 627 |
z-index: 1000;
|
| 628 |
background-color: #083c40;
|
| 629 |
color: #e5e7eb;
|
|
|
|
| 633 |
max-width: 400px;
|
| 634 |
text-align: left;
|
| 635 |
}
|
| 636 |
+
.tooltip-card.visible {
|
|
|
|
| 637 |
opacity: 1;
|
| 638 |
visibility: visible;
|
| 639 |
+
}
|
|
|
|
| 640 |
.tooltip-card h3 {
|
| 641 |
font-size: 18px;
|
| 642 |
color: #fff;
|
|
|
|
| 683 |
display: flex;
|
| 684 |
flex-direction: column;
|
| 685 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 686 |
.table-legend-item {
|
| 687 |
display: flex;
|
| 688 |
align-items: center;
|
|
|
|
| 690 |
margin-top: 8px;
|
| 691 |
flex-wrap: wrap;
|
| 692 |
}
|
| 693 |
+
|
| 694 |
/* About Page CSS */
|
| 695 |
#about-page-content-wrapper {
|
| 696 |
margin-left: auto;
|
ui_components.py
CHANGED
|
@@ -324,11 +324,11 @@ def create_legend_markdown(which_table: str) -> str:
|
|
| 324 |
descriptions_tooltip_content = build_descriptions_tooltip_content(which_table)
|
| 325 |
trophy_uri = get_svg_as_data_uri("assets/trophy.svg")
|
| 326 |
legend_markdown = f"""
|
| 327 |
-
<div style="display: flex; flex-wrap: wrap; align-items: flex-start; gap:
|
| 328 |
|
| 329 |
<div> <!-- Container for the Pareto section -->
|
| 330 |
<b>Pareto</b>
|
| 331 |
-
<span class="tooltip-icon-legend
|
| 332 |
ⓘ
|
| 333 |
<span class="tooltip-card">{pareto_tooltip_content}</span>
|
| 334 |
</span>
|
|
@@ -366,7 +366,7 @@ def create_legend_markdown(which_table: str) -> str:
|
|
| 366 |
|
| 367 |
<div><!-- Container for the Column Descriptions section -->
|
| 368 |
<b>Column Descriptions</b>
|
| 369 |
-
<span class="tooltip-icon-legend
|
| 370 |
ⓘ
|
| 371 |
<span class="tooltip-card">
|
| 372 |
<h3>Column Descriptions</h3>
|
|
|
|
| 324 |
descriptions_tooltip_content = build_descriptions_tooltip_content(which_table)
|
| 325 |
trophy_uri = get_svg_as_data_uri("assets/trophy.svg")
|
| 326 |
legend_markdown = f"""
|
| 327 |
+
<div style="display: flex; flex-wrap: wrap; align-items: flex-start; gap: 20px; font-size: 14px; padding-bottom: 8px;">
|
| 328 |
|
| 329 |
<div> <!-- Container for the Pareto section -->
|
| 330 |
<b>Pareto</b>
|
| 331 |
+
<span class="tooltip-icon-legend">
|
| 332 |
ⓘ
|
| 333 |
<span class="tooltip-card">{pareto_tooltip_content}</span>
|
| 334 |
</span>
|
|
|
|
| 366 |
|
| 367 |
<div><!-- Container for the Column Descriptions section -->
|
| 368 |
<b>Column Descriptions</b>
|
| 369 |
+
<span class="tooltip-icon-legend">
|
| 370 |
ⓘ
|
| 371 |
<span class="tooltip-card">
|
| 372 |
<h3>Column Descriptions</h3>
|