id-ocr-engine / static /js /stats.js
Kevin-KES
Deploy current main to HF Space
50c6ee2
Raw
History Blame Contribute Delete
4.64 kB
window.Stats = {
init: function () {
this.update(History.entries);
},
update: function (entries) {
var stats = this.calculate(entries);
this.render(stats);
},
calculate: function (entries) {
if (!entries || entries.length === 0) return null;
var successful = entries.filter(function (e) { return e.status === 'success'; });
var total = entries.length;
var durationValues = entries.map(function (e) { return e.duration || 0; });
// Count pass/fail/inconclusive
var passCount = successful.filter(function (e) { return e.overallResult === 'pass'; }).length;
var failCount = successful.filter(function (e) { return e.overallResult === 'fail'; }).length;
// Collect all field keys seen across results
var allFieldKeys = {};
for (var i = 0; i < successful.length; i++) {
var fields = successful[i].result && successful[i].result.fields ? successful[i].result.fields : {};
var keys = Object.keys(fields);
for (var k = 0; k < keys.length; k++) {
allFieldKeys[keys[k]] = true;
}
}
var fieldRates = {};
var fieldKeyList = Object.keys(allFieldKeys);
for (var j = 0; j < fieldKeyList.length; j++) {
var key = fieldKeyList[j];
fieldRates[key] = this._rate(successful, function (e) {
return e.result && e.result.fields && e.result.fields[key] != null && e.result.fields[key] !== '';
});
}
return {
totalProcessed: total,
successCount: successful.length,
errorCount: total - successful.length,
passCount: passCount,
failCount: failCount,
successRate: total > 0 ? successful.length / total : 0,
avgDuration: this._avg(durationValues),
fieldRates: fieldRates,
fieldKeyList: fieldKeyList,
};
},
_avg: function (values) {
if (!values.length) return 0;
return values.reduce(function (a, b) { return a + b; }, 0) / values.length;
},
_rate: function (entries, predicate) {
if (!entries.length) return 0;
return entries.filter(predicate).length / entries.length;
},
render: function (stats) {
var hasStats = stats !== null;
Utils.$('#stats-empty').classList.toggle('hidden', hasStats);
Utils.$('#stats-data').classList.toggle('hidden', !hasStats);
if (!hasStats) return;
// Stat cards
var cardsContainer = Utils.$('#stat-cards');
cardsContainer.innerHTML = '';
var cards = [
{ value: stats.totalProcessed, label: 'Total Processed' },
{ value: stats.passCount, label: 'Passed' },
{ value: stats.failCount, label: 'Failed' },
{ value: (stats.avgDuration / 1000).toFixed(1) + 's', label: 'Avg Duration' },
];
for (var i = 0; i < cards.length; i++) {
var card = document.createElement('div');
card.className = 'stat-card';
var val = document.createElement('div');
val.className = 'stat-value';
val.textContent = cards[i].value;
var lbl = document.createElement('div');
lbl.className = 'stat-label';
lbl.textContent = cards[i].label;
card.appendChild(val);
card.appendChild(lbl);
cardsContainer.appendChild(card);
}
// Field extraction rates
var ratesContainer = Utils.$('#field-rates');
ratesContainer.innerHTML = '';
var fieldKeys = stats.fieldKeyList || [];
for (var j = 0; j < fieldKeys.length; j++) {
var key = fieldKeys[j];
var rate = stats.fieldRates[key] || 0;
var row = document.createElement('div');
row.className = 'confidence-row';
var label = document.createElement('span');
label.className = 'confidence-label';
label.textContent = Utils.fieldLabel(key);
var bar = document.createElement('div');
bar.className = 'confidence-bar';
var fill = document.createElement('div');
fill.className = 'confidence-fill ' + Utils.confidenceLevel(rate);
fill.style.width = Utils.formatConfidence(rate);
fill.textContent = Utils.formatConfidence(rate);
bar.appendChild(fill);
row.appendChild(label);
row.appendChild(bar);
ratesContainer.appendChild(row);
}
},
};