lit-litelements 2.2.3 → 2.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,23 +23,13 @@ declare class ChartElement extends LitElement {
23
23
  chart: Chart | null;
24
24
  constructor();
25
25
  firstUpdated(): void;
26
+ _resetZoom(): void;
26
27
  willUpdate(changedProperties: {
27
28
  has: (arg0: string) => any;
28
29
  }): Promise<void>;
29
30
  customLinePlugin: {
30
31
  id: string;
31
- afterDraw: (chart: {
32
- tooltip: {
33
- _active: string | any[];
34
- };
35
- ctx: any;
36
- scales: {
37
- yPrice: {
38
- top: any;
39
- bottom: any;
40
- };
41
- };
42
- }) => void;
32
+ afterDraw: (chart: any) => void;
43
33
  };
44
34
  _getChartData(): {
45
35
  dates: string[];
@@ -18,6 +18,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
18
18
  };
19
19
  import { LitElement, html } from "lit";
20
20
  import Chart from "chart.js/auto";
21
+ import zoomPlugin from "chartjs-plugin-zoom";
21
22
  import { customElement, property } from "lit/decorators.js";
22
23
  let ChartElement = class ChartElement extends LitElement {
23
24
  constructor() {
@@ -27,24 +28,101 @@ let ChartElement = class ChartElement extends LitElement {
27
28
  // Define the custom plugin
28
29
  this.customLinePlugin = {
29
30
  id: "customLinePlugin",
30
- afterDraw: function (chart) {
31
- // Check if tooltip is defined and active
32
- if (chart.tooltip &&
33
- chart.tooltip._active &&
34
- chart.tooltip._active.length) {
35
- const ctx = chart.ctx;
36
- const activePoint = chart.tooltip._active[0];
37
- const x = activePoint.element.x;
38
- const topY = chart.scales.yPrice.top;
39
- const bottomY = chart.scales.yPrice.bottom;
40
- ctx.save();
41
- ctx.beginPath();
42
- ctx.moveTo(x, topY);
43
- ctx.lineTo(x, bottomY);
44
- ctx.lineWidth = 1;
45
- ctx.strokeStyle = "rgba(0, 0, 0, 0.5)";
46
- ctx.stroke();
47
- ctx.restore();
31
+ afterDraw: (chart) => {
32
+ const ctx = chart.ctx;
33
+ const { chartArea, scales, data } = chart;
34
+ const rsiDataset = chart.data.datasets.find((ds) => ds.label === "RSI");
35
+ const closeDataset = data.datasets.find((ds) => ds.label === "Close Price");
36
+ const ma200Dataset = data.datasets.find((ds) => ds.label === "MA200");
37
+ if (!rsiDataset || !closeDataset || !ma200Dataset)
38
+ return;
39
+ const rsiData = rsiDataset.data;
40
+ const closeData = closeDataset.data;
41
+ const ma200Data = ma200Dataset.data;
42
+ const RISK_PERCENT = 0.01;
43
+ const REWARD_RATIO = 2;
44
+ for (let i = 1; i < closeData.length; i++) {
45
+ //base on rsi
46
+ const rsiValue = rsiData[i];
47
+ if (rsiValue !== null && rsiValue < 30) {
48
+ const x = scales.x.getPixelForValue(i);
49
+ const y = scales.yRSI.getPixelForValue(rsiValue);
50
+ ctx.beginPath();
51
+ ctx.arc(x, y, 4, 0, 2 * Math.PI);
52
+ ctx.fillStyle = "green";
53
+ ctx.fill();
54
+ ctx.fillStyle = "green";
55
+ ctx.font = "bold 12px sans-serif";
56
+ ctx.fillText("Buy", x + 6, y - 6);
57
+ }
58
+ else if (rsiValue !== null && rsiValue > 70) {
59
+ const x = scales.x.getPixelForValue(i);
60
+ const y = scales.yRSI.getPixelForValue(rsiValue);
61
+ ctx.beginPath();
62
+ ctx.arc(x, y, 4, 0, 2 * Math.PI);
63
+ ctx.fillStyle = "red";
64
+ ctx.fill();
65
+ ctx.fillStyle = "red";
66
+ ctx.font = "bold 12px sans-serif";
67
+ ctx.fillText("Sell", x + 6, y - 6);
68
+ }
69
+ // Add MA200 bullish/bearish crossover signals
70
+ const prevClose = closeData[i - 1];
71
+ const prevMA200 = ma200Data[i - 1];
72
+ const currClose = closeData[i];
73
+ const currMA200 = ma200Data[i];
74
+ if (prevClose == null ||
75
+ prevMA200 == null ||
76
+ currClose == null ||
77
+ currMA200 == null)
78
+ continue;
79
+ const x = scales.x.getPixelForValue(i);
80
+ const y = scales.yPrice.getPixelForValue(currClose);
81
+ if (currClose > currMA200 && prevClose < prevMA200) {
82
+ ctx.beginPath();
83
+ ctx.arc(x, y, 4, 0, 2 * Math.PI);
84
+ ctx.fillStyle = "green";
85
+ ctx.fill();
86
+ ctx.fillStyle = "green";
87
+ ctx.font = "bold 12px sans-serif";
88
+ ctx.fillText("Bull", x + 6, y - 6);
89
+ const stop = currClose * (1 - RISK_PERCENT);
90
+ const target = currClose + (currClose - stop) * REWARD_RATIO;
91
+ const yStop = scales.yPrice.getPixelForValue(stop);
92
+ const yTarget = scales.yPrice.getPixelForValue(target);
93
+ // Stop-Loss (SL) line
94
+ ctx.fillStyle = "red";
95
+ ctx.fillRect(x, yStop, 100, 1); // 100px wide, 1px high
96
+ ctx.font = "bold 12px sans-serif";
97
+ ctx.fillText("SL " + stop.toFixed(2), x + 12, yStop - 4);
98
+ // Take-Profit (TP) line
99
+ ctx.fillStyle = "green";
100
+ ctx.fillRect(x, yTarget, 100, 1); // 100px wide, 1px high
101
+ ctx.fillText("TP " + target.toFixed(2), x + 12, yTarget - 4);
102
+ }
103
+ else if (currClose < currMA200 && prevClose > prevMA200) {
104
+ ctx.beginPath();
105
+ ctx.arc(x, y, 4, 0, 2 * Math.PI);
106
+ ctx.fillStyle = "purple";
107
+ ctx.fill();
108
+ ctx.fillStyle = "purple";
109
+ ctx.font = "bold 12px sans-serif";
110
+ ctx.fillText("Bear", x + 6, y - 6);
111
+ const stop = currClose * (1 + RISK_PERCENT);
112
+ const target = currClose - (stop - currClose) * REWARD_RATIO;
113
+ const yStop = scales.yPrice.getPixelForValue(stop);
114
+ const yTarget = scales.yPrice.getPixelForValue(target);
115
+ // // Stop-Loss (SL) line
116
+ // ctx.fillStyle = "purple";
117
+ // ctx.fillRect(x, yStop, 100, 1); // 100px wide, 1px high
118
+ // ctx.font = "bold 12px sans-serif";
119
+ // ctx.fillText("BEAR-SL", x + 12, yStop - 4);
120
+ // // Take-Profit (TP) line
121
+ // ctx.fillStyle = "purple";
122
+ // ctx.fillRect(x, yTarget, 100, 1); // 100px wide, 1px high
123
+ // ctx.fillText("BEAR-TP", x + 12, yTarget - 4);
124
+ }
125
+ ctx.setLineDash([]);
48
126
  }
49
127
  },
50
128
  };
@@ -54,6 +132,10 @@ let ChartElement = class ChartElement extends LitElement {
54
132
  firstUpdated() {
55
133
  this._createChart();
56
134
  }
135
+ _resetZoom() {
136
+ var _a;
137
+ (_a = this.chart) === null || _a === void 0 ? void 0 : _a.resetZoom();
138
+ }
57
139
  willUpdate(changedProperties) {
58
140
  return __awaiter(this, void 0, void 0, function* () {
59
141
  if (changedProperties.has("stockData")) {
@@ -86,7 +168,7 @@ let ChartElement = class ChartElement extends LitElement {
86
168
  }
87
169
  _updateChart() {
88
170
  if (this.chart) {
89
- const { dates, closePrices, ma5, ma10, ma20, ma50, ma100, ma200, RSI, MACDLine, SignalLine, MACDHistogram, volumes } = this._getChartData();
171
+ const { dates, closePrices, ma5, ma10, ma20, ma50, ma100, ma200, RSI, MACDLine, SignalLine, MACDHistogram, volumes, } = this._getChartData();
90
172
  // Update labels (dates)
91
173
  this.chart.data.labels = dates;
92
174
  // Update each dataset
@@ -109,7 +191,7 @@ let ChartElement = class ChartElement extends LitElement {
109
191
  // This will handle creating the Chart.js chart
110
192
  _createChart() {
111
193
  var _a;
112
- const { dates, closePrices, ma5, ma10, ma20, ma50, ma100, ma200, RSI, MACDLine, SignalLine, MACDHistogram, volumes } = this._getChartData();
194
+ const { dates, closePrices, ma5, ma10, ma20, ma50, ma100, ma200, RSI, MACDLine, SignalLine, MACDHistogram, volumes, } = this._getChartData();
113
195
  const canvas = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.getElementById("stockChart");
114
196
  if (!canvas) {
115
197
  return;
@@ -123,6 +205,7 @@ let ChartElement = class ChartElement extends LitElement {
123
205
  }
124
206
  // Register the custom plugin
125
207
  Chart.register(this.customLinePlugin);
208
+ Chart.register(zoomPlugin);
126
209
  this.chart = new Chart(ctx, {
127
210
  type: "line",
128
211
  data: {
@@ -272,14 +355,14 @@ let ChartElement = class ChartElement extends LitElement {
272
355
  ticks: {
273
356
  color: (ctx) => {
274
357
  const label = ctx.tick.label;
275
- if (typeof label === 'string') {
358
+ if (typeof label === "string") {
276
359
  const labelDate = new Date(label).toISOString().split("T")[0];
277
360
  const todayStr = new Date().toISOString().split("T")[0];
278
361
  return labelDate === todayStr ? "Salmon" : "black";
279
362
  }
280
363
  return "black"; // default fallback
281
- }
282
- }
364
+ },
365
+ },
283
366
  },
284
367
  yPrice: {
285
368
  type: "linear",
@@ -312,12 +395,34 @@ let ChartElement = class ChartElement extends LitElement {
312
395
  interaction: { mode: "index", intersect: false },
313
396
  plugins: {
314
397
  tooltip: { mode: "index", axis: "x" },
398
+ zoom: {
399
+ pan: {
400
+ enabled: true,
401
+ mode: "xy",
402
+ modifierKey: undefined, // Optional: only pan while holding Ctrl
403
+ },
404
+ zoom: {
405
+ wheel: {
406
+ enabled: true,
407
+ },
408
+ pinch: {
409
+ enabled: true,
410
+ },
411
+ mode: "x",
412
+ },
413
+ limits: {
414
+ x: { minRange: 10 }, // prevent zooming too far
415
+ },
416
+ },
315
417
  },
316
418
  },
317
419
  });
318
420
  }
319
421
  render() {
320
- return html `<canvas id="stockChart"></canvas>`;
422
+ return html `
423
+ <button @click="${this._resetZoom}">Reset Zoom</button>
424
+ <canvas id="stockChart"></canvas>
425
+ `;
321
426
  }
322
427
  };
323
428
  __decorate([