lit-litelements 2.2.7 → 2.2.9

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.
@@ -16,19 +16,16 @@ interface StockData {
16
16
  RSI?: number;
17
17
  MACDLine?: number;
18
18
  SignalLine?: any;
19
- MACDHistogram?: any;
19
+ divergence?: any;
20
20
  }
21
21
  declare class ChartElement extends LitElement {
22
22
  stockData: StockData[];
23
23
  zoomEnabled: boolean;
24
24
  chart: Chart | null;
25
- constructor();
26
25
  firstUpdated(): void;
27
26
  _resetZoom(): void;
28
27
  _Zoomenalbe(): void;
29
- willUpdate(changedProperties: {
30
- has: (arg0: string) => any;
31
- }): Promise<void>;
28
+ willUpdate(changed: Map<string, any>): Promise<void>;
32
29
  customLinePlugin: {
33
30
  id: string;
34
31
  afterDraw: (chart: any) => void;
@@ -36,16 +33,16 @@ declare class ChartElement extends LitElement {
36
33
  _getChartData(): {
37
34
  dates: string[];
38
35
  closePrices: number[];
36
+ rsi: number[];
39
37
  ma5: number[];
40
38
  ma10: number[];
41
39
  ma20: number[];
42
40
  ma50: number[];
43
41
  ma100: number[];
44
42
  ma200: number[];
45
- RSI: number[];
46
43
  MACDLine: number[];
47
44
  SignalLine: any[];
48
- MACDHistogram: any[];
45
+ divergence: any[];
49
46
  volumes: number[];
50
47
  };
51
48
  _updateChart(): void;
@@ -22,11 +22,13 @@ import zoomPlugin from "chartjs-plugin-zoom";
22
22
  import { customElement, property } from "lit/decorators.js";
23
23
  let ChartElement = class ChartElement extends LitElement {
24
24
  constructor() {
25
- super();
25
+ super(...arguments);
26
26
  this.stockData = [];
27
27
  this.zoomEnabled = false;
28
28
  this.chart = null;
29
- // Define the custom plugin
29
+ // --------------------------------------------------------------------
30
+ // CUSTOM SIGNAL PLUGIN (RSI + MA200 + SL/TP)
31
+ // --------------------------------------------------------------------
30
32
  this.customLinePlugin = {
31
33
  id: "customLinePlugin",
32
34
  afterDraw: (chart) => {
@@ -54,7 +56,7 @@ let ChartElement = class ChartElement extends LitElement {
54
56
  ctx.fill();
55
57
  ctx.fillStyle = "green";
56
58
  ctx.font = "bold 12px sans-serif";
57
- ctx.fillText("Buy", x + 6, y - 6);
59
+ ctx.fillText("Buy_rsi", x + 6, y - 6);
58
60
  }
59
61
  else if (rsiValue !== null && rsiValue > 70) {
60
62
  const x = scales.x.getPixelForValue(i);
@@ -65,7 +67,7 @@ let ChartElement = class ChartElement extends LitElement {
65
67
  ctx.fill();
66
68
  ctx.fillStyle = "red";
67
69
  ctx.font = "bold 12px sans-serif";
68
- ctx.fillText("Sell", x + 6, y - 6);
70
+ ctx.fillText("Sell_rsi", x + 6, y - 6);
69
71
  }
70
72
  // Add MA200 bullish/bearish crossover signals
71
73
  const prevClose = closeData[i - 1];
@@ -116,9 +118,7 @@ let ChartElement = class ChartElement extends LitElement {
116
118
  }
117
119
  },
118
120
  };
119
- this.stockData = [];
120
121
  }
121
- // First updated is called after the element has been rendered into the DOM
122
122
  firstUpdated() {
123
123
  this._createChart();
124
124
  }
@@ -128,89 +128,84 @@ let ChartElement = class ChartElement extends LitElement {
128
128
  }
129
129
  _Zoomenalbe() {
130
130
  var _a, _b, _c, _d;
131
- if ((_b = (_a = this.chart) === null || _a === void 0 ? void 0 : _a.options.plugins) === null || _b === void 0 ? void 0 : _b.zoom) {
132
- const zoomOptions = this.chart.options.plugins.zoom;
133
- const newState = !this.zoomEnabled;
134
- if ((_c = zoomOptions.zoom) === null || _c === void 0 ? void 0 : _c.wheel)
135
- zoomOptions.zoom.wheel.enabled = newState;
136
- if ((_d = zoomOptions.zoom) === null || _d === void 0 ? void 0 : _d.pinch)
137
- zoomOptions.zoom.pinch.enabled = newState;
138
- if (zoomOptions.pan)
139
- zoomOptions.pan.enabled = newState;
140
- this.zoomEnabled = newState;
141
- this.chart.update();
142
- }
131
+ if (!((_b = (_a = this.chart) === null || _a === void 0 ? void 0 : _a.options.plugins) === null || _b === void 0 ? void 0 : _b.zoom))
132
+ return;
133
+ const zoomOptions = this.chart.options.plugins.zoom;
134
+ const newState = !this.zoomEnabled;
135
+ if ((_c = zoomOptions.zoom) === null || _c === void 0 ? void 0 : _c.wheel)
136
+ zoomOptions.zoom.wheel.enabled = newState;
137
+ if ((_d = zoomOptions.zoom) === null || _d === void 0 ? void 0 : _d.pinch)
138
+ zoomOptions.zoom.pinch.enabled = newState;
139
+ if (zoomOptions.pan)
140
+ zoomOptions.pan.enabled = newState;
141
+ this.zoomEnabled = newState;
142
+ this.chart.update();
143
143
  }
144
- willUpdate(changedProperties) {
144
+ willUpdate(changed) {
145
145
  return __awaiter(this, void 0, void 0, function* () {
146
- if (changedProperties.has("stockData")) {
147
- if (!this.chart) {
148
- this._createChart(); // Ensure the chart is created
149
- }
150
- else {
151
- this._updateChart(); // Update the chart if it exists
152
- }
146
+ if (changed.has("stockData")) {
147
+ this.chart ? this._updateChart() : this._createChart();
153
148
  }
154
149
  });
155
150
  }
151
+ // --------------------------------------------------------------------
152
+ // Data extraction
153
+ // --------------------------------------------------------------------
156
154
  _getChartData() {
157
- const data = {
158
- dates: this.stockData.map((data) => data.date),
159
- closePrices: this.stockData.map((data) => data.close),
160
- ma5: this.stockData.map((data) => { var _a; return (_a = data.MA5) !== null && _a !== void 0 ? _a : null; }),
161
- ma10: this.stockData.map((data) => { var _a; return (_a = data.MA10) !== null && _a !== void 0 ? _a : null; }),
162
- ma20: this.stockData.map((data) => { var _a; return (_a = data.MA20) !== null && _a !== void 0 ? _a : null; }),
163
- ma50: this.stockData.map((data) => { var _a; return (_a = data.MA50) !== null && _a !== void 0 ? _a : null; }),
164
- ma100: this.stockData.map((data) => { var _a; return (_a = data.MA100) !== null && _a !== void 0 ? _a : null; }),
165
- ma200: this.stockData.map((data) => { var _a; return (_a = data.MA200) !== null && _a !== void 0 ? _a : null; }),
166
- RSI: this.stockData.map((data) => { var _a; return (_a = data.RSI) !== null && _a !== void 0 ? _a : null; }),
167
- MACDLine: this.stockData.map((data) => { var _a; return (_a = data.MACDLine) !== null && _a !== void 0 ? _a : null; }),
168
- SignalLine: this.stockData.map((data) => { var _a; return (_a = data.SignalLine) !== null && _a !== void 0 ? _a : null; }),
169
- MACDHistogram: this.stockData.map((data) => { var _a; return (_a = data.MACDHistogram) !== null && _a !== void 0 ? _a : null; }),
170
- volumes: this.stockData.map((data) => { var _a; return (_a = data.volume) !== null && _a !== void 0 ? _a : 0; }), // Volume data
155
+ return {
156
+ dates: this.stockData.map((d) => d.date),
157
+ closePrices: this.stockData.map((d) => d.close),
158
+ rsi: this.stockData.map((d) => { var _a; return (_a = d.RSI) !== null && _a !== void 0 ? _a : null; }),
159
+ ma5: this.stockData.map((d) => { var _a; return (_a = d.MA5) !== null && _a !== void 0 ? _a : null; }),
160
+ ma10: this.stockData.map((d) => { var _a; return (_a = d.MA10) !== null && _a !== void 0 ? _a : null; }),
161
+ ma20: this.stockData.map((d) => { var _a; return (_a = d.MA20) !== null && _a !== void 0 ? _a : null; }),
162
+ ma50: this.stockData.map((d) => { var _a; return (_a = d.MA50) !== null && _a !== void 0 ? _a : null; }),
163
+ ma100: this.stockData.map((d) => { var _a; return (_a = d.MA100) !== null && _a !== void 0 ? _a : null; }),
164
+ ma200: this.stockData.map((d) => { var _a; return (_a = d.MA200) !== null && _a !== void 0 ? _a : null; }),
165
+ MACDLine: this.stockData.map((d) => { var _a; return (_a = d.MACDLine) !== null && _a !== void 0 ? _a : null; }),
166
+ SignalLine: this.stockData.map((d) => { var _a; return (_a = d.SignalLine) !== null && _a !== void 0 ? _a : null; }),
167
+ divergence: this.stockData.map((d) => { var _a; return (_a = d.divergence) !== null && _a !== void 0 ? _a : null; }),
168
+ volumes: this.stockData.map((d) => { var _a; return (_a = d.volume) !== null && _a !== void 0 ? _a : 0; }),
171
169
  };
172
- return data;
173
170
  }
171
+ // --------------------------------------------------------------------
172
+ // Update
173
+ // --------------------------------------------------------------------
174
174
  _updateChart() {
175
- if (this.chart) {
176
- const { dates, closePrices, ma5, ma10, ma20, ma50, ma100, ma200, RSI, MACDLine, SignalLine, MACDHistogram, volumes, } = this._getChartData();
177
- // Update labels (dates)
178
- this.chart.data.labels = dates;
179
- // Update each dataset
180
- this.chart.data.datasets[0].data = RSI; // RSI
181
- this.chart.data.datasets[1].data = MACDHistogram; // MACDHistogram
182
- this.chart.data.datasets[2].data = SignalLine; // SignalLine
183
- this.chart.data.datasets[3].data = MACDLine; // MACDLine
184
- this.chart.data.datasets[4].data = closePrices; // Close Price
185
- this.chart.data.datasets[5].data = ma20; // MA20
186
- this.chart.data.datasets[6].data = ma50; // MA50
187
- this.chart.data.datasets[7].data = ma100; // MA50
188
- this.chart.data.datasets[8].data = ma200; // MA200
189
- this.chart.data.datasets[9].data = volumes; // Volume
190
- this.chart.data.datasets[10].data = ma10; // Volume
191
- this.chart.data.datasets[11].data = ma5; // Volume
192
- // Trigger chart update
193
- this.chart.update();
194
- }
175
+ if (!this.chart)
176
+ return;
177
+ const { dates, closePrices, rsi, ma5, ma10, ma20, ma50, ma100, ma200, MACDLine, SignalLine, divergence, volumes, } = this._getChartData();
178
+ this.chart.data.labels = dates;
179
+ const ds = this.chart.data.datasets;
180
+ ds[0].data = rsi;
181
+ ds[1].data = divergence;
182
+ ds[2].data = MACDLine;
183
+ ds[3].data = SignalLine;
184
+ ds[4].data = closePrices;
185
+ ds[5].data = ma20;
186
+ ds[6].data = ma50;
187
+ ds[7].data = ma100;
188
+ ds[8].data = ma200;
189
+ ds[9].data = ma10;
190
+ ds[10].data = ma5;
191
+ ds[11].data = volumes;
192
+ this.chart.update();
195
193
  }
196
- // This will handle creating the Chart.js chart
194
+ // --------------------------------------------------------------------
195
+ // Create Chart
196
+ // --------------------------------------------------------------------
197
197
  _createChart() {
198
198
  var _a;
199
- const { dates, closePrices, ma5, ma10, ma20, ma50, ma100, ma200, RSI, MACDLine, SignalLine, MACDHistogram, volumes, } = this._getChartData();
199
+ const { dates, closePrices, rsi, ma5, ma10, ma20, ma50, ma100, ma200, MACDLine, SignalLine, divergence, volumes, } = this._getChartData();
200
200
  const canvas = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.getElementById("stockChart");
201
- if (!canvas) {
201
+ if (!canvas)
202
202
  return;
203
- }
204
203
  const ctx = canvas.getContext("2d");
205
- if (!ctx) {
206
- return;
207
- }
208
- if (this.chart) {
209
- this.chart.destroy(); // Destroy existing chart if necessary
210
- }
211
- // Register the custom plugin
212
- Chart.register(this.customLinePlugin);
204
+ if (this.chart)
205
+ this.chart.destroy();
206
+ // Register plugins
213
207
  Chart.register(zoomPlugin);
208
+ Chart.register(this.customLinePlugin);
214
209
  this.chart = new Chart(ctx, {
215
210
  type: "line",
216
211
  data: {
@@ -218,213 +213,154 @@ let ChartElement = class ChartElement extends LitElement {
218
213
  datasets: [
219
214
  {
220
215
  label: "RSI",
221
- data: RSI,
222
- borderColor: "rgba(15, 92, 92, 1)",
223
- backgroundColor: "rgba(15, 92, 92, 0.2)",
224
- fill: false,
225
- borderWidth: 2,
216
+ data: rsi,
226
217
  yAxisID: "yRSI",
227
- pointRadius: 1,
228
- pointHoverRadius: 3,
229
- hidden: true,
218
+ borderColor: "rgba(61, 58, 215, 0.2)",
219
+ borderWidth: 1,
220
+ pointRadius: 0,
230
221
  },
231
222
  {
232
- label: "MACDHistogram",
233
- data: MACDHistogram,
234
- borderColor: "rgba(175, 92, 92, 1)",
235
- backgroundColor: "rgba(175, 92, 92, 0.2)",
236
- fill: false,
237
- borderWidth: 2,
223
+ label: "MACD Histogram",
224
+ data: divergence,
225
+ type: "bar",
238
226
  yAxisID: "yMACD",
239
- hidden: true,
240
- pointRadius: 1,
241
- pointHoverRadius: 3,
227
+ backgroundColor: (ctx) => ctx.raw >= 0 ? "rgba(9, 225, 9, 0.4)" : "rgba(227, 5, 5, 0.4)",
242
228
  },
243
229
  {
244
- label: "SignalLine",
245
- data: SignalLine,
246
- borderColor: "rgba(75, 92, 192, 1)",
247
- backgroundColor: "rgba(75, 92, 192, 0.2)",
248
- fill: false,
249
- borderWidth: 1,
230
+ label: "MACD Line",
231
+ data: MACDLine,
232
+ borderColor: "blue",
250
233
  yAxisID: "yMACD",
251
- hidden: true,
252
- pointRadius: 1,
253
- pointHoverRadius: 3,
234
+ borderWidth: 1.2,
235
+ fill: false,
236
+ pointRadius: 0,
254
237
  },
255
238
  {
256
- label: "MACDLine",
257
- data: MACDLine,
258
- borderColor: "rgba(175, 192, 192, 1)",
259
- backgroundColor: "rgba(175, 192, 192, 0.2)",
260
- fill: false,
261
- borderWidth: 1,
239
+ label: "Signal Line",
240
+ data: SignalLine,
241
+ borderColor: "orange",
262
242
  yAxisID: "yMACD",
263
- hidden: true,
264
- pointRadius: 1,
265
- pointHoverRadius: 3,
243
+ borderWidth: 1.2,
244
+ fill: false,
245
+ pointRadius: 0,
266
246
  },
247
+ // Price section (middle)
267
248
  {
268
249
  label: "Close Price",
269
250
  data: closePrices,
270
- borderColor: "rgba(75, 192, 192, 1)",
271
- backgroundColor: "rgba(75, 192, 192, 0.2)",
272
- fill: true,
273
- borderWidth: 1,
274
251
  yAxisID: "yPrice",
275
- pointRadius: 1,
276
- pointHoverRadius: 3,
252
+ borderColor: "rgba(75,192,192,1)",
253
+ backgroundColor: "rgba(75,192,192,0.2)",
254
+ fill: true,
255
+ pointRadius: 0,
277
256
  },
278
257
  {
279
258
  label: "MA20",
280
259
  data: ma20,
281
- borderColor: "rgba(255, 99, 132, 1)",
282
- backgroundColor: "rgba(255, 99, 132, 0.2)",
283
- fill: false,
284
- borderWidth: 2,
285
260
  yAxisID: "yPrice",
286
- pointRadius: 1,
287
- pointHoverRadius: 3,
261
+ borderColor: "#ff6384",
262
+ borderWidth: 1.5,
263
+ fill: false,
288
264
  },
289
265
  {
290
266
  label: "MA50",
291
267
  data: ma50,
292
- borderColor: "rgba(255, 206, 86, 1)",
293
- backgroundColor: "rgba(255, 206, 86, 0.2)",
294
- fill: false,
295
- borderWidth: 2,
296
268
  yAxisID: "yPrice",
297
- pointRadius: 1,
298
- pointHoverRadius: 3,
269
+ borderColor: "#ffce56",
270
+ borderWidth: 1.5,
271
+ fill: false,
299
272
  },
300
273
  {
301
274
  label: "MA100",
302
275
  data: ma100,
303
- borderColor: "rgba(153, 102, 25, 1)",
304
- backgroundColor: "rgba(153, 102, 25, 0.2)",
305
- fill: false,
306
- borderWidth: 2,
307
276
  yAxisID: "yPrice",
308
- pointRadius: 1,
309
- pointHoverRadius: 3,
277
+ borderColor: "#996633",
278
+ borderWidth: 1.5,
279
+ fill: false,
310
280
  },
311
281
  {
312
282
  label: "MA200",
313
283
  data: ma200,
314
- borderColor: "rgba(153, 102, 255, 1)",
315
- backgroundColor: "rgba(153, 102, 255, 0.2)",
316
- fill: false,
317
- borderWidth: 2,
318
284
  yAxisID: "yPrice",
319
- pointRadius: 1,
320
- pointHoverRadius: 3,
321
- },
322
- {
323
- label: "Volume",
324
- data: volumes, // Volume data
325
- yAxisID: "yVolume", // Assign to the volume axis
326
- fill: true,
327
- backgroundColor: "rgba(252, 3, 57, 0.5)",
328
- borderWidth: 1,
329
- pointRadius: 1,
330
- pointHoverRadius: 3,
285
+ borderColor: "#9966ff",
286
+ borderWidth: 1.5,
287
+ fill: false,
331
288
  },
332
289
  {
333
290
  label: "MA10",
334
291
  data: ma10,
335
- borderColor: "rgba(153, 12, 25, 1)",
336
- backgroundColor: "rgba(153, 12, 25, 0.2)",
337
- fill: false,
338
- borderWidth: 1,
339
292
  yAxisID: "yPrice",
340
- pointRadius: 1,
341
- pointHoverRadius: 3,
293
+ borderColor: "#cc3333",
294
+ borderWidth: 1,
295
+ fill: false,
342
296
  },
343
297
  {
344
298
  label: "MA5",
345
299
  data: ma5,
346
- borderColor: "rgba(13, 12, 25, 1)",
347
- backgroundColor: "rgba(13, 12, 25, 0.2)",
348
- fill: false,
349
- borderWidth: 1,
350
300
  yAxisID: "yPrice",
351
- pointRadius: 1,
352
- pointHoverRadius: 3,
301
+ borderColor: "#111111",
302
+ borderWidth: 1,
303
+ fill: false,
304
+ },
305
+ // Volume (bottom)
306
+ {
307
+ label: "Volume",
308
+ data: volumes,
309
+ type: "bar",
310
+ yAxisID: "yVolume",
311
+ backgroundColor: "rgba(252, 3, 57, 0.5)",
353
312
  },
354
313
  ],
355
314
  },
356
315
  options: {
357
316
  responsive: true,
317
+ maintainAspectRatio: true,
318
+ interaction: { mode: "index", intersect: false },
319
+ plugins: {
320
+ legend: { position: "top" },
321
+ zoom: {
322
+ pan: { enabled: this.zoomEnabled, mode: "x" },
323
+ zoom: { wheel: { enabled: this.zoomEnabled }, mode: "x" },
324
+ },
325
+ tooltip: { mode: "index", intersect: false },
326
+ },
358
327
  scales: {
359
328
  x: {
329
+ type: "category",
360
330
  ticks: {
361
331
  color: (ctx) => {
362
332
  const label = ctx.tick.label;
363
333
  if (typeof label === "string") {
364
- // Replace space with T to make it ISO-compliant
365
- const safeLabel = label.includes(" ") ? label.replace(" ", "T") : label;
366
- const labelDate = new Date(safeLabel);
367
- // If the date is invalid, return default color
334
+ const labelDate = new Date(label.replace(" ", "T")); // make ISO-compatible
368
335
  if (isNaN(labelDate.getTime()))
369
336
  return "black";
370
- // Compare date part only
371
337
  const todayStr = new Date().toISOString().split("T")[0];
372
338
  const labelStr = labelDate.toISOString().split("T")[0];
373
- return labelStr === todayStr ? "Salmon" : "black";
339
+ return labelStr === todayStr ? "Salmon" : "black"; // highlight today
374
340
  }
375
- return "black"; // fallback for non-string labels
341
+ return "black";
376
342
  },
377
343
  },
378
344
  },
379
- yPrice: {
380
- type: "linear",
381
- position: "left",
382
- beginAtZero: false,
383
- title: { display: true, text: "Price" },
384
- },
385
- yRSI: {
386
- type: "linear",
387
- position: "right",
388
- beginAtZero: true,
389
- title: { display: true, text: "RSI" },
390
- grid: { drawOnChartArea: false },
391
- },
392
345
  yMACD: {
393
- type: "linear",
394
346
  position: "right",
395
- beginAtZero: true,
396
347
  title: { display: true, text: "MACD" },
397
- grid: { drawOnChartArea: false },
348
+ beginAtZero: false,
349
+ weight: 1,
350
+ },
351
+ yPrice: {
352
+ position: "left",
353
+ title: { display: true, text: "Price" },
354
+ beginAtZero: false,
355
+ weight: 3,
356
+ grid: { drawOnChartArea: true },
398
357
  },
399
358
  yVolume: {
400
- type: "linear",
401
359
  position: "left",
402
- beginAtZero: true,
403
360
  title: { display: true, text: "Volume" },
404
- grid: { drawOnChartArea: false }, // To prevent grid overlap
405
- },
406
- },
407
- interaction: { mode: "index", intersect: false },
408
- plugins: {
409
- tooltip: { mode: "index", axis: "x" },
410
- zoom: {
411
- pan: {
412
- enabled: false,
413
- mode: "xy",
414
- modifierKey: undefined, // Optional: only pan while holding Ctrl
415
- },
416
- zoom: {
417
- wheel: {
418
- enabled: false,
419
- },
420
- pinch: {
421
- enabled: false,
422
- },
423
- mode: "x",
424
- },
425
- limits: {
426
- x: { minRange: 10 }, // prevent zooming too far
427
- },
361
+ beginAtZero: true,
362
+ weight: 1,
363
+ grid: { drawOnChartArea: false },
428
364
  },
429
365
  },
430
366
  },
@@ -437,7 +373,8 @@ let ChartElement = class ChartElement extends LitElement {
437
373
  </button>
438
374
 
439
375
  <button @click="${this._resetZoom}">Reset Zoom</button>
440
- <canvas id="stockChart"></canvas>
376
+
377
+ <canvas id="stockChart" style="width:100%;"></canvas>
441
378
  `;
442
379
  }
443
380
  };
@@ -447,9 +384,8 @@ __decorate([
447
384
  ], ChartElement.prototype, "stockData", void 0);
448
385
  __decorate([
449
386
  property({ type: Boolean }),
450
- __metadata("design:type", Boolean)
387
+ __metadata("design:type", Object)
451
388
  ], ChartElement.prototype, "zoomEnabled", void 0);
452
389
  ChartElement = __decorate([
453
- customElement("stock-chart-display"),
454
- __metadata("design:paramtypes", [])
390
+ customElement("stock-chart-display")
455
391
  ], ChartElement);