Compare commits
6 Commits
df657ec621
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 02c54cb354 | |||
| c3ca5670e3 | |||
| bde7945a1b | |||
| eccfcc4b79 | |||
| 31ac1ead5b | |||
| a3bf8624fb |
166
index.html
166
index.html
@ -34,47 +34,67 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Hide scrollbar for clean UI */
|
/* Hide scrollbar for clean UI */
|
||||||
.no-scrollbar::-webkit-scrollbar {
|
.no-scrollbar::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.no-scrollbar {
|
.no-scrollbar {
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Chart type button active state */
|
||||||
|
.chart-type-btn.active {
|
||||||
|
background-color: #2d3a4f;
|
||||||
|
color: #3b82f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Chart type button hover effect */
|
||||||
|
.chart-type-btn:hover {
|
||||||
|
background-color: #2d3a4f;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="flex flex-col h-screen overflow-hidden bg-[#0d1421] text-white font-['Inter']">
|
<body class="flex flex-col h-screen overflow-hidden bg-[#0d1421] text-white font-['Inter']">
|
||||||
|
|
||||||
<!-- Top Navigation Bar -->
|
<!-- Top Navigation Bar -->
|
||||||
<header class="bg-[#0f131e] fixed top-0 w-full z-[60] h-16 px-6 flex items-center justify-between border-b border-[#1b1f2b]">
|
<header class="bg-[#0f131e] fixed top-0 w-full z-[60] h-16 px-4 flex items-center justify-between border-b border-[#1b1f2b]">
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center shrink-0">
|
||||||
<!-- Mobile Menu Button -->
|
|
||||||
<button id="mobileMenuBtn" class="md:hidden w-10 h-10 flex items-center justify-center text-[#8fa2b3] hover:text-white hover:bg-[#2d3a4f] rounded-md transition-colors z-50">
|
|
||||||
<span class="material-symbols-outlined text-lg">menu</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- Search/Symbol Button -->
|
<!-- Search/Symbol Button -->
|
||||||
<div class="hidden md:flex items-center space-x-3 bg-[#1a2333] px-3 py-1.5 rounded-md cursor-pointer border border-[#2d3a4f]">
|
<div class="flex items-center space-x-2 bg-[#1a2333] px-3 py-1.5 rounded-md cursor-pointer border border-[#2d3a4f]">
|
||||||
<span class="material-symbols-outlined text-sm text-[#8fa2b3]">search</span>
|
<span class="material-symbols-outlined text-sm text-[#8fa2b3]">search</span>
|
||||||
<span class="font-bold text-sm text-[#dfe2f2]">BTC/USD</span>
|
<span class="font-bold text-sm text-[#dfe2f2]">BTC/USD</span>
|
||||||
<span class="material-symbols-outlined text-sm text-[#8fa2b3]">chevron_right</span>
|
<span class="material-symbols-outlined text-sm text-[#8fa2b3]">chevron_right</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Mobile Search -->
|
<!-- Desktop Status (Moved inside the left-aligned group) -->
|
||||||
<div class="md:hidden flex items-center bg-[#1a2333] px-3 py-1.5 rounded-md cursor-pointer border border-[#2d3a4f]">
|
<div class="hidden lg:flex items-center gap-2 ml-6 shrink-0 border-l border-[#2d3a4f] pl-6">
|
||||||
<span class="material-symbols-outlined text-sm text-[#8fa2b3]">search</span>
|
<div class="w-2 h-2 rounded-full bg-green-500" id="statusDot"></div>
|
||||||
<span class="font-bold text-sm text-[#dfe2f2] ml-2">BTC/USD</span>
|
<span class="text-xs text-[#8fa2b3]" id="statusText">Live</span>
|
||||||
<span class="material-symbols-outlined text-sm text-[#8fa2b3] ml-2">chevron_right</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="hidden md:flex items-center gap-2 mr-4">
|
<!-- Scrollable Controls Container (Right-aligned on desktop via parent justify-between) -->
|
||||||
<div class="w-2 h-2 rounded-full bg-green-500" id="statusDot"></div>
|
<div class="flex-1 md:flex-none flex items-center gap-2 ml-4 overflow-x-auto no-scrollbar touch-pan-x justify-end" style="-webkit-overflow-scrolling: touch;">
|
||||||
<span class="text-xs text-[#8fa2b3]" id="statusText">Live</span>
|
<!-- Chart Type Buttons -->
|
||||||
</div>
|
<div class="flex space-x-1 shrink-0">
|
||||||
|
<button class="chart-type-btn w-10 h-10 flex items-center justify-center text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded transition-colors" data-chart-type="candlestick" title="Candlestick">
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M7 5v3M7 16v3M17 3v2M17 11v4"/><rect x="5" y="8" width="4" height="8" rx="0.5"/><rect x="15" y="5" width="4" height="6" rx="0.5"/></svg>
|
||||||
|
</button>
|
||||||
|
<button class="chart-type-btn w-10 h-10 flex items-center justify-center text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded transition-colors" data-chart-type="line" title="Line">
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 17l6-6 4 4 8-8"/></svg>
|
||||||
|
</button>
|
||||||
|
<button class="chart-type-btn w-10 h-10 flex items-center justify-center text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded transition-colors" data-chart-type="bar" title="Bar">
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M7 5v14M7 10H5M7 15h2M17 5v14M17 7h-2M17 12h2"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex space-x-1 items-center overflow-x-auto no-scrollbar" id="timeframeContainer">
|
<!-- Separator -->
|
||||||
<!-- Timeframes injected by JS -->
|
<div class="w-px h-8 bg-[#2d3a4f] mx-1 shrink-0"></div>
|
||||||
|
|
||||||
|
<!-- Timeframes Container -->
|
||||||
|
<div class="flex space-x-1 items-center shrink-0" id="timeframeContainer">
|
||||||
|
<!-- Timeframes injected by JS -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@ -324,8 +344,8 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Draggable Divider -->
|
<!-- Draggable Divider -->
|
||||||
<div id="mainChartResizer" class="h-1.5 bg-[#1e293b] hover:bg-blue-500 cursor-row-resize shrink-0 transition-colors z-20 flex items-center justify-center group relative">
|
<div id="mainChartResizer" class="h-4 bg-[#1e293b] hover:bg-blue-500 cursor-row-resize shrink-0 transition-colors z-20 flex items-center justify-center group relative">
|
||||||
<div class="w-10 h-0.5 bg-gray-500 rounded opacity-0 group-hover:opacity-100 transition-opacity"></div>
|
<div class="w-10 h-0.5 bg-gray-500 rounded opacity-50 transition-all"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Technical Analysis Section -->
|
<!-- Technical Analysis Section -->
|
||||||
@ -336,15 +356,9 @@
|
|||||||
Technical Analysis
|
Technical Analysis
|
||||||
<span id="taInterval" class="text-[10px] bg-blue-600/20 text-blue-400 px-2 py-0.5 rounded ml-2 border border-blue-600/30">1D</span>
|
<span id="taInterval" class="text-[10px] bg-blue-600/20 text-blue-400 px-2 py-0.5 rounded ml-2 border border-blue-600/30">1D</span>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span id="taLastUpdate" class="text-xs text-gray-600 mr-2 hidden sm:inline-block">--</span>
|
<span id="taLastUpdate" class="text-xs text-gray-600 mr-2 hidden sm:inline-block">--</span>
|
||||||
<button class="bg-gradient-to-r from-blue-600 to-indigo-600 text-white px-3 py-1.5 rounded text-xs font-bold hover:shadow-lg transition-all flex items-center gap-1" id="aiBtn" onclick="window.openAIAnalysis()">
|
</div>
|
||||||
<span class="material-symbols-outlined text-sm">smart_toy</span> AI Insight
|
|
||||||
</button>
|
|
||||||
<button class="bg-[#1e222d] border border-[#2d3a4f] text-gray-400 px-3 py-1.5 rounded text-xs hover:text-white hover:border-gray-500 transition-colors" onclick="window.refreshTA()">
|
|
||||||
<span class="material-symbols-outlined text-sm align-bottom">refresh</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="taContent" class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
<div id="taContent" class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
@ -428,7 +442,7 @@
|
|||||||
<span class="material-symbols-outlined text-sm">menu</span>
|
<span class="material-symbols-outlined text-sm">menu</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="flex-1 overflow-y-auto p-0 sidebar-content bg-[#0d1421]">
|
<div class="flex-1 overflow-y-auto p-0 sidebar-content bg-[#0d1421] no-scrollbar">
|
||||||
<div class="sidebar-tab-panel active h-full" id="tab-indicators">
|
<div class="sidebar-tab-panel active h-full" id="tab-indicators">
|
||||||
<div id="indicatorPanel" class="p-2">
|
<div id="indicatorPanel" class="p-2">
|
||||||
<!-- Indicators content injected here -->
|
<!-- Indicators content injected here -->
|
||||||
@ -503,6 +517,20 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.hideSidebar = function() {
|
||||||
|
const sidebar = document.getElementById('rightSidebar');
|
||||||
|
if (sidebar && !sidebar.classList.contains('collapsed')) {
|
||||||
|
sidebar.classList.add('collapsed');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.hideSidebarAndClearDrawings = function() {
|
||||||
|
window.hideSidebar();
|
||||||
|
if (window.dashboard?.drawingManager) {
|
||||||
|
window.dashboard.drawingManager.clearAll();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Chart Resizer Logic
|
// Chart Resizer Logic
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const resizer = document.getElementById('mainChartResizer');
|
const resizer = document.getElementById('mainChartResizer');
|
||||||
@ -510,29 +538,33 @@
|
|||||||
|
|
||||||
let isResizing = false;
|
let isResizing = false;
|
||||||
let lastDownY = 0;
|
let lastDownY = 0;
|
||||||
|
let savedHeight = localStorage.getItem('chart_height');
|
||||||
|
|
||||||
if (resizer && chartWrapper) {
|
if (resizer && chartWrapper) {
|
||||||
resizer.addEventListener('mousedown', (e) => {
|
if (savedHeight) {
|
||||||
isResizing = true;
|
chartWrapper.style.flex = 'none';
|
||||||
lastDownY = e.clientY;
|
chartWrapper.style.height = savedHeight + 'px';
|
||||||
document.body.style.cursor = 'row-resize';
|
}
|
||||||
chartWrapper.style.pointerEvents = 'none'; // Prevent iframe/canvas capturing mouse
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('mousemove', (e) => {
|
const startResize = (y) => {
|
||||||
|
isResizing = true;
|
||||||
|
lastDownY = y;
|
||||||
|
document.body.style.cursor = 'row-resize';
|
||||||
|
chartWrapper.style.pointerEvents = 'none';
|
||||||
|
};
|
||||||
|
|
||||||
|
const doResize = (y) => {
|
||||||
if (!isResizing) return;
|
if (!isResizing) return;
|
||||||
|
|
||||||
const deltaY = e.clientY - lastDownY;
|
const deltaY = y - lastDownY;
|
||||||
lastDownY = e.clientY;
|
lastDownY = y;
|
||||||
|
|
||||||
const newHeight = chartWrapper.offsetHeight + deltaY;
|
const newHeight = chartWrapper.offsetHeight + deltaY;
|
||||||
|
|
||||||
// Min 200px, Max windowHeight - 150px
|
|
||||||
if (newHeight > 200 && newHeight < window.innerHeight - 150) {
|
if (newHeight > 200 && newHeight < window.innerHeight - 150) {
|
||||||
chartWrapper.style.flex = 'none';
|
chartWrapper.style.flex = 'none';
|
||||||
chartWrapper.style.height = newHeight + 'px';
|
chartWrapper.style.height = newHeight + 'px';
|
||||||
|
|
||||||
// Force chart layout recalculation if applicable
|
|
||||||
if (window.dashboard && window.dashboard.chart) {
|
if (window.dashboard && window.dashboard.chart) {
|
||||||
const container = document.getElementById('chart');
|
const container = document.getElementById('chart');
|
||||||
window.dashboard.chart.applyOptions({
|
window.dashboard.chart.applyOptions({
|
||||||
@ -541,17 +573,47 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
document.addEventListener('mouseup', () => {
|
const endResize = () => {
|
||||||
if (isResizing) {
|
if (isResizing) {
|
||||||
isResizing = false;
|
isResizing = false;
|
||||||
document.body.style.cursor = '';
|
document.body.style.cursor = '';
|
||||||
chartWrapper.style.pointerEvents = 'auto';
|
chartWrapper.style.pointerEvents = 'auto';
|
||||||
|
const currentHeight = chartWrapper.style.height;
|
||||||
|
localStorage.setItem('chart_height', currentHeight ? parseFloat(currentHeight) : 75);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
resizer.addEventListener('mousedown', (e) => startResize(e.clientY));
|
||||||
|
resizer.addEventListener('touchstart', (e) => startResize(e.touches[0].clientY), {passive: false});
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', (e) => doResize(e.clientY));
|
||||||
|
document.addEventListener('touchmove', (e) => doResize(e.touches[0].clientY), {passive: false});
|
||||||
|
|
||||||
|
document.addEventListener('mouseup', endResize);
|
||||||
|
document.addEventListener('touchend', endResize);
|
||||||
|
document.addEventListener('touchcancel', endResize);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Hide sidebar when clicking on chart container (but not on drawing toolbar or sidebar itself)
|
||||||
|
const chartWrapper = document.getElementById('chartWrapper');
|
||||||
|
if (chartWrapper) {
|
||||||
|
chartWrapper.addEventListener('click', function(e) {
|
||||||
|
const sidebar = document.getElementById('rightSidebar');
|
||||||
|
const drawingToolbar = document.getElementById('drawingToolbar');
|
||||||
|
|
||||||
|
if (!sidebar || sidebar.classList.contains('collapsed')) return;
|
||||||
|
|
||||||
|
const isDrawingToolbar = e.target.closest('#drawingToolbar');
|
||||||
|
const isSidebar = e.target.closest('#rightSidebar');
|
||||||
|
|
||||||
|
if (!isDrawingToolbar && !isSidebar) {
|
||||||
|
hideSidebar();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="./config.js"></script>
|
<script src="./config.js"></script>
|
||||||
|
|||||||
694
js/ui/chart.js
694
js/ui/chart.js
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user