Spaces:
Running
Running
Update indices_html.py
Browse files- indices_html.py +49 -49
indices_html.py
CHANGED
|
@@ -9,7 +9,6 @@ def build_indices_html():
|
|
| 9 |
data_df = p["data"]
|
| 10 |
dates_df = p["dates"]
|
| 11 |
|
| 12 |
-
# JSON conversion
|
| 13 |
data_json = json.dumps(data_df.to_dict(orient="records"), ensure_ascii=False)
|
| 14 |
dates_json = json.dumps(dates_df.to_dict(orient="records"), ensure_ascii=False)
|
| 15 |
|
|
@@ -68,7 +67,6 @@ th {{
|
|
| 68 |
grid-template-columns: 1fr 1fr;
|
| 69 |
grid-template-rows: 200px 200px;
|
| 70 |
gap: 20px;
|
| 71 |
-
width: 100%;
|
| 72 |
}}
|
| 73 |
|
| 74 |
.chart-box {{
|
|
@@ -99,7 +97,7 @@ const DEFAULT_KEY = "{DEFAULT_KEY}";
|
|
| 99 |
const DEFAULT_SYMBOL = "{DEFAULT_SYMBOL}";
|
| 100 |
</script>
|
| 101 |
|
| 102 |
-
<!--
|
| 103 |
<h3>Main Full Indices Table</h3>
|
| 104 |
<button onclick="toggleMainTable()">Show / Hide Main Table</button>
|
| 105 |
|
|
@@ -109,7 +107,7 @@ const DEFAULT_SYMBOL = "{DEFAULT_SYMBOL}";
|
|
| 109 |
|
| 110 |
<hr>
|
| 111 |
|
| 112 |
-
<!--
|
| 113 |
<h3>Filter Table by Category</h3>
|
| 114 |
|
| 115 |
<label><b>Select Index Category:</b></label>
|
|
@@ -121,7 +119,7 @@ const DEFAULT_SYMBOL = "{DEFAULT_SYMBOL}";
|
|
| 121 |
|
| 122 |
<hr>
|
| 123 |
|
| 124 |
-
<!--
|
| 125 |
<h3>Charts Based on Index</h3>
|
| 126 |
|
| 127 |
<label><b>Select Index:</b></label>
|
|
@@ -135,58 +133,57 @@ const DEFAULT_SYMBOL = "{DEFAULT_SYMBOL}";
|
|
| 135 |
|
| 136 |
<script>
|
| 137 |
|
| 138 |
-
//
|
| 139 |
-
|
|
|
|
| 140 |
const table = document.getElementById("mainTable");
|
| 141 |
const cols = Object.keys(records[0]);
|
| 142 |
|
| 143 |
let header = "<tr>";
|
| 144 |
-
cols.forEach(c => header += `<th>${c}</th>`);
|
| 145 |
header += "</tr>";
|
| 146 |
|
| 147 |
let rows = "";
|
| 148 |
-
records.forEach(r => {
|
| 149 |
rows += "<tr>";
|
| 150 |
-
cols.forEach(c => rows += `<td>${r[c]}</td>`);
|
| 151 |
rows += "</tr>";
|
| 152 |
-
});
|
| 153 |
|
| 154 |
table.innerHTML = header + rows;
|
| 155 |
-
}
|
| 156 |
|
| 157 |
-
function toggleMainTable() {
|
| 158 |
const sec = document.getElementById("mainTableSection");
|
| 159 |
sec.style.display = sec.style.display === "none" ? "block" : "none";
|
| 160 |
-
}
|
| 161 |
|
| 162 |
-
// Build main table immediately
|
| 163 |
buildMainTable();
|
| 164 |
|
| 165 |
|
| 166 |
-
//
|
|
|
|
| 167 |
const keyDropdown = document.getElementById("keyDropdown");
|
| 168 |
const chartDropdown = document.getElementById("chartDropdown");
|
| 169 |
|
| 170 |
const keyList = [...new Set(records.map(r => r.key))];
|
| 171 |
-
keyList.forEach(k => {
|
| 172 |
const opt = document.createElement("option");
|
| 173 |
opt.value = k;
|
| 174 |
opt.textContent = k;
|
| 175 |
if (k === DEFAULT_KEY) opt.selected = true;
|
| 176 |
keyDropdown.appendChild(opt);
|
| 177 |
-
});
|
| 178 |
-
|
| 179 |
|
| 180 |
-
|
| 181 |
-
function buildAltTable(keyName) {
|
| 182 |
const table = document.getElementById("altTable");
|
| 183 |
-
const sec = document.getElementById("altTableSection");
|
| 184 |
|
| 185 |
const filtered = records.filter(r => r.key === keyName);
|
| 186 |
-
|
|
|
|
| 187 |
table.innerHTML = "<tr><td>No Data</td></tr>";
|
| 188 |
return;
|
| 189 |
-
}
|
| 190 |
|
| 191 |
const hiddenCols = [
|
| 192 |
"key","chartTodayPath","chart30dPath","chart30Path","chart365dPath",
|
|
@@ -197,72 +194,75 @@ function buildAltTable(keyName) {
|
|
| 197 |
const cols = Object.keys(filtered[0]).filter(c => !hiddenCols.includes(c));
|
| 198 |
|
| 199 |
let header = "<tr>";
|
| 200 |
-
cols.forEach(c => header += `<th>${c}</th>`);
|
| 201 |
header += "</tr>";
|
| 202 |
|
| 203 |
let rows = "";
|
| 204 |
-
filtered.forEach(obj => {
|
| 205 |
rows += "<tr>";
|
| 206 |
-
cols.forEach(c => rows += `<td>${obj[c]}</td>`);
|
| 207 |
rows += "</tr>";
|
| 208 |
-
});
|
| 209 |
|
| 210 |
table.innerHTML = header + rows;
|
| 211 |
-
}
|
| 212 |
|
| 213 |
|
| 214 |
-
//
|
| 215 |
-
|
|
|
|
| 216 |
chartDropdown.innerHTML = "";
|
| 217 |
|
| 218 |
-
records.filter(r => r.key === keyVal).forEach(r => {
|
| 219 |
const opt = document.createElement("option");
|
| 220 |
opt.value = r.indexSymbol;
|
| 221 |
opt.textContent = r.index;
|
| 222 |
chartDropdown.appendChild(opt);
|
| 223 |
-
});
|
| 224 |
|
| 225 |
-
|
|
|
|
| 226 |
if (opt.textContent.toUpperCase().includes(DEFAULT_SYMBOL.toUpperCase()))
|
| 227 |
opt.selected = true;
|
| 228 |
-
});
|
| 229 |
-
}
|
| 230 |
-
|
| 231 |
|
| 232 |
-
|
| 233 |
-
function loadCharts(symbol) {
|
| 234 |
const row = records.find(r => r.indexSymbol === symbol);
|
| 235 |
if (!row) return;
|
| 236 |
|
| 237 |
document.getElementById("chartToday").src = row.chartTodayPath;
|
| 238 |
document.getElementById("chart30").src = row.chart30dPath || row.chart30Path;
|
| 239 |
document.getElementById("chart365").src = row.chart365dPath;
|
| 240 |
-
}
|
| 241 |
|
| 242 |
|
| 243 |
-
//
|
| 244 |
-
|
|
|
|
| 245 |
const keyVal = keyDropdown.value;
|
| 246 |
buildAltTable(keyVal);
|
| 247 |
populateChartDropdown(keyVal);
|
| 248 |
loadCharts(chartDropdown.value);
|
| 249 |
-
});
|
| 250 |
|
| 251 |
-
chartDropdown.addEventListener("change", () => {
|
| 252 |
loadCharts(chartDropdown.value);
|
| 253 |
-
});
|
|
|
|
| 254 |
|
|
|
|
| 255 |
|
| 256 |
-
// ------------------ INITIAL LOAD ------------------
|
| 257 |
buildAltTable(DEFAULT_KEY);
|
| 258 |
populateChartDropdown(DEFAULT_KEY);
|
| 259 |
|
| 260 |
-
let
|
| 261 |
r => r.index.toUpperCase().includes(DEFAULT_SYMBOL.toUpperCase())
|
| 262 |
);
|
| 263 |
-
if (!start) start = records[0];
|
| 264 |
|
| 265 |
-
|
|
|
|
|
|
|
| 266 |
|
| 267 |
</script>
|
| 268 |
|
|
|
|
| 9 |
data_df = p["data"]
|
| 10 |
dates_df = p["dates"]
|
| 11 |
|
|
|
|
| 12 |
data_json = json.dumps(data_df.to_dict(orient="records"), ensure_ascii=False)
|
| 13 |
dates_json = json.dumps(dates_df.to_dict(orient="records"), ensure_ascii=False)
|
| 14 |
|
|
|
|
| 67 |
grid-template-columns: 1fr 1fr;
|
| 68 |
grid-template-rows: 200px 200px;
|
| 69 |
gap: 20px;
|
|
|
|
| 70 |
}}
|
| 71 |
|
| 72 |
.chart-box {{
|
|
|
|
| 97 |
const DEFAULT_SYMBOL = "{DEFAULT_SYMBOL}";
|
| 98 |
</script>
|
| 99 |
|
| 100 |
+
<!-- MAIN TABLE -->
|
| 101 |
<h3>Main Full Indices Table</h3>
|
| 102 |
<button onclick="toggleMainTable()">Show / Hide Main Table</button>
|
| 103 |
|
|
|
|
| 107 |
|
| 108 |
<hr>
|
| 109 |
|
| 110 |
+
<!-- FILTERED TABLE -->
|
| 111 |
<h3>Filter Table by Category</h3>
|
| 112 |
|
| 113 |
<label><b>Select Index Category:</b></label>
|
|
|
|
| 119 |
|
| 120 |
<hr>
|
| 121 |
|
| 122 |
+
<!-- CHARTS -->
|
| 123 |
<h3>Charts Based on Index</h3>
|
| 124 |
|
| 125 |
<label><b>Select Index:</b></label>
|
|
|
|
| 133 |
|
| 134 |
<script>
|
| 135 |
|
| 136 |
+
// ================= MAIN TABLE =================
|
| 137 |
+
|
| 138 |
+
function buildMainTable() {{
|
| 139 |
const table = document.getElementById("mainTable");
|
| 140 |
const cols = Object.keys(records[0]);
|
| 141 |
|
| 142 |
let header = "<tr>";
|
| 143 |
+
cols.forEach(c => header += `<th>${{c}}</th>`);
|
| 144 |
header += "</tr>";
|
| 145 |
|
| 146 |
let rows = "";
|
| 147 |
+
records.forEach(r => {{
|
| 148 |
rows += "<tr>";
|
| 149 |
+
cols.forEach(c => rows += `<td>${{r[c]}}</td>`);
|
| 150 |
rows += "</tr>";
|
| 151 |
+
}});
|
| 152 |
|
| 153 |
table.innerHTML = header + rows;
|
| 154 |
+
}}
|
| 155 |
|
| 156 |
+
function toggleMainTable() {{
|
| 157 |
const sec = document.getElementById("mainTableSection");
|
| 158 |
sec.style.display = sec.style.display === "none" ? "block" : "none";
|
| 159 |
+
}}
|
| 160 |
|
|
|
|
| 161 |
buildMainTable();
|
| 162 |
|
| 163 |
|
| 164 |
+
// ================= FILTERED TABLE =================
|
| 165 |
+
|
| 166 |
const keyDropdown = document.getElementById("keyDropdown");
|
| 167 |
const chartDropdown = document.getElementById("chartDropdown");
|
| 168 |
|
| 169 |
const keyList = [...new Set(records.map(r => r.key))];
|
| 170 |
+
keyList.forEach(k => {{
|
| 171 |
const opt = document.createElement("option");
|
| 172 |
opt.value = k;
|
| 173 |
opt.textContent = k;
|
| 174 |
if (k === DEFAULT_KEY) opt.selected = true;
|
| 175 |
keyDropdown.appendChild(opt);
|
| 176 |
+
}});
|
|
|
|
| 177 |
|
| 178 |
+
function buildAltTable(keyName) {{
|
|
|
|
| 179 |
const table = document.getElementById("altTable");
|
|
|
|
| 180 |
|
| 181 |
const filtered = records.filter(r => r.key === keyName);
|
| 182 |
+
|
| 183 |
+
if (!filtered.length) {{
|
| 184 |
table.innerHTML = "<tr><td>No Data</td></tr>";
|
| 185 |
return;
|
| 186 |
+
}}
|
| 187 |
|
| 188 |
const hiddenCols = [
|
| 189 |
"key","chartTodayPath","chart30dPath","chart30Path","chart365dPath",
|
|
|
|
| 194 |
const cols = Object.keys(filtered[0]).filter(c => !hiddenCols.includes(c));
|
| 195 |
|
| 196 |
let header = "<tr>";
|
| 197 |
+
cols.forEach(c => header += `<th>${{c}}</th>`);
|
| 198 |
header += "</tr>";
|
| 199 |
|
| 200 |
let rows = "";
|
| 201 |
+
filtered.forEach(obj => {{
|
| 202 |
rows += "<tr>";
|
| 203 |
+
cols.forEach(c => rows += `<td>${{obj[c]}}</td>`);
|
| 204 |
rows += "</tr>";
|
| 205 |
+
}});
|
| 206 |
|
| 207 |
table.innerHTML = header + rows;
|
| 208 |
+
}}
|
| 209 |
|
| 210 |
|
| 211 |
+
// ================= CHARTS =================
|
| 212 |
+
|
| 213 |
+
function populateChartDropdown(keyVal) {{
|
| 214 |
chartDropdown.innerHTML = "";
|
| 215 |
|
| 216 |
+
records.filter(r => r.key === keyVal).forEach(r => {{
|
| 217 |
const opt = document.createElement("option");
|
| 218 |
opt.value = r.indexSymbol;
|
| 219 |
opt.textContent = r.index;
|
| 220 |
chartDropdown.appendChild(opt);
|
| 221 |
+
}});
|
| 222 |
|
| 223 |
+
// auto select default
|
| 224 |
+
[...chartDropdown.options].forEach(opt => {{
|
| 225 |
if (opt.textContent.toUpperCase().includes(DEFAULT_SYMBOL.toUpperCase()))
|
| 226 |
opt.selected = true;
|
| 227 |
+
}});
|
| 228 |
+
}}
|
|
|
|
| 229 |
|
| 230 |
+
function loadCharts(symbol) {{
|
|
|
|
| 231 |
const row = records.find(r => r.indexSymbol === symbol);
|
| 232 |
if (!row) return;
|
| 233 |
|
| 234 |
document.getElementById("chartToday").src = row.chartTodayPath;
|
| 235 |
document.getElementById("chart30").src = row.chart30dPath || row.chart30Path;
|
| 236 |
document.getElementById("chart365").src = row.chart365dPath;
|
| 237 |
+
}}
|
| 238 |
|
| 239 |
|
| 240 |
+
// ================= EVENT HANDLERS =================
|
| 241 |
+
|
| 242 |
+
keyDropdown.addEventListener("change", () => {{
|
| 243 |
const keyVal = keyDropdown.value;
|
| 244 |
buildAltTable(keyVal);
|
| 245 |
populateChartDropdown(keyVal);
|
| 246 |
loadCharts(chartDropdown.value);
|
| 247 |
+
}});
|
| 248 |
|
| 249 |
+
chartDropdown.addEventListener("change", () => {{
|
| 250 |
loadCharts(chartDropdown.value);
|
| 251 |
+
}});
|
| 252 |
+
|
| 253 |
|
| 254 |
+
// ================= INITIAL LOAD =================
|
| 255 |
|
|
|
|
| 256 |
buildAltTable(DEFAULT_KEY);
|
| 257 |
populateChartDropdown(DEFAULT_KEY);
|
| 258 |
|
| 259 |
+
let initial = records.find(
|
| 260 |
r => r.index.toUpperCase().includes(DEFAULT_SYMBOL.toUpperCase())
|
| 261 |
);
|
|
|
|
| 262 |
|
| 263 |
+
if (!initial) initial = records[0];
|
| 264 |
+
|
| 265 |
+
loadCharts(initial.indexSymbol);
|
| 266 |
|
| 267 |
</script>
|
| 268 |
|