@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.
Files changed (41) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/tsconfig.tsbuildinfo +1 -1
  3. package/package.json +9 -9
  4. package/.editorconfig +0 -29
  5. package/.storybook/main.js +0 -3
  6. package/.storybook/preview.js +0 -52
  7. package/.storybook/server.mjs +0 -8
  8. package/demo/index.html +0 -33
  9. package/src/chartjs/config-converter.ts +0 -341
  10. package/src/chartjs/ox-chart-js.ts +0 -207
  11. package/src/editors/configurer.ts +0 -336
  12. package/src/editors/index.ts +0 -8
  13. package/src/editors/input-chart-abstract.ts +0 -202
  14. package/src/editors/input-chart-styles.ts +0 -206
  15. package/src/editors/ox-input-chart-hbar.ts +0 -157
  16. package/src/editors/ox-input-chart-mixed.ts +0 -241
  17. package/src/editors/ox-input-chart-pie.ts +0 -69
  18. package/src/editors/ox-input-chart-radar.ts +0 -56
  19. package/src/editors/ox-input-chart-timeseries.ts +0 -279
  20. package/src/editors/ox-property-editor-chart.ts +0 -72
  21. package/src/editors/templates/annotations.ts +0 -295
  22. package/src/editors/templates/display-value.ts +0 -111
  23. package/src/editors/templates/series.ts +0 -316
  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 -490
  28. package/stories/common.ts +0 -87
  29. package/stories/ox-input-chart-bar.stories.ts +0 -188
  30. package/stories/ox-input-chart-doughnut.stories.ts +0 -130
  31. package/stories/ox-input-chart-hbar.stories.ts +0 -188
  32. package/stories/ox-input-chart-line.stories.ts +0 -198
  33. package/stories/ox-input-chart-pie.stories.ts +0 -130
  34. package/stories/ox-input-chart-polar-area.stories.ts +0 -130
  35. package/stories/ox-input-chart-radar.stories.ts +0 -141
  36. package/stories/ox-input-chart-timeseries.stories.ts +0 -268
  37. package/tsconfig.json +0 -25
  38. package/web-dev-server.config.mjs +0 -27
  39. package/web-test-runner.config.mjs +0 -41
  40. /package/{src → types}/global.d.ts +0 -0
  41. /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="">&nbsp;</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
- }