@operato/scene-scichart 2.0.0-beta.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +13 -0
  3. package/assets/favicon.ico +0 -0
  4. package/assets/images/spinner.png +0 -0
  5. package/db.sqlite +0 -0
  6. package/dist/charts/sci-candle-stick-chart.d.ts +19 -0
  7. package/dist/charts/sci-candle-stick-chart.js +248 -0
  8. package/dist/charts/sci-candle-stick-chart.js.map +1 -0
  9. package/dist/charts/volume-pallette-provider.d.ts +12 -0
  10. package/dist/charts/volume-pallette-provider.js +21 -0
  11. package/dist/charts/volume-pallette-provider.js.map +1 -0
  12. package/dist/data/binance-rest-client.d.ts +14 -0
  13. package/dist/data/binance-rest-client.js +53 -0
  14. package/dist/data/binance-rest-client.js.map +1 -0
  15. package/dist/editors/index.d.ts +0 -0
  16. package/dist/editors/index.js +2 -0
  17. package/dist/editors/index.js.map +1 -0
  18. package/dist/groups/index.d.ts +0 -0
  19. package/dist/groups/index.js +2 -0
  20. package/dist/groups/index.js.map +1 -0
  21. package/dist/index.d.ts +2 -0
  22. package/dist/index.js +3 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/scichart-candle-stick.d.ts +10 -0
  25. package/dist/scichart-candle-stick.js +50 -0
  26. package/dist/scichart-candle-stick.js.map +1 -0
  27. package/dist/scichart-timeseries.d.ts +23 -0
  28. package/dist/scichart-timeseries.js +118 -0
  29. package/dist/scichart-timeseries.js.map +1 -0
  30. package/dist/scichart.d.ts +20 -0
  31. package/dist/scichart.js +70 -0
  32. package/dist/scichart.js.map +1 -0
  33. package/dist/templates/index.d.ts +14 -0
  34. package/dist/templates/index.js +4 -0
  35. package/dist/templates/index.js.map +1 -0
  36. package/dist/templates/scichart-candle-stick.d.ts +14 -0
  37. package/dist/templates/scichart-candle-stick.js +16 -0
  38. package/dist/templates/scichart-candle-stick.js.map +1 -0
  39. package/dist/templates/scichart.d.ts +14 -0
  40. package/dist/templates/scichart.js +16 -0
  41. package/dist/templates/scichart.js.map +1 -0
  42. package/dist/themes/app-theme.d.ts +56 -0
  43. package/dist/themes/app-theme.js +35 -0
  44. package/dist/themes/app-theme.js.map +1 -0
  45. package/icons/no-image.png +0 -0
  46. package/icons/scichart-candle-stick.png +0 -0
  47. package/icons/scichart.png +0 -0
  48. package/logs/.08636eb59927f12972f6774f5947c8507b3564c2-audit.json +25 -0
  49. package/logs/.5e5d741d8b7784a2fbad65eedc0fd46946aaf6f2-audit.json +30 -0
  50. package/logs/application-2024-03-15-04.log +28 -0
  51. package/logs/application-2024-03-17-03.log +12 -0
  52. package/logs/application-2024-03-17-04.log +6 -0
  53. package/logs/connections-2024-03-15-03.log +82 -0
  54. package/logs/connections-2024-03-15-04.log +164 -0
  55. package/logs/connections-2024-03-17-03.log +88 -0
  56. package/logs/connections-2024-03-17-04.log +44 -0
  57. package/package.json +62 -0
  58. package/schema.graphql +3969 -0
  59. package/src/charts/sci-candle-stick-chart.ts +305 -0
  60. package/src/charts/volume-pallette-provider.ts +41 -0
  61. package/src/data/binance-rest-client.ts +74 -0
  62. package/src/editors/index.ts +0 -0
  63. package/src/groups/index.ts +0 -0
  64. package/src/index.ts +2 -0
  65. package/src/scichart-candle-stick.ts +60 -0
  66. package/src/scichart-timeseries.ts +156 -0
  67. package/src/scichart.ts +88 -0
  68. package/src/templates/index.ts +4 -0
  69. package/src/templates/scichart-candle-stick.ts +16 -0
  70. package/src/templates/scichart.ts +16 -0
  71. package/src/themes/app-theme.ts +72 -0
  72. package/things-scene.config.js +9 -0
  73. package/translations/en.json +3 -0
  74. package/translations/ja.json +3 -0
  75. package/translations/ko.json +3 -0
  76. package/translations/ms.json +3 -0
  77. package/translations/zh.json +3 -0
  78. package/tsconfig.json +22 -0
  79. package/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [2.0.0-beta.0](https://github.com/things-scene/operato-scene/compare/v2.0.0-alpha.12...v2.0.0-beta.0) (2024-06-01)
7
+
8
+
9
+ ### :rocket: New Features
10
+
11
+ * 2.0.0-beta.0 ([a2e2869](https://github.com/things-scene/operato-scene/commit/a2e28694eedf5bab0c54bcab5432d54ec59edd7f))
12
+ * gantt and scichart ([e1c43d3](https://github.com/things-scene/operato-scene/commit/e1c43d30ad65b7d9d2d4a1f9679561339bac3db2))
13
+ * sci-chart ([25d8f98](https://github.com/things-scene/operato-scene/commit/25d8f987cd03525f6fa940a70a31e050ab71c0a4))
14
+
15
+
16
+ ### :bug: Bug Fix
17
+
18
+ * allowJs in tsconfig option ([fa77174](https://github.com/things-scene/operato-scene/commit/fa771742188f21f177f0a85281570f59f0c478cf))
19
+ * scichart-candle-stick ([853dbeb](https://github.com/things-scene/operato-scene/commit/853dbeb952580f205dd321ae6b09f0337775b106))
package/README.md ADDED
@@ -0,0 +1,13 @@
1
+ ## build
2
+
3
+ `$ yarn build`
4
+
5
+ | type | filename | for | tested |
6
+ | ---- | ------------------------------------------ | -------------- | ------ |
7
+ | UMD | things-scene-scichart.js | modern browser | O |
8
+ | UMD | things-scene-scichart-ie.js | ie 11 | O |
9
+ | ESM | things-scene-scichart.mjs | modern browser | O |
10
+
11
+ ## publish
12
+
13
+ `$ yarn publish`
Binary file
Binary file
package/db.sqlite ADDED
Binary file
@@ -0,0 +1,19 @@
1
+ import { LitElement, PropertyValues, PropertyValueMap } from 'lit';
2
+ import { SciChartSurface, FastCandlestickRenderableSeries, SciChartOverview, FastOhlcRenderableSeries } from 'scichart';
3
+ export declare class SciCandleStockChart extends LitElement {
4
+ static styles: import("lit").CSSResult[];
5
+ render(): import("lit").TemplateResult<1>;
6
+ seriesType: 'candle-stick' | 'ohlc';
7
+ candlestickChartSeries: FastCandlestickRenderableSeries;
8
+ ohlcChartSeries: FastOhlcRenderableSeries;
9
+ sciChartSurface?: SciChartSurface;
10
+ sciChartOverview?: SciChartOverview;
11
+ chart: HTMLDivElement;
12
+ overview: HTMLDivElement;
13
+ disconnectedCallback(): void;
14
+ protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): Promise<void>;
15
+ updated(changes: PropertyValues<this>): void;
16
+ private getOverviewSeries;
17
+ private getTooltipLegendTemplate;
18
+ private build;
19
+ }
@@ -0,0 +1,248 @@
1
+ import { __decorate } from "tslib";
2
+ import { LitElement, css, html } from 'lit';
3
+ import { customElement, property, query, state } from 'lit/decorators.js';
4
+ import { SciChartSurface, NumberRange, NumericAxis, OhlcDataSeries, FastCandlestickRenderableSeries, ZoomPanModifier, ZoomExtentsModifier, MouseWheelZoomModifier, ENumericFormat, DateTimeNumericAxis, EAutoRange, FastLineRenderableSeries, XyMovingAverageFilter, SciChartOverview, CursorModifier, EDataSeriesType, ESeriesType, FastMountainRenderableSeries, GradientParams, Point, FastColumnRenderableSeries, XyDataSeries, FastOhlcRenderableSeries } from 'scichart';
5
+ import { appTheme } from '../themes/app-theme';
6
+ import { VolumePaletteProvider } from './volume-pallette-provider';
7
+ import { simpleBinanceRestClient } from '../data/binance-rest-client';
8
+ const Y_AXIS_VOLUME_ID = 'Y_AXIS_VOLUME_ID';
9
+ SciChartSurface.configure({
10
+ dataUrl: `/node_modules/scichart/_wasm/scichart2d.data`,
11
+ wasmUrl: `/node_modules/scichart/_wasm/scichart2d.wasm`
12
+ });
13
+ let SciCandleStockChart = class SciCandleStockChart extends LitElement {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.seriesType = 'candle-stick';
17
+ }
18
+ render() {
19
+ return html `
20
+ <div id="chart"></div>
21
+ <div id="overview"></div>
22
+ `;
23
+ }
24
+ disconnectedCallback() {
25
+ if (this.sciChartSurface) {
26
+ this.sciChartSurface.delete();
27
+ this.sciChartOverview.delete();
28
+ this.sciChartSurface = undefined;
29
+ this.sciChartOverview = undefined;
30
+ return;
31
+ }
32
+ }
33
+ async firstUpdated(_changedProperties) {
34
+ const { sciChartSurface, overview, candlestickSeries, ohlcSeries } = await this.build();
35
+ this.candlestickChartSeries = candlestickSeries;
36
+ this.ohlcChartSeries = ohlcSeries;
37
+ this.sciChartSurface = sciChartSurface;
38
+ this.sciChartOverview = overview;
39
+ this.candlestickChartSeries.isVisible = this.seriesType == 'candle-stick';
40
+ this.ohlcChartSeries.isVisible = this.seriesType == 'ohlc';
41
+ }
42
+ updated(changes) {
43
+ if (changes.has('seriesType') && this.candlestickChartSeries) {
44
+ this.candlestickChartSeries.isVisible = this.seriesType == 'candle-stick';
45
+ this.ohlcChartSeries.isVisible = this.seriesType == 'ohlc';
46
+ }
47
+ }
48
+ // Override the Renderableseries to display on the scichart overview
49
+ getOverviewSeries(defaultSeries) {
50
+ if (defaultSeries.type === ESeriesType.CandlestickSeries) {
51
+ // Swap the default candlestick series on the overview chart for a mountain series. Same data
52
+ return new FastMountainRenderableSeries(defaultSeries.parentSurface.webAssemblyContext2D, {
53
+ dataSeries: defaultSeries.dataSeries,
54
+ fillLinearGradient: new GradientParams(new Point(0, 0), new Point(0, 1), [
55
+ { color: appTheme.VividSkyBlue + '77', offset: 0 },
56
+ { color: 'Transparent', offset: 1 }
57
+ ]),
58
+ stroke: appTheme.VividSkyBlue
59
+ });
60
+ }
61
+ }
62
+ // Override the standard tooltip displayed by CursorModifier
63
+ getTooltipLegendTemplate(seriesInfos, svgAnnotation) {
64
+ let outputSvgString = '';
65
+ // Foreach series there will be a seriesInfo supplied by SciChart. This contains info about the series under the house
66
+ seriesInfos.forEach((seriesInfo, index) => {
67
+ const y = 20 + index * 20;
68
+ const textColor = seriesInfo.stroke;
69
+ let legendText = seriesInfo.formattedYValue;
70
+ if (seriesInfo.dataSeriesType === EDataSeriesType.Ohlc) {
71
+ const o = seriesInfo;
72
+ legendText = `Open=${o.formattedOpenValue} High=${o.formattedHighValue} Low=${o.formattedLowValue} Close=${o.formattedCloseValue}`;
73
+ }
74
+ outputSvgString += `<text x="8" y="${y}" font-size="13" font-family="Verdana" fill="${textColor}">
75
+ ${seriesInfo.seriesName}: ${legendText}
76
+ </text>`;
77
+ });
78
+ return `<svg width="100%" height="100%">
79
+ ${outputSvgString}
80
+ </svg>`;
81
+ }
82
+ async build() {
83
+ // Create a SciChartSurface
84
+ const { sciChartSurface, wasmContext } = await SciChartSurface.create(this.chart, {
85
+ theme: appTheme.SciChartJsTheme
86
+ });
87
+ // Add an XAxis of type DateTimeAxis
88
+ // Note for crypto data this is fine, but for stocks/forex you will need to use CategoryAxis which collapses gaps at weekends
89
+ // In future we have a hybrid IndexDateAxis which 'magically' solves problems of different # of points in stock market datasetd with gaps
90
+ const xAxis = new DateTimeNumericAxis(wasmContext, {
91
+ // autoRange.never as we're setting visibleRange explicitly below. If you dont do this, leave this flag default
92
+ autoRange: EAutoRange.Never
93
+ });
94
+ sciChartSurface.xAxes.add(xAxis);
95
+ // Create a NumericAxis on the YAxis with 2 Decimal Places
96
+ sciChartSurface.yAxes.add(new NumericAxis(wasmContext, {
97
+ growBy: new NumberRange(0.1, 0.1),
98
+ labelFormat: ENumericFormat.Decimal,
99
+ labelPrecision: 2,
100
+ labelPrefix: '$',
101
+ autoRange: EAutoRange.Always
102
+ }));
103
+ // Create a secondary YAxis to host volume data on its own scale
104
+ sciChartSurface.yAxes.add(new NumericAxis(wasmContext, {
105
+ id: Y_AXIS_VOLUME_ID,
106
+ growBy: new NumberRange(0, 4),
107
+ isVisible: false,
108
+ autoRange: EAutoRange.Always
109
+ }));
110
+ // Fetch data from now to 300 1hr candles ago
111
+ const endDate = new Date(Date.now());
112
+ const startDate = new Date();
113
+ startDate.setHours(endDate.getHours() - 300);
114
+ const priceBars = await simpleBinanceRestClient.getCandles('BTCUSDT', '1h', startDate, endDate);
115
+ // Maps PriceBar { date, open, high, low, close, volume } to structure-of-arrays expected by scichart
116
+ const xValues = [];
117
+ const openValues = [];
118
+ const highValues = [];
119
+ const lowValues = [];
120
+ const closeValues = [];
121
+ const volumeValues = [];
122
+ priceBars.forEach((priceBar) => {
123
+ xValues.push(priceBar.date);
124
+ openValues.push(priceBar.open);
125
+ highValues.push(priceBar.high);
126
+ lowValues.push(priceBar.low);
127
+ closeValues.push(priceBar.close);
128
+ volumeValues.push(priceBar.volume);
129
+ });
130
+ // Zoom to the latest 100 candles
131
+ const startViewportRange = new Date();
132
+ startViewportRange.setHours(startDate.getHours() - 100);
133
+ xAxis.visibleRange = new NumberRange(startViewportRange.getTime() / 1000, endDate.getTime() / 1000);
134
+ // Create and add the Candlestick series
135
+ // The Candlestick Series requires a special dataseries type called OhlcDataSeries with o,h,l,c and date values
136
+ const candleDataSeries = new OhlcDataSeries(wasmContext, {
137
+ xValues,
138
+ openValues,
139
+ highValues,
140
+ lowValues,
141
+ closeValues,
142
+ dataSeriesName: 'BTC/USDT'
143
+ });
144
+ const candlestickSeries = new FastCandlestickRenderableSeries(wasmContext, {
145
+ dataSeries: candleDataSeries,
146
+ stroke: appTheme.ForegroundColor, // used by cursorModifier below
147
+ strokeThickness: 1,
148
+ brushUp: appTheme.VividGreen + '77',
149
+ brushDown: appTheme.MutedRed + '77',
150
+ strokeUp: appTheme.VividGreen,
151
+ strokeDown: appTheme.MutedRed
152
+ });
153
+ sciChartSurface.renderableSeries.add(candlestickSeries);
154
+ // Add an Ohlcseries. this will be invisible to begin with
155
+ const ohlcSeries = new FastOhlcRenderableSeries(wasmContext, {
156
+ dataSeries: candleDataSeries,
157
+ stroke: appTheme.ForegroundColor, // used by cursorModifier below
158
+ strokeThickness: 1,
159
+ dataPointWidth: 0.9,
160
+ strokeUp: appTheme.VividGreen,
161
+ strokeDown: appTheme.MutedRed,
162
+ isVisible: false
163
+ });
164
+ sciChartSurface.renderableSeries.add(ohlcSeries);
165
+ // Add some moving averages using SciChart's filters/transforms API
166
+ // when candleDataSeries updates, XyMovingAverageFilter automatically recomputes
167
+ sciChartSurface.renderableSeries.add(new FastLineRenderableSeries(wasmContext, {
168
+ dataSeries: new XyMovingAverageFilter(candleDataSeries, {
169
+ dataSeriesName: 'Moving Average (20)',
170
+ length: 20
171
+ }),
172
+ stroke: appTheme.VividSkyBlue
173
+ }));
174
+ sciChartSurface.renderableSeries.add(new FastLineRenderableSeries(wasmContext, {
175
+ dataSeries: new XyMovingAverageFilter(candleDataSeries, {
176
+ dataSeriesName: 'Moving Average (50)',
177
+ length: 50
178
+ }),
179
+ stroke: appTheme.VividPink
180
+ }));
181
+ // Add volume data onto the chart
182
+ sciChartSurface.renderableSeries.add(new FastColumnRenderableSeries(wasmContext, {
183
+ dataSeries: new XyDataSeries(wasmContext, { xValues, yValues: volumeValues, dataSeriesName: 'Volume' }),
184
+ strokeThickness: 0,
185
+ // This is how we get volume to scale - on a hidden YAxis
186
+ yAxisId: Y_AXIS_VOLUME_ID,
187
+ // This is how we colour volume bars red or green
188
+ paletteProvider: new VolumePaletteProvider(candleDataSeries, appTheme.VividGreen + '77', appTheme.MutedRed + '77')
189
+ }));
190
+ // Optional: Add some interactivity modifiers
191
+ sciChartSurface.chartModifiers.add(new ZoomExtentsModifier(), new ZoomPanModifier(), new MouseWheelZoomModifier(), new CursorModifier({
192
+ crosshairStroke: appTheme.VividOrange,
193
+ axisLabelFill: appTheme.VividOrange,
194
+ tooltipLegendTemplate: this.getTooltipLegendTemplate
195
+ }));
196
+ // Add Overview chart. This will automatically bind to the parent surface
197
+ // displaying its series. Zooming the chart will zoom the overview and vice versa
198
+ const overview = await SciChartOverview.create(sciChartSurface, this.overview, {
199
+ theme: appTheme.SciChartJsTheme,
200
+ transformRenderableSeries: this.getOverviewSeries
201
+ });
202
+ return { sciChartSurface, overview, candlestickSeries, ohlcSeries };
203
+ }
204
+ };
205
+ SciCandleStockChart.styles = [
206
+ css `
207
+ :host {
208
+ display: flex;
209
+ flex-direction: column;
210
+
211
+ width: 100%;
212
+ }
213
+
214
+ #chart {
215
+ flex: 8;
216
+ }
217
+
218
+ #overview {
219
+ flex: 2;
220
+ }
221
+ `
222
+ ];
223
+ __decorate([
224
+ property({ type: String, attribute: 'series-type' })
225
+ ], SciCandleStockChart.prototype, "seriesType", void 0);
226
+ __decorate([
227
+ state()
228
+ ], SciCandleStockChart.prototype, "candlestickChartSeries", void 0);
229
+ __decorate([
230
+ state()
231
+ ], SciCandleStockChart.prototype, "ohlcChartSeries", void 0);
232
+ __decorate([
233
+ state()
234
+ ], SciCandleStockChart.prototype, "sciChartSurface", void 0);
235
+ __decorate([
236
+ state()
237
+ ], SciCandleStockChart.prototype, "sciChartOverview", void 0);
238
+ __decorate([
239
+ query('#chart')
240
+ ], SciCandleStockChart.prototype, "chart", void 0);
241
+ __decorate([
242
+ query('#overview')
243
+ ], SciCandleStockChart.prototype, "overview", void 0);
244
+ SciCandleStockChart = __decorate([
245
+ customElement('sci-candle-stock-chart')
246
+ ], SciCandleStockChart);
247
+ export { SciCandleStockChart };
248
+ //# sourceMappingURL=sci-candle-stick-chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sci-candle-stick-chart.js","sourceRoot":"","sources":["../../src/charts/sci-candle-stick-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, PropertyValues, PropertyValueMap, css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport {\n SciChartSurface,\n NumberRange,\n NumericAxis,\n OhlcDataSeries,\n FastCandlestickRenderableSeries,\n ZoomPanModifier,\n ZoomExtentsModifier,\n MouseWheelZoomModifier,\n ENumericFormat,\n DateTimeNumericAxis,\n EAutoRange,\n FastLineRenderableSeries,\n XyMovingAverageFilter,\n SciChartOverview,\n CursorModifier,\n CursorTooltipSvgAnnotation,\n SeriesInfo,\n EDataSeriesType,\n ESeriesType,\n IRenderableSeries,\n FastMountainRenderableSeries,\n GradientParams,\n Point,\n OhlcSeriesInfo,\n FastColumnRenderableSeries,\n XyDataSeries,\n FastOhlcRenderableSeries\n} from 'scichart'\n\nimport { appTheme } from '../themes/app-theme'\nimport { VolumePaletteProvider } from './volume-pallette-provider'\nimport { simpleBinanceRestClient } from '../data/binance-rest-client'\n\nconst Y_AXIS_VOLUME_ID = 'Y_AXIS_VOLUME_ID'\n\nSciChartSurface.configure({\n dataUrl: `/node_modules/scichart/_wasm/scichart2d.data`,\n wasmUrl: `/node_modules/scichart/_wasm/scichart2d.wasm`\n})\n\n@customElement('sci-candle-stock-chart')\nexport class SciCandleStockChart extends LitElement {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n width: 100%;\n }\n\n #chart {\n flex: 8;\n }\n\n #overview {\n flex: 2;\n }\n `\n ]\n\n render() {\n return html`\n <div id=\"chart\"></div>\n <div id=\"overview\"></div>\n `\n }\n\n @property({ type: String, attribute: 'series-type' }) seriesType: 'candle-stick' | 'ohlc' = 'candle-stick'\n\n @state() candlestickChartSeries!: FastCandlestickRenderableSeries\n @state() ohlcChartSeries!: FastOhlcRenderableSeries\n @state() sciChartSurface?: SciChartSurface\n @state() sciChartOverview?: SciChartOverview\n\n @query('#chart') chart!: HTMLDivElement\n @query('#overview') overview!: HTMLDivElement\n\n disconnectedCallback(): void {\n if (this.sciChartSurface) {\n this.sciChartSurface.delete()\n this.sciChartOverview!.delete()\n this.sciChartSurface = undefined\n this.sciChartOverview = undefined\n return\n }\n }\n\n protected async firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): Promise<void> {\n const { sciChartSurface, overview, candlestickSeries, ohlcSeries } = await this.build()\n\n this.candlestickChartSeries = candlestickSeries\n this.ohlcChartSeries = ohlcSeries\n this.sciChartSurface = sciChartSurface\n this.sciChartOverview = overview\n\n this.candlestickChartSeries.isVisible = this.seriesType == 'candle-stick'\n this.ohlcChartSeries.isVisible = this.seriesType == 'ohlc'\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('seriesType') && this.candlestickChartSeries) {\n this.candlestickChartSeries.isVisible = this.seriesType == 'candle-stick'\n this.ohlcChartSeries.isVisible = this.seriesType == 'ohlc'\n }\n }\n\n // Override the Renderableseries to display on the scichart overview\n private getOverviewSeries(defaultSeries: IRenderableSeries) {\n if (defaultSeries.type === ESeriesType.CandlestickSeries) {\n // Swap the default candlestick series on the overview chart for a mountain series. Same data\n return new FastMountainRenderableSeries(defaultSeries.parentSurface.webAssemblyContext2D, {\n dataSeries: defaultSeries.dataSeries,\n fillLinearGradient: new GradientParams(new Point(0, 0), new Point(0, 1), [\n { color: appTheme.VividSkyBlue + '77', offset: 0 },\n { color: 'Transparent', offset: 1 }\n ]),\n stroke: appTheme.VividSkyBlue\n })\n }\n }\n\n // Override the standard tooltip displayed by CursorModifier\n private getTooltipLegendTemplate(seriesInfos: SeriesInfo[], svgAnnotation: CursorTooltipSvgAnnotation) {\n let outputSvgString = ''\n\n // Foreach series there will be a seriesInfo supplied by SciChart. This contains info about the series under the house\n seriesInfos.forEach((seriesInfo, index) => {\n const y = 20 + index * 20\n const textColor = seriesInfo.stroke\n let legendText = seriesInfo.formattedYValue\n if (seriesInfo.dataSeriesType === EDataSeriesType.Ohlc) {\n const o = seriesInfo as OhlcSeriesInfo\n legendText = `Open=${o.formattedOpenValue} High=${o.formattedHighValue} Low=${o.formattedLowValue} Close=${o.formattedCloseValue}`\n }\n outputSvgString += `<text x=\"8\" y=\"${y}\" font-size=\"13\" font-family=\"Verdana\" fill=\"${textColor}\">\n ${seriesInfo.seriesName}: ${legendText}\n </text>`\n })\n\n return `<svg width=\"100%\" height=\"100%\">\n ${outputSvgString}\n </svg>`\n }\n\n private async build() {\n // Create a SciChartSurface\n const { sciChartSurface, wasmContext } = await SciChartSurface.create(this.chart, {\n theme: appTheme.SciChartJsTheme\n })\n\n // Add an XAxis of type DateTimeAxis\n // Note for crypto data this is fine, but for stocks/forex you will need to use CategoryAxis which collapses gaps at weekends\n // In future we have a hybrid IndexDateAxis which 'magically' solves problems of different # of points in stock market datasetd with gaps\n const xAxis = new DateTimeNumericAxis(wasmContext, {\n // autoRange.never as we're setting visibleRange explicitly below. If you dont do this, leave this flag default\n autoRange: EAutoRange.Never\n })\n sciChartSurface.xAxes.add(xAxis)\n\n // Create a NumericAxis on the YAxis with 2 Decimal Places\n sciChartSurface.yAxes.add(\n new NumericAxis(wasmContext, {\n growBy: new NumberRange(0.1, 0.1),\n labelFormat: ENumericFormat.Decimal,\n labelPrecision: 2,\n labelPrefix: '$',\n autoRange: EAutoRange.Always\n })\n )\n\n // Create a secondary YAxis to host volume data on its own scale\n sciChartSurface.yAxes.add(\n new NumericAxis(wasmContext, {\n id: Y_AXIS_VOLUME_ID,\n growBy: new NumberRange(0, 4),\n isVisible: false,\n autoRange: EAutoRange.Always\n })\n )\n\n // Fetch data from now to 300 1hr candles ago\n const endDate = new Date(Date.now())\n const startDate = new Date()\n startDate.setHours(endDate.getHours() - 300)\n const priceBars = await simpleBinanceRestClient.getCandles('BTCUSDT', '1h', startDate, endDate)\n\n // Maps PriceBar { date, open, high, low, close, volume } to structure-of-arrays expected by scichart\n const xValues: number[] = []\n const openValues: number[] = []\n const highValues: number[] = []\n const lowValues: number[] = []\n const closeValues: number[] = []\n const volumeValues: number[] = []\n priceBars.forEach((priceBar: any) => {\n xValues.push(priceBar.date)\n openValues.push(priceBar.open)\n highValues.push(priceBar.high)\n lowValues.push(priceBar.low)\n closeValues.push(priceBar.close)\n volumeValues.push(priceBar.volume)\n })\n\n // Zoom to the latest 100 candles\n const startViewportRange = new Date()\n startViewportRange.setHours(startDate.getHours() - 100)\n xAxis.visibleRange = new NumberRange(startViewportRange.getTime() / 1000, endDate.getTime() / 1000)\n\n // Create and add the Candlestick series\n // The Candlestick Series requires a special dataseries type called OhlcDataSeries with o,h,l,c and date values\n const candleDataSeries = new OhlcDataSeries(wasmContext, {\n xValues,\n openValues,\n highValues,\n lowValues,\n closeValues,\n dataSeriesName: 'BTC/USDT'\n })\n const candlestickSeries = new FastCandlestickRenderableSeries(wasmContext, {\n dataSeries: candleDataSeries,\n stroke: appTheme.ForegroundColor, // used by cursorModifier below\n strokeThickness: 1,\n brushUp: appTheme.VividGreen + '77',\n brushDown: appTheme.MutedRed + '77',\n strokeUp: appTheme.VividGreen,\n strokeDown: appTheme.MutedRed\n })\n sciChartSurface.renderableSeries.add(candlestickSeries)\n\n // Add an Ohlcseries. this will be invisible to begin with\n const ohlcSeries = new FastOhlcRenderableSeries(wasmContext, {\n dataSeries: candleDataSeries,\n stroke: appTheme.ForegroundColor, // used by cursorModifier below\n strokeThickness: 1,\n dataPointWidth: 0.9,\n strokeUp: appTheme.VividGreen,\n strokeDown: appTheme.MutedRed,\n isVisible: false\n })\n sciChartSurface.renderableSeries.add(ohlcSeries)\n\n // Add some moving averages using SciChart's filters/transforms API\n // when candleDataSeries updates, XyMovingAverageFilter automatically recomputes\n sciChartSurface.renderableSeries.add(\n new FastLineRenderableSeries(wasmContext, {\n dataSeries: new XyMovingAverageFilter(candleDataSeries, {\n dataSeriesName: 'Moving Average (20)',\n length: 20\n }),\n stroke: appTheme.VividSkyBlue\n })\n )\n\n sciChartSurface.renderableSeries.add(\n new FastLineRenderableSeries(wasmContext, {\n dataSeries: new XyMovingAverageFilter(candleDataSeries, {\n dataSeriesName: 'Moving Average (50)',\n length: 50\n }),\n stroke: appTheme.VividPink\n })\n )\n\n // Add volume data onto the chart\n sciChartSurface.renderableSeries.add(\n new FastColumnRenderableSeries(wasmContext, {\n dataSeries: new XyDataSeries(wasmContext, { xValues, yValues: volumeValues, dataSeriesName: 'Volume' }),\n strokeThickness: 0,\n // This is how we get volume to scale - on a hidden YAxis\n yAxisId: Y_AXIS_VOLUME_ID,\n // This is how we colour volume bars red or green\n paletteProvider: new VolumePaletteProvider(\n candleDataSeries,\n appTheme.VividGreen + '77',\n appTheme.MutedRed + '77'\n )\n })\n )\n\n // Optional: Add some interactivity modifiers\n sciChartSurface.chartModifiers.add(\n new ZoomExtentsModifier(),\n new ZoomPanModifier(),\n new MouseWheelZoomModifier(),\n new CursorModifier({\n crosshairStroke: appTheme.VividOrange,\n axisLabelFill: appTheme.VividOrange,\n tooltipLegendTemplate: this.getTooltipLegendTemplate\n })\n )\n\n // Add Overview chart. This will automatically bind to the parent surface\n // displaying its series. Zooming the chart will zoom the overview and vice versa\n const overview = await SciChartOverview.create(sciChartSurface, this.overview, {\n theme: appTheme.SciChartJsTheme,\n transformRenderableSeries: this.getOverviewSeries as any\n })\n\n return { sciChartSurface, overview, candlestickSeries, ohlcSeries }\n }\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import { OhlcDataSeries, IRenderableSeries, EFillPaletteMode, IFillPaletteProvider, IPointMetadata } from 'scichart';
2
+ export declare class VolumePaletteProvider implements IFillPaletteProvider {
3
+ fillPaletteMode: EFillPaletteMode;
4
+ private ohlcDataSeries;
5
+ private upColorArgb;
6
+ private downColorArgb;
7
+ constructor(masterData: OhlcDataSeries, upColor: string, downColor: string);
8
+ onAttached(parentSeries: IRenderableSeries): void;
9
+ onDetached(): void;
10
+ overrideFillArgb(xValue: number, yValue: number, index: number, opacity?: number, metadata?: IPointMetadata): number;
11
+ overrideStrokeArgb(xValue: number, yValue: number, index: number, opacity?: number, metadata?: IPointMetadata): number;
12
+ }
@@ -0,0 +1,21 @@
1
+ import { EFillPaletteMode, parseColorToUIntArgb } from 'scichart';
2
+ export class VolumePaletteProvider {
3
+ constructor(masterData, upColor, downColor) {
4
+ this.fillPaletteMode = EFillPaletteMode.SOLID;
5
+ this.upColorArgb = parseColorToUIntArgb(upColor);
6
+ this.downColorArgb = parseColorToUIntArgb(downColor);
7
+ this.ohlcDataSeries = masterData;
8
+ }
9
+ onAttached(parentSeries) { }
10
+ onDetached() { }
11
+ // Return up or down color for the volume bars depending on Ohlc data
12
+ overrideFillArgb(xValue, yValue, index, opacity, metadata) {
13
+ const isUpCandle = this.ohlcDataSeries.getNativeOpenValues().get(index) >= this.ohlcDataSeries.getNativeCloseValues().get(index);
14
+ return isUpCandle ? this.upColorArgb : this.downColorArgb;
15
+ }
16
+ // Override stroke as well, even though strokethickness is 0, because stroke is used if column thickness goes to 0.
17
+ overrideStrokeArgb(xValue, yValue, index, opacity, metadata) {
18
+ return this.overrideFillArgb(xValue, yValue, index, opacity, metadata);
19
+ }
20
+ }
21
+ //# sourceMappingURL=volume-pallette-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"volume-pallette-provider.js","sourceRoot":"","sources":["../../src/charts/volume-pallette-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,gBAAgB,EAGhB,oBAAoB,EACrB,MAAM,UAAU,CAAA;AAEjB,MAAM,OAAO,qBAAqB;IAMhC,YAAY,UAA0B,EAAE,OAAe,EAAE,SAAiB;QAL1E,oBAAe,GAAqB,gBAAgB,CAAC,KAAK,CAAA;QAMxD,IAAI,CAAC,WAAW,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAA;QAChD,IAAI,CAAC,aAAa,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAA;QACpD,IAAI,CAAC,cAAc,GAAG,UAAU,CAAA;IAClC,CAAC;IACD,UAAU,CAAC,YAA+B,IAAS,CAAC;IACpD,UAAU,KAAU,CAAC;IAErB,qEAAqE;IACrE,gBAAgB,CAAC,MAAc,EAAE,MAAc,EAAE,KAAa,EAAE,OAAgB,EAAE,QAAyB;QACzG,MAAM,UAAU,GACd,IAAI,CAAC,cAAc,CAAC,mBAAmB,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,oBAAoB,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAC/G,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAA;IAC3D,CAAC;IAED,mHAAmH;IACnH,kBAAkB,CAChB,MAAc,EACd,MAAc,EACd,KAAa,EACb,OAAgB,EAChB,QAAyB;QAEzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;IACxE,CAAC;CACF","sourcesContent":["import {\n OhlcDataSeries,\n IRenderableSeries,\n EFillPaletteMode,\n IFillPaletteProvider,\n IPointMetadata,\n parseColorToUIntArgb\n} from 'scichart'\n\nexport class VolumePaletteProvider implements IFillPaletteProvider {\n fillPaletteMode: EFillPaletteMode = EFillPaletteMode.SOLID\n private ohlcDataSeries: OhlcDataSeries\n private upColorArgb: number\n private downColorArgb: number\n\n constructor(masterData: OhlcDataSeries, upColor: string, downColor: string) {\n this.upColorArgb = parseColorToUIntArgb(upColor)\n this.downColorArgb = parseColorToUIntArgb(downColor)\n this.ohlcDataSeries = masterData\n }\n onAttached(parentSeries: IRenderableSeries): void {}\n onDetached(): void {}\n\n // Return up or down color for the volume bars depending on Ohlc data\n overrideFillArgb(xValue: number, yValue: number, index: number, opacity?: number, metadata?: IPointMetadata): number {\n const isUpCandle =\n this.ohlcDataSeries.getNativeOpenValues().get(index) >= this.ohlcDataSeries.getNativeCloseValues().get(index)\n return isUpCandle ? this.upColorArgb : this.downColorArgb\n }\n\n // Override stroke as well, even though strokethickness is 0, because stroke is used if column thickness goes to 0.\n overrideStrokeArgb(\n xValue: number,\n yValue: number,\n index: number,\n opacity?: number,\n metadata?: IPointMetadata\n ): number {\n return this.overrideFillArgb(xValue, yValue, index, opacity, metadata)\n }\n}\n"]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Defines a price bar with Open, High, Low, Close and Date encoded as number
3
+ */
4
+ export type TPriceBar = {
5
+ date: number;
6
+ open: number;
7
+ high: number;
8
+ low: number;
9
+ close: number;
10
+ volume: number;
11
+ };
12
+ export declare const simpleBinanceRestClient: {
13
+ getCandles: (symbol: string, interval: string, startTime?: Date, endTime?: Date, limit?: number) => Promise<TPriceBar[]>;
14
+ };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Parses JSON candles into TPriceBar array
3
+ * @param candles
4
+ */
5
+ const parseCandles = (candles) => {
6
+ const priceBars = [];
7
+ candles.forEach((candle) => {
8
+ const [timestamp, open, high, low, close, volume] = candle;
9
+ const openValue = parseFloat(open);
10
+ const highValue = parseFloat(high);
11
+ const lowValue = parseFloat(low);
12
+ const closeValue = parseFloat(close);
13
+ const volumeValue = parseFloat(volume);
14
+ priceBars.push({
15
+ date: timestamp / 1000,
16
+ open: openValue,
17
+ high: highValue,
18
+ low: lowValue,
19
+ close: closeValue,
20
+ volume: volumeValue
21
+ });
22
+ });
23
+ return priceBars;
24
+ };
25
+ /**
26
+ * Fetches candles from Binance Rest API
27
+ */
28
+ const getCandles = async (symbol, interval, startTime, endTime, limit = 500) => {
29
+ let url = `https://api.binance.us/api/v3/klines?symbol=${symbol}&interval=${interval}`;
30
+ if (startTime) {
31
+ url += `&startTime=${startTime.getTime()}`;
32
+ }
33
+ if (endTime) {
34
+ url += `&endTime=${endTime.getTime()}`;
35
+ }
36
+ if (limit) {
37
+ url += `&limit=${limit}`;
38
+ }
39
+ try {
40
+ console.log(`SimpleBinanceClient: Fetching ${symbol} ${interval} from ${startTime} to ${endTime}`);
41
+ const response = await fetch(url);
42
+ const data = await response.json();
43
+ return parseCandles(data);
44
+ }
45
+ catch (err) {
46
+ console.error(err);
47
+ return [];
48
+ }
49
+ };
50
+ export const simpleBinanceRestClient = {
51
+ getCandles
52
+ };
53
+ //# sourceMappingURL=binance-rest-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binance-rest-client.js","sourceRoot":"","sources":["../../src/data/binance-rest-client.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,MAAM,YAAY,GAAG,CAAC,OAAc,EAAe,EAAE;IACnD,MAAM,SAAS,GAAgB,EAAE,CAAA;IAEjC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAW,EAAE,EAAE;QAC9B,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,CAAA;QAC1D,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;QAClC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;QAClC,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;QAChC,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QACpC,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAEtC,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,SAAS,GAAG,IAAI;YACtB,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,WAAW;SACpB,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,GAAG,KAAK,EACtB,MAAc,EACd,QAAgB,EAChB,SAAgB,EAChB,OAAc,EACd,QAAgB,GAAG,EACG,EAAE;IACxB,IAAI,GAAG,GAAG,+CAA+C,MAAM,aAAa,QAAQ,EAAE,CAAA;IACtF,IAAI,SAAS,EAAE,CAAC;QACd,GAAG,IAAI,cAAc,SAAS,CAAC,OAAO,EAAE,EAAE,CAAA;IAC5C,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACZ,GAAG,IAAI,YAAY,OAAO,CAAC,OAAO,EAAE,EAAE,CAAA;IACxC,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACV,GAAG,IAAI,UAAU,KAAK,EAAE,CAAA;IAC1B,CAAC;IACD,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,iCAAiC,MAAM,IAAI,QAAQ,SAAS,SAAS,OAAO,OAAO,EAAE,CAAC,CAAA;QAClG,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;QACjC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAClB,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,UAAU;CACX,CAAA","sourcesContent":["/**\n * Defines a price bar with Open, High, Low, Close and Date encoded as number\n */\nexport type TPriceBar = {\n date: number\n open: number\n high: number\n low: number\n close: number\n volume: number\n}\n\n/**\n * Parses JSON candles into TPriceBar array\n * @param candles\n */\nconst parseCandles = (candles: any[]): TPriceBar[] => {\n const priceBars: TPriceBar[] = []\n\n candles.forEach((candle: any) => {\n const [timestamp, open, high, low, close, volume] = candle\n const openValue = parseFloat(open)\n const highValue = parseFloat(high)\n const lowValue = parseFloat(low)\n const closeValue = parseFloat(close)\n const volumeValue = parseFloat(volume)\n\n priceBars.push({\n date: timestamp / 1000,\n open: openValue,\n high: highValue,\n low: lowValue,\n close: closeValue,\n volume: volumeValue\n })\n })\n\n return priceBars\n}\n\n/**\n * Fetches candles from Binance Rest API\n */\nconst getCandles = async (\n symbol: string,\n interval: string,\n startTime?: Date,\n endTime?: Date,\n limit: number = 500\n): Promise<TPriceBar[]> => {\n let url = `https://api.binance.us/api/v3/klines?symbol=${symbol}&interval=${interval}`\n if (startTime) {\n url += `&startTime=${startTime.getTime()}`\n }\n if (endTime) {\n url += `&endTime=${endTime.getTime()}`\n }\n if (limit) {\n url += `&limit=${limit}`\n }\n try {\n console.log(`SimpleBinanceClient: Fetching ${symbol} ${interval} from ${startTime} to ${endTime}`)\n const response = await fetch(url)\n const data = await response.json()\n return parseCandles(data)\n } catch (err) {\n console.error(err)\n return []\n }\n}\n\nexport const simpleBinanceRestClient = {\n getCandles\n}\n"]}
File without changes
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/editors/index.ts"],"names":[],"mappings":"","sourcesContent":[""]}
File without changes
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/groups/index.ts"],"names":[],"mappings":"","sourcesContent":[""]}
@@ -0,0 +1,2 @@
1
+ export { default as Scichart } from './scichart';
2
+ export { default as ScichartCandleStick } from './scichart-candle-stick';
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { default as Scichart } from './scichart';
2
+ export { default as ScichartCandleStick } from './scichart-candle-stick';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAA","sourcesContent":["export { default as Scichart } from './scichart'\nexport { default as ScichartCandleStick } from './scichart-candle-stick'\n"]}
@@ -0,0 +1,10 @@
1
+ import './charts/sci-candle-stick-chart';
2
+ import { HTMLOverlayContainer, ComponentNature } from '@hatiolab/things-scene';
3
+ import { SciCandleStockChart } from './charts/sci-candle-stick-chart';
4
+ export default class ScichartCandleStick extends HTMLOverlayContainer {
5
+ static get nature(): ComponentNature;
6
+ dispose(): void;
7
+ setElementProperties(chart: SciCandleStockChart): void;
8
+ reposition(): void;
9
+ get tagName(): string;
10
+ }
@@ -0,0 +1,50 @@
1
+ /*
2
+ * Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+ const NATURE = {
5
+ mutable: false,
6
+ resizable: true,
7
+ rotatable: true,
8
+ properties: [
9
+ {
10
+ type: 'select',
11
+ label: 'series',
12
+ name: 'series',
13
+ property: {
14
+ options: ['', 'candle-stick', 'ohlc']
15
+ }
16
+ }
17
+ ]
18
+ };
19
+ import './charts/sci-candle-stick-chart';
20
+ import { Component, HTMLOverlayContainer } from '@hatiolab/things-scene';
21
+ export default class ScichartCandleStick extends HTMLOverlayContainer {
22
+ static get nature() {
23
+ return NATURE;
24
+ }
25
+ dispose() {
26
+ super.dispose();
27
+ }
28
+ /*
29
+ * 컴포넌트의 생성 또는 속성 변화 시에 호출되며,
30
+ * 그에 따른 html element의 반영이 필요한 부분을 구현한다.
31
+ *
32
+ * ThingsComponent state => HTML element properties
33
+ */
34
+ setElementProperties(chart) {
35
+ const { series = 'candle-stick' } = this.state;
36
+ chart.seriesType = series;
37
+ }
38
+ /*
39
+ * 컴포넌트가 ready 상태가 되거나, 컴포넌트의 속성이 변화될 시 setElementProperties 뒤에 호출된다.
40
+ * 변화에 따른 기본적인 html 속성이 super.reposition()에서 진행되고, 그 밖의 작업이 필요할 때, 오버라이드 한다.
41
+ */
42
+ reposition() {
43
+ super.reposition();
44
+ }
45
+ get tagName() {
46
+ return 'sci-candle-stock-chart';
47
+ }
48
+ }
49
+ Component.register('scichart-candle-stick', ScichartCandleStick);
50
+ //# sourceMappingURL=scichart-candle-stick.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scichart-candle-stick.js","sourceRoot":"","sources":["../src/scichart-candle-stick.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,GAAG;IACb,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE;gBACR,OAAO,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,MAAM,CAAC;aACtC;SACF;KACF;CACF,CAAA;AAED,OAAO,iCAAiC,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAsC,MAAM,wBAAwB,CAAA;AAI5G,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,oBAAoB;IACnE,MAAM,KAAK,MAAM;QACf,OAAO,MAAM,CAAA;IACf,CAAC;IAED,OAAO;QACL,KAAK,CAAC,OAAO,EAAE,CAAA;IACjB,CAAC;IAED;;;;;OAKG;IACH,oBAAoB,CAAC,KAA0B;QAC7C,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAE9C,KAAK,CAAC,UAAU,GAAG,MAAM,CAAA;IAC3B,CAAC;IAED;;;OAGG;IACH,UAAU;QACR,KAAK,CAAC,UAAU,EAAE,CAAA;IACpB,CAAC;IAED,IAAI,OAAO;QACT,OAAO,wBAAwB,CAAA;IACjC,CAAC;CACF;AAED,SAAS,CAAC,QAAQ,CAAC,uBAAuB,EAAE,mBAAmB,CAAC,CAAA","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nconst NATURE = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'series',\n name: 'series',\n property: {\n options: ['', 'candle-stick', 'ohlc']\n }\n }\n ]\n}\n\nimport './charts/sci-candle-stick-chart'\nimport { Component, HTMLOverlayContainer, Properties, ComponentNature, error } from '@hatiolab/things-scene'\n\nimport { SciCandleStockChart } from './charts/sci-candle-stick-chart'\n\nexport default class ScichartCandleStick extends HTMLOverlayContainer {\n static get nature(): ComponentNature {\n return NATURE\n }\n\n dispose() {\n super.dispose()\n }\n\n /*\n * 컴포넌트의 생성 또는 속성 변화 시에 호출되며,\n * 그에 따른 html element의 반영이 필요한 부분을 구현한다.\n *\n * ThingsComponent state => HTML element properties\n */\n setElementProperties(chart: SciCandleStockChart) {\n const { series = 'candle-stick' } = this.state\n\n chart.seriesType = series\n }\n\n /*\n * 컴포넌트가 ready 상태가 되거나, 컴포넌트의 속성이 변화될 시 setElementProperties 뒤에 호출된다.\n * 변화에 따른 기본적인 html 속성이 super.reposition()에서 진행되고, 그 밖의 작업이 필요할 때, 오버라이드 한다.\n */\n reposition() {\n super.reposition()\n }\n\n get tagName() {\n return 'sci-candle-stock-chart'\n }\n}\n\nComponent.register('scichart-candle-stick', ScichartCandleStick)\n"]}
@@ -0,0 +1,23 @@
1
+ import { HTMLOverlayContainer } from '@hatiolab/things-scene';
2
+ export default class ScichartTimeSeries extends HTMLOverlayContainer {
3
+ static get nature(): {
4
+ mutable: boolean;
5
+ resizable: boolean;
6
+ rotatable: boolean;
7
+ properties: {
8
+ type: string;
9
+ label: string;
10
+ name: string;
11
+ }[];
12
+ };
13
+ _anchor?: HTMLDivElement;
14
+ oncreate_element(div: HTMLDivElement): Promise<void>;
15
+ dispose(): void;
16
+ setElementProperties(div: HTMLDivElement): void;
17
+ reposition(): void;
18
+ get dataSet(): {
19
+ xValue: number;
20
+ yValue: number;
21
+ }[];
22
+ get tagName(): string;
23
+ }