folder rename
This commit is contained in:
253
ANNOTATE/web/templates/components/inference_panel.html
Normal file
253
ANNOTATE/web/templates/components/inference_panel.html
Normal file
@@ -0,0 +1,253 @@
|
||||
<div class="inference-panel">
|
||||
<!-- Inference Controls -->
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-8">
|
||||
<h6>Inference Simulation</h6>
|
||||
<p class="text-muted small mb-0">
|
||||
Replay annotated periods with model predictions to measure performance
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-4 text-end">
|
||||
<div class="btn-group" role="group">
|
||||
<button class="btn btn-sm btn-outline-primary" id="inference-play-btn">
|
||||
<i class="fas fa-play"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline-primary" id="inference-pause-btn" disabled>
|
||||
<i class="fas fa-pause"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline-primary" id="inference-stop-btn" disabled>
|
||||
<i class="fas fa-stop"></i>
|
||||
</button>
|
||||
</div>
|
||||
<select class="form-select form-select-sm d-inline-block w-auto ms-2" id="inference-speed-select">
|
||||
<option value="1">1x</option>
|
||||
<option value="2">2x</option>
|
||||
<option value="5">5x</option>
|
||||
<option value="10">10x</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Inference Chart -->
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
<div id="inference-chart" style="height: 400px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Performance Metrics -->
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-dark">
|
||||
<div class="card-body text-center py-2">
|
||||
<div class="small text-muted">Accuracy</div>
|
||||
<div class="h4 mb-0" id="metric-accuracy">--</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-dark">
|
||||
<div class="card-body text-center py-2">
|
||||
<div class="small text-muted">Precision</div>
|
||||
<div class="h4 mb-0" id="metric-precision">--</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-dark">
|
||||
<div class="card-body text-center py-2">
|
||||
<div class="small text-muted">Recall</div>
|
||||
<div class="h4 mb-0" id="metric-recall">--</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-dark">
|
||||
<div class="card-body text-center py-2">
|
||||
<div class="small text-muted">F1 Score</div>
|
||||
<div class="h4 mb-0" id="metric-f1">--</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Prediction Timeline -->
|
||||
<div class="row mt-3">
|
||||
<div class="col-12">
|
||||
<h6>Prediction Timeline</h6>
|
||||
<div class="table-responsive" style="max-height: 300px; overflow-y: auto;">
|
||||
<table class="table table-sm table-dark table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Time</th>
|
||||
<th>Prediction</th>
|
||||
<th>Confidence</th>
|
||||
<th>Actual</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="prediction-timeline-body">
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted">
|
||||
No predictions yet
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Confusion Matrix -->
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-6">
|
||||
<h6>Confusion Matrix</h6>
|
||||
<table class="table table-sm table-dark table-bordered text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th colspan="2">Predicted</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Actual</th>
|
||||
<th>BUY</th>
|
||||
<th>SELL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>BUY</th>
|
||||
<td id="cm-tp-buy">0</td>
|
||||
<td id="cm-fn-buy">0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>SELL</th>
|
||||
<td id="cm-fp-sell">0</td>
|
||||
<td id="cm-tn-sell">0</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6>Prediction Distribution</h6>
|
||||
<div id="prediction-distribution-chart" style="height: 200px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let inferenceState = {
|
||||
isPlaying: false,
|
||||
currentIndex: 0,
|
||||
predictions: [],
|
||||
annotations: [],
|
||||
speed: 1
|
||||
};
|
||||
|
||||
// Playback controls
|
||||
document.getElementById('inference-play-btn').addEventListener('click', function() {
|
||||
inferenceState.isPlaying = true;
|
||||
this.disabled = true;
|
||||
document.getElementById('inference-pause-btn').disabled = false;
|
||||
document.getElementById('inference-stop-btn').disabled = false;
|
||||
playInference();
|
||||
});
|
||||
|
||||
document.getElementById('inference-pause-btn').addEventListener('click', function() {
|
||||
inferenceState.isPlaying = false;
|
||||
this.disabled = true;
|
||||
document.getElementById('inference-play-btn').disabled = false;
|
||||
});
|
||||
|
||||
document.getElementById('inference-stop-btn').addEventListener('click', function() {
|
||||
inferenceState.isPlaying = false;
|
||||
inferenceState.currentIndex = 0;
|
||||
document.getElementById('inference-play-btn').disabled = false;
|
||||
document.getElementById('inference-pause-btn').disabled = true;
|
||||
this.disabled = true;
|
||||
resetInferenceDisplay();
|
||||
});
|
||||
|
||||
document.getElementById('inference-speed-select').addEventListener('change', function(e) {
|
||||
inferenceState.speed = parseFloat(e.target.value);
|
||||
});
|
||||
|
||||
function playInference() {
|
||||
if (!inferenceState.isPlaying || inferenceState.currentIndex >= inferenceState.predictions.length) {
|
||||
inferenceState.isPlaying = false;
|
||||
document.getElementById('inference-play-btn').disabled = false;
|
||||
document.getElementById('inference-pause-btn').disabled = true;
|
||||
document.getElementById('inference-stop-btn').disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const prediction = inferenceState.predictions[inferenceState.currentIndex];
|
||||
displayPrediction(prediction);
|
||||
|
||||
inferenceState.currentIndex++;
|
||||
|
||||
// Schedule next prediction
|
||||
const delay = 1000 / inferenceState.speed;
|
||||
setTimeout(playInference, delay);
|
||||
}
|
||||
|
||||
function displayPrediction(prediction) {
|
||||
// Add to timeline table
|
||||
const tbody = document.getElementById('prediction-timeline-body');
|
||||
if (tbody.children[0].colSpan === 5) {
|
||||
tbody.innerHTML = ''; // Clear "no predictions" message
|
||||
}
|
||||
|
||||
const row = document.createElement('tr');
|
||||
const resultClass = prediction.correct ? 'text-success' : 'text-danger';
|
||||
const resultIcon = prediction.correct ? 'fa-check' : 'fa-times';
|
||||
|
||||
row.innerHTML = `
|
||||
<td>${new Date(prediction.timestamp).toLocaleTimeString()}</td>
|
||||
<td><span class="badge bg-${prediction.predicted_action === 'BUY' ? 'success' : 'danger'}">${prediction.predicted_action}</span></td>
|
||||
<td>${(prediction.confidence * 100).toFixed(1)}%</td>
|
||||
<td><span class="badge bg-${prediction.actual_action === 'BUY' ? 'success' : 'danger'}">${prediction.actual_action}</span></td>
|
||||
<td class="${resultClass}"><i class="fas ${resultIcon}"></i></td>
|
||||
`;
|
||||
|
||||
tbody.appendChild(row);
|
||||
|
||||
// Scroll to bottom
|
||||
tbody.parentElement.scrollTop = tbody.parentElement.scrollHeight;
|
||||
|
||||
// Update chart (if implemented)
|
||||
updateInferenceChart(prediction);
|
||||
}
|
||||
|
||||
function updateInferenceChart(prediction) {
|
||||
// TODO: Update Plotly chart with prediction marker
|
||||
}
|
||||
|
||||
function resetInferenceDisplay() {
|
||||
document.getElementById('prediction-timeline-body').innerHTML = `
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted">
|
||||
No predictions yet
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
document.getElementById('metric-accuracy').textContent = '--';
|
||||
document.getElementById('metric-precision').textContent = '--';
|
||||
document.getElementById('metric-recall').textContent = '--';
|
||||
document.getElementById('metric-f1').textContent = '--';
|
||||
}
|
||||
|
||||
function updateMetrics(metrics) {
|
||||
document.getElementById('metric-accuracy').textContent = (metrics.accuracy * 100).toFixed(1) + '%';
|
||||
document.getElementById('metric-precision').textContent = (metrics.precision * 100).toFixed(1) + '%';
|
||||
document.getElementById('metric-recall').textContent = (metrics.recall * 100).toFixed(1) + '%';
|
||||
document.getElementById('metric-f1').textContent = (metrics.f1_score * 100).toFixed(1) + '%';
|
||||
|
||||
// Update confusion matrix
|
||||
document.getElementById('cm-tp-buy').textContent = metrics.confusion_matrix.tp_buy;
|
||||
document.getElementById('cm-fn-buy').textContent = metrics.confusion_matrix.fn_buy;
|
||||
document.getElementById('cm-fp-sell').textContent = metrics.confusion_matrix.fp_sell;
|
||||
document.getElementById('cm-tn-sell').textContent = metrics.confusion_matrix.tn_sell;
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user