chore: resolve merge conflicts in index.html and finalize drawing tools
This commit is contained in:
57
index.html
57
index.html
@ -104,16 +104,61 @@
|
|||||||
<!-- Chart Container -->
|
<!-- Chart Container -->
|
||||||
<section class="relative w-full bg-[#0d1421] h-[60vh] md:h-[70vh]" data-purpose="chart-container" id="chartWrapper">
|
<section class="relative w-full bg-[#0d1421] h-[60vh] md:h-[70vh]" data-purpose="chart-container" id="chartWrapper">
|
||||||
<div id="chart" class="w-full h-full"></div>
|
<div id="chart" class="w-full h-full"></div>
|
||||||
|
|
||||||
<!-- Drawing Layer Overlay -->
|
<!-- Drawing Layer Overlay -->
|
||||||
<canvas id="drawingLayer" class="absolute inset-0 pointer-events-none z-20 w-full h-full"></canvas>
|
<canvas id="drawingLayer" class="absolute inset-0 pointer-events-none z-20 w-full h-full"></canvas>
|
||||||
|
|
||||||
<!-- Overlay Controls --> <div class="absolute bottom-4 right-4 flex gap-2 z-10 opacity-0 hover:opacity-100 transition-opacity" id="priceScaleControls">
|
<!-- Vertical Drawing Toolbar (Left) -->
|
||||||
<button class="w-8 h-8 bg-[#1e222d] border border-[#2d3a4f] text-gray-300 flex items-center justify-center rounded hover:bg-[#2d3a4f] transition-colors shadow-lg" id="btnSettings" title="Settings">
|
<div class="absolute left-2 top-1/2 -translate-y-1/2 flex flex-col gap-1 z-30 bg-[#1a2333]/80 backdrop-blur border border-[#2d3a4f] p-1 rounded-md shadow-xl" id="drawingToolbar">
|
||||||
<span class="material-symbols-outlined text-sm">settings</span>
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('cursor')" title="Cursor">
|
||||||
</button>
|
<span class="material-symbols-outlined text-sm">near_me</span>
|
||||||
|
</button>
|
||||||
|
<div class="w-full h-[1px] bg-[#2d3a4f] my-0.5"></div>
|
||||||
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('trend_line')" title="Trend Line">
|
||||||
|
<span class="material-symbols-outlined text-sm">call_split</span>
|
||||||
|
</button>
|
||||||
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('ray')" title="Ray">
|
||||||
|
<span class="material-symbols-outlined text-sm">trending_flat</span>
|
||||||
|
</button>
|
||||||
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('horizontal_line')" title="Horizontal Line">
|
||||||
|
<span class="material-symbols-outlined text-sm">swap_horizontal_circle</span>
|
||||||
|
</button>
|
||||||
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('vertical_line')" title="Vertical Line">
|
||||||
|
<span class="material-symbols-outlined text-sm">swap_vert</span>
|
||||||
|
</button>
|
||||||
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('fib_retracement')" title="Fibonacci Retracement">
|
||||||
|
<span class="material-symbols-outlined text-sm">reorder</span>
|
||||||
|
</button>
|
||||||
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('rectangle')" title="Rectangle">
|
||||||
|
<span class="material-symbols-outlined text-sm">crop_square</span>
|
||||||
|
</button>
|
||||||
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('text')" title="Text Label">
|
||||||
|
<span class="material-symbols-outlined text-sm">text_fields</span>
|
||||||
|
</button>
|
||||||
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('arrow_up')" title="Arrow Up">
|
||||||
|
<span class="material-symbols-outlined text-sm">arrow_upward</span>
|
||||||
|
</button>
|
||||||
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('arrow_down')" title="Arrow Down">
|
||||||
|
<span class="material-symbols-outlined text-sm">arrow_downward</span>
|
||||||
|
</button>
|
||||||
|
<button class="w-8 h-8 text-gray-400 hover:text-white hover:bg-[#2d3a4f] rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('measure')" title="Measure">
|
||||||
|
<span class="material-symbols-outlined text-sm">straighten</span>
|
||||||
|
</button>
|
||||||
|
<div class="w-full h-[1px] bg-[#2d3a4f] my-0.5"></div>
|
||||||
|
<button class="w-8 h-8 text-red-400 hover:text-red-300 hover:bg-red-900/20 rounded flex items-center justify-center transition-colors" onclick="window.activateDrawingTool('clear')" title="Clear All">
|
||||||
|
<span class="material-symbols-outlined text-sm">delete</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Overlay Controls -->
|
||||||
|
<div class="absolute bottom-4 right-4 flex gap-2 z-10 opacity-0 hover:opacity-100 transition-opacity" id="priceScaleControls">
|
||||||
|
<button class="w-8 h-8 bg-[#1e222d] border border-[#2d3a4f] text-gray-300 flex items-center justify-center rounded hover:bg-[#2d3a4f] transition-colors shadow-lg" id="btnSettings" title="Settings">
|
||||||
|
<span class="material-symbols-outlined text-sm">settings</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Settings Popup -->
|
||||||
|
<div class="hidden absolute bottom-10 right-0 bg-[#1a2333] border border-[#2d3a4f] rounded-lg py-2 z-50 w-64 shadow-xl text-sm" id="settingsPopup">
|
||||||
|
|
||||||
<!-- Settings Popup -->
|
|
||||||
<div class="hidden absolute bottom-10 right-0 bg-[#1a2333] border border-[#2d3a4f] rounded-lg py-2 z-50 w-64 shadow-xl text-sm" id="settingsPopup">
|
|
||||||
<!-- Reset Scale -->
|
<!-- Reset Scale -->
|
||||||
<div class="px-4 py-2 hover:bg-[#252f3f] cursor-pointer flex items-center gap-3" onclick="window.dashboard.chart.timeScale().fitContent()">
|
<div class="px-4 py-2 hover:bg-[#252f3f] cursor-pointer flex items-center gap-3" onclick="window.dashboard.chart.timeScale().fitContent()">
|
||||||
<span class="material-symbols-outlined text-sm">refresh</span> Reset price scale
|
<span class="material-symbols-outlined text-sm">refresh</span> Reset price scale
|
||||||
|
|||||||
BIN
indicator_panel issue.PNG
Normal file
BIN
indicator_panel issue.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 181 KiB |
348
js/ui/chart.js
348
js/ui/chart.js
@ -169,6 +169,7 @@ constructor() {
|
|||||||
this.avgPriceSeries = null;
|
this.avgPriceSeries = null;
|
||||||
this.dailyMAData = new Map(); // timestamp -> { ma44, ma125, price }
|
this.dailyMAData = new Map(); // timestamp -> { ma44, ma125, price }
|
||||||
this.currentMouseTime = null;
|
this.currentMouseTime = null;
|
||||||
|
this.drawingItems = []; // Store drawing items for management
|
||||||
|
|
||||||
// Throttled versions of heavy functions
|
// Throttled versions of heavy functions
|
||||||
this.throttledOnVisibleRangeChange = throttle(this.onVisibleRangeChange.bind(this), 150);
|
this.throttledOnVisibleRangeChange = throttle(this.onVisibleRangeChange.bind(this), 150);
|
||||||
@ -501,6 +502,8 @@ constructor() {
|
|||||||
initPriceScaleControls() {
|
initPriceScaleControls() {
|
||||||
const btnSettings = document.getElementById('btnSettings');
|
const btnSettings = document.getElementById('btnSettings');
|
||||||
const settingsPopup = document.getElementById('settingsPopup');
|
const settingsPopup = document.getElementById('settingsPopup');
|
||||||
|
const toggleToolbarBtn = document.getElementById('toggleChartToolbar');
|
||||||
|
const chartToolbar = document.getElementById('chartToolbar');
|
||||||
|
|
||||||
// Settings Popup Toggle and Outside Click
|
// Settings Popup Toggle and Outside Click
|
||||||
if (btnSettings && settingsPopup) {
|
if (btnSettings && settingsPopup) {
|
||||||
@ -522,6 +525,16 @@ constructor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Toggle Chart Toolbar
|
||||||
|
if (toggleToolbarBtn && chartToolbar) {
|
||||||
|
toggleToolbarBtn.addEventListener('click', () => {
|
||||||
|
chartToolbar.style.display = chartToolbar.style.display === 'flex' ? 'none' : 'flex';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drawing Tools
|
||||||
|
this.initDrawingTools();
|
||||||
|
|
||||||
// Initialize state from storage
|
// Initialize state from storage
|
||||||
this.scaleState = {
|
this.scaleState = {
|
||||||
autoScale: localStorage.getItem('winterfail_scale_auto') !== 'false',
|
autoScale: localStorage.getItem('winterfail_scale_auto') !== 'false',
|
||||||
@ -579,6 +592,341 @@ constructor() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initDrawingTools() {
|
||||||
|
const btnDrawingTools = document.getElementById('btnDrawingTools');
|
||||||
|
const drawingToolsPopup = document.getElementById('drawingToolsPopup');
|
||||||
|
|
||||||
|
if (btnDrawingTools && drawingToolsPopup) {
|
||||||
|
btnDrawingTools.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
drawingToolsPopup.classList.toggle('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('click', closeDrawingToolsPopup);
|
||||||
|
document.addEventListener('touchstart', closeDrawingToolsPopup, { passive: true });
|
||||||
|
|
||||||
|
function closeDrawingToolsPopup(e) {
|
||||||
|
const isInside = drawingToolsPopup.contains(e.target) || e.target === btnDrawingTools;
|
||||||
|
const isDrawingButton = e.target.closest('#btnDrawingTools');
|
||||||
|
|
||||||
|
if (!isInside && !isDrawingButton) {
|
||||||
|
drawingToolsPopup.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let isDrawing = false;
|
||||||
|
let drawMode = null;
|
||||||
|
let startPoint = null;
|
||||||
|
let drawLine = null;
|
||||||
|
let drawArrow = null;
|
||||||
|
let drawText = null;
|
||||||
|
|
||||||
|
window.activateDrawingTool = (tool) => {
|
||||||
|
if (tool === 'clear') {
|
||||||
|
this.clearDrawingTools();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawMode = tool;
|
||||||
|
isDrawing = true;
|
||||||
|
|
||||||
|
const chart = this.chart;
|
||||||
|
const container = chart.container();
|
||||||
|
|
||||||
|
const onMouseDown = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const rect = container.getBoundingClientRect();
|
||||||
|
const x = e.clientX - rect.left;
|
||||||
|
const y = e.clientY - rect.top;
|
||||||
|
|
||||||
|
if (drawMode === 'trend_line' || drawMode === 'horizontal_line' || drawMode === 'vertical_line') {
|
||||||
|
this.createLine(x, y);
|
||||||
|
} else if (drawMode === 'arrow_up' || drawMode === 'arrow_down') {
|
||||||
|
this.createArrow(drawMode === 'arrow_up' ? 'arrowUp' : 'arrowDown', x, y);
|
||||||
|
} else if (drawMode === 'text') {
|
||||||
|
this.createText(x, y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onTouchStart = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const touch = e.touches[0];
|
||||||
|
const rect = container.getBoundingClientRect();
|
||||||
|
const x = touch.clientX - rect.left;
|
||||||
|
const y = touch.clientY - rect.top;
|
||||||
|
|
||||||
|
if (drawMode === 'trend_line' || drawMode === 'horizontal_line' || drawMode === 'vertical_line') {
|
||||||
|
this.createLine(x, y);
|
||||||
|
} else if (drawMode === 'arrow_up' || drawMode === 'arrow_down') {
|
||||||
|
this.createArrow(drawMode === 'arrow_up' ? 'arrowUp' : 'arrowDown', x, y);
|
||||||
|
} else if (drawMode === 'text') {
|
||||||
|
this.createText(x, y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
container.addEventListener('mousedown', onMouseDown);
|
||||||
|
container.addEventListener('touchstart', onTouchStart);
|
||||||
|
|
||||||
|
const closeDrawing = () => {
|
||||||
|
container.removeEventListener('mousedown', onMouseDown);
|
||||||
|
container.removeEventListener('touchstart', onTouchStart);
|
||||||
|
document.removeEventListener('click', closeDrawing);
|
||||||
|
document.removeEventListener('touchstart', closeDrawing);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('click', closeDrawing);
|
||||||
|
document.addEventListener('touchstart', closeDrawing);
|
||||||
|
|
||||||
|
drawingToolsPopup.classList.add('hidden');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
createLine(x, y) {
|
||||||
|
const chart = this.chart;
|
||||||
|
const candleSeries = this.candleSeries;
|
||||||
|
|
||||||
|
let lineData = {
|
||||||
|
time: [],
|
||||||
|
value: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const line = chart.addLineSeries({
|
||||||
|
color: '#2962ff',
|
||||||
|
lineWidth: 2,
|
||||||
|
lineStyle: LightweightCharts.LineStyle.Solid,
|
||||||
|
crosshairMarkerVisible: true,
|
||||||
|
crosshairMarkerRadius: 4,
|
||||||
|
baseIndex: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
let points = [];
|
||||||
|
|
||||||
|
const container = chart.container();
|
||||||
|
let startTime = null;
|
||||||
|
let startPrice = null;
|
||||||
|
|
||||||
|
const onMouseDown = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const rect = container.getBoundingClientRect();
|
||||||
|
const clientX = e.clientX;
|
||||||
|
const clientY = e.clientY;
|
||||||
|
|
||||||
|
const timeCoord = chart.timeScale().coordinateToTime(x);
|
||||||
|
const price = chart.priceScale().coordinateToPrice(y);
|
||||||
|
|
||||||
|
if (startTime === null) {
|
||||||
|
startTime = timeCoord;
|
||||||
|
startPrice = price;
|
||||||
|
|
||||||
|
line.setData([{
|
||||||
|
time: startTime,
|
||||||
|
value: startPrice
|
||||||
|
}]);
|
||||||
|
} else {
|
||||||
|
line.setData([
|
||||||
|
{ time: startTime, value: startPrice },
|
||||||
|
{ time: timeCoord, value: price }
|
||||||
|
]);
|
||||||
|
startTime = null;
|
||||||
|
startPrice = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onTouchStart = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const touch = e.touches[0];
|
||||||
|
const rect = container.getBoundingClientRect();
|
||||||
|
const clientX = touch.clientX;
|
||||||
|
const clientY = touch.clientY;
|
||||||
|
|
||||||
|
const timeCoord = chart.timeScale().coordinateToTime(x);
|
||||||
|
const price = chart.priceScale().coordinateToPrice(y);
|
||||||
|
|
||||||
|
if (startTime === null) {
|
||||||
|
startTime = timeCoord;
|
||||||
|
startPrice = price;
|
||||||
|
|
||||||
|
line.setData([{
|
||||||
|
time: startTime,
|
||||||
|
value: startPrice
|
||||||
|
}]);
|
||||||
|
} else {
|
||||||
|
line.setData([
|
||||||
|
{ time: startTime, value: startPrice },
|
||||||
|
{ time: timeCoord, value: price }
|
||||||
|
]);
|
||||||
|
startTime = null;
|
||||||
|
startPrice = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
container.addEventListener('mousedown', onMouseDown);
|
||||||
|
container.addEventListener('touchstart', onTouchStart);
|
||||||
|
|
||||||
|
const cleanup = () => {
|
||||||
|
container.removeEventListener('mousedown', onMouseDown);
|
||||||
|
container.removeEventListener('touchstart', onTouchStart);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('click', cleanup);
|
||||||
|
document.addEventListener('touchstart', cleanup);
|
||||||
|
}
|
||||||
|
|
||||||
|
createArrow(arrowType, x, y) {
|
||||||
|
const chart = this.chart;
|
||||||
|
const container = chart.container();
|
||||||
|
|
||||||
|
const markerPrimitive = new SeriesMarkersPrimitive();
|
||||||
|
this.candleSeries.attachPrimitive(markerPrimitive);
|
||||||
|
|
||||||
|
const rect = container.getBoundingClientRect();
|
||||||
|
const time = chart.timeScale().coordinateToTime(x);
|
||||||
|
const price = chart.priceScale().coordinateToPrice(y);
|
||||||
|
|
||||||
|
const marker = {
|
||||||
|
time: time,
|
||||||
|
position: arrowType === 'arrowUp' ? 'belowBar' : 'aboveBar',
|
||||||
|
color: arrowType === 'arrowUp' ? '#26a69a' : '#ef5350',
|
||||||
|
shape: arrowType === 'arrowUp' ? 'arrowUp' : 'arrowDown',
|
||||||
|
text: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
markerPrimitive.setMarkers([marker]);
|
||||||
|
|
||||||
|
let isDragging = false;
|
||||||
|
let startX = 0;
|
||||||
|
let startY = 0;
|
||||||
|
let startTime = time;
|
||||||
|
let startPrice = price;
|
||||||
|
|
||||||
|
const onMouseDown = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
isDragging = true;
|
||||||
|
startX = e.clientX;
|
||||||
|
startY = e.clientY;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseMove = (e) => {
|
||||||
|
if (!isDragging) return;
|
||||||
|
|
||||||
|
const dx = e.clientX - startX;
|
||||||
|
const dy = e.clientY - startY;
|
||||||
|
const rect = container.getBoundingClientRect();
|
||||||
|
|
||||||
|
const timeCoord = chart.timeScale().coordinateToTime(x + dx);
|
||||||
|
const newPrice = chart.priceScale().coordinateToPrice(y + dy);
|
||||||
|
|
||||||
|
const newMarker = {
|
||||||
|
time: timeCoord,
|
||||||
|
position: arrowType === 'arrowUp' ? 'belowBar' : 'aboveBar',
|
||||||
|
color: arrowType === 'arrowUp' ? '#26a69a' : '#ef5350',
|
||||||
|
shape: arrowType === 'arrowUp' ? 'arrowUp' : 'arrowDown',
|
||||||
|
text: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
markerPrimitive.setMarkers([newMarker]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseUp = () => {
|
||||||
|
isDragging = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
container.addEventListener('mousedown', onMouseDown);
|
||||||
|
document.addEventListener('mousemove', onMouseMove);
|
||||||
|
document.addEventListener('mouseup', onMouseUp);
|
||||||
|
|
||||||
|
const cleanup = () => {
|
||||||
|
container.removeEventListener('mousedown', onMouseDown);
|
||||||
|
document.removeEventListener('mousemove', onMouseMove);
|
||||||
|
document.removeEventListener('mouseup', onMouseUp);
|
||||||
|
document.removeEventListener('click', cleanup);
|
||||||
|
document.removeEventListener('touchstart', cleanup);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('click', cleanup);
|
||||||
|
document.addEventListener('touchstart', cleanup);
|
||||||
|
}
|
||||||
|
|
||||||
|
createText(x, y) {
|
||||||
|
const chart = this.chart;
|
||||||
|
const container = chart.container();
|
||||||
|
|
||||||
|
const text = prompt('Enter text label:', '');
|
||||||
|
if (!text) return;
|
||||||
|
|
||||||
|
const rect = container.getBoundingClientRect();
|
||||||
|
const time = chart.timeScale().coordinateToTime(x);
|
||||||
|
const price = chart.priceScale().coordinateToPrice(y);
|
||||||
|
|
||||||
|
const label = chart.addLabel({
|
||||||
|
text: text,
|
||||||
|
color: '#ffffff',
|
||||||
|
fontSize: 11,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
crosshairMarkerVisible: false,
|
||||||
|
time: time,
|
||||||
|
price: price
|
||||||
|
});
|
||||||
|
|
||||||
|
let isDragging = false;
|
||||||
|
let startX = 0;
|
||||||
|
let startY = 0;
|
||||||
|
let startTime = time;
|
||||||
|
let startPrice = price;
|
||||||
|
|
||||||
|
const onMouseDown = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
isDragging = true;
|
||||||
|
startX = e.clientX;
|
||||||
|
startY = e.clientY;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseMove = (e) => {
|
||||||
|
if (!isDragging) return;
|
||||||
|
|
||||||
|
const dx = e.clientX - startX;
|
||||||
|
const dy = e.clientY - startY;
|
||||||
|
|
||||||
|
const newTime = chart.timeScale().coordinateToTime(x + dx);
|
||||||
|
const newPrice = chart.priceScale().coordinateToPrice(y + dy);
|
||||||
|
|
||||||
|
label.applyOptions({
|
||||||
|
time: newTime,
|
||||||
|
price: newPrice
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseUp = () => {
|
||||||
|
isDragging = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
container.addEventListener('mousedown', onMouseDown);
|
||||||
|
document.addEventListener('mousemove', onMouseMove);
|
||||||
|
document.addEventListener('mouseup', onMouseUp);
|
||||||
|
|
||||||
|
const cleanup = () => {
|
||||||
|
container.removeEventListener('mousedown', onMouseDown);
|
||||||
|
document.removeEventListener('mousemove', onMouseMove);
|
||||||
|
document.removeEventListener('mouseup', onMouseUp);
|
||||||
|
document.removeEventListener('click', cleanup);
|
||||||
|
document.removeEventListener('touchstart', cleanup);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('click', cleanup);
|
||||||
|
document.addEventListener('touchstart', cleanup);
|
||||||
|
}
|
||||||
|
|
||||||
|
clearDrawingTools() {
|
||||||
|
const allSeries = this.chart.series();
|
||||||
|
allSeries.forEach(series => {
|
||||||
|
if (series.type !== 'Candlestick' && series.type !== 'Line' && series.type !== 'Area') {
|
||||||
|
this.chart.removeSeries(series);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
initNavigationControls() {
|
initNavigationControls() {
|
||||||
const chartWrapper = document.getElementById('chartWrapper');
|
const chartWrapper = document.getElementById('chartWrapper');
|
||||||
const navLeft = document.getElementById('navLeft');
|
const navLeft = document.getElementById('navLeft');
|
||||||
|
|||||||
27
test.json
Normal file
27
test.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://opencode.ai/theme.json",
|
||||||
|
"theme": {
|
||||||
|
"background": "#09141B",
|
||||||
|
"text": "#DEB88D",
|
||||||
|
"textMuted": "#17384C",
|
||||||
|
"border": "#17384C",
|
||||||
|
"borderActive": "#1BBCDD",
|
||||||
|
"primary": "#FCA02F",
|
||||||
|
"secondary": "#027C9B",
|
||||||
|
"accent": "#68D4F1",
|
||||||
|
"error": "#D15123",
|
||||||
|
"warning": "#FDD39F",
|
||||||
|
"success": "#50A3B5",
|
||||||
|
"info": "#1E4950",
|
||||||
|
"backgroundPanel": "#17384C",
|
||||||
|
"backgroundElement": "#1E4950",
|
||||||
|
"diffAdded": "#628D98",
|
||||||
|
"diffRemoved": "#D48678",
|
||||||
|
"diffContext": "#17384C",
|
||||||
|
"diffHunkHeader": "#434B53",
|
||||||
|
"diffHighlightAdded": "#1BBCDD",
|
||||||
|
"diffHighlightRemoved": "#D48678",
|
||||||
|
"diffAddedBg": "#09141B",
|
||||||
|
"diffRemovedBg": "#09141B"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user