@orbcharts/core 3.0.0-beta.8 → 3.0.0

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 (76) hide show
  1. package/LICENSE +200 -200
  2. package/dist/orbcharts-core.es.js +2734 -2353
  3. package/dist/orbcharts-core.umd.js +4 -4
  4. package/dist/src/defaults.d.ts +2 -1
  5. package/dist/src/utils/gridObservables.d.ts +8 -4
  6. package/dist/src/utils/index.d.ts +0 -3
  7. package/dist/src/utils/multiGridObservables.d.ts +3 -2
  8. package/dist/src/utils/multiValueObservables.d.ts +76 -29
  9. package/dist/src/utils/observables.d.ts +8 -1
  10. package/dist/src/utils/orbchartsUtils.d.ts +9 -9
  11. package/dist/src/utils/seriesObservables.d.ts +1 -1
  12. package/lib/core-types.ts +7 -7
  13. package/package.json +42 -42
  14. package/src/AbstractChart.ts +57 -57
  15. package/src/GridChart.ts +24 -24
  16. package/src/MultiGridChart.ts +24 -24
  17. package/src/MultiValueChart.ts +24 -24
  18. package/src/RelationshipChart.ts +24 -24
  19. package/src/SeriesChart.ts +24 -24
  20. package/src/TreeChart.ts +24 -24
  21. package/src/base/createBaseChart.ts +506 -505
  22. package/src/base/createBasePlugin.ts +154 -153
  23. package/src/base/validators/chartOptionsValidator.ts +23 -23
  24. package/src/base/validators/chartParamsValidator.ts +133 -133
  25. package/src/base/validators/elementValidator.ts +13 -13
  26. package/src/base/validators/pluginsValidator.ts +14 -14
  27. package/src/defaults.ts +282 -238
  28. package/src/defineGridPlugin.ts +3 -3
  29. package/src/defineMultiGridPlugin.ts +3 -3
  30. package/src/defineMultiValuePlugin.ts +3 -3
  31. package/src/defineNoneDataPlugin.ts +4 -4
  32. package/src/defineRelationshipPlugin.ts +3 -3
  33. package/src/defineSeriesPlugin.ts +3 -3
  34. package/src/defineTreePlugin.ts +3 -3
  35. package/src/grid/computedDataFn.ts +129 -129
  36. package/src/grid/contextObserverCallback.ts +198 -176
  37. package/src/grid/dataFormatterValidator.ts +120 -101
  38. package/src/grid/dataValidator.ts +12 -12
  39. package/src/index.ts +20 -20
  40. package/src/multiGrid/computedDataFn.ts +123 -123
  41. package/src/multiGrid/contextObserverCallback.ts +72 -41
  42. package/src/multiGrid/dataFormatterValidator.ts +115 -115
  43. package/src/multiGrid/dataValidator.ts +12 -12
  44. package/src/multiValue/computedDataFn.ts +113 -110
  45. package/src/multiValue/contextObserverCallback.ts +276 -160
  46. package/src/multiValue/dataFormatterValidator.ts +89 -9
  47. package/src/multiValue/dataValidator.ts +12 -9
  48. package/src/relationship/computedDataFn.ts +159 -144
  49. package/src/relationship/contextObserverCallback.ts +80 -80
  50. package/src/relationship/dataFormatterValidator.ts +13 -9
  51. package/src/relationship/dataValidator.ts +13 -9
  52. package/src/series/computedDataFn.ts +88 -88
  53. package/src/series/contextObserverCallback.ts +107 -100
  54. package/src/series/dataFormatterValidator.ts +41 -41
  55. package/src/series/dataValidator.ts +12 -12
  56. package/src/tree/computedDataFn.ts +129 -129
  57. package/src/tree/contextObserverCallback.ts +58 -58
  58. package/src/tree/dataFormatterValidator.ts +13 -13
  59. package/src/tree/dataValidator.ts +13 -13
  60. package/src/utils/commonUtils.ts +55 -55
  61. package/src/utils/d3Scale.ts +198 -198
  62. package/src/utils/errorMessage.ts +42 -42
  63. package/src/utils/gridObservables.ts +705 -683
  64. package/src/utils/index.ts +10 -10
  65. package/src/utils/multiGridObservables.ts +401 -392
  66. package/src/utils/multiValueObservables.ts +1044 -662
  67. package/src/utils/observables.ts +281 -219
  68. package/src/utils/orbchartsUtils.ts +377 -377
  69. package/src/utils/relationshipObservables.ts +84 -84
  70. package/src/utils/seriesObservables.ts +175 -175
  71. package/src/utils/treeObservables.ts +105 -105
  72. package/src/utils/validator.ts +126 -126
  73. package/tsconfig.base.json +13 -13
  74. package/tsconfig.json +2 -2
  75. package/vite-env.d.ts +6 -6
  76. package/vite.config.js +22 -22
