Replace drag-pan with ‹ / › buttons in the chart header
Removed click-and-drag panning; the chart header now has ‹ and › buttons that shift the price window left/right by ~40% of the current half-width per click. Fit still re-centres and resets zoom. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -99,12 +99,14 @@
|
|||||||
<div class="card-header d-flex align-items-center justify-content-between flex-wrap gap-3">
|
<div class="card-header d-flex align-items-center justify-content-between flex-wrap gap-3">
|
||||||
<h3 class="card-title text-white mb-0">Profit / Loss vs. Underlying Price</h3>
|
<h3 class="card-title text-white mb-0">Profit / Loss vs. Underlying Price</h3>
|
||||||
<div class="d-flex align-items-center flex-wrap gap-3">
|
<div class="d-flex align-items-center flex-wrap gap-3">
|
||||||
<!-- price-range zoom -->
|
<!-- pan + zoom price range -->
|
||||||
<div class="btn-group btn-group-sm" role="group" aria-label="Zoom price range">
|
<div class="btn-group btn-group-sm" role="group" aria-label="Pan and zoom price range">
|
||||||
|
<button class="btn btn-outline-secondary" @click="panLeft()" title="Move left — show lower prices">‹</button>
|
||||||
<button class="btn btn-outline-secondary" @click="zoomOut()" title="Zoom out — wider price range">−</button>
|
<button class="btn btn-outline-secondary" @click="zoomOut()" title="Zoom out — wider price range">−</button>
|
||||||
<button class="btn btn-outline-secondary" disabled style="min-width:5rem" x-text="'±' + lastHalfPct + '%'"></button>
|
<button class="btn btn-outline-secondary" disabled style="min-width:5rem" x-text="'±' + lastHalfPct + '%'"></button>
|
||||||
<button class="btn btn-outline-secondary" @click="zoomIn()" title="Zoom in — narrower price range">+</button>
|
<button class="btn btn-outline-secondary" @click="zoomIn()" title="Zoom in — narrower price range">+</button>
|
||||||
<button class="btn btn-outline-secondary" @click="zoomFit()" title="Reset zoom">Fit</button>
|
<button class="btn btn-outline-secondary" @click="panRight()" title="Move right — show higher prices">›</button>
|
||||||
|
<button class="btn btn-outline-secondary" @click="zoomFit()" title="Reset pan & zoom">Fit</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- time slider -->
|
<!-- time slider -->
|
||||||
<div class="d-flex align-items-center gap-2" style="min-width:300px;">
|
<div class="d-flex align-items-center gap-2" style="min-width:300px;">
|
||||||
@@ -116,9 +118,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div id="plChart" :style="'min-height:380px;user-select:none;cursor:' + (_drag ? 'grabbing' : 'grab')"
|
<div id="plChart" style="min-height:380px;" role="img" aria-label="Profit and loss diagram"></div>
|
||||||
@mousedown="startPan($event)" @mousemove.window="onPan($event)" @mouseup.window="endPan()" @mouseleave.window="endPan()"
|
|
||||||
role="img" aria-label="Profit and loss diagram (drag left/right to pan the price range)"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -318,7 +318,6 @@
|
|||||||
symbol: '', symbols: [], spot: 0, legs: [],
|
symbol: '', symbols: [], spot: 0, legs: [],
|
||||||
dteOffset: 0,
|
dteOffset: 0,
|
||||||
xZoom: 1, xPan: 0, lastHalfPct: 0,
|
xZoom: 1, xPan: 0, lastHalfPct: 0,
|
||||||
_drag: null,
|
|
||||||
refreshing: false, showManual: false, toast: '',
|
refreshing: false, showManual: false, toast: '',
|
||||||
manual: { side:'long', type:'call', qty:1, strike:null, expiry:'', entryPrice:null, ivPct:null },
|
manual: { side:'long', type:'call', qty:1, strike:null, expiry:'', entryPrice:null, ivPct:null },
|
||||||
chart: null, _renderTimer: null,
|
chart: null, _renderTimer: null,
|
||||||
@@ -587,22 +586,9 @@
|
|||||||
zoomIn() { this.xZoom = Math.max(0.2, +(this.xZoom / 1.4).toFixed(3)); this.renderChart(); },
|
zoomIn() { this.xZoom = Math.max(0.2, +(this.xZoom / 1.4).toFixed(3)); this.renderChart(); },
|
||||||
zoomOut() { this.xZoom = Math.min(8, +(this.xZoom * 1.4).toFixed(3)); this.renderChart(); },
|
zoomOut() { this.xZoom = Math.min(8, +(this.xZoom * 1.4).toFixed(3)); this.renderChart(); },
|
||||||
zoomFit() { this.xZoom = 1; this.xPan = 0; this.renderChart(); },
|
zoomFit() { this.xZoom = 1; this.xPan = 0; this.renderChart(); },
|
||||||
|
_panStep() { return 0.4 * (this._lastHalf || (Math.max(this.spot, 1) * 0.22)); },
|
||||||
// click-and-drag to pan the price window
|
panLeft() { this.xPan -= this._panStep(); this.renderChart(); },
|
||||||
startPan(e) {
|
panRight() { this.xPan += this._panStep(); this.renderChart(); },
|
||||||
if (e.button !== 0) return;
|
|
||||||
const pw = (this._lastPlotW && this._lastPlotW > 50) ? this._lastPlotW
|
|
||||||
: ((document.getElementById('plChart')?.clientWidth || 600) - 70);
|
|
||||||
this._drag = { x: e.clientX, pan: this.xPan || 0, half: this._lastHalf || ((this.spot || 100) * 0.22), pw };
|
|
||||||
e.preventDefault();
|
|
||||||
},
|
|
||||||
onPan(e) {
|
|
||||||
if (!this._drag) return;
|
|
||||||
const dx = e.clientX - this._drag.x; // drag right -> show lower prices
|
|
||||||
this.xPan = this._drag.pan - (dx / this._drag.pw) * (2 * this._drag.half);
|
|
||||||
this.scheduleRender();
|
|
||||||
},
|
|
||||||
endPan() { if (this._drag) this._drag = null; },
|
|
||||||
|
|
||||||
renderChart() {
|
renderChart() {
|
||||||
const legs = this.activeLegs, net = this.netCost;
|
const legs = this.activeLegs, net = this.netCost;
|
||||||
@@ -711,11 +697,6 @@
|
|||||||
this.chart = new ApexCharts(document.getElementById('plChart'), opts);
|
this.chart = new ApexCharts(document.getElementById('plChart'), opts);
|
||||||
this.chart.render();
|
this.chart.render();
|
||||||
}
|
}
|
||||||
// remember the plot-area width for drag-to-pan math
|
|
||||||
try {
|
|
||||||
const gw = this.chart && this.chart.w && this.chart.w.globals && this.chart.w.globals.gridWidth;
|
|
||||||
this._lastPlotW = (gw && gw > 50) ? gw : ((document.getElementById('plChart')?.clientWidth || 600) - 70);
|
|
||||||
} catch {}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
fmtMoney,
|
fmtMoney,
|
||||||
|
|||||||
Reference in New Issue
Block a user