fix: restore gear icon toggle and fix chart settings persistence
This commit is contained in:
BIN
ignore/menu.PNG
Normal file
BIN
ignore/menu.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
70
index.html
70
index.html
@ -114,37 +114,53 @@
|
|||||||
<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="btnLogScale" title="Log Scale">L</button>
|
<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="btnLogScale" title="Log Scale">L</button>
|
||||||
|
|
||||||
<!-- Settings Popup -->
|
<!-- Settings Popup -->
|
||||||
<div class="hidden absolute bottom-10 right-0 bg-[#1e222d] border border-[#2d3a4f] rounded-lg p-3 z-50 w-56 shadow-xl" id="settingsPopup">
|
<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">
|
||||||
<div class="mb-3">
|
<!-- Reset Scale -->
|
||||||
<label class="block text-[10px] text-[#8fa2b3] mb-1 uppercase tracking-wider">Candle Colors</label>
|
<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
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="border-[#2d3a4f] my-1">
|
||||||
|
|
||||||
|
<!-- Scale Toggles -->
|
||||||
|
<div class="px-4 py-2 hover:bg-[#252f3f] cursor-pointer" onclick="window.toggleScaleOption('autoScale')">
|
||||||
|
<span id="autoScaleCheck">✓</span> Auto (fits data to screen)
|
||||||
|
</div>
|
||||||
|
<div class="px-4 py-2 hover:bg-[#252f3f] cursor-pointer" onclick="window.toggleScaleOption('invertScale')">
|
||||||
|
<span id="invertScaleCheck"></span> Invert scale
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="border-[#2d3a4f] my-1">
|
||||||
|
|
||||||
|
<!-- Scale Modes -->
|
||||||
|
<div class="px-4 py-2 hover:bg-[#252f3f] cursor-pointer" onclick="window.setScaleMode(0)">
|
||||||
|
<span id="modeNormalCheck">✓</span> Regular
|
||||||
|
</div>
|
||||||
|
<div class="px-4 py-2 hover:bg-[#252f3f] cursor-pointer" onclick="window.setScaleMode(2)">
|
||||||
|
<span id="modePercentCheck"></span> Percent
|
||||||
|
</div>
|
||||||
|
<div class="px-4 py-2 hover:bg-[#252f3f] cursor-pointer" onclick="window.setScaleMode(3)">
|
||||||
|
<span id="modeIndexedCheck"></span> Indexed to 100
|
||||||
|
</div>
|
||||||
|
<div class="px-4 py-2 hover:bg-[#252f3f] cursor-pointer" onclick="window.setScaleMode(1)">
|
||||||
|
<span id="modeLogCheck"></span> Logarithmic
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="border-[#2d3a4f] my-1">
|
||||||
|
|
||||||
|
<!-- Candle Colors -->
|
||||||
|
<div class="px-4 py-2">
|
||||||
|
<label class="text-[10px] text-[#8fa2b3] uppercase tracking-wider mb-1 block">Candle Colors</label>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<div class="flex-1">
|
<input type="color" id="candleUpColor" value="#ff9800" class="flex-1 h-6 cursor-pointer">
|
||||||
<label class="text-[9px] text-[#8fa2b3] block mb-0.5">Up</label>
|
<input type="color" id="candleDownColor" value="#ff9800" class="flex-1 h-6 cursor-pointer">
|
||||||
<div class="h-6 w-full rounded border border-[#2d3a4f] relative overflow-hidden">
|
|
||||||
<input type="color" id="candleUpColor" value="#ff9800" class="absolute -top-2 -left-2 w-[200%] h-[200%] cursor-pointer p-0 m-0 border-0">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1">
|
|
||||||
<label class="text-[9px] text-[#8fa2b3] block mb-0.5">Down</label>
|
|
||||||
<div class="h-6 w-full rounded border border-[#2d3a4f] relative overflow-hidden">
|
|
||||||
<input type="color" id="candleDownColor" value="#ff9800" class="absolute -top-2 -left-2 w-[200%] h-[200%] cursor-pointer p-0 m-0 border-0">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-[1fr_auto] items-center gap-2 mb-3">
|
<!-- Decimals -->
|
||||||
<label class="text-[10px] text-[#8fa2b3] uppercase tracking-wider">Decimals</label>
|
<div class="px-4 py-2 flex items-center justify-between">
|
||||||
<input type="number" id="priceFormatInput" min="0" max="8" value="2" class="w-16 bg-[#0d1421] border border-[#2d3a4f] text-gray-300 text-xs rounded p-1.5 text-center focus:ring-1 focus:ring-blue-500 focus:border-blue-500">
|
<label class="text-sm text-gray-300">Decimals</label>
|
||||||
</div>
|
<input type="number" id="priceFormatInput" min="0" max="8" value="2" class="w-16 bg-[#0d1421] border border-[#2d3a4f] text-center rounded text-xs">
|
||||||
|
|
||||||
<div class="grid grid-cols-[auto_1fr] items-center gap-2 mb-0">
|
|
||||||
<label class="text-[10px] text-[#8fa2b3] uppercase tracking-wider whitespace-nowrap">Timezone</label>
|
|
||||||
<select class="w-full bg-[#0d1421] border border-[#2d3a4f] text-gray-300 text-[10px] rounded p-1.5 focus:ring-1 focus:ring-blue-500 focus:border-blue-500" id="timezoneSelect">
|
|
||||||
<option value="UTC">UTC</option>
|
|
||||||
<option value="Europe/Warsaw" selected>Warsaw</option>
|
|
||||||
<option value="America/New_York">New York</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
111
js/ui/chart.js
111
js/ui/chart.js
@ -485,10 +485,9 @@ constructor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initPriceScaleControls() {
|
initPriceScaleControls() {
|
||||||
|
// Gear Button Toggle
|
||||||
const btnSettings = document.getElementById('btnSettings');
|
const btnSettings = document.getElementById('btnSettings');
|
||||||
const settingsPopup = document.getElementById('settingsPopup');
|
const settingsPopup = document.getElementById('settingsPopup');
|
||||||
const btnAutoScale = document.getElementById('btnAutoScale');
|
|
||||||
const btnLogScale = document.getElementById('btnLogScale');
|
|
||||||
|
|
||||||
if (btnSettings && settingsPopup) {
|
if (btnSettings && settingsPopup) {
|
||||||
btnSettings.addEventListener('click', (e) => {
|
btnSettings.addEventListener('click', (e) => {
|
||||||
@ -502,78 +501,56 @@ constructor() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!btnAutoScale || !btnLogScale) return;
|
// Initialize state from storage
|
||||||
|
this.scaleState = {
|
||||||
this.priceScaleState = {
|
autoScale: localStorage.getItem('winterfail_scale_auto') !== 'false',
|
||||||
autoScale: true,
|
invertScale: localStorage.getItem('winterfail_scale_invert') === 'true',
|
||||||
logScale: false
|
scaleMode: parseInt(localStorage.getItem('winterfail_scale_mode')) || 0
|
||||||
};
|
};
|
||||||
|
|
||||||
btnAutoScale.addEventListener('click', () => {
|
// UI Helpers
|
||||||
this.priceScaleState.autoScale = !this.priceScaleState.autoScale;
|
const updateCheckmark = (id, active) => {
|
||||||
btnAutoScale.classList.toggle('active', this.priceScaleState.autoScale);
|
const el = document.getElementById(id);
|
||||||
|
if (el) el.textContent = active ? '✓' : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateUI = () => {
|
||||||
|
updateCheckmark('autoScaleCheck', this.scaleState.autoScale);
|
||||||
|
updateCheckmark('invertScaleCheck', this.scaleState.invertScale);
|
||||||
|
updateCheckmark('modeNormalCheck', this.scaleState.scaleMode === 0);
|
||||||
|
updateCheckmark('modeLogCheck', this.scaleState.scaleMode === 1);
|
||||||
|
updateCheckmark('modePercentCheck', this.scaleState.scaleMode === 2);
|
||||||
|
updateCheckmark('modeIndexedCheck', this.scaleState.scaleMode === 3);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Apply initial state
|
||||||
|
this.candleSeries.priceScale().applyOptions({
|
||||||
|
autoScale: this.scaleState.autoScale,
|
||||||
|
invertScale: this.scaleState.invertScale,
|
||||||
|
mode: this.scaleState.scaleMode
|
||||||
|
});
|
||||||
|
updateUI();
|
||||||
|
|
||||||
|
window.toggleScaleOption = (option) => {
|
||||||
|
this.scaleState[option] = !this.scaleState[option];
|
||||||
|
localStorage.setItem(`winterfail_scale_${option}`, this.scaleState[option]);
|
||||||
|
|
||||||
this.candleSeries.priceScale().applyOptions({
|
this.candleSeries.priceScale().applyOptions({
|
||||||
autoScale: this.priceScaleState.autoScale
|
[option]: this.scaleState[option]
|
||||||
});
|
});
|
||||||
|
updateUI();
|
||||||
console.log('Auto Scale:', this.priceScaleState.autoScale ? 'ON' : 'OFF');
|
};
|
||||||
});
|
|
||||||
|
window.setScaleMode = (mode) => {
|
||||||
btnLogScale.addEventListener('click', () => {
|
this.scaleState.scaleMode = mode;
|
||||||
this.priceScaleState.logScale = !this.priceScaleState.logScale;
|
localStorage.setItem('winterfail_scale_mode', mode);
|
||||||
btnLogScale.classList.toggle('active', this.priceScaleState.logScale);
|
|
||||||
|
|
||||||
let currentPriceRange = null;
|
|
||||||
let currentTimeRange = null;
|
|
||||||
if (!this.priceScaleState.autoScale) {
|
|
||||||
try {
|
|
||||||
currentPriceRange = this.candleSeries.priceScale().getVisiblePriceRange();
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Could not get price range');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
currentTimeRange = this.chart.timeScale().getVisibleLogicalRange();
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Could not get time range');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.candleSeries.priceScale().applyOptions({
|
this.candleSeries.priceScale().applyOptions({
|
||||||
mode: this.priceScaleState.logScale ? LightweightCharts.PriceScaleMode.Logarithmic : LightweightCharts.PriceScaleMode.Normal
|
mode: mode
|
||||||
});
|
});
|
||||||
|
updateUI();
|
||||||
this.chart.applyOptions({});
|
};
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
if (currentTimeRange) {
|
|
||||||
try {
|
|
||||||
this.chart.timeScale().setVisibleLogicalRange(currentTimeRange);
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Could not restore time range');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.priceScaleState.autoScale && currentPriceRange) {
|
|
||||||
try {
|
|
||||||
this.candleSeries.priceScale().setVisiblePriceRange(currentPriceRange);
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Could not restore price range');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
console.log('Log Scale:', this.priceScaleState.logScale ? 'ON' : 'OFF');
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('keydown', (e) => {
|
|
||||||
if (e.key === 'a' || e.key === 'A') {
|
|
||||||
if (e.target.tagName !== 'INPUT') {
|
|
||||||
btnAutoScale.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initNavigationControls() {
|
initNavigationControls() {
|
||||||
|
|||||||
Reference in New Issue
Block a user