diff --git a/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts b/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts
index a970827b52..47ceb7468f 100644
--- a/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts
+++ b/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts
@@ -189,16 +189,16 @@ export default class BoxRendererType extends FeatureRendererType {
args,
) as ResultsSerialized
- return {
- ...serialized,
- layout: results.layout.serializeRegion(
- this.getExpandedRegion(args.regions[0]!, args),
- ),
- maxHeightReached: serialized.layout.maxHeightReached,
- features: serialized.features.filter(
- f => !!serialized.layout.rectangles[f.uniqueId],
- ),
- }
+ const region = args.regions[0]!
+ serialized.layout = results.layout.serializeRegion(
+ this.getExpandedRegion(region, args),
+ )
+ serialized.features = serialized.features.filter(f => {
+ return Boolean(serialized.layout.rectangles[f.uniqueId])
+ })
+
+ serialized.maxHeightReached = serialized.layout.maxHeightReached
+ return serialized
}
/**
diff --git a/packages/core/pluggableElementTypes/renderers/ServerSideRendererType.tsx b/packages/core/pluggableElementTypes/renderers/ServerSideRendererType.tsx
index f436d1b9a1..6ce8897b15 100644
--- a/packages/core/pluggableElementTypes/renderers/ServerSideRendererType.tsx
+++ b/packages/core/pluggableElementTypes/renderers/ServerSideRendererType.tsx
@@ -87,26 +87,34 @@ export default class ServerSideRenderer extends RendererType {
* @param results - the results of the render
* @param args - the arguments passed to render
*/
- deserializeResultsInClient(res: ResultsSerialized, args: RenderArgs) {
- // if we are rendering svg, we skip hydration and check if rendere support
- // SVG (e.g. this.supportsSVG) and then return just the HTML if so
- return args.exportSVG
- ? {
- ...res,
- html: this.supportsSVG
- ? res.html
- : 'SVG export not supported for this track',
- }
- : {
- ...res,
- reactElement: (
-
- ),
- }
+ deserializeResultsInClient(
+ res: ResultsSerialized,
+ args: RenderArgs,
+ ): ResultsDeserialized {
+ // if we are rendering svg, we skip hydration
+ if (args.exportSVG) {
+ // only return the res if the renderer explicitly has
+ // this.supportsSVG support to avoid garbage being rendered in SVG
+ // document
+ return {
+ ...res,
+ html: this.supportsSVG
+ ? res.html
+ : 'SVG export not supported for this track',
+ }
+ }
+
+ // get res using ServerSideRenderedContent
+ return {
+ ...res,
+ reactElement: (
+
+ ),
+ }
}
/**
@@ -115,17 +123,18 @@ export default class ServerSideRenderer extends RendererType {
*
* @param args - the converted arguments to modify
*/
- deserializeArgsInWorker(args: RenderArgsSerialized) {
- console.log('deserializeArgsInWorker', { args })
- return {
- ...args,
- config: this.configSchema.create(args.config || {}, {
- pluginManager: this.pluginManager,
- }),
- filters: args.filters
- ? new SerializableFilterChain({ filters: args.filters })
- : undefined,
- }
+ deserializeArgsInWorker(args: RenderArgsSerialized): RenderArgsDeserialized {
+ const deserialized = { ...args } as unknown as RenderArgsDeserialized
+ deserialized.config = this.configSchema.create(args.config || {}, {
+ pluginManager: this.pluginManager,
+ })
+ deserialized.filters = args.filters
+ ? new SerializableFilterChain({
+ filters: args.filters,
+ })
+ : undefined
+
+ return deserialized
}
/**
@@ -206,4 +215,4 @@ export default class ServerSideRenderer extends RendererType {
}
}
-export type { RenderResults } from './RendererType'
+export { type RenderResults } from './RendererType'
diff --git a/plugins/breakpoint-split-view/src/BreakpointAlignmentsFeatureDetail/BreakpointAlignmentsFeatureDetail.tsx b/plugins/breakpoint-split-view/src/BreakpointAlignmentsFeatureDetail/BreakpointAlignmentsFeatureDetail.tsx
index e502e5c21c..dee96293b6 100644
--- a/plugins/breakpoint-split-view/src/BreakpointAlignmentsFeatureDetail/BreakpointAlignmentsFeatureDetail.tsx
+++ b/plugins/breakpoint-split-view/src/BreakpointAlignmentsFeatureDetail/BreakpointAlignmentsFeatureDetail.tsx
@@ -6,15 +6,22 @@ import {
} from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
import { Paper } from '@mui/material'
import { observer } from 'mobx-react'
+import { SimpleFeatureSerialized } from '@jbrowse/core/util'
const BreakpointAlignmentsFeatureDetail = observer(function ({
model,
}: {
- model: { featureData: Record }
+ model: {
+ featureData: {
+ feature1: SimpleFeatureSerialized
+ feature2: SimpleFeatureSerialized
+ }
+ }
}) {
- const { feature1, feature2 } = JSON.parse(JSON.stringify(model.featureData))
+ const { featureData } = model
+ const { feature1, feature2 } = structuredClone(featureData)
return (
-
+
diff --git a/plugins/linear-comparative-view/src/SyntenyFeatureDetail/SyntenyFeatureDetail.tsx b/plugins/linear-comparative-view/src/SyntenyFeatureDetail/SyntenyFeatureDetail.tsx
index 83b74a0ba7..f05e47a462 100644
--- a/plugins/linear-comparative-view/src/SyntenyFeatureDetail/SyntenyFeatureDetail.tsx
+++ b/plugins/linear-comparative-view/src/SyntenyFeatureDetail/SyntenyFeatureDetail.tsx
@@ -114,7 +114,7 @@ const SyntenyFeatureDetail = observer(function ({
model: SyntenyFeatureDetailModel
}) {
return (
-
+
diff --git a/plugins/variants/src/MultiLinearVariantDisplay/model.ts b/plugins/variants/src/MultiLinearVariantDisplay/model.ts
index 21905b76aa..1bf5d02bd9 100644
--- a/plugins/variants/src/MultiLinearVariantDisplay/model.ts
+++ b/plugins/variants/src/MultiLinearVariantDisplay/model.ts
@@ -22,9 +22,7 @@ import type { Instance } from 'mobx-state-tree'
// lazies
const Tooltip = lazy(() => import('../shared/Tooltip'))
const SetColorDialog = lazy(() => import('../shared/SetColorDialog'))
-const HierarchicalClusterDialog = lazy(
- () => import('../shared/HierarchicalClusterDialog'),
-)
+const ClusterDialog = lazy(() => import('../shared/ClusterDialog'))
// using a map because it preserves order
const rendererTypes = new Map([['multivariant', 'MultiVariantRenderer']])
@@ -263,7 +261,7 @@ export function stateModelFactory(
label: 'Cluster by genotype',
onClick: () => {
getSession(self).queueDialog(handleClose => [
- HierarchicalClusterDialog,
+ ClusterDialog,
{
model: self,
handleClose,
diff --git a/plugins/variants/src/MultiLinearVariantMatrixDisplay/components/VariantDisplayComponent.tsx b/plugins/variants/src/MultiLinearVariantMatrixDisplay/components/VariantDisplayComponent.tsx
index 94b11871b6..6d4f95d288 100644
--- a/plugins/variants/src/MultiLinearVariantMatrixDisplay/components/VariantDisplayComponent.tsx
+++ b/plugins/variants/src/MultiLinearVariantMatrixDisplay/components/VariantDisplayComponent.tsx
@@ -15,6 +15,7 @@ import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
const useStyles = makeStyles()({
cursor: {
pointerEvents: 'none',
+ zIndex: 1000,
},
})
diff --git a/plugins/variants/src/MultiLinearVariantMatrixDisplay/model.ts b/plugins/variants/src/MultiLinearVariantMatrixDisplay/model.ts
index 5fd03bcc20..187b9fc452 100644
--- a/plugins/variants/src/MultiLinearVariantMatrixDisplay/model.ts
+++ b/plugins/variants/src/MultiLinearVariantMatrixDisplay/model.ts
@@ -19,9 +19,7 @@ import type { Instance } from 'mobx-state-tree'
// lazies
const SetColorDialog = lazy(() => import('../shared/SetColorDialog'))
const MAFFilterDialog = lazy(() => import('../shared/MAFFilterDialog'))
-const HierarchicalClusterDialog = lazy(
- () => import('../shared/HierarchicalClusterDialog'),
-)
+const ClusterDialog = lazy(() => import('../shared/ClusterDialog'))
/**
* #stateModel LinearVariantMatrixDisplay
@@ -176,7 +174,7 @@ export default function stateModelFactory(
label: 'Cluster by genotype',
onClick: () => {
getSession(self).queueDialog(handleClose => [
- HierarchicalClusterDialog,
+ ClusterDialog,
{
model: self,
handleClose,
@@ -252,6 +250,21 @@ export default function stateModelFactory(
}
}
})()
+
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
+ ;(async () => {
+ try {
+ const { getMultiVariantSourcesAutorun } = await import(
+ '../getMultiVariantSourcesAutorun'
+ )
+ getMultiVariantSourcesAutorun(self)
+ } catch (e) {
+ if (isAlive(self)) {
+ console.error(e)
+ getSession(self).notifyError(`${e}`, e)
+ }
+ }
+ })()
},
/**
diff --git a/plugins/variants/src/MultiLinearVariantMatrixRenderer/components/LinearVariantMatrixRendering.tsx b/plugins/variants/src/MultiLinearVariantMatrixRenderer/components/LinearVariantMatrixRendering.tsx
index ee24e51dfa..d29ee1ef00 100644
--- a/plugins/variants/src/MultiLinearVariantMatrixRenderer/components/LinearVariantMatrixRendering.tsx
+++ b/plugins/variants/src/MultiLinearVariantMatrixRenderer/components/LinearVariantMatrixRendering.tsx
@@ -17,11 +17,11 @@ const LinearVariantMatrixRendering = observer(function (props: {
regions: Region[]
bpPerPx: number
simplifiedFeatures: Feature[]
- exportSVG: boolean
onMouseMove?: (event: React.MouseEvent, featureId?: string) => void
}) {
- const { exportSVG, simplifiedFeatures, displayModel, width, height } = props
- const [renderLines, setRenderLines] = useState(exportSVG)
+ const { simplifiedFeatures, displayModel, width, height } = props
+ console.log('Rendering', props.regions)
+ const [renderLines, setRenderLines] = useState(false)
useEffect(() => {
setRenderLines(true)
}, [])
diff --git a/plugins/variants/src/VariantRPC/MultiVariantGetHierarchicalMatrix.ts b/plugins/variants/src/VariantRPC/MultiVariantGetGenotypeMatrix.ts
similarity index 96%
rename from plugins/variants/src/VariantRPC/MultiVariantGetHierarchicalMatrix.ts
rename to plugins/variants/src/VariantRPC/MultiVariantGetGenotypeMatrix.ts
index be0a2a51b1..d0f2ff6e01 100644
--- a/plugins/variants/src/VariantRPC/MultiVariantGetHierarchicalMatrix.ts
+++ b/plugins/variants/src/VariantRPC/MultiVariantGetGenotypeMatrix.ts
@@ -9,8 +9,8 @@ import type { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAda
import type { RenderArgs } from '@jbrowse/core/rpc/coreRpcMethods'
import type { Feature, Region } from '@jbrowse/core/util'
-export class MultiVariantGetHierarchicalMatrix extends RpcMethodType {
- name = 'MultiVariantGetHierarchicalMatrix'
+export class MultiVariantGetGenotypeMatrix extends RpcMethodType {
+ name = 'MultiVariantGetGenotypeMatrix'
async deserializeArguments(args: any, rpcDriverClassName: string) {
const l = await super.deserializeArguments(args, rpcDriverClassName)
diff --git a/plugins/variants/src/VariantRPC/MultiVariantGetSimplifiedFeatures.ts b/plugins/variants/src/VariantRPC/MultiVariantGetSimplifiedFeatures.ts
new file mode 100644
index 0000000000..50d43c8c55
--- /dev/null
+++ b/plugins/variants/src/VariantRPC/MultiVariantGetSimplifiedFeatures.ts
@@ -0,0 +1,76 @@
+import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache'
+import RpcMethodType from '@jbrowse/core/pluggableElementTypes/RpcMethodType'
+import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain'
+import { renameRegionsIfNeeded } from '@jbrowse/core/util'
+
+import type { AnyConfigurationModel } from '@jbrowse/core/configuration'
+import type { RenderArgs } from '@jbrowse/core/rpc/coreRpcMethods'
+import type { Region } from '@jbrowse/core/util'
+import { toArray } from 'rxjs'
+
+export class MultiVariantGetSimplifiedFeatures extends RpcMethodType {
+ name = 'MultiVariantGetSimplifiedFeatures'
+
+ async deserializeArguments(args: any, rpcDriverClassName: string) {
+ const l = await super.deserializeArguments(args, rpcDriverClassName)
+ return {
+ ...l,
+ filters: args.filters
+ ? new SerializableFilterChain({
+ filters: args.filters,
+ })
+ : undefined,
+ }
+ }
+
+ async serializeArguments(
+ args: RenderArgs & {
+ stopToken?: string
+ statusCallback?: (arg: string) => void
+ },
+ rpcDriverClassName: string,
+ ) {
+ const pm = this.pluginManager
+ const assemblyManager = pm.rootModel?.session?.assemblyManager
+ if (!assemblyManager) {
+ return args
+ }
+
+ const renamedArgs = await renameRegionsIfNeeded(assemblyManager, {
+ ...args,
+ filters: args.filters?.toJSON().filters,
+ })
+
+ return super.serializeArguments(renamedArgs, rpcDriverClassName)
+ }
+
+ async execute(
+ args: {
+ adapterConfig: AnyConfigurationModel
+ stopToken?: string
+ sessionId: string
+ headers?: Record
+ regions: Region[]
+ bpPerPx: number
+ },
+ rpcDriverClassName: string,
+ ) {
+ const pm = this.pluginManager
+ const deserializedArgs = await this.deserializeArguments(
+ args,
+ rpcDriverClassName,
+ )
+ const { regions, adapterConfig, sessionId } = deserializedArgs
+ const { dataAdapter } = await getAdapter(pm, sessionId, adapterConfig)
+
+ // @ts-expect-error
+ const feats = await firstValuFrom(
+ dataAdapter.getFeatures(regions, deserializedArgs).pipe(toArray()),
+ )
+ return feats.map(f => ({
+ start: f.get('start'),
+ end: f.get('end'),
+ refName: f.get('refName'),
+ }))
+ }
+}
diff --git a/plugins/variants/src/getMultiVariantSourcesAutorun.ts b/plugins/variants/src/getMultiVariantSourcesAutorun.ts
index 65276e67be..7c660a2f1f 100644
--- a/plugins/variants/src/getMultiVariantSourcesAutorun.ts
+++ b/plugins/variants/src/getMultiVariantSourcesAutorun.ts
@@ -42,7 +42,41 @@ export function getMultiVariantSourcesAutorun(self: {
sessionId,
'MultiVariantGetSources',
{
- regions: view.staticBlocks.contentBlocks,
+ regions: view.dynamicBlocks.contentBlocks,
+ sessionId,
+ adapterConfig,
+ },
+ )) as Source[]
+ if (isAlive(self)) {
+ self.setSources(sources)
+ }
+ } catch (e) {
+ if (!isAbortException(e) && isAlive(self)) {
+ console.error(e)
+ getSession(self).notifyError(`${e}`, e)
+ }
+ }
+ }),
+ )
+
+ addDisposer(
+ self,
+ autorun(async () => {
+ try {
+ const view = getContainingView(self) as LinearGenomeViewModel
+ if (!view.initialized) {
+ return
+ }
+ const { rpcManager } = getSession(self)
+ const { adapterConfig } = self
+ const token = createStopToken()
+ self.setSourcesLoading(token)
+ const sessionId = getRpcSessionId(self)
+ const sources = (await rpcManager.call(
+ sessionId,
+ 'MultiVariantGetSimplifiedFeatures',
+ {
+ regions: view.dynamicBlocks.contentBlocks,
sessionId,
adapterConfig,
},
diff --git a/plugins/variants/src/index.ts b/plugins/variants/src/index.ts
index e2295dd3cd..b01eecb32f 100644
--- a/plugins/variants/src/index.ts
+++ b/plugins/variants/src/index.ts
@@ -8,8 +8,9 @@ import LinearVariantMatrixRendererF from './MultiLinearVariantMatrixRenderer'
import MultiVariantRendererF from './MultiLinearVariantRenderer'
import StructuralVariantChordRendererF from './StructuralVariantChordRenderer'
import VariantFeatureWidgetF from './VariantFeatureWidget'
-import { MultiVariantGetHierarchicalMatrix } from './VariantRPC/MultiVariantGetHierarchicalMatrix'
+import { MultiVariantGetGenotypeMatrix } from './VariantRPC/MultiVariantGetGenotypeMatrix'
import { MultiVariantGetSources } from './VariantRPC/MultiVariantGetSources'
+import { MultiVariantGetSimplifiedFeatures } from './VariantRPC/MultiVariantGetSimplifiedFeatures'
import VariantTrackF from './VariantTrack'
import VcfAdapterF from './VcfAdapter'
import VcfTabixAdapterF from './VcfTabixAdapter'
@@ -36,7 +37,10 @@ export default class VariantsPlugin extends Plugin {
pluginManager.addRpcMethod(() => new MultiVariantGetSources(pluginManager))
pluginManager.addRpcMethod(
- () => new MultiVariantGetHierarchicalMatrix(pluginManager),
+ () => new MultiVariantGetGenotypeMatrix(pluginManager),
+ )
+ pluginManager.addRpcMethod(
+ () => new MultiVariantGetSimplifiedFeatures(pluginManager),
)
}
}
diff --git a/plugins/variants/src/shared/HierarchicalClusterDialog.tsx b/plugins/variants/src/shared/ClusterDialog.tsx
similarity index 99%
rename from plugins/variants/src/shared/HierarchicalClusterDialog.tsx
rename to plugins/variants/src/shared/ClusterDialog.tsx
index daf763c046..3c0f4102ec 100644
--- a/plugins/variants/src/shared/HierarchicalClusterDialog.tsx
+++ b/plugins/variants/src/shared/ClusterDialog.tsx
@@ -68,7 +68,7 @@ export default function HierarchicalCluster({
const sessionId = getRpcSessionId(model)
const ret = (await rpcManager.call(
sessionId,
- 'MultiVariantGetHierarchicalMatrix',
+ 'MultiVariantGetGenotypeMatrix',
{
regions: view.dynamicBlocks.contentBlocks,
sources,
diff --git a/yarn.lock b/yarn.lock
index 7f0059b2a0..f90a5798ad 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -139,9 +139,9 @@
tslib "^2.6.2"
"@aws-sdk/client-s3@^3.701.0":
- version "3.705.0"
- resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.705.0.tgz#7a4a4784bd5b3ca3187ff876b771eaf0cbde1c42"
- integrity sha512-Fm0Cbc4zr0yG0DnNycz7ywlL5tQFdLSb7xCIPfzrxJb3YQiTXWxH5eu61SSsP/Z6RBNRolmRPvst/iNgX0fWvA==
+ version "3.703.0"
+ resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.703.0.tgz#5ca20c606e13ca751ef972c82bb8ef27095db083"
+ integrity sha512-4TSrIamzASTeRPKXrTLcEwo+viPTuOSGcbXh4HC1R0m/rXwK0BHJ4btJ0Q34nZNF+WzvM+FiemXVjNc8qTAxog==
dependencies:
"@aws-crypto/sha1-browser" "5.2.0"
"@aws-crypto/sha256-browser" "5.2.0"
@@ -8074,9 +8074,9 @@ dotenv-expand@^11.0.3, dotenv-expand@^11.0.6, dotenv-expand@~11.0.6:
dotenv "^16.4.5"
dotenv@^16.3.1, dotenv@^16.4.5, dotenv@~16.4.5:
- version "16.4.7"
- resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26"
- integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==
+ version "16.4.6"
+ resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.6.tgz#fc88e8a664087abf3e19d61e21f7feee1849bbb1"
+ integrity sha512-JhcR/+KIjkkjiU8yEpaB/USlzVi3i5whwOjpIRNGi9svKEXZSe+Qp6IWAjFjv+2GViAoDRCUv/QLNziQxsLqDg==
duplexer@^0.1.1, duplexer@^0.1.2:
version "0.1.2"
@@ -16370,9 +16370,9 @@ whatwg-url@^11.0.0:
webidl-conversions "^7.0.0"
whatwg-url@^14.0.0:
- version "14.1.0"
- resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-14.1.0.tgz#fffebec86cc8e6c2a657e50dc606207b870f0ab3"
- integrity sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==
+ version "14.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-14.0.0.tgz#00baaa7fd198744910c4b1ef68378f2200e4ceb6"
+ integrity sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==
dependencies:
tr46 "^5.0.0"
webidl-conversions "^7.0.0"