ui
This commit is contained in:
@@ -116,23 +116,46 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"annotation_id": "bbafc50c-f885-4dbc-b0cb-fdfb48223b5c",
|
"annotation_id": "cdf32bb9-8f0f-467d-abc2-d409a7c22bcc",
|
||||||
"symbol": "ETH/USDT",
|
"symbol": "ETH/USDT",
|
||||||
"timeframe": "1m",
|
"timeframe": "1m",
|
||||||
"entry": {
|
"entry": {
|
||||||
"timestamp": "2025-11-12 07:58",
|
"timestamp": "2025-11-22 06:41",
|
||||||
"price": 3424.58,
|
"price": 2759.12,
|
||||||
"index": 284
|
"index": 250
|
||||||
},
|
},
|
||||||
"exit": {
|
"exit": {
|
||||||
"timestamp": "2025-11-12 11:08",
|
"timestamp": "2025-11-22 10:42",
|
||||||
"price": 3546.35,
|
"price": 2709.14,
|
||||||
"index": 329
|
"index": 335
|
||||||
},
|
},
|
||||||
"direction": "LONG",
|
"direction": "SHORT",
|
||||||
"profit_loss_pct": 3.5557645025083366,
|
"profit_loss_pct": 1.8114471280698201,
|
||||||
"notes": "",
|
"notes": "",
|
||||||
"created_at": "2025-11-12T13:11:31.267142",
|
"created_at": "2025-11-22T13:09:16.675137",
|
||||||
|
"market_context": {
|
||||||
|
"entry_state": {},
|
||||||
|
"exit_state": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"annotation_id": "5cf94e70-e8f7-4c29-a860-4c2bc516bd8c",
|
||||||
|
"symbol": "ETH/USDT",
|
||||||
|
"timeframe": "1s",
|
||||||
|
"entry": {
|
||||||
|
"timestamp": "2025-11-22 11:00:30",
|
||||||
|
"price": 2714.28,
|
||||||
|
"index": 63
|
||||||
|
},
|
||||||
|
"exit": {
|
||||||
|
"timestamp": "2025-11-22 11:05:19",
|
||||||
|
"price": 2705.95,
|
||||||
|
"index": 90
|
||||||
|
},
|
||||||
|
"direction": "SHORT",
|
||||||
|
"profit_loss_pct": 0.30689538293766233,
|
||||||
|
"notes": "",
|
||||||
|
"created_at": "2025-11-22T13:09:40.711052",
|
||||||
"market_context": {
|
"market_context": {
|
||||||
"entry_state": {},
|
"entry_state": {},
|
||||||
"exit_state": {}
|
"exit_state": {}
|
||||||
@@ -140,7 +163,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"total_annotations": 6,
|
"total_annotations": 7,
|
||||||
"last_updated": "2025-11-12T13:11:31.267456"
|
"last_updated": "2025-11-22T13:09:40.712602"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -462,7 +462,7 @@ class ChartManager {
|
|||||||
font: { color: '#f8f9fa', size: 11 },
|
font: { color: '#f8f9fa', size: 11 },
|
||||||
margin: { l: 60, r: 20, t: 10, b: 40 },
|
margin: { l: 60, r: 20, t: 10, b: 40 },
|
||||||
hovermode: 'x unified',
|
hovermode: 'x unified',
|
||||||
dragmode: 'pan',
|
dragmode: 'zoom', // Use zoom mode for better scroll behavior
|
||||||
// Performance optimizations
|
// Performance optimizations
|
||||||
autosize: true,
|
autosize: true,
|
||||||
staticPlot: false
|
staticPlot: false
|
||||||
@@ -473,22 +473,22 @@ class ChartManager {
|
|||||||
displayModeBar: true,
|
displayModeBar: true,
|
||||||
modeBarButtonsToRemove: ['lasso2d', 'select2d'], // Allow autoScale2d
|
modeBarButtonsToRemove: ['lasso2d', 'select2d'], // Allow autoScale2d
|
||||||
displaylogo: false,
|
displaylogo: false,
|
||||||
scrollZoom: true,
|
scrollZoom: true, // Enable mouse wheel zoom
|
||||||
// Enable vertical scaling by dragging Y-axis
|
// Enable vertical scaling by dragging Y-axis
|
||||||
doubleClick: 'reset', // Double-click to reset zoom
|
doubleClick: 'reset', // Double-click to reset zoom
|
||||||
showAxisDragHandles: true, // Show drag handles on axes
|
showAxisDragHandles: true, // Show drag handles on axes
|
||||||
showAxisRangeEntryBoxes: true, // Allow manual range entry
|
showAxisRangeEntryBoxes: true, // Allow manual range entry
|
||||||
// Axis drag behavior
|
// Make pivot lines and annotations read-only
|
||||||
editable: true, // Make axes editable
|
editable: false, // Disable editing to prevent dragging shapes
|
||||||
edits: {
|
edits: {
|
||||||
axisTitleText: false,
|
axisTitleText: false,
|
||||||
colorbarPosition: false,
|
colorbarPosition: false,
|
||||||
colorbarTitleText: false,
|
colorbarTitleText: false,
|
||||||
legendPosition: false,
|
legendPosition: false,
|
||||||
legendText: false,
|
legendText: false,
|
||||||
shapePosition: true,
|
shapePosition: false, // Prevent dragging pivot lines
|
||||||
annotationPosition: true,
|
annotationPosition: false, // Prevent dragging annotations
|
||||||
annotationTail: true,
|
annotationTail: false,
|
||||||
annotationText: false
|
annotationText: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -99,6 +99,12 @@
|
|||||||
function renderAnnotationsList(annotations) {
|
function renderAnnotationsList(annotations) {
|
||||||
const listContainer = document.getElementById('annotations-list');
|
const listContainer = document.getElementById('annotations-list');
|
||||||
const noAnnotationsMsg = document.getElementById('no-annotations-msg');
|
const noAnnotationsMsg = document.getElementById('no-annotations-msg');
|
||||||
|
const annotationCountEl = document.getElementById('annotation-count');
|
||||||
|
|
||||||
|
// Update count immediately
|
||||||
|
if (annotationCountEl) {
|
||||||
|
annotationCountEl.textContent = annotations.length;
|
||||||
|
}
|
||||||
|
|
||||||
if (annotations.length === 0) {
|
if (annotations.length === 0) {
|
||||||
noAnnotationsMsg.style.display = 'block';
|
noAnnotationsMsg.style.display = 'block';
|
||||||
@@ -196,9 +202,6 @@
|
|||||||
|
|
||||||
listContainer.appendChild(item);
|
listContainer.appendChild(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update annotation count
|
|
||||||
document.getElementById('annotation-count').textContent = annotations.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function viewAnnotation(annotation) {
|
function viewAnnotation(annotation) {
|
||||||
|
|||||||
@@ -78,18 +78,20 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-success btn-sm w-100" id="start-inference-btn">
|
<div id="inference-buttons-container">
|
||||||
<i class="fas fa-play"></i>
|
<button class="btn btn-success btn-sm w-100" id="start-inference-btn">
|
||||||
Start Live Inference (No Training)
|
<i class="fas fa-play"></i>
|
||||||
</button>
|
Start Live Inference (No Training)
|
||||||
<button class="btn btn-info btn-sm w-100 mt-1" id="start-inference-pivot-btn">
|
</button>
|
||||||
<i class="fas fa-chart-line"></i>
|
<button class="btn btn-info btn-sm w-100 mt-1" id="start-inference-pivot-btn">
|
||||||
Live Inference + Pivot Training
|
<i class="fas fa-chart-line"></i>
|
||||||
</button>
|
Live Inference + Pivot Training
|
||||||
<button class="btn btn-primary btn-sm w-100 mt-1" id="start-inference-candle-btn">
|
</button>
|
||||||
<i class="fas fa-graduation-cap"></i>
|
<button class="btn btn-primary btn-sm w-100 mt-1" id="start-inference-candle-btn">
|
||||||
Live Inference + Per-Candle Training
|
<i class="fas fa-graduation-cap"></i>
|
||||||
</button>
|
Live Inference + Per-Candle Training
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<button class="btn btn-danger btn-sm w-100 mt-1" id="stop-inference-btn" style="display: none;">
|
<button class="btn btn-danger btn-sm w-100 mt-1" id="stop-inference-btn" style="display: none;">
|
||||||
<i class="fas fa-stop"></i>
|
<i class="fas fa-stop"></i>
|
||||||
Stop Inference
|
Stop Inference
|
||||||
@@ -294,18 +296,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateButtonState() {
|
function updateButtonState() {
|
||||||
const modelSelect = document.getElementById('model-select');
|
// Get UI elements
|
||||||
const trainBtn = document.getElementById('train-model-btn');
|
const ui = {
|
||||||
const loadBtn = document.getElementById('load-model-btn');
|
modelSelect: document.getElementById('model-select'),
|
||||||
const inferenceBtn = document.getElementById('start-inference-btn');
|
trainBtn: document.getElementById('train-model-btn'),
|
||||||
|
loadBtn: document.getElementById('load-model-btn'),
|
||||||
|
inferenceContainer: document.getElementById('inference-buttons-container')
|
||||||
|
};
|
||||||
|
|
||||||
selectedModel = modelSelect.value;
|
selectedModel = ui.modelSelect.value;
|
||||||
|
|
||||||
|
// Helper to set all buttons in container
|
||||||
|
const setInferenceButtonsState = (disabled) => {
|
||||||
|
ui.inferenceContainer.querySelectorAll('button').forEach(btn => btn.disabled = disabled);
|
||||||
|
};
|
||||||
|
|
||||||
if (!selectedModel) {
|
if (!selectedModel) {
|
||||||
// No model selected
|
// No model selected - disable all inference buttons
|
||||||
trainBtn.style.display = 'none';
|
ui.trainBtn.style.display = 'none';
|
||||||
loadBtn.style.display = 'none';
|
ui.loadBtn.style.display = 'none';
|
||||||
inferenceBtn.disabled = true;
|
setInferenceButtonsState(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,15 +323,15 @@
|
|||||||
const modelState = modelStates.find(m => m.name === selectedModel);
|
const modelState = modelStates.find(m => m.name === selectedModel);
|
||||||
|
|
||||||
if (modelState && modelState.loaded) {
|
if (modelState && modelState.loaded) {
|
||||||
// Model is loaded - show train/inference buttons
|
// Model is loaded - enable all buttons
|
||||||
trainBtn.style.display = 'block';
|
ui.trainBtn.style.display = 'block';
|
||||||
loadBtn.style.display = 'none';
|
ui.loadBtn.style.display = 'none';
|
||||||
inferenceBtn.disabled = false;
|
setInferenceButtonsState(false);
|
||||||
} else {
|
} else {
|
||||||
// Model not loaded - show load button
|
// Model not loaded - disable all inference buttons
|
||||||
trainBtn.style.display = 'none';
|
ui.trainBtn.style.display = 'none';
|
||||||
loadBtn.style.display = 'block';
|
ui.loadBtn.style.display = 'block';
|
||||||
inferenceBtn.disabled = true;
|
setInferenceButtonsState(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user