@operato/chart 8.0.0-beta.0 → 8.0.0-beta.2

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/package.json +6 -6
  3. package/.editorconfig +0 -29
  4. package/.storybook/main.js +0 -3
  5. package/.storybook/preview.js +0 -52
  6. package/.storybook/server.mjs +0 -8
  7. package/demo/index.html +0 -33
  8. package/src/chartjs/config-converter.ts +0 -341
  9. package/src/chartjs/ox-chart-js.ts +0 -207
  10. package/src/editors/configurer.ts +0 -336
  11. package/src/editors/index.ts +0 -8
  12. package/src/editors/input-chart-abstract.ts +0 -202
  13. package/src/editors/input-chart-styles.ts +0 -206
  14. package/src/editors/ox-input-chart-hbar.ts +0 -157
  15. package/src/editors/ox-input-chart-mixed.ts +0 -241
  16. package/src/editors/ox-input-chart-pie.ts +0 -69
  17. package/src/editors/ox-input-chart-radar.ts +0 -56
  18. package/src/editors/ox-input-chart-timeseries.ts +0 -279
  19. package/src/editors/ox-property-editor-chart.ts +0 -72
  20. package/src/editors/templates/annotations.ts +0 -295
  21. package/src/editors/templates/display-value.ts +0 -111
  22. package/src/editors/templates/series.ts +0 -316
  23. package/src/global.d.ts +0 -1
  24. package/src/index.ts +0 -0
  25. package/src/progress/ox-progress-circle.ts +0 -133
  26. package/src/scichart/ox-scichart.ts +0 -151
  27. package/src/scichart/scichart-builder.ts +0 -508
  28. package/src/types.d.ts +0 -124
  29. package/stories/common.ts +0 -87
  30. package/stories/ox-input-chart-bar.stories.ts +0 -188
  31. package/stories/ox-input-chart-doughnut.stories.ts +0 -130
  32. package/stories/ox-input-chart-hbar.stories.ts +0 -188
  33. package/stories/ox-input-chart-line.stories.ts +0 -198
  34. package/stories/ox-input-chart-pie.stories.ts +0 -130
  35. package/stories/ox-input-chart-polar-area.stories.ts +0 -130
  36. package/stories/ox-input-chart-radar.stories.ts +0 -141
  37. package/stories/ox-input-chart-timeseries.stories.ts +0 -268
  38. package/tsconfig.json +0 -25
  39. package/web-dev-server.config.mjs +0 -27
  40. package/web-test-runner.config.mjs +0 -41
