@operato/chart 7.0.0 → 7.0.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 (55) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/src/chartjs/config-converter.js +7 -1
  3. package/dist/src/chartjs/config-converter.js.map +1 -1
  4. package/dist/src/editors/configurer.d.ts +2 -2
  5. package/dist/src/editors/configurer.js +0 -1
  6. package/dist/src/editors/configurer.js.map +1 -1
  7. package/dist/src/editors/input-chart-abstract.js +3 -2
  8. package/dist/src/editors/input-chart-abstract.js.map +1 -1
  9. package/dist/src/progress/ox-progress-circle.d.ts +41 -0
  10. package/dist/src/progress/ox-progress-circle.js +169 -0
  11. package/dist/src/progress/ox-progress-circle.js.map +1 -0
  12. package/dist/src/scichart/ox-scichart.d.ts +4 -2
  13. package/dist/src/scichart/ox-scichart.js +77 -23
  14. package/dist/src/scichart/ox-scichart.js.map +1 -1
  15. package/dist/src/scichart/scichart-builder.d.ts +1 -1
  16. package/dist/src/scichart/scichart-builder.js +216 -22
  17. package/dist/src/scichart/scichart-builder.js.map +1 -1
  18. package/dist/stories/common.d.ts +1 -1
  19. package/dist/stories/common.js +31 -9
  20. package/dist/stories/common.js.map +1 -1
  21. package/dist/stories/ox-input-chart-bar.stories.js +32 -47
  22. package/dist/stories/ox-input-chart-bar.stories.js.map +1 -1
  23. package/dist/stories/ox-input-chart-doughnut.stories.js +1 -1
  24. package/dist/stories/ox-input-chart-doughnut.stories.js.map +1 -1
  25. package/dist/stories/ox-input-chart-hbar.stories.js +1 -1
  26. package/dist/stories/ox-input-chart-hbar.stories.js.map +1 -1
  27. package/dist/stories/ox-input-chart-line.stories.js +1 -1
  28. package/dist/stories/ox-input-chart-line.stories.js.map +1 -1
  29. package/dist/stories/ox-input-chart-pie.stories.js +1 -1
  30. package/dist/stories/ox-input-chart-pie.stories.js.map +1 -1
  31. package/dist/stories/ox-input-chart-polar-area.stories.js +1 -1
  32. package/dist/stories/ox-input-chart-polar-area.stories.js.map +1 -1
  33. package/dist/stories/ox-input-chart-radar.stories.js +1 -1
  34. package/dist/stories/ox-input-chart-radar.stories.js.map +1 -1
  35. package/dist/stories/ox-input-chart-timeseries.stories.js +77 -53
  36. package/dist/stories/ox-input-chart-timeseries.stories.js.map +1 -1
  37. package/dist/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +3 -2
  39. package/src/chartjs/config-converter.ts +12 -4
  40. package/src/editors/configurer.ts +0 -1
  41. package/src/editors/input-chart-abstract.ts +3 -2
  42. package/src/progress/ox-progress-circle.ts +133 -0
  43. package/src/scichart/custom-point-markers.ts.xxx +178 -0
  44. package/src/scichart/ox-scichart.ts +83 -32
  45. package/src/scichart/scichart-builder.ts +272 -34
  46. package/src/types.d.ts +14 -2
  47. package/stories/common.ts +36 -9
  48. package/stories/ox-input-chart-bar.stories.ts +31 -45
  49. package/stories/ox-input-chart-doughnut.stories.ts +1 -1
  50. package/stories/ox-input-chart-hbar.stories.ts +1 -1
  51. package/stories/ox-input-chart-line.stories.ts +1 -1
  52. package/stories/ox-input-chart-pie.stories.ts +1 -1
  53. package/stories/ox-input-chart-polar-area.stories.ts +1 -1
  54. package/stories/ox-input-chart-radar.stories.ts +1 -1
  55. package/stories/ox-input-chart-timeseries.stories.ts +76 -51
