@operato/chart 7.0.36 → 7.0.39

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 (48) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/src/editors/configurer.d.ts +4 -2
  3. package/dist/src/editors/configurer.js +24 -13
  4. package/dist/src/editors/configurer.js.map +1 -1
  5. package/dist/src/editors/input-chart-abstract.d.ts +0 -26
  6. package/dist/src/editors/input-chart-abstract.js +1 -607
  7. package/dist/src/editors/input-chart-abstract.js.map +1 -1
  8. package/dist/src/editors/input-chart-styles.js +27 -0
  9. package/dist/src/editors/input-chart-styles.js.map +1 -1
  10. package/dist/src/editors/ox-input-chart-hbar.d.ts +1 -1
  11. package/dist/src/editors/ox-input-chart-hbar.js +2 -69
  12. package/dist/src/editors/ox-input-chart-hbar.js.map +1 -1
  13. package/dist/src/editors/ox-input-chart-mixed.d.ts +1 -0
  14. package/dist/src/editors/ox-input-chart-mixed.js +2 -2
  15. package/dist/src/editors/ox-input-chart-mixed.js.map +1 -1
  16. package/dist/src/editors/ox-input-chart-pie.d.ts +1 -0
  17. package/dist/src/editors/ox-input-chart-pie.js +3 -1
  18. package/dist/src/editors/ox-input-chart-pie.js.map +1 -1
  19. package/dist/src/editors/ox-input-chart-radar.d.ts +1 -0
  20. package/dist/src/editors/ox-input-chart-radar.js +2 -2
  21. package/dist/src/editors/ox-input-chart-radar.js.map +1 -1
  22. package/dist/src/editors/ox-input-chart-timeseries.d.ts +2 -0
  23. package/dist/src/editors/ox-input-chart-timeseries.js +9 -3
  24. package/dist/src/editors/ox-input-chart-timeseries.js.map +1 -1
  25. package/dist/src/editors/ox-property-editor-chart.js.map +1 -1
  26. package/dist/src/editors/templates/annotations.d.ts +23 -0
  27. package/dist/src/editors/templates/annotations.js +270 -0
  28. package/dist/src/editors/templates/annotations.js.map +1 -0
  29. package/dist/src/editors/templates/display-value.d.ts +12 -0
  30. package/dist/src/editors/templates/display-value.js +105 -0
  31. package/dist/src/editors/templates/display-value.js.map +1 -0
  32. package/dist/src/editors/templates/series.d.ts +31 -0
  33. package/dist/src/editors/templates/series.js +277 -0
  34. package/dist/src/editors/templates/series.js.map +1 -0
  35. package/dist/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +4 -4
  37. package/src/editors/configurer.ts +25 -14
  38. package/src/editors/input-chart-abstract.ts +1 -655
  39. package/src/editors/input-chart-styles.ts +27 -0
  40. package/src/editors/ox-input-chart-hbar.ts +3 -73
  41. package/src/editors/ox-input-chart-mixed.ts +2 -2
  42. package/src/editors/ox-input-chart-pie.ts +3 -2
  43. package/src/editors/ox-input-chart-radar.ts +3 -2
  44. package/src/editors/ox-input-chart-timeseries.ts +10 -3
  45. package/src/editors/ox-property-editor-chart.ts +1 -1
  46. package/src/editors/templates/annotations.ts +287 -0
  47. package/src/editors/templates/display-value.ts +110 -0
  48. package/src/editors/templates/series.ts +304 -0
