|
|
|
|
|
let priceChart; |
|
|
let candleChart; |
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function () { |
|
|
|
|
|
const candleCtx = document.getElementById('candleChart'); |
|
|
if (!candleCtx) { |
|
|
console.error("Canvas element with ID 'candleChart' not found!"); |
|
|
return; |
|
|
} |
|
|
const context = candleCtx.getContext('2d'); |
|
|
if (!context) { |
|
|
console.error("Could not get 2D context from canvas element."); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
function generateCandleData(count) { |
|
|
const data = []; |
|
|
let date = new Date(); |
|
|
date.setHours(date.getHours() - count, 0, 0, 0); |
|
|
let open = 80000; |
|
|
|
|
|
for (let i = 0; i < count; i++) { |
|
|
const time = date.getTime(); |
|
|
|
|
|
const change = (Math.random() - 0.5) * 500; |
|
|
const close = open + change; |
|
|
|
|
|
|
|
|
const high = Math.max(open, close) + Math.random() * 250; |
|
|
const low = Math.min(open, close) - Math.random() * 250; |
|
|
|
|
|
data.push({ x: time, o: open, h: high, l: low, c: close }); |
|
|
|
|
|
date.setHours(date.getHours() + 1); |
|
|
open = close; |
|
|
} |
|
|
return data; |
|
|
} |
|
|
|
|
|
const candleData = generateCandleData(60); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
candleChart = new Chart(context, { |
|
|
type: 'candlestick', |
|
|
data: { |
|
|
datasets: [{ |
|
|
label: 'BTC/USDT', |
|
|
data: candleData, |
|
|
color: { up: '#10b981', down: '#ef4444', unchanged: '#94a3b8' }, |
|
|
borderColor: { up: '#10b981', down: '#ef4444', unchanged: '#94a3b8' }, |
|
|
borderWidth: 1 |
|
|
}] |
|
|
}, |
|
|
options: { |
|
|
responsive: true, |
|
|
maintainAspectRatio: false, |
|
|
plugins: { legend: { display: false } }, |
|
|
scales: { |
|
|
x: { |
|
|
type: 'time', |
|
|
time: { |
|
|
unit: 'hour', |
|
|
displayFormats: { hour: 'HH:mm' } |
|
|
}, |
|
|
grid: { color: 'rgba(255, 255, 255, 0.05)' }, |
|
|
ticks: { color: '#94a3b8' } |
|
|
}, |
|
|
y: { |
|
|
position: 'right', |
|
|
grid: { |
|
|
color: 'rgba(255, 255, 255, 0.1)', |
|
|
borderDash: [5, 5] |
|
|
}, |
|
|
ticks: { color: '#94a3b8' } |
|
|
} |
|
|
} |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const chartContainer = document.querySelector('.main-chart-container'); |
|
|
if (chartContainer && candleChart) { |
|
|
const resizeObserver = new ResizeObserver(entries => { |
|
|
|
|
|
if (!Array.isArray(entries) || !entries.length) { |
|
|
return; |
|
|
} |
|
|
|
|
|
candleChart.resize(); |
|
|
}); |
|
|
resizeObserver.observe(chartContainer); |
|
|
} else { |
|
|
console.error("Could not find chart container or chart instance for ResizeObserver."); |
|
|
} |
|
|
|
|
|
} catch (error) { |
|
|
console.error("Error creating chart:", error); |
|
|
} |
|
|
|
|
|
|
|
|
const buyBtn = document.getElementById('buy-btn'); |
|
|
const sellBtn = document.getElementById('sell-btn'); |
|
|
const placeOrderBtn = document.getElementById('place-order-btn'); |
|
|
|
|
|
buyBtn.addEventListener('click', function () { |
|
|
buyBtn.classList.add('bg-green-600', 'text-white'); |
|
|
buyBtn.classList.remove('bg-green-900', 'bg-opacity-30', 'text-green-400'); |
|
|
sellBtn.classList.add('bg-red-900', 'bg-opacity-30', 'text-red-400'); |
|
|
sellBtn.classList.remove('bg-red-600', 'text-white'); |
|
|
placeOrderBtn.classList.add('bg-green-600'); |
|
|
placeOrderBtn.classList.remove('bg-red-600'); |
|
|
placeOrderBtn.textContent = 'Buy BTC'; |
|
|
}); |
|
|
|
|
|
sellBtn.addEventListener('click', function () { |
|
|
sellBtn.classList.add('bg-red-600', 'text-white'); |
|
|
sellBtn.classList.remove('bg-red-900', 'bg-opacity-30', 'text-red-400'); |
|
|
buyBtn.classList.add('bg-green-900', 'bg-opacity-30', 'text-green-400'); |
|
|
buyBtn.classList.remove('bg-green-600', 'text-white'); |
|
|
placeOrderBtn.classList.add('bg-red-600'); |
|
|
placeOrderBtn.classList.remove('bg-green-600'); |
|
|
placeOrderBtn.textContent = 'Sell BTC'; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
function switchFeed(feedType) { |
|
|
|
|
|
if (candleChart) { |
|
|
candleChart.resize(); |
|
|
} |
|
|
|
|
|
|
|
|
const feeds = ['posts-feed', 'chat-feed', 'video-feed']; |
|
|
feeds.forEach(feed => { |
|
|
const feedElement = document.getElementById(feed); |
|
|
if (feed === feedType + '-feed') { |
|
|
feedElement.style.visibility = 'visible'; |
|
|
feedElement.style.zIndex = '1'; |
|
|
} else { |
|
|
feedElement.style.visibility = 'hidden'; |
|
|
feedElement.style.zIndex = '0'; |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const buttons = document.querySelectorAll('.feed-switch-btn'); |
|
|
buttons.forEach(btn => { |
|
|
btn.classList.remove('active'); |
|
|
if (btn.getAttribute('onclick') === `switchFeed('${feedType}')`) { |
|
|
btn.classList.add('active'); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
if (candleChart) { |
|
|
|
|
|
candleChart.resize(); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
if (candleChart) { |
|
|
candleChart.resize(); |
|
|
} |
|
|
}, 50); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function updateChart(indicatorType) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const indicatorButtons = document.querySelectorAll('#indicators-menu button'); |
|
|
indicatorButtons.forEach(btn => btn.classList.remove('indicator-active')); |
|
|
|
|
|
|
|
|
const clickedButton = document.getElementById(`${indicatorType}-btn`); |
|
|
if (clickedButton) { |
|
|
clickedButton.classList.add('indicator-active'); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
function toggleDropdown(menuId) { |
|
|
const menu = document.getElementById(menuId); |
|
|
if (menu) { |
|
|
menu.classList.toggle('hidden'); |
|
|
|
|
|
const button = document.querySelector(`[onclick*="toggleDropdown('${menuId}')"]`); |
|
|
if (button) { |
|
|
const isExpanded = !menu.classList.contains('hidden'); |
|
|
button.setAttribute('aria-expanded', isExpanded.toString()); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function closeDropdown(menuId) { |
|
|
const menu = document.getElementById(menuId); |
|
|
if (menu && !menu.classList.contains('hidden')) { |
|
|
menu.classList.add('hidden'); |
|
|
const button = document.querySelector(`[onclick*="toggleDropdown('${menuId}')"]`); |
|
|
if (button) { |
|
|
button.setAttribute('aria-expanded', 'false'); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
document.addEventListener('click', function(event) { |
|
|
const dropdownContainer = document.getElementById('indicators-dropdown'); |
|
|
const menu = document.getElementById('indicators-menu'); |
|
|
|
|
|
|
|
|
if (dropdownContainer && menu && !dropdownContainer.contains(event.target)) { |
|
|
closeDropdown('indicators-menu'); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
const handle = document.getElementById('bottom-panel'); |
|
|
const chartArea = document.getElementById('chart-area'); |
|
|
const tabContent = document.getElementById('tab-content'); |
|
|
const mainTerminal = document.getElementById('main-terminal'); |
|
|
|
|
|
if (!handle || !chartArea || !tabContent || !mainTerminal) { |
|
|
console.error("Resizable panel elements not found."); |
|
|
return; |
|
|
} |
|
|
|
|
|
let isResizing = false; |
|
|
let startY = 0; |
|
|
let startChartHeight = 0; |
|
|
let startTabContentHeight = 0; |
|
|
|
|
|
const startResize = (e) => { |
|
|
isResizing = true; |
|
|
startY = e.clientY; |
|
|
startChartHeight = chartArea.offsetHeight; |
|
|
startTabContentHeight = tabContent.offsetHeight; |
|
|
|
|
|
|
|
|
document.body.style.userSelect = 'none'; |
|
|
document.body.style.cursor = 'row-resize'; |
|
|
|
|
|
|
|
|
document.addEventListener('mousemove', doResize); |
|
|
document.addEventListener('mouseup', stopResize); |
|
|
|
|
|
document.body.addEventListener('mouseleave', stopResize); |
|
|
}; |
|
|
|
|
|
const doResize = (e) => { |
|
|
if (!isResizing) return; |
|
|
|
|
|
const deltaY = e.clientY - startY; |
|
|
const totalHeight = mainTerminal.clientHeight; |
|
|
const handleHeight = handle.offsetHeight; |
|
|
|
|
|
|
|
|
let newChartHeight = Math.max(50, startChartHeight + deltaY); |
|
|
let newTabContentHeight = Math.max(50, startTabContentHeight - deltaY); |
|
|
|
|
|
|
|
|
const availableHeight = totalHeight - handleHeight; |
|
|
if (newChartHeight + newTabContentHeight > availableHeight) { |
|
|
|
|
|
newTabContentHeight = availableHeight - newChartHeight; |
|
|
if (newTabContentHeight < 50) { |
|
|
newTabContentHeight = 50; |
|
|
newChartHeight = availableHeight - 50; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
chartArea.style.flexBasis = `${newChartHeight}px`; |
|
|
tabContent.style.flexBasis = `${newTabContentHeight}px`; |
|
|
|
|
|
|
|
|
if (window.candleChart) { |
|
|
window.candleChart.resize(); |
|
|
} |
|
|
}; |
|
|
|
|
|
const stopResize = () => { |
|
|
if (isResizing) { |
|
|
isResizing = false; |
|
|
|
|
|
document.removeEventListener('mousemove', doResize); |
|
|
document.removeEventListener('mouseup', stopResize); |
|
|
document.body.removeEventListener('mouseleave', stopResize); |
|
|
|
|
|
|
|
|
document.body.style.userSelect = ''; |
|
|
document.body.style.cursor = ''; |
|
|
} |
|
|
}; |
|
|
|
|
|
handle.addEventListener('mousedown', startResize); |
|
|
}); |
|
|
|
|
|
|
|
|
|