@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.
- package/CHANGELOG.md +21 -0
- package/dist/src/chartjs/config-converter.js +7 -1
- package/dist/src/chartjs/config-converter.js.map +1 -1
- package/dist/src/editors/configurer.d.ts +2 -2
- package/dist/src/editors/configurer.js +0 -1
- package/dist/src/editors/configurer.js.map +1 -1
- package/dist/src/editors/input-chart-abstract.js +3 -2
- package/dist/src/editors/input-chart-abstract.js.map +1 -1
- package/dist/src/progress/ox-progress-circle.d.ts +41 -0
- package/dist/src/progress/ox-progress-circle.js +169 -0
- package/dist/src/progress/ox-progress-circle.js.map +1 -0
- package/dist/src/scichart/ox-scichart.d.ts +4 -2
- package/dist/src/scichart/ox-scichart.js +77 -23
- package/dist/src/scichart/ox-scichart.js.map +1 -1
- package/dist/src/scichart/scichart-builder.d.ts +1 -1
- package/dist/src/scichart/scichart-builder.js +216 -22
- package/dist/src/scichart/scichart-builder.js.map +1 -1
- package/dist/stories/common.d.ts +1 -1
- package/dist/stories/common.js +31 -9
- package/dist/stories/common.js.map +1 -1
- package/dist/stories/ox-input-chart-bar.stories.js +32 -47
- package/dist/stories/ox-input-chart-bar.stories.js.map +1 -1
- package/dist/stories/ox-input-chart-doughnut.stories.js +1 -1
- package/dist/stories/ox-input-chart-doughnut.stories.js.map +1 -1
- package/dist/stories/ox-input-chart-hbar.stories.js +1 -1
- package/dist/stories/ox-input-chart-hbar.stories.js.map +1 -1
- package/dist/stories/ox-input-chart-line.stories.js +1 -1
- package/dist/stories/ox-input-chart-line.stories.js.map +1 -1
- package/dist/stories/ox-input-chart-pie.stories.js +1 -1
- package/dist/stories/ox-input-chart-pie.stories.js.map +1 -1
- package/dist/stories/ox-input-chart-polar-area.stories.js +1 -1
- package/dist/stories/ox-input-chart-polar-area.stories.js.map +1 -1
- package/dist/stories/ox-input-chart-radar.stories.js +1 -1
- package/dist/stories/ox-input-chart-radar.stories.js.map +1 -1
- package/dist/stories/ox-input-chart-timeseries.stories.js +77 -53
- package/dist/stories/ox-input-chart-timeseries.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/src/chartjs/config-converter.ts +12 -4
- package/src/editors/configurer.ts +0 -1
- package/src/editors/input-chart-abstract.ts +3 -2
- package/src/progress/ox-progress-circle.ts +133 -0
- package/src/scichart/custom-point-markers.ts.xxx +178 -0
- package/src/scichart/ox-scichart.ts +83 -32
- package/src/scichart/scichart-builder.ts +272 -34
- package/src/types.d.ts +14 -2
- package/stories/common.ts +36 -9
- package/stories/ox-input-chart-bar.stories.ts +31 -45
- package/stories/ox-input-chart-doughnut.stories.ts +1 -1
- package/stories/ox-input-chart-hbar.stories.ts +1 -1
- package/stories/ox-input-chart-line.stories.ts +1 -1
- package/stories/ox-input-chart-pie.stories.ts +1 -1
- package/stories/ox-input-chart-polar-area.stories.ts +1 -1
- package/stories/ox-input-chart-radar.stories.ts +1 -1
- 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
|
|
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
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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,
|
|
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
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
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
|
|