diff --git a/index.html b/index.html
index d0ab1d9..335294b 100755
--- a/index.html
+++ b/index.html
@@ -49,7 +49,9 @@
.filter-group { display: grid; gap: 5px; }
.filter-group > span, .filter-group > label { color: var(--muted); font-size: 13px; }
.filter-group input, .filter-group select { min-height: 36px; padding: 6px 9px; border: 1px solid var(--border); border-radius: 8px; background: #fff; color: var(--text); font: inherit; }
+ .filter-group select[multiple] { min-width: 220px; min-height: 96px; }
.filter-group select:disabled { background: #f1f4f8; color: var(--muted); }
+ .filter-help { color: var(--muted); font-size: 12px; }
.range-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.range-button { min-height: 36px; padding: 6px 11px; border: 1px solid var(--border); border-radius: 8px; background: #fff; color: var(--text); cursor: pointer; font: inherit; }
.range-button:hover, .range-button:focus, .range-button[data-active="true"] { border-color: var(--primary); color: var(--primary); }
@@ -123,6 +125,11 @@
+
+
+
+ 无可选 LinkName
+
@@ -188,6 +195,8 @@
currencyHelp: document.getElementById('currency-help'),
startDate: document.getElementById('start-date'),
endDate: document.getElementById('end-date'),
+ linkName: document.getElementById('link-name-select'),
+ linkNameSummary: document.getElementById('link-name-summary'),
rangeButtons: Array.from(document.querySelectorAll('[data-range]')),
rateStatus: document.getElementById('rate-status'),
metrics: document.getElementById('metrics'),
@@ -213,7 +222,8 @@
dateOnlyRows: 0,
invalidCurrencyRows: 0,
syncLog: null,
- syncLogUnavailable: false
+ syncLogUnavailable: false,
+ selectedLinkNames: new Set()
};
function setStatus(message, status) {
@@ -414,6 +424,43 @@
return { start: start.time, end: end.time };
}
+ function updateLinkNameSummary() {
+ var total = elements.linkName.options.length;
+ var selected = elements.linkName.selectedOptions.length;
+ if (!total) {
+ elements.linkNameSummary.textContent = '无可选 LinkName';
+ } else if (selected === total) {
+ elements.linkNameSummary.textContent = '全部 LinkName(' + formatNumber(total) + ')';
+ } else {
+ elements.linkNameSummary.textContent = '已选 ' + formatNumber(selected) + ' / ' + formatNumber(total) + ' 个 LinkName';
+ }
+ }
+
+ function updateLinkNameOptions() {
+ var available = [];
+ try {
+ var range = currentRange();
+ available = Array.from(new Set(state.rawRecords.filter(function (record) {
+ return record.date.time >= range.start && record.date.time <= range.end;
+ }).map(function (record) { return record.linkName; }))).sort(function (a, b) {
+ return a.localeCompare(b);
+ });
+ } catch (error) {
+ available = [];
+ }
+ elements.linkName.replaceChildren();
+ available.forEach(function (linkName) {
+ var option = document.createElement('option');
+ option.value = linkName;
+ option.textContent = linkName;
+ option.selected = true;
+ elements.linkName.appendChild(option);
+ });
+ state.selectedLinkNames = new Set(available);
+ elements.linkName.disabled = available.length === 0;
+ updateLinkNameSummary();
+ }
+
function needsRates() {
return state.rawRecords.some(function (record) { return record.currency !== state.selectedCurrency; });
}
@@ -599,7 +646,9 @@
setStatus(needsRates() ? '正在准备汇率与图表…' : '正在准备图表…', 'loading');
convertedRecords().then(function (records) {
if (token !== renderToken) return;
- var filtered = records.filter(function (record) { return record.date.time >= range.start && record.date.time <= range.end; });
+ var filtered = records.filter(function (record) {
+ return record.date.time >= range.start && record.date.time <= range.end && state.selectedLinkNames.has(record.linkName);
+ });
updateSummary(filtered);
elements.error.hidden = true;
elements.metrics.hidden = false;
@@ -637,6 +686,7 @@
elements.filters.hidden = false;
updateCurrencyOptions();
updateRangeInputs();
+ updateLinkNameOptions();
if (!state.rawRecords.length) { showEmpty('没有可展示的有效数据。'); return; }
renderCurrentView();
}).catch(showError);
@@ -646,16 +696,25 @@
state.selectedCurrency = elements.currency.value;
renderCurrentView();
});
+ elements.linkName.addEventListener('change', function () {
+ state.selectedLinkNames = new Set(Array.from(elements.linkName.selectedOptions).map(function (option) {
+ return option.value;
+ }));
+ updateLinkNameSummary();
+ renderCurrentView();
+ });
elements.startDate.addEventListener('change', function () {
elements.rangeButtons.forEach(function (button) { button.dataset.active = 'false'; });
+ updateLinkNameOptions();
renderCurrentView();
});
elements.endDate.addEventListener('change', function () {
elements.rangeButtons.forEach(function (button) { button.dataset.active = 'false'; });
+ updateLinkNameOptions();
renderCurrentView();
});
elements.rangeButtons.forEach(function (button) {
- button.addEventListener('click', function () { setRange(button.dataset.range); renderCurrentView(); });
+ button.addEventListener('click', function () { setRange(button.dataset.range); updateLinkNameOptions(); renderCurrentView(); });
});
window.addEventListener('resize', function () { charts.forEach(function (chart) { chart.resize(); }); });
loadData();