@@ -0,0 +1,178 @@
1
+ import { BasePointMarker, TSciChart, IRenderableSeries, EPointMarkerType } from 'scichart'
2
+
3
+ interface PointMarkerOptions {
4
+ width?: number
5
+ height?: number
6
+ strokeThickness?: number
7
+ fill?: string
8
+ stroke?: string
9
+ }
10
+
11
+ abstract class CustomPointMarker extends BasePointMarker {
12
+ private _width: number
13
+ private _height: number
14
+ private _strokeThickness: number
15
+ private _fill: string
16
+ private _stroke: string
17
+
18
+ constructor(wasmContext: TSciChart, options: PointMarkerOptions = {}) {
19
+ super(wasmContext)
20
+ this._width = options.width ?? 10
21
+ this._height = options.height ?? 10
22
+ this._strokeThickness = options.strokeThickness ?? 2
23
+ this._fill = options.fill ?? '#FF6600'
24
+ this._stroke = options.stroke ?? '#000000'
25
+ }
26
+
27
+ get width(): number {
28
+ return this._width
29
+ }
30
+ set width(value: number) {
31
+ this._width = value
32
+ }
33
+
34
+ get height(): number {
35
+ return this._height
36
+ }
37
+ set height(value: number) {
38
+ this._height = value
39
+ }
40
+
41
+ get strokeThickness(): number {
42
+ return this._strokeThickness
43
+ }
44
+ set strokeThickness(value: number) {
45
+ this._strokeThickness = value
46
+ }
47
+
48
+ get fill(): string {
49
+ return this._fill
50
+ }
51
+ set fill(value: string) {
52
+ this._fill = value
53
+ }
54
+
55
+ get stroke(): string {
56
+ return this._stroke
57
+ }
58
+ set stroke(value: string) {
59
+ this._stroke = value
60
+ }
61
+
62
+ get type(): EPointMarkerType {
63
+ return EPointMarkerType.Custom
64
+ }
65
+
66
+ drawSprite(
67
+ context: CanvasRenderingContext2D,
68
+ x: number,
69
+ y: number,
70
+ stroke: string,
71
+ dpiAdjustedStrokeThickness: number,
72
+ fill: string
73
+ ): void {
74
+ this.draw(context, null as any, x, y)
75
+ }
76
+
77
+ abstract draw(
78
+ context: CanvasRenderingContext2D,
79
+ renderableSeries: IRenderableSeries,
80
+ xCoord: number,
81
+ yCoord: number
82
+ ): void
83
+ }
84
+
85
+ // Rotated Square Point Marker
86
+ export class RotatedSquarePointMarker extends CustomPointMarker {
87
+ draw(context: CanvasRenderingContext2D, renderableSeries: IRenderableSeries, xCoord: number, yCoord: number): void {
88
+ context.save()
89
+ context.translate(xCoord, yCoord)
90
+ context.rotate(Math.PI / 4) // 45 degrees rotation
91
+ context.fillStyle = this.fill
92
+ context.strokeStyle = this.stroke
93
+ context.lineWidth = this.strokeThickness
94
+ context.beginPath()
95
+ context.rect(-this.width / 2, -this.height / 2, this.width, this.height)
96
+ context.fill()
97
+ context.stroke()
98
+ context.restore()
99
+ }
100
+ }
101
+
102
+ // Cross Rot Point Marker
103
+ export class CrossRotPointMarker extends CustomPointMarker {
104
+ draw(context: CanvasRenderingContext2D, renderableSeries: IRenderableSeries, xCoord: number, yCoord: number): void {
105
+ context.save()
106
+ context.translate(xCoord, yCoord)
107
+ context.rotate(Math.PI / 4) // 45 degrees rotation
108
+ context.strokeStyle = this.stroke
109
+ context.lineWidth = this.strokeThickness
110
+ context.beginPath()
111
+ context.moveTo(-this.width / 2, 0)
112
+ context.lineTo(this.width / 2, 0)
113
+ context.moveTo(0, -this.height / 2)
114
+ context.lineTo(0, this.height / 2)
115
+ context.stroke()
116
+ context.restore()
117
+ }
118
+ }
119
+
120
+ // Star Point Marker
121
+ export class StarPointMarker extends CustomPointMarker {
122
+ draw(context: CanvasRenderingContext2D, renderableSeries: IRenderableSeries, xCoord: number, yCoord: number): void {
123
+ const spikes = 5
124
+ const outerRadius = this.width / 2
125
+ const innerRadius = outerRadius / 2
126
+ context.save()
127
+ context.translate(xCoord, yCoord)
128
+ context.fillStyle = this.fill
129
+ context.strokeStyle = this.stroke
130
+ context.lineWidth = this.strokeThickness
131
+ context.beginPath()
132
+ for (let i = 0; i < spikes; i++) {
133
+ context.lineTo(
134
+ Math.cos((i * 2 * Math.PI) / spikes) * outerRadius,
135
+ Math.sin((i * 2 * Math.PI) / spikes) * outerRadius
136
+ )
137
+ context.lineTo(
138
+ Math.cos(((i * 2 + 1) * Math.PI) / spikes) * innerRadius,
139
+ Math.sin(((i * 2 + 1) * Math.PI) / spikes) * innerRadius
140
+ )
141
+ }
142
+ context.closePath()
143
+ context.fill()
144
+ context.stroke()
145
+ context.restore()
146
+ }
147
+ }
148
+
149
+ // Line Point Marker
150
+ export class LinePointMarker extends CustomPointMarker {
151
+ draw(context: CanvasRenderingContext2D, renderableSeries: IRenderableSeries, xCoord: number, yCoord: number): void {
152
+ context.save()
153
+ context.translate(xCoord, yCoord)
154
+ context.strokeStyle = this.stroke
155
+ context.lineWidth = this.strokeThickness
156
+ context.beginPath()
157
+ context.moveTo(-this.width / 2, 0)
158
+ context.lineTo(this.width / 2, 0)
159
+ context.stroke()
160
+ context.restore()
161
+ }
162
+ }
163
+
164
+ // Dash Point Marker
165
+ export class DashPointMarker extends CustomPointMarker {
166
+ draw(context: CanvasRenderingContext2D, renderableSeries: IRenderableSeries, xCoord: number, yCoord: number): void {
167
+ context.save()
168
+ context.translate(xCoord, yCoord)
169
+ context.strokeStyle = this.stroke
170
+ context.lineWidth = this.strokeThickness
171
+ context.setLineDash([this.width / 4, this.width / 4])
172
+ context.beginPath()
173
+ context.moveTo(-this.width / 2, 0)
174
+ context.lineTo(this.width / 2, 0)
175
+ context.stroke()
176
+ context.restore()
177
+ }
178
+ }
@@ -2,7 +2,6 @@ import { LitElement, html, css } from 'lit'
2
2
  import { property, query, customElement } from 'lit/decorators.js'
