@operato/chart 7.1.31 → 7.1.33
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/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/.editorconfig +0 -29
- package/.storybook/main.js +0 -3
- package/.storybook/preview.js +0 -52
- package/.storybook/server.mjs +0 -8
- package/demo/index.html +0 -33
- package/src/chartjs/config-converter.ts +0 -341
- package/src/chartjs/ox-chart-js.ts +0 -207
- package/src/editors/configurer.ts +0 -336
- package/src/editors/index.ts +0 -8
- package/src/editors/input-chart-abstract.ts +0 -202
- package/src/editors/input-chart-styles.ts +0 -206
- package/src/editors/ox-input-chart-hbar.ts +0 -157
- package/src/editors/ox-input-chart-mixed.ts +0 -241
- package/src/editors/ox-input-chart-pie.ts +0 -69
- package/src/editors/ox-input-chart-radar.ts +0 -56
- package/src/editors/ox-input-chart-timeseries.ts +0 -279
- package/src/editors/ox-property-editor-chart.ts +0 -72
- package/src/editors/templates/annotations.ts +0 -295
- package/src/editors/templates/display-value.ts +0 -111
- package/src/editors/templates/series.ts +0 -316
- package/src/index.ts +0 -0
- package/src/progress/ox-progress-circle.ts +0 -133
- package/src/scichart/ox-scichart.ts +0 -151
- package/src/scichart/scichart-builder.ts +0 -490
- package/stories/common.ts +0 -87
- package/stories/ox-input-chart-bar.stories.ts +0 -188
- package/stories/ox-input-chart-doughnut.stories.ts +0 -130
- package/stories/ox-input-chart-hbar.stories.ts +0 -188
- package/stories/ox-input-chart-line.stories.ts +0 -198
- package/stories/ox-input-chart-pie.stories.ts +0 -130
- package/stories/ox-input-chart-polar-area.stories.ts +0 -130
- package/stories/ox-input-chart-radar.stories.ts +0 -141
- package/stories/ox-input-chart-timeseries.stories.ts +0 -268
- package/tsconfig.json +0 -25
- package/web-dev-server.config.mjs +0 -27
- package/web-test-runner.config.mjs +0 -41
- /package/{src → types}/global.d.ts +0 -0
- /package/{src → types}/types.d.ts +0 -0
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
import '@material/web/icon/icon.js'
|
|
2
|
-
|
|
3
|
-
import { LitElement, html, PropertyValues, nothing } from 'lit'
|
|
4
|
-
import { customElement, property, query } from 'lit/decorators.js'
|
|
5
|
-
import { keyed } from 'lit/directives/keyed.js'
|
|
6
|
-
import { MdIcon } from '@material/web/icon/icon.js'
|
|
7
|
-
import { random as randomColor, TinyColor } from '@ctrl/tinycolor'
|
|
8
|
-
|
|
9
|
-
import { Configurer } from '../configurer'
|
|
10
|
-
import './display-value'
|
|
11
|
-
|
|
12
|
-
@customElement('ox-chart-series')
|
|
13
|
-
export class MultipleSeriesTemplate extends LitElement {
|
|
14
|
-
createRenderRoot() {
|
|
15
|
-
return this
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
@property({ type: Object }) configurer!: Configurer
|
|
19
|
-
@property({ type: String }) chartType?: OperatoChart.ChartType
|
|
20
|
-
|
|
21
|
-
@query('#series-tabs') seriesTabs!: HTMLElement
|
|
22
|
-
@query('#series-tab-nav-left-button') seriesTabNavLeftButton!: MdIcon
|
|
23
|
-
@query('#series-tab-nav-right-button') seriesTabNavRightButton!: MdIcon
|
|
24
|
-
|
|
25
|
-
protected updated(_changedProperties: PropertyValues): void {
|
|
26
|
-
if (_changedProperties.has('configurer') || _changedProperties.has('chartType')) {
|
|
27
|
-
this.requestUpdate()
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
get value() {
|
|
32
|
-
return this.configurer.datasets
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
render() {
|
|
36
|
-
return keyed(
|
|
37
|
-
this.configurer.currentSeriesIndex,
|
|
38
|
-
html`
|
|
39
|
-
<div id="series-properties-container" fullwidth>
|
|
40
|
-
<div id="series-tab-header" @wheel=${this._onWheelScroll}>
|
|
41
|
-
<md-icon id="series-tab-nav-left-button" @click=${this._scrollLeft}>chevron_left</md-icon>
|
|
42
|
-
<div id="series-tabs" active-tab-index=${this.configurer.currentSeriesIndex} fit-container>
|
|
43
|
-
${this._renderTabs()}
|
|
44
|
-
</div>
|
|
45
|
-
<md-icon id="series-tab-nav-right-button" @click=${this._scrollRight}>chevron_right</md-icon>
|
|
46
|
-
</div>
|
|
47
|
-
<div id="add-series-button-container">
|
|
48
|
-
<md-icon id="add-series-button" @click=${this._addSeries}>add</md-icon>
|
|
49
|
-
</div>
|
|
50
|
-
${this._renderSeriesForm()}
|
|
51
|
-
</div>
|
|
52
|
-
`
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private _renderTabs() {
|
|
57
|
-
return this.configurer.datasets.map(
|
|
58
|
-
(dataset: OperatoChart.Dataset, index: number) => html`
|
|
59
|
-
<div
|
|
60
|
-
data-series=${index + 1}
|
|
61
|
-
data-tab-index=${index}
|
|
62
|
-
tab
|
|
63
|
-
?selected=${index === this.configurer.currentSeriesIndex}
|
|
64
|
-
@click=${() => this._selectTab(index)}
|
|
65
|
-
>
|
|
66
|
-
${index + 1}
|
|
67
|
-
${this.configurer.datasets.length > 1 && this.configurer.currentSeriesIndex === index
|
|
68
|
-
? html`<md-icon @click=${() => this._removeSeries(index)}>close</md-icon>`
|
|
69
|
-
: html``}
|
|
70
|
-
</div>
|
|
71
|
-
`
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
private _renderSeriesForm() {
|
|
76
|
-
const configurer = this.configurer
|
|
77
|
-
const chartType = this.chartType
|
|
78
|
-
|
|
79
|
-
return html`
|
|
80
|
-
<div class="tab-content">
|
|
81
|
-
<label for="data-key"> <ox-i18n msgid="label.data-key">Data Key</ox-i18n> </label>
|
|
82
|
-
<input id="data-key" type="text" value-key="dataKey" .value=${configurer.dataKey || ''} />
|
|
83
|
-
|
|
84
|
-
${chartType == 'horizontalBar' ||
|
|
85
|
-
chartType === 'doughnut' ||
|
|
86
|
-
chartType === 'pie' ||
|
|
87
|
-
chartType == 'radar' ||
|
|
88
|
-
chartType == 'polarArea'
|
|
89
|
-
? nothing
|
|
90
|
-
: html`
|
|
91
|
-
<label for="series-type"> <ox-i18n msgid="label.series-type">Type</ox-i18n> </label>
|
|
92
|
-
<select
|
|
93
|
-
id="series-type"
|
|
94
|
-
class="select-content"
|
|
95
|
-
value-key="series.type"
|
|
96
|
-
.value=${configurer.series.type || ''}
|
|
97
|
-
>
|
|
98
|
-
<option value="bar" selected>Bar</option>
|
|
99
|
-
<option value="line">Line</option>
|
|
100
|
-
</select>
|
|
101
|
-
`}
|
|
102
|
-
|
|
103
|
-
<label for="series-label"> <ox-i18n msgid="label.label">Label</ox-i18n> </label>
|
|
104
|
-
<input id="series-label" type="text" value-key="series.label" .value=${configurer.series.label || ''} />
|
|
105
|
-
|
|
106
|
-
${configurer.series.type === 'line'
|
|
107
|
-
? html`
|
|
108
|
-
<label for="series-line-tension"> <ox-i18n msgid="label.line-tension">Line Tension</ox-i18n> </label>
|
|
109
|
-
<select
|
|
110
|
-
id="series-line-tension"
|
|
111
|
-
class="select-content"
|
|
112
|
-
value-key="series.lineTension"
|
|
113
|
-
.value=${String(configurer.series.lineTension || 0)}
|
|
114
|
-
>
|
|
115
|
-
<option value="0.4">Smooth</option>
|
|
116
|
-
<option value="0">Angled</option>
|
|
117
|
-
</select>
|
|
118
|
-
`
|
|
119
|
-
: html``}
|
|
120
|
-
${configurer.series.type === 'line'
|
|
121
|
-
? html`
|
|
122
|
-
<label for="series-border-width"> <ox-i18n msgid="label.border-width">Border Width</ox-i18n> </label>
|
|
123
|
-
<input
|
|
124
|
-
id="series-border-width"
|
|
125
|
-
type="number"
|
|
126
|
-
value-key="series.borderWidth"
|
|
127
|
-
.value=${String(configurer.series.borderWidth || 0)}
|
|
128
|
-
/>
|
|
129
|
-
`
|
|
130
|
-
: html``}
|
|
131
|
-
|
|
132
|
-
<label for="series-color"> <ox-i18n msgid="label.color">Color</ox-i18n> </label>
|
|
133
|
-
<ox-input-color id="series-color" value-key="color" .value=${configurer.color}></ox-input-color>
|
|
134
|
-
|
|
135
|
-
${configurer.series.type === 'line'
|
|
136
|
-
? html`
|
|
137
|
-
<label for="series-point-style"> <ox-i18n msgid="label.point-shape">Point Shape</ox-i18n> </label>
|
|
138
|
-
<select
|
|
139
|
-
id="series-point-style"
|
|
140
|
-
class="select-content"
|
|
141
|
-
value-key="series.pointStyle"
|
|
142
|
-
.value=${configurer.series.pointStyle || ''}
|
|
143
|
-
>
|
|
144
|
-
<option value=""> </option>
|
|
145
|
-
<option value="circle">⚬</option>
|
|
146
|
-
<option value="triangle">▵</option>
|
|
147
|
-
<option value="rect">□</option>
|
|
148
|
-
<option value="rectRot">◇</option>
|
|
149
|
-
<option value="cross">+</option>
|
|
150
|
-
<option value="crossRot">⨉</option>
|
|
151
|
-
<option value="star">✱</option>
|
|
152
|
-
<option value="line">―</option>
|
|
153
|
-
<option value="dash">┄</option>
|
|
154
|
-
</select>
|
|
155
|
-
|
|
156
|
-
<label for="series-point-radius"> <ox-i18n msgid="label.point-size">Point Size</ox-i18n> </label>
|
|
157
|
-
<input
|
|
158
|
-
id="series-point-radius"
|
|
159
|
-
type="number"
|
|
160
|
-
value-key="series.pointRadius"
|
|
161
|
-
.value=${String(configurer.series.pointRadius || 0)}
|
|
162
|
-
/>
|
|
163
|
-
`
|
|
164
|
-
: html``}
|
|
165
|
-
|
|
166
|
-
<label for="series-stack"> <ox-i18n msgid="label.stack-group">Stack group</ox-i18n> </label>
|
|
167
|
-
<input id="series-stack" type="text" value-key="series.stack" .value=${configurer.series.stack || ''} />
|
|
168
|
-
|
|
169
|
-
${configurer.series.type === 'line'
|
|
170
|
-
? html`
|
|
171
|
-
<input id="series-fill" type="checkbox" value-key="series.fill" ?checked=${configurer.series.fill} />
|
|
172
|
-
<label for="series-fill"> <ox-i18n msgid="label.fill">Fill</ox-i18n> </label>
|
|
173
|
-
`
|
|
174
|
-
: html``}
|
|
175
|
-
${configurer.multiAxis && configurer.series.type !== 'horizontalBar'
|
|
176
|
-
? html`
|
|
177
|
-
<label for="series-y-axis-id"> <ox-i18n msgid="label.target-axis">Target Axis</ox-i18n> </label>
|
|
178
|
-
<select
|
|
179
|
-
id="series-y-axis-id"
|
|
180
|
-
class="select-content"
|
|
181
|
-
value-key="series.yAxisID"
|
|
182
|
-
.value=${configurer.series.yAxisID || ''}
|
|
183
|
-
>
|
|
184
|
-
<option value="left">Left</option>
|
|
185
|
-
<option value="right">Right</option>
|
|
186
|
-
</select>
|
|
187
|
-
`
|
|
188
|
-
: html``}
|
|
189
|
-
|
|
190
|
-
<label></label>
|
|
191
|
-
<ox-chart-display-value .configurer=${configurer} fullwidth></ox-chart-display-value>
|
|
192
|
-
</div>
|
|
193
|
-
`
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
_getSeriesModel({
|
|
197
|
-
chartType,
|
|
198
|
-
datasetsLength,
|
|
199
|
-
lastSeriesColor
|
|
200
|
-
}: {
|
|
201
|
-
chartType: string
|
|
202
|
-
datasetsLength: number
|
|
203
|
-
lastSeriesColor: TinyColor
|
|
204
|
-
}) {
|
|
205
|
-
const addSeriesOption: any = {
|
|
206
|
-
label: `series ${datasetsLength + 1}`,
|
|
207
|
-
data: [],
|
|
208
|
-
borderWidth: 1,
|
|
209
|
-
dataKey: '',
|
|
210
|
-
yAxisID: 'left',
|
|
211
|
-
color: randomColor({
|
|
212
|
-
hue: lastSeriesColor.toHsv().h
|
|
213
|
-
}).toRgbString(),
|
|
214
|
-
stack: ''
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
addSeriesOption.type = addSeriesOption.chartType = chartType
|
|
218
|
-
return addSeriesOption
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
private _selectTab(index: number) {
|
|
222
|
-
this.configurer.setCurrentSeriesIndex(index)
|
|
223
|
-
this.requestUpdate()
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
private _removeSeries(index: number) {
|
|
227
|
-
this.configurer.removeSeries(index)
|
|
228
|
-
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
|
|
229
|
-
|
|
230
|
-
this.requestUpdate()
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
private _addSeries() {
|
|
234
|
-
const configurer = this.configurer
|
|
235
|
-
|
|
236
|
-
if (!configurer.config.data.datasets) {
|
|
237
|
-
return
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const lastSeriesIndex = configurer.config.data.datasets.length
|
|
241
|
-
const chartType = configurer.series.type || configurer.config.type
|
|
242
|
-
const color = configurer.datasets[lastSeriesIndex - 1]?.backgroundColor
|
|
243
|
-
const lastSeriesColor = new TinyColor(Array.isArray(color) ? color[0] : color)
|
|
244
|
-
|
|
245
|
-
const seriesModel = this._getSeriesModel({
|
|
246
|
-
chartType: chartType!,
|
|
247
|
-
datasetsLength: lastSeriesIndex,
|
|
248
|
-
lastSeriesColor
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
this.configurer.addSeries(seriesModel)
|
|
252
|
-
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
|
|
253
|
-
|
|
254
|
-
this.requestUpdate()
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
private _onWheelScroll(event: WheelEvent) {
|
|
258
|
-
const tabContainer = this.seriesTabs
|
|
259
|
-
if (tabContainer) {
|
|
260
|
-
event.preventDefault()
|
|
261
|
-
|
|
262
|
-
tabContainer.scrollLeft += event.deltaY
|
|
263
|
-
|
|
264
|
-
this._onTabScroll()
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
private _scrollLeft() {
|
|
269
|
-
this._scrollTabContainer(-1)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
private _scrollRight() {
|
|
273
|
-
this._scrollTabContainer(1)
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
private _scrollTabContainer(direction: number) {
|
|
277
|
-
const tabContainer = this.renderRoot!.querySelector<HTMLElement>('#series-tabs')
|
|
278
|
-
if (tabContainer) {
|
|
279
|
-
tabContainer.style.scrollBehavior = 'smooth'
|
|
280
|
-
tabContainer.scrollLeft += direction * tabContainer.clientWidth
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
setTimeout(() => {
|
|
284
|
-
tabContainer!.style.scrollBehavior = 'auto'
|
|
285
|
-
this._onTabScroll()
|
|
286
|
-
}, 300)
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
private _onTabScroll() {
|
|
290
|
-
let tabContainer: HTMLElement | null | undefined
|
|
291
|
-
let tabNavLeftButton: MdIcon
|
|
292
|
-
let tabNavRightButton: MdIcon
|
|
293
|
-
|
|
294
|
-
tabContainer = this.seriesTabs
|
|
295
|
-
tabNavLeftButton = this.seriesTabNavLeftButton
|
|
296
|
-
tabNavRightButton = this.seriesTabNavRightButton
|
|
297
|
-
|
|
298
|
-
if (!tabContainer) {
|
|
299
|
-
return
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if (tabContainer.clientWidth == tabContainer.scrollWidth) {
|
|
303
|
-
tabNavLeftButton.setAttribute('disabled', '')
|
|
304
|
-
tabNavRightButton.setAttribute('disabled', '')
|
|
305
|
-
} else if (tabContainer.scrollLeft <= 0) {
|
|
306
|
-
tabNavLeftButton.setAttribute('disabled', '')
|
|
307
|
-
tabNavRightButton.removeAttribute('disabled')
|
|
308
|
-
} else if (tabContainer.scrollLeft + tabContainer.clientWidth >= tabContainer.scrollWidth) {
|
|
309
|
-
tabNavLeftButton.removeAttribute('disabled')
|
|
310
|
-
tabNavRightButton.setAttribute('disabled', '')
|
|
311
|
-
} else {
|
|
312
|
-
tabNavLeftButton.removeAttribute('disabled')
|
|
313
|
-
tabNavRightButton.removeAttribute('disabled')
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
package/src/index.ts
DELETED
|
File without changes
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { PropertyValues, LitElement, css, html } from 'lit'
|
|
6
|
-
import { customElement, property, query } from 'lit/decorators.js'
|
|
7
|
-
import { ScrollbarStyles } from '@operato/styles'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
A lightweight progress-circle WebComponent
|
|
11
|
-
|
|
12
|
-
Example:
|
|
13
|
-
<ox-progress-circle
|
|
14
|
-
.value=${70}
|
|
15
|
-
titleText="전체"
|
|
16
|
-
suffix="%"
|
|
17
|
-
fontSize="29px"
|
|
18
|
-
fontColor="#4E5055"
|
|
19
|
-
borderStyle="none"
|
|
20
|
-
innerCircleSize="28%"
|
|
21
|
-
circleColor="#0595E5"
|
|
22
|
-
shadow="#00000026 4px 4px 4px"
|
|
23
|
-
background="#eaf5fd"
|
|
24
|
-
></ox-progress-circle>
|
|
25
|
-
*/
|
|
26
|
-
@customElement('ox-progress-circle')
|
|
27
|
-
export class OxProgressCircle extends LitElement {
|
|
28
|
-
static styles = [
|
|
29
|
-
ScrollbarStyles,
|
|
30
|
-
css`
|
|
31
|
-
:host {
|
|
32
|
-
display: flex;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
div[circle] {
|
|
36
|
-
font-size: 29px;
|
|
37
|
-
font-weight: bold;
|
|
38
|
-
width: 100%;
|
|
39
|
-
aspect-ratio: 1;
|
|
40
|
-
display: flex;
|
|
41
|
-
border-radius: 50%;
|
|
42
|
-
border: 1px solid #353b48;
|
|
43
|
-
position: relative;
|
|
44
|
-
background: conic-gradient(yellowgreen 0deg, white 0deg);
|
|
45
|
-
box-shadow: #00000026 5px 5px 5px;
|
|
46
|
-
}
|
|
47
|
-
div[inner-circle] {
|
|
48
|
-
width: 90%;
|
|
49
|
-
aspect-ratio: 1;
|
|
50
|
-
border-radius: inherit;
|
|
51
|
-
background-color: #353b48;
|
|
52
|
-
margin: auto;
|
|
53
|
-
display: flex;
|
|
54
|
-
flex-direction: column;
|
|
55
|
-
align-items: center;
|
|
56
|
-
color: white;
|
|
57
|
-
justify-content: center;
|
|
58
|
-
box-shadow: inset #00000026 -2px 2px 8px;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
div[inner-circle] span {
|
|
62
|
-
display: flex;
|
|
63
|
-
align-items: center;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
span[progress-title] {
|
|
67
|
-
font-size: 0.65em;
|
|
68
|
-
margin-bottom: -5%;
|
|
69
|
-
}
|
|
70
|
-
`
|
|
71
|
-
]
|
|
72
|
-
|
|
73
|
-
@property({ type: Number }) value: number = 0
|
|
74
|
-
@property({ type: String }) suffix: string = ''
|
|
75
|
-
@property({ type: String }) titleText: string = ''
|
|
76
|
-
@property({ type: String }) fontSize: string = '10px'
|
|
77
|
-
@property({ type: String }) fontColor: string = ''
|
|
78
|
-
@property({ type: String }) borderStyle: string = ''
|
|
79
|
-
@property({ type: String }) innerCircleSize: string = '10%'
|
|
80
|
-
@property({ type: String }) shadow: string = ''
|
|
81
|
-
@property({ type: String }) circleColor: string = 'yellowgreen'
|
|
82
|
-
@property({ type: String }) background: string = ''
|
|
83
|
-
|
|
84
|
-
@query('div[circle]') circle!: HTMLDivElement
|
|
85
|
-
@query('div[inner-circle]') innerCircle!: HTMLDivElement
|
|
86
|
-
@query('span[progress-title]') progressTitle?: HTMLSpanElement
|
|
87
|
-
|
|
88
|
-
firstUpdated() {
|
|
89
|
-
if (this.fontSize) {
|
|
90
|
-
this.circle.style.fontSize = this.fontSize
|
|
91
|
-
}
|
|
92
|
-
if (this.fontColor) {
|
|
93
|
-
this.innerCircle.style.color = this.fontColor
|
|
94
|
-
}
|
|
95
|
-
if (this.borderStyle) {
|
|
96
|
-
this.circle.style.border = this.borderStyle
|
|
97
|
-
}
|
|
98
|
-
if (this.innerCircleSize) {
|
|
99
|
-
this.innerCircle.style.width = `calc(100% - ${this.innerCircleSize})`
|
|
100
|
-
}
|
|
101
|
-
if (this.shadow) {
|
|
102
|
-
this.circle.style.boxShadow = this.shadow
|
|
103
|
-
}
|
|
104
|
-
if (this.background) {
|
|
105
|
-
this.innerCircle.style.background = this.background
|
|
106
|
-
}
|
|
107
|
-
if (this.progressTitle && this.circleColor) {
|
|
108
|
-
this.progressTitle.style.color = this.circleColor
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
updated(changes: PropertyValues<this>) {
|
|
113
|
-
if (changes.has('value')) {
|
|
114
|
-
this.updateCircleBackground()
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
updateCircleBackground() {
|
|
119
|
-
const position = this.value * 3.6 // 360 = 100%
|
|
120
|
-
this.circle.style.background = `conic-gradient(${this.circleColor} ${position}deg, ${this.background} 0deg)`
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
render() {
|
|
124
|
-
return html`
|
|
125
|
-
<div circle>
|
|
126
|
-
<div inner-circle>
|
|
127
|
-
${this.titleText ? html`<span progress-title>${this.titleText}</span>` : ''}
|
|
128
|
-
<span>${this.value}${this.suffix}</span>
|
|
129
|
-
</div>
|
|
130
|
-
</div>
|
|
131
|
-
`
|
|
132
|
-
}
|
|
133
|
-
}
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { LitElement, html, css } from 'lit'
|
|
2
|
-
import { property, query, customElement } from 'lit/decorators.js'
|
|
3
|
-
import { buildSciChart } from './scichart-builder'
|
|
4
|
-
|
|
5
|
-
declare global {
|
|
6
|
-
interface Window {
|
|
7
|
-
sciChartLoaded: boolean
|
|
8
|
-
sciChartLoadingPromise: Promise<void>
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
@customElement('ox-scichart')
|
|
13
|
-
class OxSciChart extends LitElement {
|
|
14
|
-
@property({ type: Object }) config: OperatoChart.ChartConfig | null = null
|
|
15
|
-
@property({ type: Array }) data: { [attr: string]: any }[] = []
|
|
16
|
-
|
|
17
|
-
private chart: any = null
|
|
18
|
-
private dataSeries: any[] = []
|
|
19
|
-
|
|
20
|
-
@query('div#container') container!: HTMLDivElement
|
|
21
|
-
|
|
22
|
-
static styles = css`
|
|
23
|
-
:host {
|
|
24
|
-
display: block;
|
|
25
|
-
width: 100%;
|
|
26
|
-
height: 100%;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.chart-container {
|
|
30
|
-
display: flex;
|
|
31
|
-
width: 100%;
|
|
32
|
-
height: 100%;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.chart-content {
|
|
36
|
-
flex: 1;
|
|
37
|
-
position: relative;
|
|
38
|
-
}
|
|
39
|
-
`
|
|
40
|
-
|
|
41
|
-
firstUpdated() {
|
|
42
|
-
this.loadSciChart()
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async loadSciChart() {
|
|
46
|
-
if (!window.sciChartLoaded) {
|
|
47
|
-
if (!window.sciChartLoadingPromise) {
|
|
48
|
-
window.sciChartLoadingPromise = new Promise<void>(resolve => {
|
|
49
|
-
const script = document.createElement('script')
|
|
50
|
-
script.src = 'https://cdn.jsdelivr.net/npm/scichart/index.min.js'
|
|
51
|
-
script.crossOrigin = 'anonymous'
|
|
52
|
-
script.onload = () => {
|
|
53
|
-
window.sciChartLoaded = true
|
|
54
|
-
|
|
55
|
-
SciChart.SciChartSurface.UseCommunityLicense()
|
|
56
|
-
|
|
57
|
-
resolve()
|
|
58
|
-
}
|
|
59
|
-
document.head.appendChild(script)
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
await window.sciChartLoadingPromise
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
this.initializeSciChart()
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async initializeSciChart() {
|
|
70
|
-
const { chart, dataSeries } = (await buildSciChart(this.config, this.container, {})) || {}
|
|
71
|
-
|
|
72
|
-
this.chart = chart
|
|
73
|
-
this.dataSeries = dataSeries!
|
|
74
|
-
|
|
75
|
-
this.updateDataSeries()
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async updated(changedProperties: Map<string | number | symbol, unknown>) {
|
|
79
|
-
if (changedProperties.has('config') && this.config) {
|
|
80
|
-
await this.initializeSciChart()
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (changedProperties.has('data')) {
|
|
84
|
-
this.updateDataSeries()
|
|
85
|
-
this.chart?.sciChartSurface.zoomExtents()
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async appendData(appendum: { [attr: string]: any }[]) {}
|
|
90
|
-
|
|
91
|
-
updateDataSeries() {
|
|
92
|
-
if (!this.dataSeries?.length) return
|
|
93
|
-
|
|
94
|
-
this.dataSeries.forEach(ds => ds.clear())
|
|
95
|
-
const newData = this.dataSet
|
|
96
|
-
|
|
97
|
-
newData.forEach((data, index) => {
|
|
98
|
-
const filteredData = data.filter(d => typeof d.yValue === 'number')
|
|
99
|
-
|
|
100
|
-
if (filteredData.length > 0) {
|
|
101
|
-
this.dataSeries[index].appendRange(
|
|
102
|
-
filteredData.map(d => d.xValue),
|
|
103
|
-
filteredData.map(d => d.yValue)
|
|
104
|
-
)
|
|
105
|
-
}
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
this.chart?.sciChartSurface.zoomExtents()
|
|
109
|
-
this.chart?.sciChartSurface.invalidateElement()
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
get dataSet(): { xValue: number; yValue: number }[][] {
|
|
113
|
-
const { config, data } = this
|
|
114
|
-
const { datasets = [], labelDataKey: attrX } = config?.data || {}
|
|
115
|
-
|
|
116
|
-
if (!(data instanceof Array) || !attrX) {
|
|
117
|
-
return []
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return datasets.map(dataset => {
|
|
121
|
-
return data
|
|
122
|
-
.map(item => {
|
|
123
|
-
if (!item || typeof item !== 'object') {
|
|
124
|
-
return
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const xValue = new Date(item[attrX])
|
|
128
|
-
if (isNaN(xValue.getTime())) {
|
|
129
|
-
console.error('Invalid date:', item[attrX])
|
|
130
|
-
return
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return {
|
|
134
|
-
xValue: xValue.getTime() / 1000,
|
|
135
|
-
yValue: item[dataset.dataKey!]
|
|
136
|
-
}
|
|
137
|
-
})
|
|
138
|
-
.filter(Boolean) as { xValue: number; yValue: number }[]
|
|
139
|
-
})
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
render() {
|
|
143
|
-
return html` <div id="container" class="chart-container"></div> `
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
declare global {
|
|
148
|
-
interface HTMLElementTagNameMap {
|
|
149
|
-
'ox-scichart': OxSciChart
|
|
150
|
-
}
|
|
151
|
-
}
|