lit-litelements 2.2.8 → 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.
- package/dist/component/chart.lit.d.ts +2 -6
- package/dist/component/chart.lit.js +148 -278
- package/dist/main.js +10 -13
- package/package.json +1 -1
|
@@ -22,14 +22,10 @@ declare class ChartElement extends LitElement {
|
|
|
22
22
|
stockData: StockData[];
|
|
23
23
|
zoomEnabled: boolean;
|
|
24
24
|
chart: Chart | null;
|
|
25
|
-
macdChart: Chart | null;
|
|
26
|
-
constructor();
|
|
27
25
|
firstUpdated(): void;
|
|
28
26
|
_resetZoom(): void;
|
|
29
27
|
_Zoomenalbe(): void;
|
|
30
|
-
willUpdate(
|
|
31
|
-
has: (arg0: string) => any;
|
|
32
|
-
}): Promise<void>;
|
|
28
|
+
willUpdate(changed: Map<string, any>): Promise<void>;
|
|
33
29
|
customLinePlugin: {
|
|
34
30
|
id: string;
|
|
35
31
|
afterDraw: (chart: any) => void;
|
|
@@ -37,13 +33,13 @@ declare class ChartElement extends LitElement {
|
|
|
37
33
|
_getChartData(): {
|
|
38
34
|
dates: string[];
|
|
39
35
|
closePrices: number[];
|
|
36
|
+
rsi: number[];
|
|
40
37
|
ma5: number[];
|
|
41
38
|
ma10: number[];
|
|
42
39
|
ma20: number[];
|
|
43
40
|
ma50: number[];
|
|
44
41
|
ma100: number[];
|
|
45
42
|
ma200: number[];
|
|
46
|
-
RSI: number[];
|
|
47
43
|
MACDLine: number[];
|
|
48
44
|
SignalLine: any[];
|
|
49
45
|
divergence: any[];
|
|
@@ -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,84 @@ 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
|
-
MACDLine: this.stockData.map((
|
|
169
|
-
SignalLine: this.stockData.map((
|
|
170
|
-
divergence: this.stockData.map((
|
|
171
|
-
volumes: this.stockData.map((
|
|
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; }),
|
|
172
169
|
};
|
|
173
|
-
return data;
|
|
174
170
|
}
|
|
171
|
+
// --------------------------------------------------------------------
|
|
172
|
+
// Update
|
|
173
|
+
// --------------------------------------------------------------------
|
|
175
174
|
_updateChart() {
|
|
176
|
-
if (this.chart)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
this.chart.update();
|
|
195
|
-
if (this.macdChart) {
|
|
196
|
-
this.macdChart.data.labels = dates;
|
|
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
|
-
}
|
|
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();
|
|
203
193
|
}
|
|
204
|
-
//
|
|
194
|
+
// --------------------------------------------------------------------
|
|
195
|
+
// Create Chart
|
|
196
|
+
// --------------------------------------------------------------------
|
|
205
197
|
_createChart() {
|
|
206
|
-
var _a
|
|
207
|
-
const { dates, closePrices, ma5, ma10, ma20, ma50, ma100, ma200,
|
|
198
|
+
var _a;
|
|
199
|
+
const { dates, closePrices, rsi, ma5, ma10, ma20, ma50, ma100, ma200, MACDLine, SignalLine, divergence, volumes, } = this._getChartData();
|
|
208
200
|
const canvas = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.getElementById("stockChart");
|
|
209
|
-
|
|
210
|
-
if (!canvas || !macdCanvas) {
|
|
201
|
+
if (!canvas)
|
|
211
202
|
return;
|
|
212
|
-
}
|
|
213
203
|
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);
|
|
204
|
+
if (this.chart)
|
|
205
|
+
this.chart.destroy();
|
|
206
|
+
// Register plugins
|
|
225
207
|
Chart.register(zoomPlugin);
|
|
208
|
+
Chart.register(this.customLinePlugin);
|
|
226
209
|
this.chart = new Chart(ctx, {
|
|
227
210
|
type: "line",
|
|
228
211
|
data: {
|
|
@@ -230,280 +213,168 @@ let ChartElement = class ChartElement extends LitElement {
|
|
|
230
213
|
datasets: [
|
|
231
214
|
{
|
|
232
215
|
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,
|
|
216
|
+
data: rsi,
|
|
238
217
|
yAxisID: "yRSI",
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
218
|
+
borderColor: "rgba(61, 58, 215, 0.2)",
|
|
219
|
+
borderWidth: 1,
|
|
220
|
+
pointRadius: 0,
|
|
242
221
|
},
|
|
243
222
|
{
|
|
244
|
-
label: "
|
|
223
|
+
label: "MACD Histogram",
|
|
245
224
|
data: divergence,
|
|
246
|
-
|
|
247
|
-
backgroundColor: "rgba(175, 92, 92, 0.2)",
|
|
248
|
-
fill: false,
|
|
249
|
-
borderWidth: 2,
|
|
225
|
+
type: "bar",
|
|
250
226
|
yAxisID: "yMACD",
|
|
251
|
-
|
|
252
|
-
pointRadius: 1,
|
|
253
|
-
pointHoverRadius: 3,
|
|
227
|
+
backgroundColor: (ctx) => ctx.raw >= 0 ? "rgba(9, 225, 9, 0.4)" : "rgba(227, 5, 5, 0.4)",
|
|
254
228
|
},
|
|
255
229
|
{
|
|
256
|
-
label: "
|
|
257
|
-
data:
|
|
258
|
-
borderColor: "
|
|
259
|
-
backgroundColor: "rgba(75, 92, 192, 0.2)",
|
|
260
|
-
fill: false,
|
|
261
|
-
borderWidth: 1,
|
|
230
|
+
label: "MACD Line",
|
|
231
|
+
data: MACDLine,
|
|
232
|
+
borderColor: "blue",
|
|
262
233
|
yAxisID: "yMACD",
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
234
|
+
borderWidth: 1.2,
|
|
235
|
+
fill: false,
|
|
236
|
+
pointRadius: 0,
|
|
266
237
|
},
|
|
267
238
|
{
|
|
268
|
-
label: "
|
|
269
|
-
data:
|
|
270
|
-
borderColor: "
|
|
271
|
-
backgroundColor: "rgba(175, 192, 192, 0.2)",
|
|
272
|
-
fill: false,
|
|
273
|
-
borderWidth: 1,
|
|
239
|
+
label: "Signal Line",
|
|
240
|
+
data: SignalLine,
|
|
241
|
+
borderColor: "orange",
|
|
274
242
|
yAxisID: "yMACD",
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
243
|
+
borderWidth: 1.2,
|
|
244
|
+
fill: false,
|
|
245
|
+
pointRadius: 0,
|
|
278
246
|
},
|
|
247
|
+
// Price section (middle)
|
|
279
248
|
{
|
|
280
249
|
label: "Close Price",
|
|
281
250
|
data: closePrices,
|
|
282
|
-
borderColor: "rgba(75, 192, 192, 1)",
|
|
283
|
-
backgroundColor: "rgba(75, 192, 192, 0.2)",
|
|
284
|
-
fill: true,
|
|
285
|
-
borderWidth: 1,
|
|
286
251
|
yAxisID: "yPrice",
|
|
287
|
-
|
|
288
|
-
|
|
252
|
+
borderColor: "rgba(75,192,192,1)",
|
|
253
|
+
backgroundColor: "rgba(75,192,192,0.2)",
|
|
254
|
+
fill: true,
|
|
255
|
+
pointRadius: 0,
|
|
289
256
|
},
|
|
290
257
|
{
|
|
291
258
|
label: "MA20",
|
|
292
259
|
data: ma20,
|
|
293
|
-
borderColor: "rgba(255, 99, 132, 1)",
|
|
294
|
-
backgroundColor: "rgba(255, 99, 132, 0.2)",
|
|
295
|
-
fill: false,
|
|
296
|
-
borderWidth: 2,
|
|
297
260
|
yAxisID: "yPrice",
|
|
298
|
-
|
|
299
|
-
|
|
261
|
+
borderColor: "#ff6384",
|
|
262
|
+
borderWidth: 1.5,
|
|
263
|
+
fill: false,
|
|
300
264
|
},
|
|
301
265
|
{
|
|
302
266
|
label: "MA50",
|
|
303
267
|
data: ma50,
|
|
304
|
-
borderColor: "rgba(255, 206, 86, 1)",
|
|
305
|
-
backgroundColor: "rgba(255, 206, 86, 0.2)",
|
|
306
|
-
fill: false,
|
|
307
|
-
borderWidth: 2,
|
|
308
268
|
yAxisID: "yPrice",
|
|
309
|
-
|
|
310
|
-
|
|
269
|
+
borderColor: "#ffce56",
|
|
270
|
+
borderWidth: 1.5,
|
|
271
|
+
fill: false,
|
|
311
272
|
},
|
|
312
273
|
{
|
|
313
274
|
label: "MA100",
|
|
314
275
|
data: ma100,
|
|
315
|
-
borderColor: "rgba(153, 102, 25, 1)",
|
|
316
|
-
backgroundColor: "rgba(153, 102, 25, 0.2)",
|
|
317
|
-
fill: false,
|
|
318
|
-
borderWidth: 2,
|
|
319
276
|
yAxisID: "yPrice",
|
|
320
|
-
|
|
321
|
-
|
|
277
|
+
borderColor: "#996633",
|
|
278
|
+
borderWidth: 1.5,
|
|
279
|
+
fill: false,
|
|
322
280
|
},
|
|
323
281
|
{
|
|
324
282
|
label: "MA200",
|
|
325
283
|
data: ma200,
|
|
326
|
-
borderColor: "rgba(153, 102, 255, 1)",
|
|
327
|
-
backgroundColor: "rgba(153, 102, 255, 0.2)",
|
|
328
|
-
fill: false,
|
|
329
|
-
borderWidth: 2,
|
|
330
284
|
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,
|
|
285
|
+
borderColor: "#9966ff",
|
|
286
|
+
borderWidth: 1.5,
|
|
287
|
+
fill: false,
|
|
343
288
|
},
|
|
344
289
|
{
|
|
345
290
|
label: "MA10",
|
|
346
291
|
data: ma10,
|
|
347
|
-
borderColor: "rgba(153, 12, 25, 1)",
|
|
348
|
-
backgroundColor: "rgba(153, 12, 25, 0.2)",
|
|
349
|
-
fill: false,
|
|
350
|
-
borderWidth: 1,
|
|
351
292
|
yAxisID: "yPrice",
|
|
352
|
-
|
|
353
|
-
|
|
293
|
+
borderColor: "#cc3333",
|
|
294
|
+
borderWidth: 1,
|
|
295
|
+
fill: false,
|
|
354
296
|
},
|
|
355
297
|
{
|
|
356
298
|
label: "MA5",
|
|
357
299
|
data: ma5,
|
|
358
|
-
borderColor: "rgba(13, 12, 25, 1)",
|
|
359
|
-
backgroundColor: "rgba(13, 12, 25, 0.2)",
|
|
360
|
-
fill: false,
|
|
361
|
-
borderWidth: 1,
|
|
362
300
|
yAxisID: "yPrice",
|
|
363
|
-
|
|
364
|
-
|
|
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)",
|
|
365
312
|
},
|
|
366
313
|
],
|
|
367
314
|
},
|
|
368
315
|
options: {
|
|
369
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
|
+
},
|
|
370
327
|
scales: {
|
|
371
328
|
x: {
|
|
329
|
+
type: "category",
|
|
372
330
|
ticks: {
|
|
373
331
|
color: (ctx) => {
|
|
374
332
|
const label = ctx.tick.label;
|
|
375
333
|
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
|
|
334
|
+
const labelDate = new Date(label.replace(" ", "T")); // make ISO-compatible
|
|
380
335
|
if (isNaN(labelDate.getTime()))
|
|
381
336
|
return "black";
|
|
382
|
-
// Compare date part only
|
|
383
337
|
const todayStr = new Date().toISOString().split("T")[0];
|
|
384
338
|
const labelStr = labelDate.toISOString().split("T")[0];
|
|
385
|
-
return labelStr === todayStr ? "Salmon" : "black";
|
|
339
|
+
return labelStr === todayStr ? "Salmon" : "black"; // highlight today
|
|
386
340
|
}
|
|
387
|
-
return "black";
|
|
341
|
+
return "black";
|
|
388
342
|
},
|
|
389
343
|
},
|
|
390
344
|
},
|
|
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
345
|
yMACD: {
|
|
405
|
-
type: "linear",
|
|
406
346
|
position: "right",
|
|
407
|
-
beginAtZero: true,
|
|
408
347
|
title: { display: true, text: "MACD" },
|
|
409
|
-
|
|
348
|
+
beginAtZero: false,
|
|
349
|
+
weight: 1,
|
|
410
350
|
},
|
|
411
|
-
|
|
412
|
-
type: "linear",
|
|
351
|
+
yPrice: {
|
|
413
352
|
position: "left",
|
|
414
|
-
|
|
415
|
-
title: { display: true, text: "Volume" },
|
|
416
|
-
grid: { drawOnChartArea: false }, // To prevent grid overlap
|
|
417
|
-
},
|
|
418
|
-
},
|
|
419
|
-
interaction: { mode: "index", intersect: false },
|
|
420
|
-
plugins: {
|
|
421
|
-
tooltip: { mode: "index", axis: "x" },
|
|
422
|
-
zoom: {
|
|
423
|
-
pan: {
|
|
424
|
-
enabled: false,
|
|
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",
|
|
436
|
-
},
|
|
437
|
-
limits: {
|
|
438
|
-
x: { minRange: 10 }, // prevent zooming too far
|
|
439
|
-
},
|
|
440
|
-
},
|
|
441
|
-
},
|
|
442
|
-
},
|
|
443
|
-
});
|
|
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" },
|
|
353
|
+
title: { display: true, text: "Price" },
|
|
483
354
|
beginAtZero: false,
|
|
355
|
+
weight: 3,
|
|
356
|
+
grid: { drawOnChartArea: true },
|
|
484
357
|
},
|
|
485
|
-
|
|
486
|
-
|
|
358
|
+
yVolume: {
|
|
359
|
+
position: "left",
|
|
360
|
+
title: { display: true, text: "Volume" },
|
|
361
|
+
beginAtZero: true,
|
|
362
|
+
weight: 1,
|
|
363
|
+
grid: { drawOnChartArea: false },
|
|
487
364
|
},
|
|
488
365
|
},
|
|
489
|
-
plugins: {
|
|
490
|
-
legend: { position: "top" },
|
|
491
|
-
},
|
|
492
366
|
},
|
|
493
367
|
});
|
|
494
368
|
}
|
|
495
369
|
render() {
|
|
496
370
|
return html `
|
|
497
|
-
|
|
498
|
-
<!-- MACD chart below -->
|
|
499
|
-
<canvas id="macdChart" style="width:100%; height:120px; margin-top: 20px;"></canvas>
|
|
500
371
|
<button @click="${this._Zoomenalbe}">
|
|
501
372
|
${this.zoomEnabled ? "Disable Zoom" : "Enable Zoom"}
|
|
502
373
|
</button>
|
|
503
374
|
|
|
504
375
|
<button @click="${this._resetZoom}">Reset Zoom</button>
|
|
505
|
-
<canvas id="stockChart"></canvas>
|
|
506
376
|
|
|
377
|
+
<canvas id="stockChart" style="width:100%;"></canvas>
|
|
507
378
|
`;
|
|
508
379
|
}
|
|
509
380
|
};
|
|
@@ -513,9 +384,8 @@ __decorate([
|
|
|
513
384
|
], ChartElement.prototype, "stockData", void 0);
|
|
514
385
|
__decorate([
|
|
515
386
|
property({ type: Boolean }),
|
|
516
|
-
__metadata("design:type",
|
|
387
|
+
__metadata("design:type", Object)
|
|
517
388
|
], ChartElement.prototype, "zoomEnabled", void 0);
|
|
518
389
|
ChartElement = __decorate([
|
|
519
|
-
customElement("stock-chart-display")
|
|
520
|
-
__metadata("design:paramtypes", [])
|
|
390
|
+
customElement("stock-chart-display")
|
|
521
391
|
], ChartElement);
|