3
3
  import { buildSciChart } from './scichart-builder'
4
4
 
5
- // 전역 변수로 SciChart 로딩 상태 관리
6
5
  declare global {
7
6
  interface Window {
8
7
  sciChartLoaded: boolean
@@ -18,19 +17,46 @@ class OxSciChart extends LitElement {
18
17
  @property({ type: String, attribute: 'attr-y' }) attrY: string = 'y'
19
18
 
20
19
  private chart: any = null
21
- dataSeries?: any
20
+ private dataSeries: any[] = []
22
21
 
23
22
  @query('div#container') container!: HTMLDivElement
23
+ @query('div#legend') legendContainer!: HTMLDivElement
24
24
 
25
25
  static styles = css`
26
26
  :host {
27
27
  display: block;
28
+ width: 100%;
29
+ height: 100%;
28
30
  }
29
31
 
30
- div {
32
+ .chart-container {
33
+ display: flex;
31
34
  width: 100%;
32
35
  height: 100%;
33
36
  }
37
+
38
+ .chart-content {
39
+ flex: 1;
40
+ position: relative;
41
+ }
42
+
43
+ .legend {
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: center;
47
+ }
48
+
49
+ .legend-top,
50
+ .legend-bottom {
51
+ width: 100%;
52
+ height: 50px;
53
+ }
54
+
55
+ .legend-right,
56
+ .legend-left {
57
+ width: 150px;
58
+ height: 100%;
59
+ }
34
60
  `
35
61
 
36
62
  firstUpdated() {
@@ -65,14 +91,15 @@ class OxSciChart extends LitElement {
65
91
  const { chart, dataSeries } = (await buildSciChart(this.config, this.container, {})) || {}
66
92
 
67
93
  this.chart = chart
68
- this.dataSeries = dataSeries
94
+ this.dataSeries = dataSeries!
69
95
 
70
96
  this.updateDataSeries()
71
97
  }
72
98
 
73
99
  async updated(changedProperties: Map<string | number | symbol, unknown>) {
74
- if (changedProperties.has('config')) {
100
+ if (changedProperties.has('config') && this.config) {
75
101
  await this.initializeSciChart()
102
+ this.updateLegend()
76
103
  }
77
104
 
78
105
  if (changedProperties.has('data')) {
@@ -82,49 +109,73 @@ class OxSciChart extends LitElement {
82
109
  }
83
110
 
84
111
  updateDataSeries() {
85
- if (!this.dataSeries) return
112
+ if (!this.dataSeries?.length) return
86
113
 
87
- this.dataSeries.clear()
114
+ this.dataSeries.forEach(ds => ds.clear())
88
115
  const newData = this.dataSet
89
116
 
90
- this.dataSeries.appendRange(
91
- newData.map(d => d.xValue),
92
- newData.map(d => d.yValue)
93
- )
117
+ newData.forEach((data, index) => {
118
+ this.dataSeries[index].appendRange(
119
+ data.map(d => d.xValue),
120
+ data.map(d => d.yValue)
121
+ )
122
+ })
94
123
 
95
124
  this.chart?.sciChartSurface.zoomExtents()
96
125
  this.chart?.sciChartSurface.invalidateElement()
97
126
  }
98
127
 
99
- get dataSet(): { xValue: number; yValue: number }[] {
100
- const { attrX, attrY, data } = this
128
+ get dataSet(): { xValue: number; yValue: number }[][] {
129
+ const { attrX, data } = this
130
+ const datasets = this.config?.data?.datasets || []
101
131
 
102
132
  if (!(data instanceof Array)) {
103
133
  return []
104
134
  }
105
135
 
106
- return data
107
- .map(item => {
108
- if (!item || typeof item !== 'object') {
109
- return
110
- }
111
-
112
- const xValue = new Date(item[attrX])
113
- if (isNaN(xValue.getTime())) {
114
- console.error('Invalid date:', item[attrX])
115
- return
116
- }
117
-
118
- return {
119
- xValue: xValue.getTime() / 1000,
120
- yValue: item[attrY]
121
- }
122
- })
123
- .filter(Boolean) as { xValue: number; yValue: number }[]
136
+ return datasets.map(dataset => {
137
+ return data
138
+ .map(item => {
139
+ if (!item || typeof item !== 'object') {
140
+ return
141
+ }
142
+
143
+ const xValue = new Date(item[attrX])
144
+ if (isNaN(xValue.getTime())) {
145
+ console.error('Invalid date:', item[attrX])
146
+ return
147
+ }
148
+
149
+ return {
150
+ xValue: xValue.getTime() / 1000,
151
+ yValue: item[dataset.dataKey!]
152
+ }
153
+ })
154
+ .filter(Boolean) as { xValue: number; yValue: number }[]
155
+ })
156
+ }
157
+
158
+ updateLegend() {
159
+ const legendPosition = this.config?.options?.legend?.position || 'right'
160
+ const legendElement = this.shadowRoot?.getElementById('legend')
161
+ if (legendElement) {
162
+ legendElement.className = `legend legend-${legendPosition}`
163
+ }
124
164
  }
125
165
 
126
166
  render() {
127
- return html`<div id="container"></div>`
167
+ const legendPosition = this.config?.options?.legend?.position || 'right'
168
+ return html`
169
+ <div class="chart-container">
170
+ ${legendPosition === 'left' ? html`<div id="legend" class="legend legend-left"></div>` : ''}
171
+ <div class="chart-content">
172
+ ${legendPosition === 'top' ? html`<div id="legend" class="legend legend-top"></div>` : ''}
173
+ <div id="container"></div>
174
+ ${legendPosition === 'bottom' ? html`<div id="legend" class="legend legend-bottom"></div>` : ''}
175
+ </div>
176
+ ${legendPosition === 'right' ? html`<div id="legend" class="legend legend-right"></div>` : ''}
177
+ </div>
178
+ `
128
179
  }
129
180
  }
130
181