@jbrowse/plugin-circular-view 2.1.4 → 2.1.5

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 (64) hide show
  1. package/dist/BaseChordDisplay/components/DisplayError.d.ts +6 -5
  2. package/dist/BaseChordDisplay/components/DisplayError.js +6 -13
  3. package/dist/BaseChordDisplay/components/DisplayError.js.map +1 -1
  4. package/dist/BaseChordDisplay/components/RpcRenderedSvgGroup.d.ts +10 -2
  5. package/dist/BaseChordDisplay/components/RpcRenderedSvgGroup.js +1 -1
  6. package/dist/BaseChordDisplay/components/RpcRenderedSvgGroup.js.map +1 -1
  7. package/dist/BaseChordDisplay/models/BaseChordDisplayModel.d.ts +5 -2
  8. package/dist/BaseChordDisplay/models/BaseChordDisplayModel.js +29 -31
  9. package/dist/BaseChordDisplay/models/BaseChordDisplayModel.js.map +1 -1
  10. package/dist/BaseChordDisplay/models/renderReaction.d.ts +22 -27
  11. package/dist/BaseChordDisplay/models/renderReaction.js +53 -49
  12. package/dist/BaseChordDisplay/models/renderReaction.js.map +1 -1
  13. package/dist/CircularView/components/CircularView.d.ts +5 -3
  14. package/dist/CircularView/components/CircularView.js +8 -4
  15. package/dist/CircularView/components/CircularView.js.map +1 -1
  16. package/dist/CircularView/components/Ruler.d.ts +7 -4
  17. package/dist/CircularView/components/Ruler.js +11 -5
  18. package/dist/CircularView/components/Ruler.js.map +1 -1
  19. package/dist/CircularView/models/CircularView.d.ts +5 -4
  20. package/dist/CircularView/models/CircularView.js +5 -3
  21. package/dist/CircularView/models/CircularView.js.map +1 -1
  22. package/dist/CircularView/models/slices.d.ts +6 -1
  23. package/dist/CircularView/models/slices.js +1 -4
  24. package/dist/CircularView/models/slices.js.map +1 -1
  25. package/dist/CircularView/models/viewportVisibleRegion.d.ts +2 -2
  26. package/dist/CircularView/models/viewportVisibleRegion.js.map +1 -1
  27. package/esm/BaseChordDisplay/components/DisplayError.d.ts +6 -5
  28. package/esm/BaseChordDisplay/components/DisplayError.js +6 -13
  29. package/esm/BaseChordDisplay/components/DisplayError.js.map +1 -1
  30. package/esm/BaseChordDisplay/components/RpcRenderedSvgGroup.d.ts +10 -2
  31. package/esm/BaseChordDisplay/components/RpcRenderedSvgGroup.js +1 -1
  32. package/esm/BaseChordDisplay/components/RpcRenderedSvgGroup.js.map +1 -1
  33. package/esm/BaseChordDisplay/models/BaseChordDisplayModel.d.ts +5 -2
  34. package/esm/BaseChordDisplay/models/BaseChordDisplayModel.js +29 -31
  35. package/esm/BaseChordDisplay/models/BaseChordDisplayModel.js.map +1 -1
  36. package/esm/BaseChordDisplay/models/renderReaction.d.ts +22 -27
  37. package/esm/BaseChordDisplay/models/renderReaction.js +50 -49
  38. package/esm/BaseChordDisplay/models/renderReaction.js.map +1 -1
  39. package/esm/CircularView/components/CircularView.d.ts +5 -3
  40. package/esm/CircularView/components/CircularView.js +8 -4
  41. package/esm/CircularView/components/CircularView.js.map +1 -1
  42. package/esm/CircularView/components/Ruler.d.ts +7 -4
  43. package/esm/CircularView/components/Ruler.js +11 -5
  44. package/esm/CircularView/components/Ruler.js.map +1 -1
  45. package/esm/CircularView/models/CircularView.d.ts +5 -4
  46. package/esm/CircularView/models/CircularView.js +5 -3
  47. package/esm/CircularView/models/CircularView.js.map +1 -1
  48. package/esm/CircularView/models/slices.d.ts +6 -1
  49. package/esm/CircularView/models/slices.js +1 -4
  50. package/esm/CircularView/models/slices.js.map +1 -1
  51. package/esm/CircularView/models/viewportVisibleRegion.d.ts +2 -2
  52. package/esm/CircularView/models/viewportVisibleRegion.js.map +1 -1
  53. package/package.json +2 -2
  54. package/src/BaseChordDisplay/components/{DisplayError.js → DisplayError.tsx} +9 -28
  55. package/src/BaseChordDisplay/components/{RpcRenderedSvgGroup.js → RpcRenderedSvgGroup.tsx} +14 -2
  56. package/src/BaseChordDisplay/models/BaseChordDisplayModel.ts +49 -52
  57. package/src/BaseChordDisplay/models/renderReaction.ts +72 -0
  58. package/src/CircularView/components/{CircularView.js → CircularView.tsx} +80 -69
  59. package/src/CircularView/components/Ruler.tsx +260 -0
  60. package/src/CircularView/models/CircularView.ts +7 -4
  61. package/src/CircularView/models/slices.ts +4 -3
  62. package/src/CircularView/models/viewportVisibleRegion.ts +4 -4
  63. package/src/BaseChordDisplay/models/renderReaction.js +0 -70
  64. package/src/CircularView/components/Ruler.js +0 -222
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import { observer } from 'mobx-react'
3
3
  import { ResizeHandle, ErrorMessage } from '@jbrowse/core/ui'
