Spaces:
Sleeping
Sleeping
Deepa Shalini commited on
Commit ·
b89c575
1
Parent(s): 59ba5ac
gallery view, updated prompt for subplots choropleth
Browse files- app.py +140 -2
- assets/custom.css +238 -0
- data/1976-2020_president.csv +0 -3
- data/ewf_appearances.csv +0 -3
- data/gold prices.csv +0 -3
- data/oecd_gpia_results.csv +0 -3
- data/space_missions_data.csv +0 -3
- gallery_data.py +79 -0
- utils/prompt.py +15 -1
app.py
CHANGED
|
@@ -3,6 +3,7 @@ from dash import html, dcc, callback, Output, Input, State
|
|
| 3 |
import dash_mantine_components as dmc
|
| 4 |
import pandas as pd
|
| 5 |
from utils import prompt, helpers
|
|
|
|
| 6 |
|
| 7 |
# Initialize the Dash app
|
| 8 |
app = dash.Dash(__name__, suppress_callback_exceptions=True)
|
|
@@ -36,6 +37,34 @@ app.layout = dmc.MantineProvider(
|
|
| 36 |
],
|
| 37 |
className="brand"
|
| 38 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
html.Button(
|
| 40 |
"New Chart",
|
| 41 |
id="new-chart-button",
|
|
@@ -50,7 +79,7 @@ app.layout = dmc.MantineProvider(
|
|
| 50 |
]
|
| 51 |
),
|
| 52 |
|
| 53 |
-
# Form section
|
| 54 |
html.Div(
|
| 55 |
[
|
| 56 |
# Prompt textarea
|
|
@@ -131,7 +160,7 @@ app.layout = dmc.MantineProvider(
|
|
| 131 |
target="_blank",
|
| 132 |
style={"display": "none", "marginTop": "20px", "textAlign": "right"}
|
| 133 |
),
|
| 134 |
-
html.Div(id="dataset-explorer", style={"marginTop": "10px"}),
|
| 135 |
html.Div(id="chartbot-output", style={"marginTop": "10px"}),
|
| 136 |
html.Div(id="python-content-output", style={"marginTop": "10px"}),
|
| 137 |
|
|
@@ -140,7 +169,91 @@ app.layout = dmc.MantineProvider(
|
|
| 140 |
dcc.Store(id="stored-file-name"),
|
| 141 |
dcc.Store(id="html-buffer")
|
| 142 |
],
|
|
|
|
| 143 |
style={"marginTop": "10px"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
)
|
| 145 |
],
|
| 146 |
className="card",
|
|
@@ -373,5 +486,30 @@ def reset_chat(n_clicks):
|
|
| 373 |
return "", None, None, None, None, None, None, {"display": "none"}, None, True, None # Added None for dataset-explorer
|
| 374 |
return dash.no_update
|
| 375 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 376 |
if __name__ == "__main__":
|
| 377 |
app.run(debug=True)
|
|
|
|
| 3 |
import dash_mantine_components as dmc
|
| 4 |
import pandas as pd
|
| 5 |
from utils import prompt, helpers
|
| 6 |
+
from gallery_data import GALLERY_DATA
|
| 7 |
|
| 8 |
# Initialize the Dash app
|
| 9 |
app = dash.Dash(__name__, suppress_callback_exceptions=True)
|
|
|
|
| 37 |
],
|
| 38 |
className="brand"
|
| 39 |
),
|
| 40 |
+
# Tab switcher (added before New Chart button)
|
| 41 |
+
html.Div(
|
| 42 |
+
[
|
| 43 |
+
html.Button(
|
| 44 |
+
"VISUALIZER",
|
| 45 |
+
id="tab-visualizer",
|
| 46 |
+
className="tab active",
|
| 47 |
+
type="button",
|
| 48 |
+
**{
|
| 49 |
+
"role": "tab",
|
| 50 |
+
"aria-selected": "true"
|
| 51 |
+
}
|
| 52 |
+
),
|
| 53 |
+
html.Button(
|
| 54 |
+
"GALLERY",
|
| 55 |
+
id="tab-gallery",
|
| 56 |
+
className="tab",
|
| 57 |
+
type="button",
|
| 58 |
+
**{
|
| 59 |
+
"role": "tab",
|
| 60 |
+
"aria-selected": "false"
|
| 61 |
+
}
|
| 62 |
+
)
|
| 63 |
+
],
|
| 64 |
+
className="tabs",
|
| 65 |
+
role="tablist",
|
| 66 |
+
**{"aria-label": "ChaRtBot pages"}
|
| 67 |
+
),
|
| 68 |
html.Button(
|
| 69 |
"New Chart",
|
| 70 |
id="new-chart-button",
|
|
|
|
| 79 |
]
|
| 80 |
),
|
| 81 |
|
| 82 |
+
# Visualizer Page (Form section)
|
| 83 |
html.Div(
|
| 84 |
[
|
| 85 |
# Prompt textarea
|
|
|
|
| 160 |
target="_blank",
|
| 161 |
style={"display": "none", "marginTop": "20px", "textAlign": "right"}
|
| 162 |
),
|
| 163 |
+
html.Div(id="dataset-explorer", style={"marginTop": "10px"}),
|
| 164 |
html.Div(id="chartbot-output", style={"marginTop": "10px"}),
|
| 165 |
html.Div(id="python-content-output", style={"marginTop": "10px"}),
|
| 166 |
|
|
|
|
| 169 |
dcc.Store(id="stored-file-name"),
|
| 170 |
dcc.Store(id="html-buffer")
|
| 171 |
],
|
| 172 |
+
id="visualizer-page",
|
| 173 |
style={"marginTop": "10px"}
|
| 174 |
+
),
|
| 175 |
+
|
| 176 |
+
# Gallery Page
|
| 177 |
+
html.Div(
|
| 178 |
+
[
|
| 179 |
+
# Gallery page header
|
| 180 |
+
html.Section(
|
| 181 |
+
html.Div(
|
| 182 |
+
[
|
| 183 |
+
html.H2("Gallery", style={"margin": "0", "fontSize": "18px", "letterSpacing": "-0.02em"}),
|
| 184 |
+
html.P(
|
| 185 |
+
"Browse charts generated by ChaRtBot — each card includes the prompt and the original dataset.",
|
| 186 |
+
style={"margin": "6px 0 0", "fontSize": "13px", "color": "var(--muted)"}
|
| 187 |
+
)
|
| 188 |
+
],
|
| 189 |
+
className="page-title"
|
| 190 |
+
),
|
| 191 |
+
className="page-head"
|
| 192 |
+
),
|
| 193 |
+
|
| 194 |
+
# Gallery grid
|
| 195 |
+
html.Section(
|
| 196 |
+
[
|
| 197 |
+
# Generate cards from GALLERY_DATA
|
| 198 |
+
*[
|
| 199 |
+
html.Article(
|
| 200 |
+
[
|
| 201 |
+
html.Div(
|
| 202 |
+
[
|
| 203 |
+
html.Img(
|
| 204 |
+
src=item["image"],
|
| 205 |
+
alt=f"Chart thumbnail {i+1}"
|
| 206 |
+
)
|
| 207 |
+
],
|
| 208 |
+
className="thumb"
|
| 209 |
+
),
|
| 210 |
+
html.Div(
|
| 211 |
+
[
|
| 212 |
+
html.P(
|
| 213 |
+
f"Prompt: {item['prompt']}",
|
| 214 |
+
className="gallery-prompt"
|
| 215 |
+
),
|
| 216 |
+
html.Div(
|
| 217 |
+
[
|
| 218 |
+
html.Div(
|
| 219 |
+
[
|
| 220 |
+
html.A(
|
| 221 |
+
"📄 CSV",
|
| 222 |
+
className="link",
|
| 223 |
+
href=item["csv_link"],
|
| 224 |
+
target="_blank" if item["csv_link"] != "#" else ""
|
| 225 |
+
),
|
| 226 |
+
html.Span(
|
| 227 |
+
item["badge"],
|
| 228 |
+
className="badge"
|
| 229 |
+
) if item.get("badge") else None
|
| 230 |
+
],
|
| 231 |
+
className="links"
|
| 232 |
+
),
|
| 233 |
+
html.Button(
|
| 234 |
+
"⋮",
|
| 235 |
+
className="kebab",
|
| 236 |
+
type="button",
|
| 237 |
+
**{"aria-label": "More actions"}
|
| 238 |
+
)
|
| 239 |
+
],
|
| 240 |
+
className="meta"
|
| 241 |
+
)
|
| 242 |
+
],
|
| 243 |
+
className="content"
|
| 244 |
+
)
|
| 245 |
+
],
|
| 246 |
+
className="gallery-card"
|
| 247 |
+
)
|
| 248 |
+
for i, item in enumerate(GALLERY_DATA)
|
| 249 |
+
]
|
| 250 |
+
],
|
| 251 |
+
className="gallery-grid",
|
| 252 |
+
**{"aria-label": "Gallery grid"}
|
| 253 |
+
)
|
| 254 |
+
],
|
| 255 |
+
id="gallery-page",
|
| 256 |
+
style={"display": "none"}
|
| 257 |
)
|
| 258 |
],
|
| 259 |
className="card",
|
|
|
|
| 486 |
return "", None, None, None, None, None, None, {"display": "none"}, None, True, None # Added None for dataset-explorer
|
| 487 |
return dash.no_update
|
| 488 |
|
| 489 |
+
# Callback for tab switching
|
| 490 |
+
@callback(
|
| 491 |
+
Output("tab-visualizer", "className"),
|
| 492 |
+
Output("tab-gallery", "className"),
|
| 493 |
+
Output("visualizer-page", "style"),
|
| 494 |
+
Output("gallery-page", "style"),
|
| 495 |
+
Input("tab-visualizer", "n_clicks"),
|
| 496 |
+
Input("tab-gallery", "n_clicks"),
|
| 497 |
+
prevent_initial_call=True
|
| 498 |
+
)
|
| 499 |
+
def switch_tabs(visualizer_clicks, gallery_clicks):
|
| 500 |
+
"""Handle tab switching between Visualizer and Gallery."""
|
| 501 |
+
ctx = dash.callback_context
|
| 502 |
+
if not ctx.triggered:
|
| 503 |
+
return "tab active", "tab", {"marginTop": "10px"}, {"display": "none"}
|
| 504 |
+
|
| 505 |
+
button_id = ctx.triggered[0]["prop_id"].split(".")[0]
|
| 506 |
+
|
| 507 |
+
if button_id == "tab-visualizer":
|
| 508 |
+
return "tab active", "tab", {"marginTop": "10px"}, {"display": "none"}
|
| 509 |
+
elif button_id == "tab-gallery":
|
| 510 |
+
return "tab", "tab active", {"display": "none"}, {"marginTop": "10px"}
|
| 511 |
+
|
| 512 |
+
return "tab active", "tab", {"marginTop": "10px"}, {"display": "none"}
|
| 513 |
+
|
| 514 |
if __name__ == "__main__":
|
| 515 |
app.run(debug=True)
|
assets/custom.css
CHANGED
|
@@ -80,6 +80,48 @@ header {
|
|
| 80 |
margin-bottom: 14px;
|
| 81 |
}
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
.brand {
|
| 84 |
display: flex;
|
| 85 |
gap: 12px;
|
|
@@ -223,4 +265,200 @@ h1 {
|
|
| 223 |
.submitBtn {
|
| 224 |
width: 100%;
|
| 225 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
}
|
|
|
|
| 80 |
margin-bottom: 14px;
|
| 81 |
}
|
| 82 |
|
| 83 |
+
/* Tab switcher styles */
|
| 84 |
+
.tabs {
|
| 85 |
+
display: flex;
|
| 86 |
+
align-items: center;
|
| 87 |
+
gap: 10px;
|
| 88 |
+
padding: 6px;
|
| 89 |
+
background: rgba(255, 255, 255, 0.70);
|
| 90 |
+
border: 1px solid var(--border);
|
| 91 |
+
border-radius: 999px;
|
| 92 |
+
box-shadow: 0 10px 20px rgba(16, 24, 40, 0.05);
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
.tab {
|
| 96 |
+
border: 0;
|
| 97 |
+
background: transparent;
|
| 98 |
+
padding: 10px 14px;
|
| 99 |
+
border-radius: 999px;
|
| 100 |
+
font-weight: 600;
|
| 101 |
+
font-size: 12px;
|
| 102 |
+
letter-spacing: 0.08em;
|
| 103 |
+
text-transform: uppercase;
|
| 104 |
+
color: rgba(15, 23, 42, 0.70);
|
| 105 |
+
cursor: pointer;
|
| 106 |
+
font-family: inherit;
|
| 107 |
+
transition: all 0.2s ease;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
.tab:focus {
|
| 111 |
+
outline: none;
|
| 112 |
+
box-shadow: 0 0 0 4px rgba(47, 107, 255, 0.18);
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
.tab.active {
|
| 116 |
+
color: #0b2a7a;
|
| 117 |
+
background: linear-gradient(180deg, rgba(47, 107, 255, 0.18), rgba(47, 107, 255, 0.08));
|
| 118 |
+
border: 1px solid rgba(47, 107, 255, 0.22);
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
.tab:hover:not(.active) {
|
| 122 |
+
background: rgba(47, 107, 255, 0.05);
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
.brand {
|
| 126 |
display: flex;
|
| 127 |
gap: 12px;
|
|
|
|
| 265 |
.submitBtn {
|
| 266 |
width: 100%;
|
| 267 |
}
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
/* Gallery Page Styles */
|
| 271 |
+
.page-head {
|
| 272 |
+
display: flex;
|
| 273 |
+
align-items: flex-end;
|
| 274 |
+
justify-content: space-between;
|
| 275 |
+
gap: 18px;
|
| 276 |
+
padding: 8px 10px 14px;
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
.page-title h2 {
|
| 280 |
+
margin: 0;
|
| 281 |
+
font-size: 18px;
|
| 282 |
+
letter-spacing: -0.02em;
|
| 283 |
+
}
|
| 284 |
+
|
| 285 |
+
.page-title p {
|
| 286 |
+
margin: 6px 0 0;
|
| 287 |
+
font-size: 13px;
|
| 288 |
+
color: var(--muted);
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
/* Gallery grid: 5 rows x 4 columns = 20 items */
|
| 292 |
+
.gallery-grid {
|
| 293 |
+
margin: 8px 6px 0;
|
| 294 |
+
padding: 14px 10px 8px;
|
| 295 |
+
display: grid;
|
| 296 |
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
| 297 |
+
gap: 14px;
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
/* Gallery Cards */
|
| 301 |
+
.gallery-card {
|
| 302 |
+
background: rgba(255, 255, 255, 0.82);
|
| 303 |
+
border: 1px solid var(--border);
|
| 304 |
+
border-radius: 22px;
|
| 305 |
+
box-shadow: 0 10px 26px rgba(16, 24, 40, 0.08);
|
| 306 |
+
overflow: hidden;
|
| 307 |
+
position: relative;
|
| 308 |
+
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
|
| 309 |
+
display: flex;
|
| 310 |
+
flex-direction: column;
|
| 311 |
+
min-height: 250px;
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
.gallery-card:hover {
|
| 315 |
+
transform: translateY(-2px);
|
| 316 |
+
border-color: rgba(47, 107, 255, 0.18);
|
| 317 |
+
box-shadow: 0 18px 44px rgba(16, 24, 40, 0.12);
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
.gallery-card:focus-within {
|
| 321 |
+
box-shadow: 0 0 0 4px rgba(31, 209, 192, 0.14), 0 18px 44px rgba(16, 24, 40, 0.12);
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
/* Thumbnail area */
|
| 325 |
+
.thumb {
|
| 326 |
+
aspect-ratio: 1 / 1;
|
| 327 |
+
border-bottom: 1px solid rgba(15, 23, 42, 0.06);
|
| 328 |
+
background:
|
| 329 |
+
radial-gradient(260px 120px at 20% 30%, rgba(79, 172, 254, 0.25), transparent 60%),
|
| 330 |
+
radial-gradient(260px 120px at 80% 40%, rgba(31, 209, 192, 0.18), transparent 62%),
|
| 331 |
+
linear-gradient(180deg, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.6));
|
| 332 |
+
display: flex;
|
| 333 |
+
align-items: center;
|
| 334 |
+
justify-content: center;
|
| 335 |
+
position: relative;
|
| 336 |
+
}
|
| 337 |
+
|
| 338 |
+
.thumb img {
|
| 339 |
+
width: 92%;
|
| 340 |
+
height: 88%;
|
| 341 |
+
object-fit: contain;
|
| 342 |
+
border-radius: 14px;
|
| 343 |
+
border: 1px solid rgba(15, 23, 42, 0.10);
|
| 344 |
+
box-shadow: 0 12px 22px rgba(16, 24, 40, 0.10);
|
| 345 |
+
background: white;
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
/* Badge/Chip styling */
|
| 349 |
+
.badge {
|
| 350 |
+
display: inline-flex;
|
| 351 |
+
align-items: center;
|
| 352 |
+
padding: 4px 10px;
|
| 353 |
+
font-size: 11px;
|
| 354 |
+
font-weight: 600;
|
| 355 |
+
letter-spacing: 0.03em;
|
| 356 |
+
text-transform: uppercase;
|
| 357 |
+
color: #2f6bff;
|
| 358 |
+
background: rgba(47, 107, 255, 0.1);
|
| 359 |
+
border: 1px solid rgba(47, 107, 255, 0.2);
|
| 360 |
+
border-radius: 999px;
|
| 361 |
+
white-space: nowrap;
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
/* Content */
|
| 365 |
+
.content {
|
| 366 |
+
padding: 12px 12px 12px;
|
| 367 |
+
display: flex;
|
| 368 |
+
flex-direction: column;
|
| 369 |
+
gap: 10px;
|
| 370 |
+
flex: 1;
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
+
.gallery-prompt {
|
| 374 |
+
margin: 0;
|
| 375 |
+
font-size: 12.5px;
|
| 376 |
+
line-height: 1.35;
|
| 377 |
+
color: rgba(15, 23, 42, 0.78);
|
| 378 |
+
display: -webkit-box;
|
| 379 |
+
-webkit-box-orient: vertical;
|
| 380 |
+
overflow: hidden;
|
| 381 |
+
min-height: calc(1.35em * 3);
|
| 382 |
+
}
|
| 383 |
+
|
| 384 |
+
.meta {
|
| 385 |
+
margin-top: auto;
|
| 386 |
+
display: flex;
|
| 387 |
+
align-items: center;
|
| 388 |
+
justify-content: space-between;
|
| 389 |
+
gap: 10px;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
.links {
|
| 393 |
+
display: flex;
|
| 394 |
+
gap: 8px;
|
| 395 |
+
flex-wrap: wrap;
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
.link {
|
| 399 |
+
display: inline-flex;
|
| 400 |
+
align-items: center;
|
| 401 |
+
gap: 6px;
|
| 402 |
+
padding: 7px 10px;
|
| 403 |
+
border-radius: 999px;
|
| 404 |
+
font-size: 12px;
|
| 405 |
+
font-weight: 700;
|
| 406 |
+
color: rgba(15, 23, 42, 0.74);
|
| 407 |
+
border: 1px solid var(--border);
|
| 408 |
+
background: rgba(255, 255, 255, 0.75);
|
| 409 |
+
text-decoration: none;
|
| 410 |
+
transition: all 0.15s ease;
|
| 411 |
+
}
|
| 412 |
+
|
| 413 |
+
.link:hover {
|
| 414 |
+
border-color: rgba(47, 107, 255, 0.22);
|
| 415 |
+
color: rgba(11, 42, 122, 0.95);
|
| 416 |
+
}
|
| 417 |
+
|
| 418 |
+
.link:focus {
|
| 419 |
+
outline: none;
|
| 420 |
+
box-shadow: 0 0 0 4px rgba(47, 107, 255, 0.18);
|
| 421 |
+
}
|
| 422 |
+
|
| 423 |
+
.kebab {
|
| 424 |
+
width: 34px;
|
| 425 |
+
height: 34px;
|
| 426 |
+
border-radius: 999px;
|
| 427 |
+
border: 1px solid var(--border);
|
| 428 |
+
background: rgba(255, 255, 255, 0.75);
|
| 429 |
+
cursor: pointer;
|
| 430 |
+
display: grid;
|
| 431 |
+
place-items: center;
|
| 432 |
+
transition: border-color 0.15s ease;
|
| 433 |
+
font-size: 18px;
|
| 434 |
+
line-height: 1;
|
| 435 |
+
color: rgba(15, 23, 42, 0.74);
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
+
.kebab:hover {
|
| 439 |
+
border-color: rgba(15, 23, 42, 0.18);
|
| 440 |
+
}
|
| 441 |
+
|
| 442 |
+
.kebab:focus {
|
| 443 |
+
outline: none;
|
| 444 |
+
box-shadow: 0 0 0 4px rgba(47, 107, 255, 0.18);
|
| 445 |
+
}
|
| 446 |
+
|
| 447 |
+
/* Responsive gallery grid */
|
| 448 |
+
@media (max-width: 1200px) {
|
| 449 |
+
.gallery-grid {
|
| 450 |
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
| 451 |
+
}
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
+
@media (max-width: 980px) {
|
| 455 |
+
.gallery-grid {
|
| 456 |
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
| 457 |
+
}
|
| 458 |
+
}
|
| 459 |
+
|
| 460 |
+
@media (max-width: 680px) {
|
| 461 |
+
.gallery-grid {
|
| 462 |
+
grid-template-columns: 1fr;
|
| 463 |
+
}
|
| 464 |
}
|
data/1976-2020_president.csv
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:f6cb9143a67bdbfa805810e069027f677f56a0765b00e10ea50b7d1a70e45bb5
|
| 3 |
-
size 509865
|
|
|
|
|
|
|
|
|
|
|
|
data/ewf_appearances.csv
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:448f2700a84da26347970f2d97f957b13b484c77112f988e1f7f0b58e4c3a66a
|
| 3 |
-
size 481873
|
|
|
|
|
|
|
|
|
|
|
|
data/gold prices.csv
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:f2c08e76148ca0cf0729ec5c95dd3162e60efeb45d7c53341ee371aad887289e
|
| 3 |
-
size 128817
|
|
|
|
|
|
|
|
|
|
|
|
data/oecd_gpia_results.csv
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:3b2760c239df55b49b40b2dc461f2194a84745d631b8cd1c14af85073b0d2423
|
| 3 |
-
size 1961100
|
|
|
|
|
|
|
|
|
|
|
|
data/space_missions_data.csv
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:f95e3afab4a0ea4050125d838381771d700a18e5ae759675b133f9933f858958
|
| 3 |
-
size 137506
|
|
|
|
|
|
|
|
|
|
|
|
gallery_data.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Gallery data configuration for ChaRtBot
|
| 3 |
+
Add new gallery items by appending to the GALLERY_DATA list
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
GALLERY_DATA = [
|
| 7 |
+
{
|
| 8 |
+
"image": "/assets/gallery/1_image.png",
|
| 9 |
+
"prompt": "Build an Animated Choropleth map of the USA displaying state-wise percentage of votes for DEMOCRAT in all the years",
|
| 10 |
+
"csv_link": "/assets/gallery/datasets/1976-2020_president.csv",
|
| 11 |
+
"badge": "Animated choropleth"
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"image": "/assets/gallery/2_image.png",
|
| 15 |
+
"prompt": "Create a Manhattan-style plot where purchases are grouped along the x-axis by Category, with each point representing an Order_Value. Alternate colors by Category so each group forms its own block, highlighting large spending spikes.",
|
| 16 |
+
"csv_link": "/assets/gallery/datasets/amazon-purchases-2021-sample-5k.csv",
|
| 17 |
+
"badge": "Manhattan"
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"image": "/assets/gallery/3_image.png",
|
| 21 |
+
"prompt": "Create a sunburst chart showing the launch ecosystem hierarchy for the year 2005 Use Company as the first level, Rocket as the second level, Mission as the third level, and MissionStatus as the outer level.",
|
| 22 |
+
"csv_link": "/assets/gallery/datasets/space_missions_data.csv",
|
| 23 |
+
"badge": "Hierarchical"
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"image": "/assets/gallery/4_image.png",
|
| 27 |
+
"prompt": "Create a Sankey diagram where the flow goes from Team → Match Result where: - Source nodes are team_name - Target nodes are result Aggregate the number of matches for each team–opponent–result flow. For readability, limit the visualization to teams with the highest total match counts.",
|
| 28 |
+
"csv_link": "/assets/gallery/datasets/ewf_appearances.csv",
|
| 29 |
+
"badge": "Flow"
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"image": "/assets/gallery/5_image.png",
|
| 33 |
+
"prompt": "Create a calendar-like circular gold price chart for the year 2020, wherein going clock-wise on the chart will move from Jan -> Dec. Each month shall have a number of bars equal to the number of days in that month. The length of each bar will represent the price of gold on that day. Use a mustard colour for all the bars.",
|
| 34 |
+
"csv_link": "/assets/gallery/datasets/gold prices.csv",
|
| 35 |
+
"badge": "Circular"
|
| 36 |
+
},
|
| 37 |
+
{
|
| 38 |
+
"image": "/assets/gallery/6_image.png",
|
| 39 |
+
"prompt": "Depict the sum of the purchase amount per day of the week using a heatmap. The X-axis should represent the months, labeled with month names, and the Y-axis should represent the days of the week. Use color to depict the purchase amounts, with the X-axis ordered chronologically by both days and months.",
|
| 40 |
+
"csv_link": "/assets/gallery/datasets/amazon-purchases-2021-sample-5k.csv",
|
| 41 |
+
"badge": "Heatmap"
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"image": "/assets/gallery/7_image.png",
|
| 45 |
+
"prompt": "Create a total of four visualizations, (2 rows, 2 columns) which display: 1. Top 5 Categories by Quantity 2. Top 5 Categories by Price 3. Average Purchase Price per State (USA choropleth map, don't display the colorbar) 4. State-wise Quantity Distribution (USA choropleth map, don't display the colorbar)",
|
| 46 |
+
"csv_link": "/assets/gallery/datasets/amazon-purchases-2021-sample-5k.csv",
|
| 47 |
+
"badge": "Subplots"
|
| 48 |
+
},
|
| 49 |
+
{
|
| 50 |
+
"image": "/assets/gallery/8_image.png",
|
| 51 |
+
"prompt": "Candle-stick chart of gold prices in the year 2020, add a column named 'Ticker' and make sure all the values in this column are 'Gold'",
|
| 52 |
+
"csv_link": "/assets/gallery/datasets/gold prices.csv",
|
| 53 |
+
"badge": "Financial"
|
| 54 |
+
},
|
| 55 |
+
{
|
| 56 |
+
"image": "/assets/gallery/9_image.png",
|
| 57 |
+
"prompt": "Create a bubble chart that visualizes rocket launch prices over the years Use Date on the x-axis and Price on the y-axis. Size each bubble by Price to reflect the relative cost of each mission. Color the bubbles by Company. Ensure bubbles are semi-transparent to avoid overlap issues. Add detailed hover tooltips showing Company, Rocket, Mission, Location, MissionStatus, and Price.",
|
| 58 |
+
"csv_link": "/assets/gallery/datasets/space_missions_data.csv",
|
| 59 |
+
"badge": "Bubble"
|
| 60 |
+
},
|
| 61 |
+
{
|
| 62 |
+
"image": "/assets/gallery/10_image.png",
|
| 63 |
+
"prompt": "Create an animated bubble chart where Categories are represented as bubbles that grow, shrink, and gently reposition over time based on total Order_Value, revealing how category importance changes month by month.",
|
| 64 |
+
"csv_link": "/assets/gallery/datasets/amazon-purchases-2021-sample-5k.csv",
|
| 65 |
+
"badge": "Animated bubbles"
|
| 66 |
+
},
|
| 67 |
+
{
|
| 68 |
+
"image": "/assets/gallery/11_image.png",
|
| 69 |
+
"prompt": "Create a calendar-like circular gold price chart for the year 2020, wherein going clock-wise on the chart will move from Jan -> Dec. Each month shall have a number of bars equal to the number of days in that month. Colour of each bar: Based on the price of gold on that day. Length of each bar: Equal to the day of the month",
|
| 70 |
+
"csv_link": "/assets/gallery/datasets/gold prices.csv",
|
| 71 |
+
"badge": "Circular"
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"image": "/assets/gallery/12_image.png",
|
| 75 |
+
"prompt": "Dumbbell chart showing the teams' scores over the years. Each team shall have only two data points in their dumbbells, the first point and the last. Each point must be a sum of goals scored by the team in the specific season. Use blue colour for the first point and red for the second point in the dumbbell. In the tooltips show the following information: - Team name - Score - Season - Year",
|
| 76 |
+
"csv_link": "/assets/gallery/datasets/ewf_appearances.csv",
|
| 77 |
+
"badge": "Dumbbell"
|
| 78 |
+
}
|
| 79 |
+
]
|
utils/prompt.py
CHANGED
|
@@ -96,7 +96,21 @@ def get_prompt_text() -> str:
|
|
| 96 |
title='Map Title')
|
| 97 |
The locations parameter should reference the column with state codes, not the column with full state names.
|
| 98 |
Always verify that locationmode='USA-states' is present in the code.
|
| 99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
{dumbbell_charts_section}
|
| 101 |
|
| 102 |
{polar_charts_section}
|
|
|
|
| 96 |
title='Map Title')
|
| 97 |
The locations parameter should reference the column with state codes, not the column with full state names.
|
| 98 |
Always verify that locationmode='USA-states' is present in the code.
|
| 99 |
+
|
| 100 |
+
CHOROPLETH MAPS IN SUBPLOTS:
|
| 101 |
+
When creating a choropleth map of the USA as part of subplots using graph_objects (go.Choropleth), you MUST include the following:
|
| 102 |
+
1. After creating all traces with fig.add_trace(), add:
|
| 103 |
+
fig.update_layout(title_text='Your Title', height=800, plot_bgcolor='white', paper_bgcolor='white')
|
| 104 |
+
Note: Generic background settings don't apply to choropleths in subplots, so this is necessary.
|
| 105 |
+
2. Force the USA scope on the specific choropleth subplot using:
|
| 106 |
+
fig.update_geos(scope="usa", projection_type="albers usa", bgcolor="white", row=X, col=Y)
|
| 107 |
+
Replace X and Y with the actual row and column numbers where the choropleth is located.
|
| 108 |
+
Example:
|
| 109 |
+
# After adding all traces
|
| 110 |
+
fig.update_layout(title_text='E-commerce Data Visualization', height=800, plot_bgcolor='white', paper_bgcolor='white')
|
| 111 |
+
# Force USA scope on the choropleth subplot (adjust row, col as needed)
|
| 112 |
+
fig.update_geos(scope="usa", projection_type="albers usa", bgcolor="white", row=2, col=2)
|
| 113 |
+
|
| 114 |
{dumbbell_charts_section}
|
| 115 |
|
| 116 |
{polar_charts_section}
|