UNPKG

lwc-plugin-min-max-price-markers

Version:
294 lines (293 loc) 11 kB
var b = Object.defineProperty; var x = (i, t, e) => t in i ? b(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e; var a = (i, t, e) => (x(i, typeof t != "symbol" ? t + "" : t, e), e); import { MismatchDirection as w } from "lightweight-charts"; const z = (i, ...t) => { for (const e of t) for (const s in e) e[s] === void 0 || !Object.prototype.hasOwnProperty.call(e, s) || ["__proto__", "constructor", "prototype"].includes(s) || (typeof e[s] != "object" || i[s] === void 0 || Array.isArray(e[s]) ? i[s] = e[s] : g(i[s], e[s])); return i; }, g = (i, ...t) => z(i, ...t), T = (i) => "value" in i && typeof i.value == "number", C = (i) => "open" in i && "high" in i && "low" in i && "close" in i, R = "-apple-system, BlinkMacSystemFont, 'Trebuchet MS', Roboto, Ubuntu, sans-serif", v = (i) => { const { fontSize: t } = i; let { fontStyle: e, fontFamily: s } = i; return e !== void 0 ? e = `${e} ` : e = "", s || (s = R), `${e}${t}px ${s}`; }, V = /[2-9]/g; class O { // -------------------------------------------------- constructor(t = 50) { a(this, "_maxSize"); a(this, "_actualSize", 0); a(this, "_usageTick", 1); a(this, "_oldestTick", 1); a(this, "_tick2Labels", {}); a(this, "_cache", /* @__PURE__ */ new Map()); this._maxSize = t; } // -------------------------------------------------- reset() { this._actualSize = 0, this._cache.clear(), this._usageTick = 1, this._oldestTick = 1, this._tick2Labels = {}; } // -------------------------------------------------- measureText(t, e, s) { return this._getMetrics(t, e, s).width; } // -------------------------------------------------- yMidCorrection(t, e, s) { const r = this._getMetrics(t, e, s); return ((r.actualBoundingBoxAscent || 0) - (r.actualBoundingBoxDescent || 0)) / 2; } // -------------------------------------------------- _getMetrics(t, e, s) { const r = s || V, o = String(e).replace(r, "0"); if (this._cache.has(o)) return this._cache.get(o).metrics; if (this._actualSize === this._maxSize) { const _ = this._tick2Labels[this._oldestTick]; delete this._tick2Labels[this._oldestTick], this._cache.delete(_), this._oldestTick++, this._actualSize--; } t.save(), t.textBaseline = "middle"; const n = t.measureText(o); return t.restore(), n.width === 0 && e.length || (this._cache.set(o, { metrics: n, tick: this._usageTick }), this._tick2Labels[this._usageTick] = o, this._actualSize++, this._usageTick++), n; } } const m = { textColor: "#000", zOrder: "aboveSeries" }, S = 10, y = 4 + S; class F { constructor() { a(this, "_data", null); a(this, "_textWidthCache", new O()); a(this, "_fontSize", 10); a(this, "_fontFamily", "Roboto, sans-serif"); a(this, "_font", v({ fontSize: this._fontSize, fontFamily: this._fontFamily })); a(this, "_zOrder", "normal"); } // -------------------------------------------------- setData(t) { this._data = t; } // -------------------------------------------------- setParams(t) { const { fontSize: e, fontFamily: s, zOrder: r } = t; (this._fontSize !== e || this._fontFamily !== s) && (this._fontSize = e, this._fontFamily = s, this._font = v({ fontSize: this._fontSize, fontFamily: this._fontFamily }), this._textWidthCache.reset()), this._zOrder = r; } // -------------------------------------------------- draw(t) { this._zOrder !== "aboveSeries" && t.useBitmapCoordinateSpace((e) => { this._drawImpl(e); }); } // -------------------------------------------------- drawBackground(t) { this._zOrder === "aboveSeries" && t.useBitmapCoordinateSpace( (e) => { this._drawImpl(e); } ); } // -------------------------------------------------- _drawImpl(t) { const { context: e, horizontalPixelRatio: s, verticalPixelRatio: r } = t; if (this._data !== null) { e.textBaseline = "middle", e.font = this._font; for (let o = 0; o < this._data.length; o++) { const n = this._data[o]; n.text && (n.text.width = this._textWidthCache.measureText( e, n.text.content ), n.text.height = this._fontSize, n.text.x = n.variant === "left" ? n.x - n.text.width - y : n.x + y, I(n, e, s, r)); } } } } const I = (i, t, e, s) => { i.text && (t.fillStyle = i.color, L( t, i.text.content, i.text.x, i.text.y, e, s ), t.strokeStyle = i.color, q( i.variant === "left", t, M(i, e, s) )); }, M = (i, t, e) => ({ x: Math.round(i.x * t), y: i.y * e, pixelRatio: t }), q = (i, t, e) => { const s = e.x, r = e.y; t.beginPath(), t.lineWidth = 1 * e.pixelRatio, i ? (t.moveTo(s, r), t.lineTo(s - S, r)) : (t.moveTo(s, r), t.lineTo(s + S, r)), t.stroke(); }, L = (i, t, e, s, r, o) => { i.save(), i.scale(r, o), i.fillText(t, e, s), i.restore(); }; class B { // -------------------------------------------------- constructor(t) { a(this, "_chart"); a(this, "_series"); a(this, "_data", []); a(this, "_options"); a(this, "_invalidated", !0); a(this, "_dataInvalidated", !0); a(this, "_markers", []); a(this, "_renderer", new F()); this._chart = t.chart, this._series = t.series, this._options = t.options, this._data = []; } // -------------------------------------------------- renderer() { if (!this._series.options().visible) return null; this._invalidated && this._makeValid(); const t = this._chart.options().layout; return this._renderer.setParams({ fontSize: t.fontSize, fontFamily: t.fontFamily, zOrder: this._options.zOrder }), this._renderer.setData(this._data), this._renderer; } // -------------------------------------------------- setMarkers(t) { this._markers = t.markers, this.update("data"); } // -------------------------------------------------- update(t) { this._invalidated = !0, t === "data" && (this._dataInvalidated = !0); } // -------------------------------------------------- updateOptions(t) { this._invalidated = !0, this._options = t; } // -------------------------------------------------- zOrder() { return this._options.zOrder === "aboveSeries" ? "top" : this._options.zOrder; } // -------------------------------------------------- _makeValid() { const t = this._chart.timeScale(), e = this._markers; if (e != null && e.length && (this._dataInvalidated && (this._data = e.map((s) => ({ time: s.time, x: 0, y: 0, color: this._options.textColor, text: void 0, variant: s.variant })), this._dataInvalidated = !1), !!this._data.length)) { for (let s = 0; s < this._data.length; s++) { const r = this._data[s], n = this._markers[s].price, _ = this._series.dataByIndex( r.time, w.None ), l = this._series.priceToCoordinate(n); !_ || !l || (r.x = t.logicalToCoordinate( r.time ), r.y = l, r.text = { content: `${this._series.priceFormatter().format(n)}`, x: 0, y: l, width: 0, height: 0 }); } this._invalidated = !1; } } } class P { // -------------------------------------------------- constructor(t) { a(this, "_paneView", null); a(this, "_chart", null); a(this, "_series", null); a(this, "_requestUpdate"); a(this, "_recalculationRequired", !0); a(this, "_markers", []); a(this, "_options", m); // -------------------------------------------------- a(this, "_dataChangedHandler", (t) => this._onDataChanged(t)); // -------------------------------------------------- a(this, "_visibleRangeChanged", (t) => this._onVisibleRangeChanged(t)); this._options = t != null && t.options ? g(m, t.options) : m; } // -------------------------------------------------- applyOptions(t) { this._options = g(this._options, t); } // -------------------------------------------------- attached(t) { this._recalculateMarkers(), this._chart = t.chart, this._series = t.series, this._paneView = new B({ series: this._series, chart: this._chart, options: this._options }), this._requestUpdate = t.requestUpdate, this._recalculationRequired = !0, this.requestUpdate(), this._series.subscribeDataChanged(this._dataChangedHandler), this._chart.timeScale().subscribeVisibleLogicalRangeChange(this._visibleRangeChanged); } // -------------------------------------------------- requestUpdate() { this._requestUpdate && this._requestUpdate(); } // -------------------------------------------------- detached() { var t, e; (t = this._chart) == null || t.timeScale().unsubscribeVisibleLogicalRangeChange(this._visibleRangeChanged), (e = this._series) == null || e.unsubscribeDataChanged(this._dataChangedHandler), this._requestUpdate = void 0, this._markers = [], this._paneView = null, this._series = null, this._chart = null; } // -------------------------------------------------- paneViews() { return this._paneView ? [this._paneView] : []; } // -------------------------------------------------- updateAllViews() { this._paneView && (this._recalculateMarkers(), this._paneView.setMarkers({ markers: this._markers }), this._paneView.updateOptions(this._options), this._paneView.update()); } // -------------------------------------------------- _onDataChanged(t) { !this._chart || !this._series || (this._recalculationRequired = !0, this.requestUpdate()); } // -------------------------------------------------- _onVisibleRangeChanged(t) { !this._chart || !this._series || !t || (this._recalculationRequired = !0, this.requestUpdate()); } // -------------------------------------------------- _recalculateMarkers() { if (!this._recalculationRequired || !this._chart || !this._series) return; this._markers = []; const t = this._chart.timeScale(), e = this._series.data(), s = t.getVisibleLogicalRange(); if (!s || !e.length) return; const r = this._series.barsInLogicalRange(s); if (!r) return; const o = r.from, n = r.to; if (!o || !n) return; const _ = e.length; let l = -1 / 0, d = null, u = 1 / 0, f = null; for (let p = 0; p < _; p++) { const h = e[p], c = h.time; c < o || c > n || (C(h) ? (h.high > l && (l = h.high, d = c), h.low < u && (u = h.low, f = c)) : T(h) && (h.value > l && (l = h.value, d = c), h.value < u && (u = h.value, f = c))); } if (!d || !f) return; const k = f > d; this._markers.push({ time: t.timeToIndex(d, !0), price: l, variant: k ? "right" : "left" }), this._markers.push({ time: t.timeToIndex(f, !0), price: u, variant: k ? "left" : "right" }), this._recalculationRequired = !1; } } export { P as MinMaxPriceMarkers };