@@ -0,0 +1,304 @@
1
+ import '@material/web/icon/icon.js'
2
+
3
+ import { LitElement, html, PropertyValues } 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?: 'bar' | 'horizontalBar' | 'line' | 'radar' | 'pie' | 'doughnut' | 'polarArea'
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
+ render() {
32
+ return keyed(
33
+ this.configurer.currentSeriesIndex,
34
+ html`
35
+ <div id="series-properties-container" fullwidth>
36
+ <div id="series-tab-header" @wheel=${this._onWheelScroll}>
37
+ <md-icon id="series-tab-nav-left-button" @click=${this._scrollLeft}>chevron_left</md-icon>
38
+ <div id="series-tabs" active-tab-index=${this.configurer.currentSeriesIndex} fit-container>
39
+ ${this._renderTabs()}
40
+ </div>
41
+ <md-icon id="series-tab-nav-right-button" @click=${this._scrollRight}>chevron_right</md-icon>
42
+ </div>
43
+ <div id="add-series-button-container">
44
+ <md-icon id="add-series-button" @click=${this._addSeries}>add</md-icon>
45
+ </div>
46
+ ${this._renderSeriesForm()}
47
+ </div>
48
+ `
49
+ )
50
+ }
51
+
52
+ private _renderTabs() {
53
+ return this.configurer.datasets.map(
54
+ (dataset: OperatoChart.Dataset, index: number) => html`
55
+ <div
56
+ data-series=${index + 1}
57
+ data-tab-index=${index}
58
+ tab
59
+ ?selected=${index === this.configurer.currentSeriesIndex}
60
+ @click=${() => this._selectTab(index)}
61
+ >
62
+ ${index + 1}
63
+ ${this.configurer.datasets.length > 1 && this.configurer.currentSeriesIndex === index
64
+ ? html`<md-icon @click=${() => this._removeSeries(index)}>close</md-icon>`
65
+ : html``}
66
+ </div>
67
+ `
68
+ )
69
+ }
70
+
71
+ private _renderSeriesForm() {
72
+ const configurer = this.configurer
73
+ const chartType = this.chartType
74
+
75
+ return html`
76
+ <div class="tab-content">
77
+ <label for="data-key"> <ox-i18n msgid="label.data-key">Data Key</ox-i18n> </label>
78
+ <input id="data-key" type="text" value-key="dataKey" .value=${configurer.dataKey || ''} />
79
+
80
+ ${chartType === 'line' || chartType === 'bar'
81
+ ? html`
82
+ <label for="series-type"> <ox-i18n msgid="label.series-type">Type</ox-i18n> </label>
83
+ <select
84
+ id="series-type"
85
+ class="select-content"
86
+ value-key="series.type"
87
+ .value=${configurer.series.type || ''}
88
+ >
89
+ <option value="bar" selected>Bar</option>
90
+ <option value="line">Line</option>
91
+ </select>
92
+ `
93
+ : html``}
94
+
95
+ <label for="series-label"> <ox-i18n msgid="label.label">Label</ox-i18n> </label>
96
+ <input id="series-label" type="text" value-key="series.label" .value=${configurer.series.label || ''} />
97
+
98
+ ${configurer.series.type === 'line'
99
+ ? html`
100
+ <label for="series-line-tension"> <ox-i18n msgid="label.line-tension">Line Tension</ox-i18n> </label>
101
+ <select
102
+ id="series-line-tension"
103
+ class="select-content"
104
+ value-key="series.lineTension"
105
+ .value=${String(configurer.series.lineTension || 0)}
106
+ >
107
+ <option value="0.4">Smooth</option>
108
+ <option value="0">Angled</option>
109
+ </select>
110
+ `
111
+ : html``}
112
+ ${configurer.series.type === 'line'
113
+ ? html`
114
+ <label for="series-border-width"> <ox-i18n msgid="label.border-width">Border Width</ox-i18n> </label>
115
+ <input
116
+ id="series-border-width"
117
+ type="number"
118
+ value-key="series.borderWidth"
119
+ .value=${String(configurer.series.borderWidth || 0)}
120
+ />
121
+ `
122
+ : html``}
123
+
124
+ <label for="series-color"> <ox-i18n msgid="label.color">Color</ox-i18n> </label>
125
+ <ox-input-color id="series-color" value-key="color" .value=${configurer.color}></ox-input-color>
126
+
127
+ ${configurer.series.type === 'line'
128
+ ? html`
129
+ <label for="series-point-style"> <ox-i18n msgid="label.point-shape">Point Shape</ox-i18n> </label>
130
+ <select
131
+ id="series-point-style"
132
+ class="select-content"
133
+ value-key="series.pointStyle"
134
+ .value=${configurer.series.pointStyle || ''}
135
+ >
136
+ <option value="">&nbsp;</option>
137
+ <option value="circle">⚬</option>
138
+ <option value="triangle">▵</option>
139
+ <option value="rect">□</option>
140
+ <option value="rectRot">◇</option>
141
+ <option value="cross">+</option>
142
+ <option value="crossRot">⨉</option>
143
+ <option value="star">✱</option>
144
+ <option value="line">―</option>
145
+ <option value="dash">┄</option>
146
+ </select>
147
+
148
+ <label for="series-point-radius"> <ox-i18n msgid="label.point-size">Point Size</ox-i18n> </label>
149
+ <input
150
+ id="series-point-radius"
151
+ type="number"
152
+ value-key="series.pointRadius"
153
+ .value=${String(configurer.series.pointRadius || 0)}
154
+ />
155
+ `
156
+ : html``}
157
+
158
+ <label for="series-stack"> <ox-i18n msgid="label.stack-group">Stack group</ox-i18n> </label>
159
+ <input id="series-stack" type="text" value-key="series.stack" .value=${configurer.series.stack || ''} />
160
+
161
+ ${configurer.series.type === 'line'
162
+ ? html`
163
+ <input id="series-fill" type="checkbox" value-key="series.fill" ?checked=${configurer.series.fill} />
164
+ <label for="series-fill"> <ox-i18n msgid="label.fill">Fill</ox-i18n> </label>
165
+ `
166
+ : html``}
167
+ ${configurer.multiAxis && configurer.series.type !== 'horizontalBar'
168
+ ? html`
169
+ <label for="series-y-axis-id"> <ox-i18n msgid="label.target-axis">Target Axis</ox-i18n> </label>
170
+ <select
171
+ id="series-y-axis-id"
172
+ class="select-content"
173
+ value-key="series.yAxisID"
174
+ .value=${configurer.series.yAxisID || ''}
175
+ >
176
+ <option value="left">Left</option>
177
+ <option value="right">Right</option>
178
+ </select>
179
+ `
180
+ : html``}
181
+
182
+ <label></label>
183
+ <ox-chart-display-value .configurer=${configurer} fullwidth></ox-chart-display-value>
184
+ </div>
185
+ `
186
+ }
187
+
188
+ _getSeriesModel({
189
+ chartType,
190
+ datasetsLength,
191
+ lastSeriesColor
192
+ }: {
193
+ chartType: string
194
+ datasetsLength: number
195
+ lastSeriesColor: TinyColor
196
+ }) {
197
+ const addSeriesOption: any = {
198
+ label: `series ${datasetsLength + 1}`,
199
+ data: [],
200
+ borderWidth: 1,
201
+ dataKey: '',
202
+ yAxisID: 'left',
203
+ color: randomColor({
204
+ hue: lastSeriesColor.toHsv().h
205
+ }).toRgbString(),
206
+ stack: ''
207
+ }
208
+
209
+ addSeriesOption.type = addSeriesOption.chartType = chartType
210
+ return addSeriesOption
211
+ }
212
+
213
+ private _selectTab(index: number) {
214
+ this.configurer.setCurrentSeriesIndex(index)
215
+ this.requestUpdate()
216
+ }
217
+
218
+ private _removeSeries(index: number) {
219
+ this.configurer.removeSeries(index)
220
+ this.requestUpdate()
221
+ }
222
+
223
+ private _addSeries() {
224
+ const configurer = this.configurer
225
+
226
+ if (!configurer.config.data.datasets) {
227
+ return
228
+ }
229
+
230
+ const lastSeriesIndex = configurer.config.data.datasets.length
231
+ const chartType = configurer.series.type || configurer.config.type
232
+ const color = configurer.datasets[lastSeriesIndex - 1]?.backgroundColor
233
+ const lastSeriesColor = new TinyColor(Array.isArray(color) ? color[0] : color)
234
+
235
+ const seriesModel = this._getSeriesModel({
236
+ chartType: chartType!,
237
+ datasetsLength: lastSeriesIndex,
238
+ lastSeriesColor
239
+ })
240
+
241
+ this.configurer.addSeries(seriesModel)
242
+ this.requestUpdate()
243
+ }
244
+
245
+ private _onWheelScroll(event: WheelEvent) {
246
+ const tabContainer = this.seriesTabs
247
+ if (tabContainer) {
248
+ event.preventDefault()
249
+
250
+ tabContainer.scrollLeft += event.deltaY
251
+
252
+ this._onTabScroll()
253
+ }
254
+ }
255
+
256
+ private _scrollLeft() {
257
+ this._scrollTabContainer(-1)
258
+ }
259
+
260
+ private _scrollRight() {
261
+ this._scrollTabContainer(1)
262
+ }
263
+
264
+ private _scrollTabContainer(direction: number) {
265
+ const tabContainer = this.renderRoot!.querySelector<HTMLElement>('#series-tabs')
266
+ if (tabContainer) {
267
+ tabContainer.style.scrollBehavior = 'smooth'
268
+ tabContainer.scrollLeft += direction * tabContainer.clientWidth
269
+ }
270
+
271
+ setTimeout(() => {
272
+ tabContainer!.style.scrollBehavior = 'auto'
273
+ this._onTabScroll()
274
+ }, 300)
275
+ }
276
+
277
+ private _onTabScroll() {
278
+ let tabContainer: HTMLElement | null | undefined
279
+ let tabNavLeftButton: MdIcon
280
+ let tabNavRightButton: MdIcon
281
+
282
+ tabContainer = this.seriesTabs
283
+ tabNavLeftButton = this.seriesTabNavLeftButton
284
+ tabNavRightButton = this.seriesTabNavRightButton
285
+
286
+ if (!tabContainer) {
287
+ return
288
+ }
289
+
290
+ if (tabContainer.clientWidth == tabContainer.scrollWidth) {
291
+ tabNavLeftButton.setAttribute('disabled', '')
292
+ tabNavRightButton.setAttribute('disabled', '')
293
+ } else if (tabContainer.scrollLeft <= 0) {
294
+ tabNavLeftButton.setAttribute('disabled', '')
295
+ tabNavRightButton.removeAttribute('disabled')
296
+ } else if (tabContainer.scrollLeft + tabContainer.clientWidth >= tabContainer.scrollWidth) {
297
+ tabNavLeftButton.removeAttribute('disabled')
298
+ tabNavRightButton.setAttribute('disabled', '')
299
+ } else {
300
+ tabNavLeftButton.removeAttribute('disabled')
301
+ tabNavRightButton.removeAttribute('disabled')
302
+ }
303
+ }
304
+ }