lit-litelements 2.2.8 → 2.3.0
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.
- package/dist/component/chart.lit.d.ts +10 -10
- package/dist/component/chart.lit.js +180 -274
- package/dist/main.js +7 -10
- package/package.json +1 -1
- package/readme.md +45 -26
|
@@ -15,21 +15,19 @@ interface StockData {
|
|
|
15
15
|
MA100?: number;
|
|
16
16
|
RSI?: number;
|
|
17
17
|
MACDLine?: number;
|
|
18
|
-
SignalLine?:
|
|
19
|
-
divergence?:
|
|
18
|
+
SignalLine?: number;
|
|
19
|
+
divergence?: number;
|
|
20
|
+
StochRSI_K?: number;
|
|
21
|
+
StochRSI_D?: number;
|
|
20
22
|
}
|
|
21
23
|
declare class ChartElement extends LitElement {
|
|
22
24
|
stockData: StockData[];
|
|
23
25
|
zoomEnabled: boolean;
|
|
24
26
|
chart: Chart | null;
|
|
25
|
-
macdChart: Chart | null;
|
|
26
|
-
constructor();
|
|
27
27
|
firstUpdated(): void;
|
|
28
28
|
_resetZoom(): void;
|
|
29
29
|
_Zoomenalbe(): void;
|
|
30
|
-
willUpdate(
|
|
31
|
-
has: (arg0: string) => any;
|
|
32
|
-
}): Promise<void>;
|
|
30
|
+
willUpdate(changed: Map<string, any>): Promise<void>;
|
|
33
31
|
customLinePlugin: {
|
|
34
32
|
id: string;
|
|
35
33
|
afterDraw: (chart: any) => void;
|
|
@@ -37,16 +35,18 @@ declare class ChartElement extends LitElement {
|
|
|
37
35
|
_getChartData(): {
|
|
38
36
|
dates: string[];
|
|
39
37
|
closePrices: number[];
|
|
38
|
+
rsi: number[];
|
|
39
|
+
stochRSI_K: number[];
|
|
40
|
+
stochRSI_D: number[];
|
|
40
41
|
ma5: number[];
|
|
41
42
|
ma10: number[];
|
|
42
43
|
ma20: number[];
|
|
43
44
|
ma50: number[];
|
|
44
45
|
ma100: number[];
|
|
45
46
|
ma200: number[];
|
|
46
|
-
RSI: number[];
|
|
47
47
|
MACDLine: number[];
|
|
48
|
-
SignalLine:
|
|
49
|
-
divergence:
|
|
48
|
+
SignalLine: number[];
|
|
49
|
+
divergence: number[];
|
|
50
50
|
volumes: number[];
|
|
51
51
|
};
|
|
52
52
|
_updateChart(): void;
|
|
@@ -22,12 +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
|
-
|
|
30
|
-
//
|
|
29
|
+
// --------------------------------------------------------------------
|
|
30
|
+
// CUSTOM SIGNAL PLUGIN (RSI + MA200 + SL/TP)
|
|
31
|
+
// --------------------------------------------------------------------
|
|
31
32
|
this.customLinePlugin = {
|
|
32
33
|
id: "customLinePlugin",
|
|
33
34
|
afterDraw: (chart) => {
|
|
@@ -55,7 +56,7 @@ let ChartElement = class ChartElement extends LitElement {
|
|
|
55
56
|
ctx.fill();
|
|
56
57
|
ctx.fillStyle = "green";
|
|
57
58
|
ctx.font = "bold 12px sans-serif";
|
|
58
|
-
ctx.fillText("
|
|
59
|
+
ctx.fillText("Buy_rsi", x + 6, y - 6);
|
|
59
60
|
}
|
|
60
61
|
else if (rsiValue !== null && rsiValue > 70) {
|
|
61
62
|
const x = scales.x.getPixelForValue(i);
|
|
@@ -66,7 +67,7 @@ let ChartElement = class ChartElement extends LitElement {
|
|
|
66
67
|
ctx.fill();
|
|
67
68
|
ctx.fillStyle = "red";
|
|
68
69
|
ctx.font = "bold 12px sans-serif";
|
|
69
|
-
ctx.fillText("
|
|
70
|
+
ctx.fillText("Sell_rsi", x + 6, y - 6);
|
|
70
71
|
}
|
|
71
72
|
// Add MA200 bullish/bearish crossover signals
|
|
72
73
|
const prevClose = closeData[i - 1];
|
|
@@ -117,9 +118,7 @@ let ChartElement = class ChartElement extends LitElement {
|
|
|
117
118
|
}
|
|
118
119
|
},
|
|
119
120
|
};
|
|
120
|
-
this.stockData = [];
|
|
121
121
|
}
|
|
122
|
-
// First updated is called after the element has been rendered into the DOM
|
|
123
122
|
firstUpdated() {
|
|
124
123
|
this._createChart();
|
|
125
124
|
}
|
|
@@ -129,100 +128,90 @@ let ChartElement = class ChartElement extends LitElement {
|
|
|
129
128
|
}
|
|
130
129
|
_Zoomenalbe() {
|
|
131
130
|
var _a, _b, _c, _d;
|
|
132
|
-
if ((_b = (_a = this.chart) === null || _a === void 0 ? void 0 : _a.options.plugins) === null || _b === void 0 ? void 0 : _b.zoom)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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();
|
|
144
143
|
}
|
|
145
|
-
willUpdate(
|
|
144
|
+
willUpdate(changed) {
|
|
146
145
|
return __awaiter(this, void 0, void 0, function* () {
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
this._createChart(); // Ensure the chart is created
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
this._updateChart(); // Update the chart if it exists
|
|
153
|
-
}
|
|
146
|
+
if (changed.has("stockData")) {
|
|
147
|
+
this.chart ? this._updateChart() : this._createChart();
|
|
154
148
|
}
|
|
155
149
|
});
|
|
156
150
|
}
|
|
151
|
+
// --------------------------------------------------------------------
|
|
152
|
+
// Data extraction
|
|
153
|
+
// --------------------------------------------------------------------
|
|
157
154
|
_getChartData() {
|
|
158
|
-
|
|
159
|
-
dates: this.stockData.map((
|
|
160
|
-
closePrices: this.stockData.map((
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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
|
+
// ✅ StochRSI
|
|
160
|
+
stochRSI_K: this.stockData.map((d) => { var _a; return (_a = d.StochRSI_K) !== null && _a !== void 0 ? _a : null; }),
|
|
161
|
+
stochRSI_D: this.stockData.map((d) => { var _a; return (_a = d.StochRSI_D) !== null && _a !== void 0 ? _a : null; }),
|
|
162
|
+
ma5: this.stockData.map((d) => { var _a; return (_a = d.MA5) !== null && _a !== void 0 ? _a : null; }),
|
|
163
|
+
ma10: this.stockData.map((d) => { var _a; return (_a = d.MA10) !== null && _a !== void 0 ? _a : null; }),
|
|
164
|
+
ma20: this.stockData.map((d) => { var _a; return (_a = d.MA20) !== null && _a !== void 0 ? _a : null; }),
|
|
165
|
+
ma50: this.stockData.map((d) => { var _a; return (_a = d.MA50) !== null && _a !== void 0 ? _a : null; }),
|
|
166
|
+
ma100: this.stockData.map((d) => { var _a; return (_a = d.MA100) !== null && _a !== void 0 ? _a : null; }),
|
|
167
|
+
ma200: this.stockData.map((d) => { var _a; return (_a = d.MA200) !== null && _a !== void 0 ? _a : null; }),
|
|
168
|
+
MACDLine: this.stockData.map((d) => { var _a; return (_a = d.MACDLine) !== null && _a !== void 0 ? _a : null; }),
|
|
169
|
+
SignalLine: this.stockData.map((d) => { var _a; return (_a = d.SignalLine) !== null && _a !== void 0 ? _a : null; }),
|
|
170
|
+
divergence: this.stockData.map((d) => { var _a; return (_a = d.divergence) !== null && _a !== void 0 ? _a : null; }),
|
|
171
|
+
volumes: this.stockData.map((d) => { var _a; return (_a = d.volume) !== null && _a !== void 0 ? _a : 0; }),
|
|
172
172
|
};
|
|
173
|
-
return data;
|
|
174
173
|
}
|
|
174
|
+
// --------------------------------------------------------------------
|
|
175
|
+
// Update
|
|
176
|
+
// --------------------------------------------------------------------
|
|
175
177
|
_updateChart() {
|
|
176
|
-
if (this.chart)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
this.macdChart.data.datasets[0].data = divergence;
|
|
198
|
-
this.macdChart.data.datasets[1].data = MACDLine;
|
|
199
|
-
this.macdChart.data.datasets[2].data = SignalLine;
|
|
200
|
-
this.macdChart.update();
|
|
201
|
-
}
|
|
202
|
-
}
|
|
178
|
+
if (!this.chart)
|
|
179
|
+
return;
|
|
180
|
+
const { dates, closePrices, rsi, ma5, ma10, ma20, ma50, ma100, ma200, MACDLine, SignalLine, divergence, volumes, stochRSI_K, stochRSI_D, } = this._getChartData();
|
|
181
|
+
this.chart.data.labels = dates;
|
|
182
|
+
const ds = this.chart.data.datasets;
|
|
183
|
+
ds[0].data = rsi;
|
|
184
|
+
ds[1].data = divergence;
|
|
185
|
+
ds[2].data = MACDLine;
|
|
186
|
+
ds[3].data = SignalLine;
|
|
187
|
+
ds[4].data = closePrices;
|
|
188
|
+
ds[5].data = ma20;
|
|
189
|
+
ds[6].data = ma50;
|
|
190
|
+
ds[7].data = ma100;
|
|
191
|
+
ds[8].data = ma200;
|
|
192
|
+
ds[9].data = ma10;
|
|
193
|
+
ds[10].data = ma5;
|
|
194
|
+
ds[11].data = volumes;
|
|
195
|
+
// ✅ Update StochRSI datasets (just like MACDLine and SignalLine)
|
|
196
|
+
ds[12].data = stochRSI_K; // %K line
|
|
197
|
+
ds[13].data = stochRSI_D; // %D line
|
|
198
|
+
this.chart.update();
|
|
203
199
|
}
|
|
204
|
-
//
|
|
200
|
+
// --------------------------------------------------------------------
|
|
201
|
+
// Create Chart
|
|
202
|
+
// --------------------------------------------------------------------
|
|
205
203
|
_createChart() {
|
|
206
|
-
var _a
|
|
207
|
-
const { dates, closePrices, ma5, ma10, ma20, ma50, ma100, ma200,
|
|
204
|
+
var _a;
|
|
205
|
+
const { dates, closePrices, rsi, ma5, ma10, ma20, ma50, ma100, ma200, MACDLine, SignalLine, divergence, volumes, stochRSI_K, stochRSI_D, } = this._getChartData();
|
|
208
206
|
const canvas = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.getElementById("stockChart");
|
|
209
|
-
|
|
210
|
-
if (!canvas || !macdCanvas) {
|
|
207
|
+
if (!canvas)
|
|
211
208
|
return;
|
|
212
|
-
}
|
|
213
209
|
const ctx = canvas.getContext("2d");
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
if (this.chart) {
|
|
219
|
-
this.chart.destroy(); // Destroy existing chart if necessary
|
|
220
|
-
}
|
|
221
|
-
if (this.macdChart)
|
|
222
|
-
this.macdChart.destroy();
|
|
223
|
-
// Register the custom plugin
|
|
224
|
-
Chart.register(this.customLinePlugin);
|
|
210
|
+
if (this.chart)
|
|
211
|
+
this.chart.destroy();
|
|
212
|
+
// Register plugins
|
|
225
213
|
Chart.register(zoomPlugin);
|
|
214
|
+
// Chart.register(this.customLinePlugin);
|
|
226
215
|
this.chart = new Chart(ctx, {
|
|
227
216
|
type: "line",
|
|
228
217
|
data: {
|
|
@@ -230,280 +219,198 @@ let ChartElement = class ChartElement extends LitElement {
|
|
|
230
219
|
datasets: [
|
|
231
220
|
{
|
|
232
221
|
label: "RSI",
|
|
233
|
-
data:
|
|
234
|
-
borderColor: "rgba(15, 92, 92, 1)",
|
|
235
|
-
backgroundColor: "rgba(15, 92, 92, 0.2)",
|
|
236
|
-
fill: false,
|
|
237
|
-
borderWidth: 2,
|
|
222
|
+
data: rsi,
|
|
238
223
|
yAxisID: "yRSI",
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
224
|
+
borderColor: "rgba(61, 58, 215, 0.2)",
|
|
225
|
+
borderWidth: 1,
|
|
226
|
+
pointRadius: 0,
|
|
242
227
|
},
|
|
243
228
|
{
|
|
244
|
-
label: "
|
|
229
|
+
label: "MACD Histogram",
|
|
245
230
|
data: divergence,
|
|
246
|
-
|
|
247
|
-
backgroundColor: "rgba(175, 92, 92, 0.2)",
|
|
248
|
-
fill: false,
|
|
249
|
-
borderWidth: 2,
|
|
231
|
+
type: "bar",
|
|
250
232
|
yAxisID: "yMACD",
|
|
251
|
-
|
|
252
|
-
pointRadius: 1,
|
|
253
|
-
pointHoverRadius: 3,
|
|
233
|
+
backgroundColor: (ctx) => ctx.raw >= 0 ? "rgba(9, 225, 9, 0.4)" : "rgba(227, 5, 5, 0.4)",
|
|
254
234
|
},
|
|
255
235
|
{
|
|
256
|
-
label: "
|
|
257
|
-
data:
|
|
258
|
-
borderColor: "
|
|
259
|
-
backgroundColor: "rgba(75, 92, 192, 0.2)",
|
|
260
|
-
fill: false,
|
|
261
|
-
borderWidth: 1,
|
|
236
|
+
label: "MACD Line",
|
|
237
|
+
data: MACDLine,
|
|
238
|
+
borderColor: "blue",
|
|
262
239
|
yAxisID: "yMACD",
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
240
|
+
borderWidth: 1.2,
|
|
241
|
+
fill: false,
|
|
242
|
+
pointRadius: 0,
|
|
266
243
|
},
|
|
267
244
|
{
|
|
268
|
-
label: "
|
|
269
|
-
data:
|
|
270
|
-
borderColor: "
|
|
271
|
-
backgroundColor: "rgba(175, 192, 192, 0.2)",
|
|
272
|
-
fill: false,
|
|
273
|
-
borderWidth: 1,
|
|
245
|
+
label: "Signal Line",
|
|
246
|
+
data: SignalLine,
|
|
247
|
+
borderColor: "orange",
|
|
274
248
|
yAxisID: "yMACD",
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
249
|
+
borderWidth: 1.2,
|
|
250
|
+
fill: false,
|
|
251
|
+
pointRadius: 0,
|
|
278
252
|
},
|
|
253
|
+
// Price section (middle)
|
|
279
254
|
{
|
|
280
255
|
label: "Close Price",
|
|
281
256
|
data: closePrices,
|
|
282
|
-
borderColor: "rgba(75, 192, 192, 1)",
|
|
283
|
-
backgroundColor: "rgba(75, 192, 192, 0.2)",
|
|
284
|
-
fill: true,
|
|
285
|
-
borderWidth: 1,
|
|
286
257
|
yAxisID: "yPrice",
|
|
287
|
-
|
|
288
|
-
|
|
258
|
+
borderColor: "rgba(75,192,192,1)",
|
|
259
|
+
backgroundColor: "rgba(75,192,192,0.2)",
|
|
260
|
+
fill: true,
|
|
261
|
+
pointRadius: 0,
|
|
289
262
|
},
|
|
290
263
|
{
|
|
291
264
|
label: "MA20",
|
|
292
265
|
data: ma20,
|
|
293
|
-
borderColor: "rgba(255, 99, 132, 1)",
|
|
294
|
-
backgroundColor: "rgba(255, 99, 132, 0.2)",
|
|
295
|
-
fill: false,
|
|
296
|
-
borderWidth: 2,
|
|
297
266
|
yAxisID: "yPrice",
|
|
298
|
-
|
|
299
|
-
|
|
267
|
+
borderColor: "#ff6384",
|
|
268
|
+
borderWidth: 1.5,
|
|
269
|
+
pointRadius: 0,
|
|
300
270
|
},
|
|
301
271
|
{
|
|
302
272
|
label: "MA50",
|
|
303
273
|
data: ma50,
|
|
304
|
-
borderColor: "rgba(255, 206, 86, 1)",
|
|
305
|
-
backgroundColor: "rgba(255, 206, 86, 0.2)",
|
|
306
|
-
fill: false,
|
|
307
|
-
borderWidth: 2,
|
|
308
274
|
yAxisID: "yPrice",
|
|
309
|
-
|
|
310
|
-
|
|
275
|
+
borderColor: "#ffce56",
|
|
276
|
+
borderWidth: 1.5,
|
|
277
|
+
pointRadius: 0,
|
|
311
278
|
},
|
|
312
279
|
{
|
|
313
280
|
label: "MA100",
|
|
314
281
|
data: ma100,
|
|
315
|
-
borderColor: "rgba(153, 102, 25, 1)",
|
|
316
|
-
backgroundColor: "rgba(153, 102, 25, 0.2)",
|
|
317
|
-
fill: false,
|
|
318
|
-
borderWidth: 2,
|
|
319
282
|
yAxisID: "yPrice",
|
|
320
|
-
|
|
321
|
-
|
|
283
|
+
borderColor: "#996633",
|
|
284
|
+
borderWidth: 1.5,
|
|
285
|
+
pointRadius: 0,
|
|
322
286
|
},
|
|
323
287
|
{
|
|
324
288
|
label: "MA200",
|
|
325
289
|
data: ma200,
|
|
326
|
-
borderColor: "rgba(153, 102, 255, 1)",
|
|
327
|
-
backgroundColor: "rgba(153, 102, 255, 0.2)",
|
|
328
|
-
fill: false,
|
|
329
|
-
borderWidth: 2,
|
|
330
290
|
yAxisID: "yPrice",
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
{
|
|
335
|
-
label: "Volume",
|
|
336
|
-
data: volumes, // Volume data
|
|
337
|
-
yAxisID: "yVolume", // Assign to the volume axis
|
|
338
|
-
fill: true,
|
|
339
|
-
backgroundColor: "rgba(252, 3, 57, 0.5)",
|
|
340
|
-
borderWidth: 1,
|
|
341
|
-
pointRadius: 1,
|
|
342
|
-
pointHoverRadius: 3,
|
|
291
|
+
borderColor: "#9966ff",
|
|
292
|
+
borderWidth: 1.5,
|
|
293
|
+
pointRadius: 0,
|
|
343
294
|
},
|
|
344
295
|
{
|
|
345
296
|
label: "MA10",
|
|
346
297
|
data: ma10,
|
|
347
|
-
borderColor: "rgba(153, 12, 25, 1)",
|
|
348
|
-
backgroundColor: "rgba(153, 12, 25, 0.2)",
|
|
349
|
-
fill: false,
|
|
350
|
-
borderWidth: 1,
|
|
351
298
|
yAxisID: "yPrice",
|
|
352
|
-
|
|
353
|
-
|
|
299
|
+
borderColor: "#cc3333",
|
|
300
|
+
borderWidth: 1,
|
|
301
|
+
fill: false,
|
|
354
302
|
},
|
|
355
303
|
{
|
|
356
304
|
label: "MA5",
|
|
357
305
|
data: ma5,
|
|
358
|
-
borderColor: "rgba(13, 12, 25, 1)",
|
|
359
|
-
backgroundColor: "rgba(13, 12, 25, 0.2)",
|
|
360
|
-
fill: false,
|
|
361
|
-
borderWidth: 1,
|
|
362
306
|
yAxisID: "yPrice",
|
|
363
|
-
|
|
364
|
-
|
|
307
|
+
borderColor: "#111111",
|
|
308
|
+
borderWidth: 1,
|
|
309
|
+
fill: false,
|
|
310
|
+
},
|
|
311
|
+
// Volume (bottom)
|
|
312
|
+
{
|
|
313
|
+
label: "Volume",
|
|
314
|
+
data: volumes,
|
|
315
|
+
type: "bar",
|
|
316
|
+
yAxisID: "yVolume",
|
|
317
|
+
backgroundColor: "rgba(252, 3, 57, 0.5)",
|
|
318
|
+
},
|
|
319
|
+
// StochRSI %K
|
|
320
|
+
{
|
|
321
|
+
label: "StochRSI %K",
|
|
322
|
+
data: stochRSI_K,
|
|
323
|
+
yAxisID: "yStochRSI",
|
|
324
|
+
borderColor: "#00c853", // Green color for %K
|
|
325
|
+
borderWidth: 0.5,
|
|
326
|
+
pointRadius: 0,
|
|
327
|
+
},
|
|
328
|
+
// StochRSI %D
|
|
329
|
+
{
|
|
330
|
+
label: "StochRSI %D",
|
|
331
|
+
data: stochRSI_D,
|
|
332
|
+
yAxisID: "yStochRSI",
|
|
333
|
+
borderColor: "#ff5252", // Red color for %D
|
|
334
|
+
borderWidth: 0.5,
|
|
335
|
+
pointRadius: 0,
|
|
365
336
|
},
|
|
366
337
|
],
|
|
367
338
|
},
|
|
368
339
|
options: {
|
|
369
340
|
responsive: true,
|
|
341
|
+
maintainAspectRatio: true,
|
|
342
|
+
interaction: { mode: "index", intersect: false },
|
|
343
|
+
plugins: {
|
|
344
|
+
legend: { position: "top" },
|
|
345
|
+
zoom: {
|
|
346
|
+
pan: { enabled: this.zoomEnabled, mode: "x" },
|
|
347
|
+
zoom: { wheel: { enabled: this.zoomEnabled }, mode: "x" },
|
|
348
|
+
},
|
|
349
|
+
tooltip: { mode: "index", intersect: false },
|
|
350
|
+
},
|
|
370
351
|
scales: {
|
|
371
352
|
x: {
|
|
353
|
+
type: "category",
|
|
372
354
|
ticks: {
|
|
373
355
|
color: (ctx) => {
|
|
374
356
|
const label = ctx.tick.label;
|
|
375
357
|
if (typeof label === "string") {
|
|
376
|
-
|
|
377
|
-
const safeLabel = label.includes(" ") ? label.replace(" ", "T") : label;
|
|
378
|
-
const labelDate = new Date(safeLabel);
|
|
379
|
-
// If the date is invalid, return default color
|
|
358
|
+
const labelDate = new Date(label.replace(" ", "T"));
|
|
380
359
|
if (isNaN(labelDate.getTime()))
|
|
381
360
|
return "black";
|
|
382
|
-
// Compare date part only
|
|
383
361
|
const todayStr = new Date().toISOString().split("T")[0];
|
|
384
362
|
const labelStr = labelDate.toISOString().split("T")[0];
|
|
385
363
|
return labelStr === todayStr ? "Salmon" : "black";
|
|
386
364
|
}
|
|
387
|
-
return "black";
|
|
365
|
+
return "black";
|
|
388
366
|
},
|
|
389
367
|
},
|
|
390
368
|
},
|
|
391
|
-
yPrice: {
|
|
392
|
-
type: "linear",
|
|
393
|
-
position: "left",
|
|
394
|
-
beginAtZero: false,
|
|
395
|
-
title: { display: true, text: "Price" },
|
|
396
|
-
},
|
|
397
|
-
yRSI: {
|
|
398
|
-
type: "linear",
|
|
399
|
-
position: "right",
|
|
400
|
-
beginAtZero: true,
|
|
401
|
-
title: { display: true, text: "RSI" },
|
|
402
|
-
grid: { drawOnChartArea: false },
|
|
403
|
-
},
|
|
404
369
|
yMACD: {
|
|
405
|
-
type: "linear",
|
|
406
370
|
position: "right",
|
|
407
|
-
beginAtZero: true,
|
|
408
371
|
title: { display: true, text: "MACD" },
|
|
409
|
-
|
|
372
|
+
beginAtZero: false,
|
|
373
|
+
weight: 1,
|
|
374
|
+
},
|
|
375
|
+
yPrice: {
|
|
376
|
+
position: "left",
|
|
377
|
+
title: { display: true, text: "Price" },
|
|
378
|
+
beginAtZero: false,
|
|
379
|
+
weight: 3,
|
|
380
|
+
grid: { drawOnChartArea: true },
|
|
410
381
|
},
|
|
411
382
|
yVolume: {
|
|
412
|
-
type: "linear",
|
|
413
383
|
position: "left",
|
|
414
|
-
beginAtZero: true,
|
|
415
384
|
title: { display: true, text: "Volume" },
|
|
416
|
-
|
|
385
|
+
beginAtZero: true,
|
|
386
|
+
weight: 1,
|
|
387
|
+
grid: { drawOnChartArea: false },
|
|
417
388
|
},
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
mode: "xy",
|
|
426
|
-
modifierKey: undefined, // Optional: only pan while holding Ctrl
|
|
427
|
-
},
|
|
428
|
-
zoom: {
|
|
429
|
-
wheel: {
|
|
430
|
-
enabled: false,
|
|
431
|
-
},
|
|
432
|
-
pinch: {
|
|
433
|
-
enabled: false,
|
|
434
|
-
},
|
|
435
|
-
mode: "x",
|
|
389
|
+
yStochRSI: {
|
|
390
|
+
position: "right",
|
|
391
|
+
min: -0.5,
|
|
392
|
+
max: 1.5, // you can adjust this for your scale, or 100 if you use the full range
|
|
393
|
+
title: {
|
|
394
|
+
display: true,
|
|
395
|
+
text: "StochRSI",
|
|
436
396
|
},
|
|
437
|
-
|
|
438
|
-
|
|
397
|
+
grid: {
|
|
398
|
+
drawOnChartArea: false,
|
|
439
399
|
},
|
|
440
400
|
},
|
|
441
401
|
},
|
|
442
402
|
},
|
|
443
403
|
});
|
|
444
|
-
// 🎯 MACD CHART (bottom)
|
|
445
|
-
this.macdChart = new Chart(macdCtx, {
|
|
446
|
-
type: "bar",
|
|
447
|
-
data: {
|
|
448
|
-
labels: dates,
|
|
449
|
-
datasets: [
|
|
450
|
-
{
|
|
451
|
-
label: "MACD Histogram",
|
|
452
|
-
data: divergence,
|
|
453
|
-
backgroundColor: (ctx) => (ctx.raw >= 0 ? "rgba(0, 200, 0, 0.5)" : "rgba(200, 0, 0, 0.5)"),
|
|
454
|
-
yAxisID: "yMACD",
|
|
455
|
-
},
|
|
456
|
-
{
|
|
457
|
-
label: "MACD Line",
|
|
458
|
-
data: MACDLine,
|
|
459
|
-
type: "line",
|
|
460
|
-
borderColor: "blue",
|
|
461
|
-
borderWidth: 1.5,
|
|
462
|
-
yAxisID: "yMACD",
|
|
463
|
-
fill: false,
|
|
464
|
-
pointRadius: 0,
|
|
465
|
-
},
|
|
466
|
-
{
|
|
467
|
-
label: "Signal Line",
|
|
468
|
-
data: SignalLine,
|
|
469
|
-
type: "line",
|
|
470
|
-
borderColor: "orange",
|
|
471
|
-
borderWidth: 1.5,
|
|
472
|
-
yAxisID: "yMACD",
|
|
473
|
-
fill: false,
|
|
474
|
-
pointRadius: 0,
|
|
475
|
-
},
|
|
476
|
-
],
|
|
477
|
-
},
|
|
478
|
-
options: {
|
|
479
|
-
responsive: true,
|
|
480
|
-
scales: {
|
|
481
|
-
yMACD: {
|
|
482
|
-
title: { display: true, text: "MACD" },
|
|
483
|
-
beginAtZero: false,
|
|
484
|
-
},
|
|
485
|
-
x: {
|
|
486
|
-
ticks: { display: false }, // hide overlapping date labels
|
|
487
|
-
},
|
|
488
|
-
},
|
|
489
|
-
plugins: {
|
|
490
|
-
legend: { position: "top" },
|
|
491
|
-
},
|
|
492
|
-
},
|
|
493
|
-
});
|
|
494
404
|
}
|
|
495
405
|
render() {
|
|
496
406
|
return html `
|
|
497
|
-
|
|
498
|
-
<!-- MACD chart below -->
|
|
499
|
-
<canvas id="macdChart" style="width:100%; height:120px; margin-top: 20px;"></canvas>
|
|
500
407
|
<button @click="${this._Zoomenalbe}">
|
|
501
408
|
${this.zoomEnabled ? "Disable Zoom" : "Enable Zoom"}
|
|
502
409
|
</button>
|
|
503
410
|
|
|
504
411
|
<button @click="${this._resetZoom}">Reset Zoom</button>
|
|
505
|
-
<canvas id="stockChart"></canvas>
|
|
506
412
|
|
|
413
|
+
<canvas id="stockChart" style="width:100%;"></canvas>
|
|
507
414
|
`;
|
|
508
415
|
}
|
|
509
416
|
};
|
|
@@ -513,9 +420,8 @@ __decorate([
|
|
|
513
420
|
], ChartElement.prototype, "stockData", void 0);
|
|
514
421
|
__decorate([
|
|
515
422
|
property({ type: Boolean }),
|
|
516
|
-
__metadata("design:type",
|
|
423
|
+
__metadata("design:type", Object)
|
|
517
424
|
], ChartElement.prototype, "zoomEnabled", void 0);
|
|
518
425
|
ChartElement = __decorate([
|
|
519
|
-
customElement("stock-chart-display")
|
|
520
|
-
__metadata("design:paramtypes", [])
|
|
426
|
+
customElement("stock-chart-display")
|
|
521
427
|
], ChartElement);
|