4
4
  import { assembleLocString } from '@jbrowse/core/util'
5
+ import { CircularViewModel } from '../models/CircularView'
5
6
  import { IconButton } from '@mui/material'
6
7
  import { makeStyles } from 'tss-react/mui'
7
8
  import { grey } from '@mui/material/colors'
@@ -57,12 +58,13 @@ const useStyles = makeStyles()(theme => ({
57
58
  },
58
59
  }))
59
60
 
60
- const Slices = observer(({ model }) => {
61
+ const Slices = observer(({ model }: { model: CircularViewModel }) => {
61
62
  return (
62
63
  <>
63
64
  {model.staticSlices.map(slice => (
64
65
  <Ruler
65
66
  key={assembleLocString(
67
+ // @ts-ignore
66
68
  slice.region.elided ? slice.region.regions[0] : slice.region,
67
69
  )}
68
70
  model={model}
@@ -83,84 +85,94 @@ const Slices = observer(({ model }) => {
83
85
  )
84
86
  })
85
87
 
86
- const Controls = observer(({ model, showingFigure }) => {
87
- const { classes } = useStyles()
88
- return (
89
- <div className={classes.controls}>
90
- <IconButton
91
- onClick={model.zoomOutButton}
92
- className={classes.iconButton}
93
- title={model.lockedFitToWindow ? 'unlock to zoom out' : 'zoom out'}
94
- disabled={
95
- !showingFigure || model.atMaxBpPerPx || model.lockedFitToWindow
96
- }
97
- color="secondary"
98
- >
99
- <ZoomOutIcon />
100
- </IconButton>
101
-
102
- <IconButton
103
- onClick={model.zoomInButton}
104
- className={classes.iconButton}
105
- title="zoom in"
106
- disabled={!showingFigure || model.atMinBpPerPx}
107
- color="secondary"
108
- >
109
- <ZoomInIcon />
110
- </IconButton>
88
+ const Controls = observer(
89
+ ({
90
+ model,
91
+ showingFigure,
92
+ }: {
93
+ model: CircularViewModel
94
+ showingFigure: boolean
95
+ }) => {
96
+ const { classes } = useStyles()
97
+ return (
98
+ <div className={classes.controls}>
99
+ <IconButton
100
+ onClick={model.zoomOutButton}
101
+ className={classes.iconButton}
102
+ title={model.lockedFitToWindow ? 'unlock to zoom out' : 'zoom out'}
103
+ disabled={
104
+ !showingFigure || model.atMaxBpPerPx || model.lockedFitToWindow
105
+ }
106
+ color="secondary"
107
+ >
108
+ <ZoomOutIcon />
109
+ </IconButton>
111
110
 
112
- <IconButton
113
- onClick={model.rotateCounterClockwiseButton}
114
- className={classes.iconButton}
115
- title="rotate counter-clockwise"
116
- disabled={!showingFigure}
117
- color="secondary"
118
- >
119
- <RotateLeftIcon />
120
- </IconButton>
111
+ <IconButton
112
+ onClick={model.zoomInButton}
113
+ className={classes.iconButton}
114
+ title="zoom in"
115
+ disabled={!showingFigure || model.atMinBpPerPx}
116
+ color="secondary"
117
+ >
118
+ <ZoomInIcon />
119
+ </IconButton>
121
120
 
122
- <IconButton
123
- onClick={model.rotateClockwiseButton}
124
- className={classes.iconButton}
125
- title="rotate clockwise"
126
- disabled={!showingFigure}
127
- color="secondary"
128
- >
129
- <RotateRightIcon />
130
- </IconButton>
121
+ <IconButton
122
+ onClick={model.rotateCounterClockwiseButton}
123
+ className={classes.iconButton}
124
+ title="rotate counter-clockwise"
125
+ disabled={!showingFigure}
126
+ color="secondary"
127
+ >
128
+ <RotateLeftIcon />
129
+ </IconButton>
131
130
 
132
- <IconButton
133
- onClick={model.toggleFitToWindowLock}
134
- className={classes.iconButton}
135
- title={
136
- model.lockedFitToWindow
137
- ? 'locked model to window size'
138
- : 'unlocked model to zoom further'
139
- }
140
- disabled={model.tooSmallToLock}
141
- color="secondary"
142
- >
143
- {model.lockedFitToWindow ? <LockIcon /> : <LockOpenIcon />}
144
- </IconButton>
131
+ <IconButton
132
+ onClick={model.rotateClockwiseButton}
133
+ className={classes.iconButton}
134
+ title="rotate clockwise"
135
+ disabled={!showingFigure}
136
+ color="secondary"
137
+ >
138
+ <RotateRightIcon />
139
+ </IconButton>
145
140
 
146
- {model.hideTrackSelectorButton ? null : (
147
141
  <IconButton
148
- onClick={model.activateTrackSelector}
149
- title="Open track selector"
150
- data-testid="circular_track_select"
142
+ onClick={model.toggleFitToWindowLock}
143
+ className={classes.iconButton}
144
+ title={
145
+ model.lockedFitToWindow
146
+ ? 'locked model to window size'
147
+ : 'unlocked model to zoom further'
148
+ }
149
+ disabled={model.tooSmallToLock}
151
150
  color="secondary"
152
151
  >
153
- <TrackSelectorIcon />
152
+ {model.lockedFitToWindow ? <LockIcon /> : <LockOpenIcon />}
154
153
  </IconButton>
155
- )}
156
- </div>
157
- )
158
- })
159
154
 
160
- const CircularView = observer(({ model }) => {
155
+ {model.hideTrackSelectorButton ? null : (
156
+ <IconButton
157
+ onClick={model.activateTrackSelector}
158
+ title="Open track selector"
159
+ data-testid="circular_track_select"
160
+ color="secondary"
161
+ >
162
+ <TrackSelectorIcon />
163
+ </IconButton>
164
+ )}
165
+ </div>
166
+ )
167
+ },
168
+ )
169
+
170
+ const CircularView = observer(({ model }: { model: CircularViewModel }) => {
161
171
  const { classes } = useStyles()
162
172
  const initialized =
163
- !!model.displayedRegions.length && model.figureWidth && model.figureHeight
173
+ !!model.displayedRegions.length &&
174
+ !!model.figureWidth &&
175
+ !!model.figureHeight
164
176
 
165
177
  const showImportForm = !initialized && !model.disableImportForm
166
178
  const showFigure = initialized && !showImportForm
@@ -189,7 +201,6 @@ const CircularView = observer(({ model }) => {
189
201
  }}
190
202
  >
191
203
  <div
192
- className={classes.rotator}
193
204
  style={{
194
205
  transform: [`rotate(${model.offsetRadians}rad)`].join(' '),
195
206
  transition: 'transform 0.5s',
@@ -0,0 +1,260 @@
1
+ import React from 'react'
2
+ import { observer } from 'mobx-react'
3
+ import {
4
+ getSession,
5
+ polarToCartesian,
6
+ radToDeg,
7
+ assembleLocString,
8
+ } from '@jbrowse/core/util'
9
+ import { makeContrasting } from '@jbrowse/core/util/color'
10
+ import { useTheme } from '@mui/material/styles'
11
+ import { makeStyles } from 'tss-react/mui'
12
+
13
+ // locals
14
+ import { Slice } from '../models/slices'
15
+ import { CircularViewModel } from '../models/CircularView'
16
+
17
+ const useStyles = makeStyles()({
18
+ rulerLabel: {
19
+ fontSize: '0.8rem',
20
+ fontWeight: 500,
21
+ lineHeight: 1.6,
22
+ letterSpacing: '0.0075em',
23
+ },
24
+ })
25
+
26
+ function sliceArcPath(
27
+ slice: Slice,
28
+ radiusPx: number,
29
+ startBase: number,
30
+ endBase: number,
31
+ ) {
32
+ // A rx ry x-axis-rotation large-arc-flag sweep-flag x y
33
+ if (slice.flipped) {
34
+ ;[startBase, endBase] = [endBase, startBase]
35
+ }
36
+ const startXY = slice.bpToXY(startBase, radiusPx)
37
+ const endXY = slice.bpToXY(endBase, radiusPx)
38
+ const largeArc =
39
+ Math.abs(endBase - startBase) / slice.bpPerRadian > Math.PI ? '1' : '0'
40
+ const sweepFlag = '1'
41
+ return [
42
+ 'M',
43
+ ...startXY,
44
+ 'A',
45
+ radiusPx,
46
+ radiusPx,
47
+ '0',
48
+ largeArc,
49
+ sweepFlag,
50
+ ...endXY,
51
+ ].join(' ')
52
+ }
53
+
54
+ const ElisionRulerArc = observer(
55
+ ({ model, slice }: { model: CircularViewModel; slice: Slice }) => {
56
+ const theme = useTheme()
57
+ const { radiusPx: modelRadiusPx } = model
58
+ const radiusPx = modelRadiusPx + 1
59
+ const { endRadians, startRadians, region } = slice
60
+ const startXY = polarToCartesian(radiusPx, startRadians)
61
+ const endXY = polarToCartesian(radiusPx, endRadians)
62
+ const widthPx = (endRadians - startRadians) * radiusPx
63
+ const largeArc = endRadians - startRadians > Math.PI ? '1' : '0'
64
+ // TODO: draw the elision
65
+ const centerRadians = (endRadians + startRadians) / 2
66
+ const regionCountString = `[${Number(
67
+ // @ts-ignore
68
+ region.regions.length,
69
+ ).toLocaleString()}]`
70
+ return (
71
+ <>
72
+ <RulerLabel
73
+ text={regionCountString}
74
+ view={model}
75
+ maxWidthPx={widthPx}
76
+ radians={centerRadians}
77
+ radiusPx={radiusPx}
78
+ title={`${Number(
79
+ // @ts-ignore
80
+ region.regions.length,
81
+ ).toLocaleString()} more regions`}
82
+ color={theme.palette.text.primary}
83
+ />
84
+ <path
85
+ d={[
86
+ 'M',
87
+ ...startXY,
88
+ 'A',
89
+ radiusPx,
90
+ radiusPx,
91
+ '0',
92
+ largeArc,
93
+ '1',
94
+ ...endXY,
95
+ ].join(' ')}
96
+ stroke={theme.palette.text.secondary}
97
+ strokeWidth={2}
98
+ strokeDasharray="2,2"
99
+ fill="none"
100
+ />
101
+ </>
102
+ )
103
+ },
104
+ )
105
+
106
+ const RulerLabel = observer(
107
+ ({
108
+ view,
109
+ text,
110
+ maxWidthPx,
111
+ radians,
112
+ radiusPx,
113
+ title,
114
+ color,
115
+ }: {
116
+ view: CircularViewModel
117
+ text: string
118
+ maxWidthPx: number
119
+ radiusPx: number
120
+ radians: number
121
+ title?: string
122
+ color: string
123
+ }) => {
124
+ const { classes } = useStyles()
125
+ const textXY = polarToCartesian(radiusPx + 5, radians)
126
+ if (!text) {
127
+ return null
128
+ }
129
+
130
+ if (text.length * 6.5 < maxWidthPx) {
131
+ // text is rotated parallel to the ruler arc
132
+ return (
133
+ <text
134
+ x={0}
135
+ y={0}
136
+ className={classes.rulerLabel}
137
+ textAnchor="middle"
138
+ dominantBaseline="baseline"
139
+ transform={`translate(${textXY}) rotate(${radToDeg(radians) + 90})`}
140
+ style={{ fill: color }}
141
+ >
142
+ {text}
143
+ <title>{title || text}</title>
144
+ </text>
145
+ )
146
+ }
147
+ if (maxWidthPx > 4) {
148
+ // text is rotated perpendicular to the ruler arc
149
+ const overallRotation = radToDeg(
150
+ radians + view.offsetRadians - Math.PI / 2,
151
+ )
152
+ if (overallRotation >= 180) {
153
+ return (
154
+ <text
155
+ x={0}
156
+ y={0}
157
+ className={classes.rulerLabel}
158
+ textAnchor="start"
159
+ dominantBaseline="middle"
160
+ transform={`translate(${textXY}) rotate(${radToDeg(radians)})`}
161
+ style={{ fill: color }}
162
+ >
163
+ {text}
164
+ <title>{title || text}</title>
165
+ </text>
166
+ )
167
+ }
168
+ return (
169
+ <text
170
+ x={0}
171
+ y={0}
172
+ className={classes.rulerLabel}
173
+ textAnchor="end"
174
+ dominantBaseline="middle"
175
+ transform={`translate(${textXY}) rotate(${radToDeg(radians) + 180})`}
176
+ style={{ fill: color }}
177
+ >
178
+ {text}
179
+ <title>{title || text}</title>
180
+ </text>
181
+ )
182
+ }
183
+
184
+ // if you get here there is no room for the text at all
185
+ return null
186
+ },
187
+ )
188
+
189
+ const RegionRulerArc = observer(
190
+ ({ model, slice }: { model: CircularViewModel; slice: Slice }) => {
191
+ const theme = useTheme()
192
+ const { radiusPx } = model
193
+ const { region, endRadians, startRadians } = slice
194
+ const centerRadians = (endRadians + startRadians) / 2
195
+ const widthPx = (endRadians - startRadians) * radiusPx
196
+ const session = getSession(model)
197
+ let color
198
+ const assembly = session.assemblyManager.get(slice.region.assemblyName)
199
+ if (assembly) {
200
+ color = assembly.getRefNameColor(region.refName)
201
+ }
202
+ if (color) {
203
+ try {
204
+ color = makeContrasting(color, theme.palette.background.paper)
205
+ } catch (error) {
206
+ color = theme.palette.text.primary
207
+ }
208
+ } else {
209
+ color = theme.palette.text.primary
210
+ }
211
+
212
+ // TODO: slice flipping
213
+ return (
214
+ <>
215
+ <RulerLabel
216
+ text={region.refName}
217
+ view={model}
218
+ maxWidthPx={widthPx}
219
+ radians={centerRadians}
220
+ radiusPx={radiusPx}
221
+ color={color}
222
+ />
223
+ <path
224
+ d={sliceArcPath(slice, radiusPx + 1, region.start, region.end)}
225
+ stroke={color}
226
+ strokeWidth={2}
227
+ fill="none"
228
+ >
229
+ <title>{region.refName}</title>
230
+ </path>
231
+ </>
232
+ )
233
+ },
234
+ )
235
+
236
+ const CircularRuler = observer(
237
+ ({ model, slice }: { model: CircularViewModel; slice: Slice }) => {
238
+ if (slice.region.elided) {
239
+ return (
240
+ <ElisionRulerArc
241
+ key={
242
+ /* @ts-ignore */
243
+ assembleLocString(slice.region.regions[0])
244
+ }
245
+ model={model}
246
+ slice={slice}
247
+ />
248
+ )
249
+ }
250
+ return (
251
+ <RegionRulerArc
252
+ key={assembleLocString(slice.region)}
253
+ model={model}
254
+ slice={slice}
255
+ />
256
+ )
257
+ },
258
+ )
259
+
260
+ export default CircularRuler
@@ -67,9 +67,7 @@ export default function CircularView(pluginManager: PluginManager) {
67
67
  get staticSlices() {
68
68
  return calculateStaticSlices(self)
69
69
  },
70
- get visibleStaticSlices() {
71
- return this.staticSlices.filter(sliceIsVisible.bind(this, self))
72
- },
70
+
73
71
  get visibleSection() {
74
72
  return viewportVisibleSection(
75
73
  [
@@ -140,7 +138,7 @@ export default function CircularView(pluginManager: PluginManager) {
140
138
  get tooSmallToLock() {
141
139
  return this.minBpPerPx <= 0.0000000001
142
140
  },
143
- get figureDimensions() {
141
+ get figureDimensions(): [number, number] {
144
142
  return [
145
143
  this.radiusPx * 2 + 2 * self.paddingPx,
146
144
  this.radiusPx * 2 + 2 * self.paddingPx,
@@ -206,6 +204,11 @@ export default function CircularView(pluginManager: PluginManager) {
206
204
  )
207
205
  },
208
206
  }))
207
+ .views(self => ({
208
+ get visibleStaticSlices() {
209
+ return self.staticSlices.filter(s => sliceIsVisible(self, s))
210
+ },
211
+ }))
209
212
  .volatile(() => ({
210
213
  error: undefined as unknown,
211
214
  }))
@@ -62,10 +62,11 @@ function calculateStaticSlices(self: any) {
62
62
  return slices
63
63
  }
64
64
 
65
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
- function sliceIsVisible(self: any, slice: Slice) {
65
+ function sliceIsVisible(
66
+ self: { offsetRadians: number; visibleSection: { theta: [number, number] } },
67
+ slice: Slice,
68
+ ) {
67
69
  const {
68
- // rho: visibleRhoRange,
69
70
  theta: [visibleThetaMin, visibleThetaMax],
70
71
  } = self.visibleSection
71
72
 
@@ -124,8 +124,8 @@ export function viewportVisibleSection(
124
124
  }
125
125
  }
126
126
  return {
127
- rho: [0, Math.min(circleRadius, maxRho)],
128
- theta: [0, 2 * Math.PI],
127
+ rho: [0, Math.min(circleRadius, maxRho)] as [number, number],
128
+ theta: [0, 2 * Math.PI] as [number, number],
129
129
  }
130
130
  }
131
131
  // const viewportCompletelyContainsCircle =
@@ -268,7 +268,7 @@ export function viewportVisibleSection(
268
268
  }
269
269
 
270
270
  return {
271
- rho: [rhoMin, Math.min(circleRadius, rhoMax)],
272
- theta: [thetaMin, thetaMax],
271
+ rho: [rhoMin, Math.min(circleRadius, rhoMax)] as [number, number],
272
+ theta: [thetaMin, thetaMax] as [number, number],
273
273
  }
274
274
  }
@@ -1,70 +0,0 @@
1
- export default ({ jbrequire }) => {
2
- const { getRpcSessionId } = jbrequire('@jbrowse/core/util/tracks')
3
- const { getContainingView } = jbrequire('@jbrowse/core/util')
4
- const { getSession } = jbrequire('@jbrowse/core/util')
5
-
6
- function renderReactionData(self) {
7
- const view = getContainingView(self)
8
- const { rendererType } = self
9
- const { rpcManager } = getSession(view)
10
-
11
- return {
12
- rendererType,
13
- rpcManager,
14
- renderProps: self.renderProps(),
15
- renderArgs: {
16
- assemblyName: view.displayedRegions[0]?.assemblyName,
17
- adapterConfig: JSON.parse(JSON.stringify(self.adapterConfig)),
18
- rendererType: rendererType.name,
19
- regions: JSON.parse(JSON.stringify(view.displayedRegions)),
20
- blockDefinitions: self.blockDefinitions,
21
- sessionId: getRpcSessionId(self),
22
- timeout: 1000000,
23
- },
24
- }
25
- }
26
-
27
- async function renderReactionEffect(props, signal, self) {
28
- if (!props) {
29
- throw new Error('cannot render with no props')
30
- }
31
-
32
- const {
33
- rendererType,
34
- rpcManager,
35
- cannotBeRenderedReason,
36
- renderArgs,
37
- renderProps,
38
- } = props
39
-
40
- if (cannotBeRenderedReason) {
41
- return { message: cannotBeRenderedReason }
42
- }
43
-
44
- // don't try to render 0 or NaN radius or no regions
45
- if (
46
- !props.renderProps.radius ||
47
- !props.renderArgs.regions ||
48
- !props.renderArgs.regions.length
49
- ) {
50
- return { message: 'Skipping render' }
51
- }
52
-
53
- // check renderertype compatibility
54
- if (!self.isCompatibleWithRenderer(rendererType)) {
55
- throw new Error(
56
- `renderer ${rendererType.name} is not compatible with this display type`,
57
- )
58
- }
59
-
60
- const { html, ...data } = await rendererType.renderInClient(rpcManager, {
61
- ...renderArgs,
62
- ...renderProps,
63
- signal,
64
- })
65
-
66
- return { html, data, renderingComponent: rendererType.ReactComponent }
67
- }
68
-
69
- return { renderReactionData, renderReactionEffect }
70
- }