@@ -1,508 +0,0 @@
1
- import { TinyColor } from '@ctrl/tinycolor'
2
- import { format as formatText } from '@operato/utils/format.js'
3
-
4
- function getBaseColorFromTheme(theme?: 'light' | 'dark' | 'auto') {
5
- return new TinyColor(theme == 'dark' ? '#fff' : '#000')
6
- }
7
-
8
- function getThemeFromBrowser() {
9
- return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
10
- }
11
-
12
- function convertColor(color: string | string[] | undefined, defaultColor?: string) {
13
- const tinyColor = new TinyColor(color as string)
14
- return tinyColor.toHex8String() || defaultColor
15
- }
16
-
17
- function getLocalTimeOffset() {
18
- const now = new Date()
19
- return now.getTimezoneOffset() * -60
20
- }
21
-
22
- function calculatePrecision(stepSize: number = 1) {
23
- // stepSize를 문자열로 변환한 다음, 소수점 이후 자릿수를 계산
24
- const stepSizeString = stepSize.toString()
25
-
26
- // 소수점이 있는 경우, 소수점 이후 자릿수 계산
27
- if (stepSizeString.indexOf('.') !== -1) {
28
- return stepSizeString.split('.')[1].length
29
- }
30
-
31
- // 소수점이 없는 경우, precision은 0
32
- return 0
33
- }
34
-
35
- export async function buildSciChart(
36
- config: OperatoChart.ChartConfig | undefined | null,
37
- container: any,
38
- { fontSize = 14, fontFamily = 'Roboto', fontColor }: { fontSize?: number; fontFamily?: string; fontColor?: string }
39
- ): Promise<{ chart: any; dataSeries: any[] } | undefined> {
40
- if (!config) {
41
- return
42
- }
43
-
44
- const {
45
- SciChartSurface,
46
- SciChartJSLightTheme,
47
- SciChartJSDarkv2Theme,
48
- XyDataSeries,
49
- FastLineRenderableSeries,
50
- SplineLineRenderableSeries,
51
- FastColumnRenderableSeries,
52
- StackedColumnRenderableSeries,
53
- StackedMountainRenderableSeries,
54
- StackedColumnCollection,
55
- StackedMountainCollection,
56
- NumericAxis,
57
- DateTimeNumericAxis,
58
- ENumericFormat,
59
- EAutoRange,
60
- EAxisAlignment,
61
- ECoordinateMode,
62
- EHorizontalAnchorPoint,
63
- EVerticalAnchorPoint,
64
- NumberRange,
65
- MouseWheelZoomModifier,
66
- RubberBandXyZoomModifier,
67
- ZoomPanModifier,
68
- ZoomExtentsModifier,
69
- RolloverModifier,
70
- SmartDateLabelProvider,
71
- NumericLabelProvider,
72
- EllipsePointMarker,
73
- SquarePointMarker,
74
- TrianglePointMarker,
75
- CrossPointMarker,
76
- XPointMarker,
77
- WaveAnimation,
78
- LegendModifier,
79
- XAxisDragModifier,
80
- YAxisDragModifier,
81
- TextAnnotation,
82
- LineAnnotation,
83
- BoxAnnotation,
84
- HorizontalLineAnnotation,
85
- VerticalLineAnnotation
86
- } = SciChart
87
-
88
- class LocalTimeLabelProvider extends SmartDateLabelProvider {
89
- formatLabel(value: number): string {
90
- const date = new Date(value)
91
-
92
- try {
93
- const formatter = new Intl.DateTimeFormat(navigator.language || 'en-US', {
94
- year: 'numeric',
95
- month: '2-digit',
96
- day: '2-digit',
97
- hour: '2-digit',
98
- minute: '2-digit',
99
- second: '2-digit'
100
- })
101
-
102
- return formatter.format(date)
103
- } catch (e) {
104
- console.warn('Invalid locale or options provided, falling back to default.', e)
105
-
106
- const fallbackFormatter = new Intl.DateTimeFormat('en-US', {
107
- year: 'numeric',
108
- month: '2-digit',
109
- day: '2-digit',
110
- hour: '2-digit',
111
- minute: '2-digit',
112
- second: '2-digit'
113
- })
114
-
115
- return fallbackFormatter.format(date)
116
- }
117
- }
118
- }
119
-
120
- const { type: chartType, options, data: fromData } = config
121
- const { datasets = [] } = fromData || {}
122
- var {
123
- theme,
124
- tooltip = true,
125
- animation = true,
126
- legend = {
127
- display: true,
128
- position: 'top'
129
- },
130
- scales: fromScales,
131
- xGridLine = true,
132
- yGridLine = true,
133
- y2ndGridLine = false,
134
- stacked = false,
135
- multiAxis = false,
136
- annotations = []
137
- } = options || {}
138
-
139
- var baseColor = getBaseColorFromTheme(theme)
140
-
141
- if (theme === 'auto') {
142
- theme = getThemeFromBrowser()
143
- }
144
-
145
- fontColor = fontColor || baseColor.clone().toString()
146
-
147
- const { xAxes = [], yAxes = [] } = fromScales || {}
148
-
149
- const chart = await SciChartSurface.create(container, {
150
- theme: theme == 'dark' ? new SciChartJSDarkv2Theme() : new SciChartJSLightTheme()
151
- })
152
- const { sciChartSurface, wasmContext } = chart
153
-
154
- // X 축 설정
155
- xAxes.forEach((axis, index) => {
156
- const { axisTitle, ticks } = axis
157
- const {
158
- autoMax,
159
- autoMin,
160
- min,
161
- max,
162
- stepSize,
163
- beginAtZero,
164
- color = fontColor,
165
- textStrokeColor = fontColor,
166
- display = !!axisTitle
167
- } = ticks || {}
168
-
169
- const labelProvider = new SmartDateLabelProvider({
170
- showWiderDateOnFirstLabel: true,
171
- showYearOnWiderDate: true,
172
- dateOffset: getLocalTimeOffset()
173
- })
174
-
175
- labelProvider.cursorNumericFormat = ENumericFormat.Date_MMHHSS
176
-
177
- const xAxis = new DateTimeNumericAxis(wasmContext, {
178
- axisTitle,
179
- autoRange: autoMin || autoMax ? EAutoRange.Always : undefined,
180
- axisAlignment: EAxisAlignment.Bottom,
181
- visibleRange: min !== undefined && max !== undefined ? new NumberRange(min, max) : undefined,
182
- majorDelta: stepSize,
183
- growBy: beginAtZero ? new NumberRange(0.1, 0.1) : undefined,
184
- labelStyle: {
185
- fontFamily,
186
- fontSize,
187
- color
188
- },
189
- axisTitleStyle: {
190
- fontFamily,
191
- fontSize,
192
- color: textStrokeColor
193
- },
194
- labelProvider
195
- })
196
-
197
- sciChartSurface.xAxes.add(xAxis)
198
- })
199
-
200
- // Y 축 설정
201
- ;(multiAxis ? yAxes : [yAxes[0]]).forEach((axis, index) => {
202
- const { axisTitle, ticks } = axis
203
- const { autoMax, autoMin, min, max, stepSize, beginAtZero, display } = ticks || {}
204
-
205
- const labelProvider = display ? new NumericLabelProvider() : undefined
206
-
207
- if (labelProvider) {
208
- labelProvider.numericFormat = ENumericFormat.Decimal
209
- labelProvider.precision = calculatePrecision(stepSize || 0.1)
210
- labelProvider.cursorNumericFormat = ENumericFormat.NoFormat
211
- }
212
-
213
- const yAxis = new NumericAxis(wasmContext, {
214
- id: index == 0 ? undefined : `yAxis${index}`,
215
- axisTitle,
216
- autoRange: autoMin || autoMax ? EAutoRange.Always : undefined,
217
- axisAlignment: index === 0 ? EAxisAlignment.Left : EAxisAlignment.Right,
218
- visibleRange: min !== undefined && max !== undefined ? new NumberRange(min, max) : undefined,
219
- majorDelta: stepSize || 0.1,
220
- minorDelta: (stepSize || 1) * 0.1,
221
- growBy: beginAtZero ? new NumberRange(0.1, 0.1) : undefined,
222
- labelStyle: {
223
- display: !!display,
224
- fontFamily,
225
- fontSize,
226
- color: fontColor
227
- },
228
- axisTitleStyle: {
229
- fontFamily,
230
- fontSize,
231
- color: fontColor
232
- },
233
- labelProvider
234
- })
235
-
236
- sciChartSurface.yAxes.add(yAxis)
237
- })
238
-
239
- // 시리즈 설정
240
- const dataSeriesArray = datasets.map((dataset, index) => {
241
- const dataSeries = new XyDataSeries(wasmContext, {
242
- dataSeriesName: dataset.label,
243
- containsNaN: false
244
- })
245
-
246
- const yAxisId = dataset.yAxisID == 'right' && multiAxis ? 'yAxis1' : undefined
247
- const stackGroupId = dataset.stack || `__stack${index}__`
248
-
249
- let series: any
250
- if (dataset.type === 'bar') {
251
- if (stacked) {
252
- series = new StackedColumnRenderableSeries(wasmContext, {
253
- dataSeries,
254
- strokeThickness: dataset.borderWidth || 2,
255
- fill: convertColor(dataset.backgroundColor, '#FF6600'),
256
- yAxisId,
257
- stackedGroupId: stackGroupId
258
- })
259
- } else {
260
- series = new FastColumnRenderableSeries(wasmContext, {
261
- dataSeries,
262
- strokeThickness: dataset.borderWidth || 2,
263
- stroke: convertColor(dataset.backgroundColor, '#FF6600'),
264
- animation: animation && new WaveAnimation({ duration: 1000, fadeEffect: true }),
265
- yAxisId
266
- })
267
- }
268
- } else {
269
- const { pointStyle, pointRadius = 10, lineTension } = dataset
270
- let pointMarker = null // 초기값을 null로 설정
271
-
272
- if (pointStyle) {
273
- switch (pointStyle) {
274
- case 'circle':
275
- pointMarker = new EllipsePointMarker(wasmContext, {
276
- width: pointRadius,
277
- height: pointRadius,
278
- strokeThickness: 2,
279
- fill: convertColor(dataset.color, '#FF6600'),
280
- stroke: '#000000'
281
- })
282
- break
283
- case 'triangle':
284
- pointMarker = new TrianglePointMarker(wasmContext, {
285
- width: pointRadius,
286
- height: pointRadius,
287
- strokeThickness: 2,
288
- fill: convertColor(dataset.color, '#FF6600'),
289
- stroke: '#000000'
290
- })
291
- break
292
- case 'rect':
293
- pointMarker = new SquarePointMarker(wasmContext, {
294
- width: pointRadius,
295
- height: pointRadius,
296
- strokeThickness: 2,
297
- fill: convertColor(dataset.color, '#FF6600'),
298
- stroke: '#000000'
299
- })
300
- break
301
- case 'cross':
302
- pointMarker = new CrossPointMarker(wasmContext, {
303
- width: pointRadius,
304
- height: pointRadius,
305
- strokeThickness: 2,
306
- fill: convertColor(dataset.color, '#FF6600'),
307
- stroke: '#000000'
308
- })
309
- break
310
- case 'crossRot':
311
- pointMarker = new XPointMarker(wasmContext, {
312
- width: pointRadius,
313
- height: pointRadius,
314
- strokeThickness: 2,
315
- fill: convertColor(dataset.color, '#FF6600'),
316
- stroke: '#000000'
317
- })
318
- break
319
- default:
320
- pointMarker = new EllipsePointMarker(wasmContext, {
321
- width: pointRadius,
322
- height: pointRadius,
323
- strokeThickness: 2,
324
- fill: convertColor(dataset.color, '#FF6600'),
325
- stroke: '#000000'
326
- })
327
- }
328
- }
329
-
330
- if (stacked) {
331
- series = new StackedMountainRenderableSeries(wasmContext, {
332
- dataSeries,
333
- strokeThickness: dataset.borderWidth || 2,
334
- stroke: convertColor(dataset.color, '#FF6600'),
335
- fill: dataset.backgroundColor || '#FF6600',
336
- yAxisId,
337
- stackedGroupId: stackGroupId
338
- })
339
- } else {
340
- series =
341
- !!lineTension && lineTension > 0
342
- ? new SplineLineRenderableSeries(wasmContext, {
343
- dataSeries,
344
- strokeThickness: dataset.borderWidth || 2,
345
- stroke: convertColor(dataset.color, '#FF6600'),
346
- pointMarker,
347
- animation: animation && new WaveAnimation({ duration: 1000, fadeEffect: true }),
348
- yAxisId
349
- })
350
- : new FastLineRenderableSeries(wasmContext, {
351
- dataSeries,
352
- strokeThickness: dataset.borderWidth || 2,
353
- stroke: convertColor(dataset.color, '#FF6600'),
354
- pointMarker,
355
- animation: animation && new WaveAnimation({ duration: 1000, fadeEffect: true }),
356
- yAxisId
357
- })
358
- }
359
- }
360
-
361
- sciChartSurface.renderableSeries.add(series)
362
-
363
- if (tooltip) {
364
- const rolloverModifier = new RolloverModifier({
365
- showTooltip: true,
366
- showAxisLabel: false /* 한글의 크기를 잘 계산하지 못하므로 false */,
367
- tooltipColor: 'white',
368
- tooltipBackgroundColor: 'rgba(0, 0, 0, 0.7)',
369
- rollOverDataSeries: dataSeries
370
- })
371
-
372
- sciChartSurface.chartModifiers.add(rolloverModifier)
373
- }
374
-
375
- return dataSeries
376
- })
377
-
378
- // Stacked collections 추가
379
- if (stacked) {
380
- const stackedColumnCollection = new StackedColumnCollection(wasmContext)
381
- const stackedMountainCollection = new StackedMountainCollection(wasmContext)
382
-
383
- sciChartSurface.renderableSeries.asArray().forEach((series: any) => {
384
- if (series instanceof StackedColumnRenderableSeries) {
385
- stackedColumnCollection.add(series)
386
- } else if (series instanceof StackedMountainRenderableSeries) {
387
- stackedMountainCollection.add(series)
388
- }
389
- })
390
-
391
- if (stackedColumnCollection.size() > 0) {
392
- sciChartSurface.renderableSeries.add(stackedColumnCollection)
393
- }
394
-
395
- if (stackedMountainCollection.size() > 0) {
396
- sciChartSurface.renderableSeries.add(stackedMountainCollection)
397
- }
398
- }
399
-
400
- if (annotations) {
401
- annotations.forEach(annotation => {
402
- let sciAnnotation
403
- let horizontalAnchorPoint =
404
- annotation.horizontalAnchorPoint == 'Right'
405
- ? EHorizontalAnchorPoint.Right
406
- : annotation.horizontalAnchorPoint == 'Left'
407
- ? EHorizontalAnchorPoint.Left
408
- : EHorizontalAnchorPoint.Center
409
- let verticalAnchorPoint =
410
- annotation.verticalAnchorPoint == 'Top'
411
- ? EVerticalAnchorPoint.Top
412
- : annotation.verticalAnchorPoint == 'Bottom'
413
- ? EVerticalAnchorPoint.Bottom
414
- : EVerticalAnchorPoint.Center
415
-
416
- switch (annotation.type) {
417
- case 'text':
418
- sciAnnotation = new TextAnnotation({
419
- x1: annotation.x1,
420
- y1: annotation.y1,
421
- text: annotation.text,
422
- horizontalAnchorPoint,
423
- verticalAnchorPoint,
424
- fontSize: annotation.fontSize,
425
- fontFamily: annotation.fontFamily,
426
- textColor: convertColor(annotation.stroke, fontColor),
427
- xCoordinateMode: annotation.xCoordinateMode || ECoordinateMode.DataValue,
428
- yCoordinateMode: annotation.yCoordinateMode || ECoordinateMode.DataValue
429
- })
430
- break
431
- case 'line':
432
- sciAnnotation = new LineAnnotation({
433
- x1: annotation.x1,
434
- y1: annotation.y1,
435
- x2: annotation.x2,
436
- y2: annotation.y2,
437
- stroke: convertColor(annotation.stroke, '#FF0000'),
438
- strokeThickness: annotation.strokeThickness,
439
- xCoordinateMode: annotation.xCoordinateMode || ECoordinateMode.DataValue,
440
- yCoordinateMode: annotation.yCoordinateMode || ECoordinateMode.DataValue
441
- })
442
- break
443
- case 'box':
444
- sciAnnotation = new BoxAnnotation({
445
- x1: annotation.x1,
446
- y1: annotation.y1,
447
- x2: annotation.x2,
448
- y2: annotation.y2,
449
- fill: convertColor(annotation.fill, '#FF0000'),
450
- stroke: convertColor(annotation.stroke, '#FF0000'),
451
- strokeThickness: annotation.strokeThickness,
452
- xCoordinateMode: annotation.xCoordinateMode || ECoordinateMode.DataValue,
453
- yCoordinateMode: annotation.yCoordinateMode || ECoordinateMode.DataValue
454
- })
455
- break
456
- case 'horizontalLine':
457
- sciAnnotation = new HorizontalLineAnnotation({
458
- y1: annotation.y1,
459
- stroke: convertColor(annotation.stroke, '#FF0000'),
460
- strokeThickness: annotation.strokeThickness,
461
- xCoordinateMode: annotation.xCoordinateMode || ECoordinateMode.DataValue,
462
- yCoordinateMode: annotation.yCoordinateMode || ECoordinateMode.DataValue
463
- })
464
- break
465
- case 'verticalLine':
466
- sciAnnotation = new VerticalLineAnnotation({
467
- x1: annotation.x1,
468
- stroke: convertColor(annotation.stroke, '#FF0000'),
469
- strokeThickness: annotation.strokeThickness,
470
- xCoordinateMode: annotation.xCoordinateMode || ECoordinateMode.DataValue,
471
- yCoordinateMode: annotation.yCoordinateMode || ECoordinateMode.DataValue
472
- })
473
- break
474
- default:
475
- console.error('Unknown annotation type:', annotation.type)
476
- break
477
- }
478
- if (sciAnnotation) {
479
- sciChartSurface.annotations.add(sciAnnotation)
480
- } else {
481
- console.error('Failed to create annotation:', annotation)
482
- }
483
- })
484
- }
485
-
486
- // 줌인/줌아웃 모디파이어 추가
487
- sciChartSurface.chartModifiers.add(
488
- // new RubberBandXyZoomModifier(),
489
- new ZoomPanModifier(),
490
- new MouseWheelZoomModifier(),
491
- new ZoomExtentsModifier(),
492
- new XAxisDragModifier(),
493
- new YAxisDragModifier()
494
- )
495
-
496
- // Legend 설정
497
- if (legend?.display) {
498
- const legendModifier = new LegendModifier({
499
- showCheckboxes: true,
500
- showSeriesMarkers: true,
501
- showLegend: true,
502
- placement: legend.position || 'bottom-right'
503
- })
504
- sciChartSurface.chartModifiers.add(legendModifier)
505
- }
506
-
507
- return { chart, dataSeries: dataSeriesArray }
508
- }
package/src/types.d.ts DELETED
@@ -1,124 +0,0 @@
1
- declare namespace OperatoChart {
2
- export type SeriesType = 'bar' | 'horizontalBar' | 'line' | 'radar' | 'pie' | 'doughnut' | 'polarArea' | undefined
3
- export type ChartType =
4
- | 'bar'
5
- | 'horizontalBar'
6
- | 'line'
7
- | 'radar'
8
- | 'pie'
9
- | 'doughnut'
10
- | 'polarArea'
11
- | 'mixed'
12
- | 'timeseries'
13
-
14
- export interface ChartConfig {
15
- data: ChartData
16
- options?: ChartOptions
17
- type?: ChartType
18
- }
19
-
20
- export interface ChartData {
21
- labels?: Array<string | string[]>
22
- datasets: Dataset[]
23
- labelDataKey?: string
24
- }
25
-
26
- export interface Dataset {
27
- label?: string
28
- data?: any[]
29
- borderWidth?: number
30
- dataKey?: string
31
- yAxisID?: string
32
- color?: string | string[]
33
- type?: ChartType
34
- backgroundColor?: string | string[]
35
- stack?: string
36
- fill?: boolean
37
- lineTension?: number
38
- pointStyle?:
39
- | 'circle'
40
- | 'triangle'
41
- | 'rect'
42
- | 'rectRot'
43
- | 'cross'
44
- | 'crossRot'
45
- | 'star'
46
- | 'line'
47
- | 'dash'
48
- | undefined
49
- pointRadius?: number
50
- valuePrefix?: string
51
- valueSuffix?: string
52
- valueFormat?: string
53
- displayValue?: boolean | 'T' | 'F' | 'auto'
54
- dataLabelAnchor?: string
55
- dataLabelOffset?: number
56
- dataLabelRotation?: number
57
- [key: string]: any
58
- }
59
-
60
- export interface ChartOptions {
61
- theme?: 'dark' | 'light' | 'auto'
62
- tooltip?: boolean
63
- animation?: boolean
64
- legend?: LegendOptions
65
- scales?: ScalesOptions
66
- stacked?: boolean
67
- xGridLine?: boolean
68
- yGridLine?: boolean
69
- y2ndGridLine?: boolean
70
- multiAxis?: boolean
71
- maintainAspectRatio?: boolean
72
- plugins?: { [plugin: string]: any }
73
- annotations?: Annotation[]
74
- }
75
-
76
- export interface LegendOptions {
77
- display?: boolean
78
- position?: 'top' | 'right' | 'bottom' | 'left'
79
- }
80
-
81
- export interface ScalesOptions {
82
- xAxes?: AxisOptions[]
83
- yAxes?: AxisOptions[]
84
- }
85
-
86
- export interface AxisOptions {
87
- axisTitle?: string
88
- barSpacing?: number
89
- categorySpacing?: number
90
- barPercentage?: number
91
- ticks?: TickOptions
92
- }
93
-
94
- export interface TickOptions {
95
- display?: boolean
96
- autoMin?: boolean
97
- autoMax?: boolean
98
- min?: number
99
- max?: number
100
- stepSize?: number
101
- beginAtZero?: boolean
102
- color?: string
103
- textStrokeColor?: string
104
- }
105
-
106
- export interface Annotation {
107
- type: AnnotationType
108
- x1?: number
109
- y1?: number
110
- x2?: number
111
- y2?: number
112
- stroke?: string
113
- strokeThickness?: number
114
- fill?: string
115
- text?: string
116
- horizontalAnchorPoint?: 'Left' | 'Center' | 'Right'
117
- verticalAnchorPoint?: 'Top' | 'Center' | 'Bottom'
118
- xCoordinateMode?: 'DataValue' | 'Pixel' | 'Relative'
119
- yCoordinateMode?: 'DataValue' | 'Pixel' | 'Relative'
120
- [key: string]: any
121
- }
122
-
123
- export type AnnotationType = 'line' | 'text' | 'box' | 'horizontalLine' | 'verticalLine' | undefined
124
- }
package/stories/common.ts DELETED
@@ -1,87 +0,0 @@
1
- export function getDefaultChartConfig(
2
- type: OperatoChart.ChartType,
3
- datasets?: OperatoChart.Dataset[]
4
- ): OperatoChart.ChartConfig {
5
- return {
6
- data: {
7
- datasets: datasets || [],
8
- labelDataKey: ''
9
- },
10
- options: {
11
- theme: 'light',
12
- tooltip: true,
13
- animation: true,
14
- legend: {
15
- display: true,
16
- position: 'top'
17
- },
18
- scales: {
19
- xAxes: [getDefaultAxisOptions()],
20
- yAxes: [getDefaultAxisOptions(), getDefaultAxisOptions()] // Two y-axes for multi-axis support
21
- },
22
- stacked: false,
23
- xGridLine: true,
24
- yGridLine: true,
25
- y2ndGridLine: false,
26
- multiAxis: false
27
- },
28
- type
29
- }
30
- }
31
-
32
- export function getDefaultAxisOptions(): OperatoChart.AxisOptions {
33
- return {
34
- axisTitle: '',
35
- barSpacing: 0,
36
- categorySpacing: 0,
37
- barPercentage: 0.9,
38
- ticks: {
39
- display: true,
40
- autoMin: true,
41
- autoMax: true,
42
- min: undefined,
43
- max: undefined,
44
- stepSize: undefined
45
- }
46
- }
47
- }
48
-
49
- // export const data = [
50
- // { timestamp: 2010, count: 10, average: 120 },
51
- // { timestamp: 2011, count: 20, average: 110 },
52
- // { timestamp: 2012, count: 15, average: 80 },
53
- // { timestamp: 2013, count: 25, average: 130 },
54
- // { timestamp: 2014, count: 22, average: 120 },
55
- // { timestamp: 2015, count: 30, average: 60 },
56
- // { timestamp: 2016, count: 28, average: 90 }
57
- // ]
58
- // 랜덤한 범위의 숫자를 생성하는 함수
59
- function getRandomInRange(i: number, min: number, max: number) {
60
- if (!(i % 11)) {
61
- return null
62
- }
63
- return Math.floor(Math.random() * (max - min + 1)) + min
64
- }
65
-
66
- // 랜덤 데이터를 생성하는 함수
67
- function generateRandomData(count: number) {
68
- const randomData = []
69
- const startTimestamp = Math.floor(Date.now()) // 현재 시간을 Unix 타임스탬프로 설정
70
-
71
- for (let i = 0; i < count; i++) {
72
- const timestamp = startTimestamp + i * 360 * 30 * 1000 // 3초씩 증가하는 타임스탬프 설정
73
- const randomCount = getRandomInRange(i, 5, 35) // count 값을 5에서 35 사이로 랜덤 생성
74
- const randomAverage = getRandomInRange(i, 50, 150) // average 값을 50에서 150 사이로 랜덤 생성
75
-
76
- randomData.push({
77
- timestamp: timestamp,
78
- count: randomCount,
79
- average: randomAverage
80
- })
81
- }
82
-
83
- return randomData
84
- }
85
-
86
- // 100개의 랜덤 데이터를 생성
87
- export const data = generateRandomData(100)