@@ -1,220 +1,282 @@
1
- import {
2
- combineLatest,
3
- distinctUntilChanged,
4
- filter,
5
- map,
6
- merge,
7
- takeUntil,
8
- shareReplay,
9
- switchMap,
10
- Subject,
11
- Observable } from 'rxjs'
12
- import type {
13
- ChartType,
14
- ChartParams,
15
- ComputedDatumBase,
16
- ComputedDataTypeMap,
17
- ComputedDatumTypeMap,
18
- DataFormatterTypeMap,
19
- EventTypeMap,
20
- HighlightTarget,
21
- Layout,
22
- TransformData } from '../../lib/core-types'
23
-
24
- // interface DatumUnknown {
25
- // value: number | null
26
- // id: string
27
- // // label: string
28
- // seriesLabel?: string // 要符合每一種computedData所以不一定會有seriesLabel
29
- // groupLabel?: string // 要符合每一種computedData所以不一定會有groupLabel
30
- // }
31
-
32
- export function resizeObservable(elem: HTMLElement | Element): Observable<DOMRectReadOnly> {
33
- return new Observable(subscriber => {
34
- const ro = new ResizeObserver(entries => {
35
- const entry = entries[0]
36
- if (entry && entry.contentRect) {
37
- subscriber.next(entry.contentRect)
38
- }
39
- })
40
-
41
- ro.observe(elem)
42
- return function unsubscribe() {
43
- ro.unobserve(elem)
44
- }
45
- })
46
- }
47
-
48
- // 通用 highlight Observable
49
- export const highlightObservable = <T extends ChartType, D>({ datumList$, fullChartParams$, event$ }: {
50
- datumList$: Observable<D[]>
51
- fullChartParams$: Observable<ChartParams>
52
- event$: Subject<EventTypeMap<T>>
53
- }): Observable<D[]> => {
54
- const destroy$ = new Subject()
55
-
56
- // 預設的highlight
57
- const highlightDefault$ = fullChartParams$.pipe(
58
- takeUntil(destroy$),
59
- map(d => {
60
- return {
61
- id: null,
62
- seriesLabel: null,
63
- groupLabel: null,
64
- categoryLabel: null,
65
- highlightDefault: d.highlightDefault
66
- }
67
- }),
68
- distinctUntilChanged()
69
- )
70
-
71
- // 事件觸發的highlight
72
- const highlightMouseover$ = event$.pipe(
73
- takeUntil(destroy$),
74
- // filter(d => d.eventName === 'mouseover' || d.eventName === 'mousemove'),
75
- filter(d => d.eventName === 'mouseover'),
76
- // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
77
- map(d => {
78
- return (d as any).datum
79
- ? {
80
- id: ((d as any).datum as any).id,
81
- seriesLabel: ((d as any).datum as any).seriesLabel,
82
- groupLabel: ((d as any).datum as any).groupLabel,
83
- categoryLabel: ((d as any).datum as any).categoryLabel,
84
- highlightDefault: null
85
- }
86
- : {
87
- id: null,
88
- seriesLabel: null,
89
- groupLabel: null,
90
- categoryLabel: null,
91
- highlightDefault: null
92
- }
93
- })
94
- )
95
- const highlightMouseout$ = event$.pipe(
96
- takeUntil(destroy$),
97
- filter(d => d.eventName === 'mouseout'),
98
- // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
99
- // map(d => {
100
- // return { id: '', label: '' }
101
- // })
102
- switchMap(d => highlightDefault$)
103
- )
104
-
105
- function getDatumIds (datumList: ComputedDatumTypeMap<T>[], id: string | null) {
106
- const datum = datumList.find(d => (d as ComputedDatumBase).id === id)
107
- return datum ? [datum] : []
108
- }
109
-
110
- function getSeriesIds (datumList: ComputedDatumTypeMap<T>[], seriesLabel: string | null) {
111
- return seriesLabel == null
112
- ? []
113
- : datumList.filter(d => (d as ComputedDatumTypeMap<"series">).seriesLabel === seriesLabel)
114
- }
115
-
116
- function getGroupIds (datumList: ComputedDatumTypeMap<T>[], groupLabel: string | null) {
117
- return groupLabel == null
118
- ? []
119
- : datumList.filter(d => (d as ComputedDatumTypeMap<"grid">).groupLabel === groupLabel)
120
- }
121
-
122
- function getCategoryIds (datumList: ComputedDatumTypeMap<T>[], categoryLabel: string | null) {
123
- return categoryLabel == null
124
- ? []
125
- : datumList.filter(d => (d as ComputedDatumTypeMap<"multiValue" | "relationship" | "tree">).categoryLabel === categoryLabel)
126
- }
127
-
128
- return new Observable<D[]>(subscriber => {
129
- combineLatest({
130
- target: merge(highlightMouseover$, highlightMouseout$, highlightDefault$),
131
- datumList: datumList$,
132
- fullChartParams: fullChartParams$,
133
- }).pipe(
134
- takeUntil(destroy$),
135
- switchMap(async d => d)
136
- ).subscribe(data => {
137
- let datumList: ComputedDatumTypeMap<T>[] = []
138
- if (data.fullChartParams.highlightTarget === 'datum') {
139
- datumList = getDatumIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.id)
140
- } else if (data.fullChartParams.highlightTarget === 'series') {
141
- datumList = getSeriesIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.seriesLabel)
142
- } else if (data.fullChartParams.highlightTarget === 'group') {
143
- datumList = getGroupIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.groupLabel)
144
- } else if (data.fullChartParams.highlightTarget === 'category') {
145
- datumList = getCategoryIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.categoryLabel)
146
- }
147
- subscriber.next(datumList as D[])
148
- })
149
-
150
- return function unsubscribe () {
151
- destroy$.next(undefined)
152
- }
153
- })
154
- }
155
-
156
- export const seriesDataMapObservable = <DatumType extends ComputedDatumTypeMap<'series' | 'grid'>>({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
157
- return datumList$.pipe(
158
- map(data => {
159
- const SeriesDataMap: Map<string, DatumType[]> = new Map()
160
- data.forEach(d => {
161
- const seriesData = SeriesDataMap.get(d.seriesLabel) ?? []
162
- seriesData.push(d)
163
- SeriesDataMap.set(d.seriesLabel, seriesData)
164
- })
165
- return SeriesDataMap
166
- })
167
- )
168
- }
169
-
170
- export const groupDataMapObservable = <DatumType extends ComputedDatumTypeMap<'grid'>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
171
- return datumList$.pipe(
172
- map(data => {
173
- const GroupDataMap: Map<string, DatumType[]> = new Map()
174
- data.forEach(d => {
175
- const groupData = GroupDataMap.get(d.groupLabel) ?? []
176
- groupData.push(d)
177
- GroupDataMap.set(d.groupLabel, groupData)
178
- })
179
- return GroupDataMap
180
- })
181
- )
182
- }
183
-
184
- export const categoryDataMapObservable = <DatumType extends ComputedDatumTypeMap<'multiValue' | 'relationship' | 'tree'>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
185
- return datumList$.pipe(
186
- map(data => {
187
- const GroupDataMap: Map<string, DatumType[]> = new Map()
188
- data
189
- .filter(d => d.categoryLabel != null)
190
- .forEach(d => {
191
- const groupData = GroupDataMap.get(d.categoryLabel) ?? []
192
- groupData.push(d)
193
- GroupDataMap.set(d.categoryLabel, groupData)
194
- })
195
- return GroupDataMap
196
- })
197
- )
198
- }
199
-
200
- export const textSizePxObservable = (chartParams$: Observable<ChartParams>) => {
201
- return chartParams$.pipe(
202
- map(d => d.styles.textSize),
203
- distinctUntilChanged(),
204
- map(data => {
205
- let value = NaN
206
- if (typeof data === 'string') {
207
- if (data.includes('rem')) {
208
- const rootFontSizePx = parseFloat(getComputedStyle(document.documentElement).fontSize)
209
- const num = parseFloat(data)
210
- value = num * rootFontSizePx
211
- } else if (data.includes('px')) {
212
- value = parseFloat(data)
213
- }
214
- } else if (typeof data === 'number') {
215
- return data
216
- }
217
- return value ? value : 14 // default
218
- })
219
- )
1
+ import {
2
+ combineLatest,
3
+ distinctUntilChanged,
4
+ filter,
5
+ map,
6
+ merge,
7
+ takeUntil,
8
+ shareReplay,
9
+ switchMap,
10
+ Subject,
11
+ Observable } from 'rxjs'
12
+ import type {
13
+ ChartType,
14
+ ChartParams,
15
+ ComputedDatumBase,
16
+ ComputedDataTypeMap,
17
+ ComputedDatumTypeMap,
18
+ ContainerPositionScaled,
19
+ DataFormatterTypeMap,
20
+ EventTypeMap,
21
+ HighlightTarget,
22
+ Layout,
23
+ TransformData } from '../../lib/core-types'
24
+
25
+ // interface DatumUnknown {
26
+ // value: number | null
27
+ // id: string
28
+ // // label: string
29
+ // seriesLabel?: string // 要符合每一種computedData所以不一定會有seriesLabel
30
+ // groupLabel?: string // 要符合每一種computedData所以不一定會有groupLabel
31
+ // }
32
+
33
+ export function resizeObservable(elem: HTMLElement | Element): Observable<DOMRectReadOnly> {
34
+ return new Observable(subscriber => {
35
+ const ro = new ResizeObserver(entries => {
36
+ const entry = entries[0]
37
+ if (entry && entry.contentRect) {
38
+ subscriber.next(entry.contentRect)
39
+ }
40
+ })
41
+
42
+ ro.observe(elem)
43
+ return function unsubscribe() {
44
+ ro.unobserve(elem)
45
+ }
46
+ })
47
+ }
48
+
49
+ interface HighlightTargetValue {
50
+ id: string | null
51
+ label: string | null
52
+ seriesLabel: string | null
53
+ groupLabel: string | null
54
+ categoryLabel: string | null
55
+ highlightDefault: string | null
56
+ }
57
+
58
+ // 通用 highlight Observable
59
+ export const highlightObservable = <T extends ChartType, D>({ datumList$, fullChartParams$, event$ }: {
60
+ datumList$: Observable<D[]>
61
+ fullChartParams$: Observable<ChartParams>
62
+ event$: Subject<EventTypeMap<T>>
63
+ }): Observable<D[]> => {
64
+ const destroy$ = new Subject()
65
+
66
+ // 預設的highlight
67
+ const highlightDefault$: Observable<HighlightTargetValue> = fullChartParams$.pipe(
68
+ takeUntil(destroy$),
69
+ map(d => {
70
+ return {
71
+ id: null,
72
+ label: null,
73
+ seriesLabel: null,
74
+ groupLabel: null,
75
+ categoryLabel: null,
76
+ highlightDefault: d.highlightDefault
77
+ } as HighlightTargetValue
78
+ }),
79
+ distinctUntilChanged()
80
+ )
81
+
82
+ // 事件觸發的highlight
83
+ const highlightMouseover$: Observable<HighlightTargetValue> = event$.pipe(
84
+ takeUntil(destroy$),
85
+ // filter(d => d.eventName === 'mouseover' || d.eventName === 'mousemove'),
86
+ filter(d => d.eventName === 'mouseover'),
87
+ // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
88
+ map(_d => {
89
+ const d = _d as any
90
+ return d.datum
91
+ ? {
92
+ id: d.datum.id,
93
+ label: d.datum.label,
94
+ seriesLabel: d.datum.seriesLabel,
95
+ groupLabel: d.datum.groupLabel,
96
+ categoryLabel: d.datum.categoryLabel,
97
+ highlightDefault: null
98
+ } as HighlightTargetValue
99
+ : {
100
+ id: null,
101
+ label: null,
102
+ seriesLabel: null,
103
+ groupLabel: null,
104
+ categoryLabel: null,
105
+ highlightDefault: null
106
+ } as HighlightTargetValue
107
+ })
108
+ )
109
+ const highlightMouseout$ = event$.pipe(
110
+ takeUntil(destroy$),
111
+ filter(d => d.eventName === 'mouseout'),
112
+ // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
113
+ // map(d => {
114
+ // return { id: '', label: '' }
115
+ // })
116
+ switchMap(d => highlightDefault$)
117
+ )
118
+
119
+ // function getDatumIds (datumList: ComputedDatumTypeMap<T>[], id: string | null) {
120
+ // const datum = datumList.find(d => (d as ComputedDatumBase).id === id)
121
+ // return datum ? [datum] : []
122
+ // }
123
+ function getDatumIds (datumList: ComputedDatumTypeMap<T>[], id: string | null, label: string | null) {
124
+ return id == null && label == null
125
+ ? []
126
+ : datumList.filter(d => (d as ComputedDatumBase).id === id || (d as ComputedDatumBase).label === label)
127
+ }
128
+
129
+ function getSeriesIds (datumList: ComputedDatumTypeMap<T>[], seriesLabel: string | null) {
130
+ return seriesLabel == null
131
+ ? []
132
+ : datumList.filter(d => (d as ComputedDatumTypeMap<"series">).seriesLabel === seriesLabel)
133
+ }
134
+
135
+ function getGroupIds (datumList: ComputedDatumTypeMap<T>[], groupLabel: string | null) {
136
+ return groupLabel == null
137
+ ? []
138
+ : datumList.filter(d => (d as ComputedDatumTypeMap<"grid">).groupLabel === groupLabel)
139
+ }
140
+
141
+ function getCategoryIds (datumList: ComputedDatumTypeMap<T>[], categoryLabel: string | null) {
142
+ return categoryLabel == null
143
+ ? []
144
+ : datumList.filter(d => (d as ComputedDatumTypeMap<"multiValue" | "relationship" | "tree">).categoryLabel === categoryLabel)
145
+ }
146
+
147
+ return new Observable<D[]>(subscriber => {
148
+ combineLatest({
149
+ target: merge(highlightMouseover$, highlightMouseout$, highlightDefault$),
150
+ datumList: datumList$,
151
+ fullChartParams: fullChartParams$,
152
+ }).pipe(
153
+ takeUntil(destroy$),
154
+ switchMap(async d => d)
155
+ ).subscribe(data => {
156
+ let datumList: ComputedDatumTypeMap<T>[] = []
157
+ if (data.fullChartParams.highlightTarget === 'datum') {
158
+ datumList = getDatumIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.id, data.target.label)
159
+ } else if (data.fullChartParams.highlightTarget === 'series') {
160
+ datumList = getSeriesIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.seriesLabel)
161
+ } else if (data.fullChartParams.highlightTarget === 'group') {
162
+ datumList = getGroupIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.groupLabel)
163
+ } else if (data.fullChartParams.highlightTarget === 'category') {
164
+ datumList = getCategoryIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.categoryLabel)
165
+ }
166
+ subscriber.next(datumList as D[])
167
+ })
168
+
169
+ return function unsubscribe () {
170
+ destroy$.next(undefined)
171
+ }
172
+ })
173
+ }
174
+
175
+ export const seriesDataMapObservable = <DatumType extends ComputedDatumTypeMap<'series' | 'grid'>>({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
176
+ return datumList$.pipe(
177
+ map(data => {
178
+ const SeriesDataMap: Map<string, DatumType[]> = new Map()
179
+ data.forEach(d => {
180
+ const seriesData = SeriesDataMap.get(d.seriesLabel) ?? []
181
+ seriesData.push(d)
182
+ SeriesDataMap.set(d.seriesLabel, seriesData)
183
+ })
184
+ return SeriesDataMap
185
+ })
186
+ )
187
+ }
188
+
189
+ export const groupDataMapObservable = <DatumType extends ComputedDatumTypeMap<'grid'>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
190
+ return datumList$.pipe(
191
+ map(data => {
192
+ const GroupDataMap: Map<string, DatumType[]> = new Map()
193
+ data.forEach(d => {
194
+ const groupData = GroupDataMap.get(d.groupLabel) ?? []
195
+ groupData.push(d)
196
+ GroupDataMap.set(d.groupLabel, groupData)
197
+ })
198
+ return GroupDataMap
199
+ })
200
+ )
201
+ }
202
+
203
+ export const categoryDataMapObservable = <DatumType extends ComputedDatumTypeMap<'multiValue' | 'relationship' | 'tree'>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
204
+ return datumList$.pipe(
205
+ map(data => {
206
+ const GroupDataMap: Map<string, DatumType[]> = new Map()
207
+ data
208
+ .filter(d => d.categoryLabel != null)
209
+ .forEach(d => {
210
+ const groupData = GroupDataMap.get(d.categoryLabel) ?? []
211
+ groupData.push(d)
212
+ GroupDataMap.set(d.categoryLabel, groupData)
213
+ })
214
+ return GroupDataMap
215
+ })
216
+ )
217
+ }
218
+
219
+ export const textSizePxObservable = (chartParams$: Observable<ChartParams>) => {
220
+ return chartParams$.pipe(
221
+ map(d => d.styles.textSize),
222
+ distinctUntilChanged(),
223
+ map(data => {
224
+ let value = NaN
225
+ if (typeof data === 'string') {
226
+ if (data.includes('rem')) {
227
+ const rootFontSizePx = parseFloat(getComputedStyle(document.documentElement).fontSize)
228
+ const num = parseFloat(data)
229
+ value = num * rootFontSizePx
230
+ } else if (data.includes('px')) {
231
+ value = parseFloat(data)
232
+ }
233
+ } else if (typeof data === 'number') {
234
+ return data
235
+ }
236
+ return value ? value : 14 // default
237
+ })
238
+ )
239
+ }
240
+
241
+ export const containerSizeObservable = ({ layout$, containerPosition$ }: {
242
+ layout$: Observable<Layout>
243
+ containerPosition$: Observable<ContainerPositionScaled[]>
244
+ }) => {
245
+ const rowAmount$ = containerPosition$.pipe(
246
+ map(containerPosition => {
247
+ const maxRowIndex = containerPosition.reduce((acc, current) => {
248
+ return current.rowIndex > acc ? current.rowIndex : acc
249
+ }, 0)
250
+ return maxRowIndex + 1
251
+ }),
252
+ distinctUntilChanged(),
253
+ )
254
+
255
+ const columnAmount$ = containerPosition$.pipe(
256
+ map(containerPosition => {
257
+ const maxColumnIndex = containerPosition.reduce((acc, current) => {
258
+ return current.columnIndex > acc ? current.columnIndex : acc
259
+ }, 0)
260
+ return maxColumnIndex + 1
261
+ }),
262
+ distinctUntilChanged()
263
+ )
264
+
265
+ return combineLatest({
266
+ layout: layout$,
267
+ rowAmount: rowAmount$,
268
+ columnAmount: columnAmount$
269
+ }).pipe(
270
+ switchMap(async (d) => d),
271
+ map(data => {
272
+ const width = (data.layout.rootWidth / data.columnAmount) - (data.layout.left + data.layout.right)
273
+ const height = (data.layout.rootHeight / data.rowAmount) - (data.layout.top + data.layout.bottom)
274
+ return {
275
+ width,
276
+ height
277
+ }
278
+ }),
279
+ distinctUntilChanged((a, b) => a.width === b.width && a.height === b.height),
280
+ // shareReplay(1)
281
+ )
220
282
  }