From 18f93f79b802cd583595917d3c7ab4e1241edf24 Mon Sep 17 00:00:00 2001 From: Colin Date: Thu, 19 Aug 2021 12:12:36 -0400 Subject: [PATCH] Remove filtering display type --- .../PluginStoreWidget.test.js.snap | 21 --- plugins/filtering/.babelrc | 9 - plugins/filtering/package.json | 48 ----- .../components/FilterControls.js | 167 ------------------ .../components/LinearFilteringDisplay.js | 53 ------ .../src/LinearFilteringDisplay/index.js | 22 --- .../src/LinearFilteringDisplay/model.js | 90 ---------- .../src/__snapshots__/index.test.js.snap | 5 - plugins/filtering/src/index.test.js | 28 --- plugins/filtering/src/index.ts | 28 --- plugins/filtering/tsconfig.json | 10 -- plugins/filtering/tsdx.config.js | 8 - products/jbrowse-desktop/package.json | 1 - products/jbrowse-desktop/src/corePlugins.ts | 2 - products/jbrowse-web/package.json | 1 - .../__snapshots__/jbrowseModel.test.ts.snap | 67 ------- products/jbrowse-web/src/corePlugins.ts | 2 - test_data/volvox/config.json | 62 ------- 18 files changed, 624 deletions(-) delete mode 100644 plugins/filtering/.babelrc delete mode 100644 plugins/filtering/package.json delete mode 100644 plugins/filtering/src/LinearFilteringDisplay/components/FilterControls.js delete mode 100644 plugins/filtering/src/LinearFilteringDisplay/components/LinearFilteringDisplay.js delete mode 100644 plugins/filtering/src/LinearFilteringDisplay/index.js delete mode 100644 plugins/filtering/src/LinearFilteringDisplay/model.js delete mode 100644 plugins/filtering/src/__snapshots__/index.test.js.snap delete mode 100644 plugins/filtering/src/index.test.js delete mode 100644 plugins/filtering/src/index.ts delete mode 100644 plugins/filtering/tsconfig.json delete mode 100644 plugins/filtering/tsdx.config.js diff --git a/plugins/data-management/src/PluginStoreWidget/components/__snapshots__/PluginStoreWidget.test.js.snap b/plugins/data-management/src/PluginStoreWidget/components/__snapshots__/PluginStoreWidget.test.js.snap index 66f5bb272d..80aa4b4008 100644 --- a/plugins/data-management/src/PluginStoreWidget/components/__snapshots__/PluginStoreWidget.test.js.snap +++ b/plugins/data-management/src/PluginStoreWidget/components/__snapshots__/PluginStoreWidget.test.js.snap @@ -279,27 +279,6 @@ exports[` renders with the available plugins 1`] = ` DotplotPlugin

-
  • - -

    - FilteringTrackPlugin -

    -
  • diff --git a/plugins/filtering/.babelrc b/plugins/filtering/.babelrc deleted file mode 100644 index dde1819d9f..0000000000 --- a/plugins/filtering/.babelrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "presets": [ - // need this to be able to use spread operator on Set and Map - // see https://github.com/formium/tsdx/issues/376#issuecomment-566750042 - ["@babel/preset-env", { "loose": false }], - // can remove this if all .js files are converted to .ts - "@babel/preset-react" - ] -} diff --git a/plugins/filtering/package.json b/plugins/filtering/package.json deleted file mode 100644 index 6c1fc41c70..0000000000 --- a/plugins/filtering/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@jbrowse/plugin-filtering", - "version": "1.3.3", - "description": "JBrowse 2 filtering tracks, etc.", - "keywords": [ - "jbrowse", - "jbrowse2" - ], - "license": "Apache-2.0", - "homepage": "https://jbrowse.org", - "bugs": "https://github.com/GMOD/jbrowse-components/issues", - "repository": { - "type": "git", - "url": "https://github.com/GMOD/jbrowse-components.git", - "directory": "plugins/filtering" - }, - "author": "JBrowse Team", - "distMain": "dist/index.js", - "srcMain": "src/index.ts", - "main": "src/index.ts", - "distModule": "dist/plugin-filtering.esm.js", - "module": "", - "files": [ - "dist", - "src" - ], - "scripts": { - "start": "tsdx watch --verbose --noClean", - "build": "tsdx build", - "test": "cd ../..; jest plugins/filtering", - "prepublishOnly": "yarn test", - "prepack": "yarn build; yarn useDist", - "postpack": "yarn useSrc", - "useDist": "node ../../scripts/useDist.js", - "useSrc": "node ../../scripts/useSrc.js" - }, - "peerDependencies": { - "@jbrowse/core": "^1.0.0", - "@jbrowse/plugin-linear-genome-view": "^1.0.0", - "@material-ui/core": "^4.12.2", - "mobx": "^5.0.0", - "mobx-react": "^6.0.0", - "mobx-state-tree": "3.14.1", - "prop-types": "^15.0.0", - "react": ">=16.8.0" - }, - "private": true -} diff --git a/plugins/filtering/src/LinearFilteringDisplay/components/FilterControls.js b/plugins/filtering/src/LinearFilteringDisplay/components/FilterControls.js deleted file mode 100644 index 79b949fb8d..0000000000 --- a/plugins/filtering/src/LinearFilteringDisplay/components/FilterControls.js +++ /dev/null @@ -1,167 +0,0 @@ -import { getConf } from '@jbrowse/core/configuration' -import Checkbox from '@material-ui/core/Checkbox' -import FormControl from '@material-ui/core/FormControl' -import FormControlLabel from '@material-ui/core/FormControlLabel' -import FormGroup from '@material-ui/core/FormGroup' -import FormHelperText from '@material-ui/core/FormHelperText' -import FormLabel from '@material-ui/core/FormLabel' -import { withStyles } from '@material-ui/core/styles' -import Typography from '@material-ui/core/Typography' -import { reaction } from 'mobx' -import { observer, PropTypes as MxPropTypes } from 'mobx-react' -import ReactPropTypes from 'prop-types' -import React, { Component } from 'react' - -const styles = theme => ({ - root: { - background: theme.palette.background.default, - overflow: 'auto', - paddingTop: 0, - paddingBottom: theme.spacing(1), - paddingLeft: theme.spacing(1), - paddingRight: theme.spacing(1), - display: 'flex', - flexWrap: 'wrap', - }, - header: { - width: '100%', - }, - title: { - // fontSize: '80%', - }, -}) - -function visibleValues(model, attrName) { - const { features, filterOut } = model - const values = new Set() - for (const feature of features.values()) { - values.add(feature.get(attrName)) - } - if (filterOut.has(attrName)) { - for (const value of filterOut.get(attrName).keys()) { - values.add(value) - } - } - return Array.from(values.values()).sort() -} - -const AttributeFilter = withStyles(styles)( - observer(({ attrName, model, classes, values }) => ( - - {attrName} - - {!values.length ? ( - - no values seen yet - - ) : ( - values.map(value => ( - - model.toggleFilter(attrName, value, evt.target.checked) - } - /> - } - label={value} - /> - )) - )} - - - )), -) - -AttributeFilter.propTypes = { - attrName: ReactPropTypes.string.isRequired, - model: MxPropTypes.objectOrObservableObject.isRequired, - values: ReactPropTypes.arrayOf(ReactPropTypes.string).isRequired, -} - -class FilterControls extends Component { - constructor(props) { - super(props) - this.state = { seenAttributes: {} } - const { model } = props - this.autorunDisposer = reaction( - () => { - const newSeenAttributes = {} - getConf(model, 'filterAttributes').forEach(attrName => { - if (!newSeenAttributes[attrName]) { - newSeenAttributes[attrName] = {} - } - visibleValues(model, attrName).forEach(value => { - newSeenAttributes[attrName][value] = true - }) - }) - return newSeenAttributes - }, - newSeenAttributes => { - this.setState(state => { - const seenAttributes = {} - Object.keys(newSeenAttributes).forEach(attrName => { - seenAttributes[attrName] = { - ...(state.seenAttributes[attrName] || {}), - ...newSeenAttributes[attrName], - } - }) - return { seenAttributes } - }) - }, - { delay: 400 }, - ) - } - - componentWillUnmount() { - this.autorunDisposer() - } - - render() { - const { classes, style, model } = this.props - const { seenAttributes } = this.state - return ( -
    -
    - - Filters - -
    - {Object.keys(seenAttributes) - .sort() - .map(attrName => ( - - ))} -
    - ) - } -} -FilterControls.propTypes = { - classes: ReactPropTypes.shape({ - root: ReactPropTypes.string, - header: ReactPropTypes.string, - title: ReactPropTypes.string, - }).isRequired, - style: ReactPropTypes.shape({ height: ReactPropTypes.any }), - model: MxPropTypes.objectOrObservableObject.isRequired, -} - -FilterControls.defaultProps = { style: {} } - -export default withStyles(styles)(observer(FilterControls)) diff --git a/plugins/filtering/src/LinearFilteringDisplay/components/LinearFilteringDisplay.js b/plugins/filtering/src/LinearFilteringDisplay/components/LinearFilteringDisplay.js deleted file mode 100644 index 13690c218d..0000000000 --- a/plugins/filtering/src/LinearFilteringDisplay/components/LinearFilteringDisplay.js +++ /dev/null @@ -1,53 +0,0 @@ -import { ResizeHandle } from '@jbrowse/core/ui' -import { BaseLinearDisplayComponent } from '@jbrowse/plugin-linear-genome-view' -import { makeStyles } from '@material-ui/core/styles' -import { observer, PropTypes } from 'mobx-react' -import React from 'react' -import FilterControls from './FilterControls' - -const useStyles = makeStyles(theme => ({ - display: { - background: 'white', - height: '100%', - overflow: 'hidden', - }, - innerDisplay: { - overflowY: 'auto', - overflowX: 'hidden', - }, - filterControls: { - background: theme.palette.background.default, - }, -})) - -function LinearFilteringDisplay(props) { - const { model } = props - const classes = useStyles() - const { innerDisplayHeight, filterControlsHeight, dragHandleHeight } = model - return ( -
    -
    - -
    - - -
    - ) -} - -LinearFilteringDisplay.propTypes = { - model: PropTypes.observableObject.isRequired, -} - -export default observer(LinearFilteringDisplay) diff --git a/plugins/filtering/src/LinearFilteringDisplay/index.js b/plugins/filtering/src/LinearFilteringDisplay/index.js deleted file mode 100644 index 8138689db5..0000000000 --- a/plugins/filtering/src/LinearFilteringDisplay/index.js +++ /dev/null @@ -1,22 +0,0 @@ -import { ConfigurationSchema } from '@jbrowse/core/configuration' -import { linearBasicDisplayConfigSchemaFactory } from '@jbrowse/plugin-linear-genome-view' - -export { default as modelFactory } from './model' -export { default as ReactComponent } from './components/LinearFilteringDisplay' - -export function configSchemaFactory(pluginManager) { - return ConfigurationSchema( - 'LinearFilteringDisplay', - { - filterAttributes: { - type: 'stringArray', - defaultValue: ['type'], - description: 'list of feature attributes to use for filtering', - }, - }, - { - baseConfiguration: linearBasicDisplayConfigSchemaFactory(pluginManager), - explicitlyTyped: true, - }, - ) -} diff --git a/plugins/filtering/src/LinearFilteringDisplay/model.js b/plugins/filtering/src/LinearFilteringDisplay/model.js deleted file mode 100644 index 1c2470af89..0000000000 --- a/plugins/filtering/src/LinearFilteringDisplay/model.js +++ /dev/null @@ -1,90 +0,0 @@ -import { ConfigurationReference } from '@jbrowse/core/configuration' -import { BaseLinearDisplay } from '@jbrowse/plugin-linear-genome-view' -import { types } from 'mobx-state-tree' - -function makeFilters(displayModel) { - const filters = [] - const { filterOut } = displayModel - for (const attrName of filterOut.keys()) { - for (const value of filterOut.get(attrName).keys()) { - if (filterOut.get(attrName).get(value)) { - filters.push(`jexl:get(feature,'${attrName}') != '${value}'`) - } - } - } - return filters -} - -export default configSchema => { - return types.compose( - 'LinearFilteringDisplay', - BaseLinearDisplay, - types - .model({ - type: types.literal('LinearFilteringDisplay'), - configuration: ConfigurationReference(configSchema), - hideExpressions: types.optional(types.array(types.string), () => []), - height: 193, - filterControlsHeight: 70, - dragHandleHeight: 3, - filterOut: types.map(types.map(types.boolean)), // model[attrName][value] = true if filtering out - }) - .views(self => { - const { renderProps: superRenderProps } = self - return { - renderProps() { - const filters = makeFilters(self) - return { - ...superRenderProps(), - rpcDriverName: self.rpcDriverName, - displayModel: self, - config: self.configuration.renderer, - filters, - } - }, - get innerDisplayHeight() { - return ( - self.height - self.dragHandleHeight - self.filterControlsHeight - ) - }, - get filterControlsMinHeight() { - return Math.min(self.filterControlsMaxHeight, 40) - }, - get filterControlsMaxHeight() { - return Math.max(self.height - 20, 0) - }, - get rendererTypeName() { - return self.configuration.renderer.type - }, - } - }) - .actions(self => ({ - setFilterControlsHeight(newHeight) { - if (newHeight > self.filterControlsMinHeight) { - if (newHeight < self.filterControlsMaxHeight) { - self.filterControlsHeight = newHeight - } else { - self.filterControlsHeight = self.filterControlsMaxHeight - } - } else { - self.filterControlsHeight = self.filterControlsMinHeight - } - return self.filterControlsHeight - }, - resizeFilterControls(distance) { - const oldHeight = self.filterControlsHeight - const newHeight = self.setFilterControlsHeight( - self.filterControlsHeight - distance, - ) - return oldHeight - newHeight - }, - toggleFilter(attrName, value, checked) { - if (!self.filterOut.has(attrName)) { - self.filterOut.set(attrName, {}) - } - const values = self.filterOut.get(attrName) - values.set(String(value), !checked) - }, - })), - ) -} diff --git a/plugins/filtering/src/__snapshots__/index.test.js.snap b/plugins/filtering/src/__snapshots__/index.test.js.snap deleted file mode 100644 index d14f789554..0000000000 --- a/plugins/filtering/src/__snapshots__/index.test.js.snap +++ /dev/null @@ -1,5 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`plugin in a stock JBrowse 1`] = `Object {}`; - -exports[`plugin in a stock JBrowse 2`] = `Object {}`; diff --git a/plugins/filtering/src/index.test.js b/plugins/filtering/src/index.test.js deleted file mode 100644 index 866c22c7f3..0000000000 --- a/plugins/filtering/src/index.test.js +++ /dev/null @@ -1,28 +0,0 @@ -import PluginManager from '@jbrowse/core/PluginManager' -import Sequence from '@jbrowse/plugin-sequence' -import { getSnapshot } from 'mobx-state-tree' -import ThisPlugin from '.' - -test('plugin in a stock JBrowse', () => { - const originalConsoleWarn = console.warn - console.warn = jest.fn() - const pluginManager = new PluginManager([new ThisPlugin(), new Sequence()]) - pluginManager.createPluggableElements() - pluginManager.configure() - console.warn = originalConsoleWarn - expect(() => pluginManager.addPlugin(new ThisPlugin())).toThrow( - /JBrowse already configured, cannot add plugins/, - ) - - const TwoBitAdapter = pluginManager.getAdapterType('TwoBitAdapter') - const config = TwoBitAdapter.configSchema.create({ type: 'TwoBitAdapter' }) - expect(getSnapshot(config)).toMatchSnapshot() - - const IndexedFastaAdapter = pluginManager.getAdapterType( - 'IndexedFastaAdapter', - ) - const config2 = IndexedFastaAdapter.configSchema.create({ - type: 'IndexedFastaAdapter', - }) - expect(getSnapshot(config2)).toMatchSnapshot() -}) diff --git a/plugins/filtering/src/index.ts b/plugins/filtering/src/index.ts deleted file mode 100644 index 47bbffb95f..0000000000 --- a/plugins/filtering/src/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType' -import Plugin from '@jbrowse/core/Plugin' -import PluginManager from '@jbrowse/core/PluginManager' -import { - configSchemaFactory as linearFilteringDisplayConfigSchemaFactory, - modelFactory as linearFilteringDisplayModelFactory, - ReactComponent as LinearFilteringDisplayReactComponent, -} from './LinearFilteringDisplay' - -export default class extends Plugin { - name = 'FilteringTrackPlugin' - - install(pluginManager: PluginManager) { - pluginManager.addDisplayType(() => { - const configSchema = linearFilteringDisplayConfigSchemaFactory( - pluginManager, - ) - return new DisplayType({ - name: 'LinearFilteringDisplay', - configSchema, - stateModel: linearFilteringDisplayModelFactory(configSchema), - trackType: 'FilteringTrack', - viewType: 'LinearGenomeView', - ReactComponent: LinearFilteringDisplayReactComponent, - }) - }) - } -} diff --git a/plugins/filtering/tsconfig.json b/plugins/filtering/tsconfig.json deleted file mode 100644 index ca7cf4fc83..0000000000 --- a/plugins/filtering/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "include": ["src", "types"], - "compilerOptions": { - "importHelpers": true, - "declaration": true, - "sourceMap": true, - "rootDir": "./src" - } -} diff --git a/plugins/filtering/tsdx.config.js b/plugins/filtering/tsdx.config.js deleted file mode 100644 index 02db3c28c4..0000000000 --- a/plugins/filtering/tsdx.config.js +++ /dev/null @@ -1,8 +0,0 @@ -// Not transpiled with TypeScript or Babel, so use plain Es6/Node.js! -module.exports = { - // This function will run for each entry/format/env combination - rollup(config) { - config.inlineDynamicImports = true - return config // always return a config. - }, -} diff --git a/products/jbrowse-desktop/package.json b/products/jbrowse-desktop/package.json index 97fc8abad3..9a4b5786da 100644 --- a/products/jbrowse-desktop/package.json +++ b/products/jbrowse-desktop/package.json @@ -45,7 +45,6 @@ "@jbrowse/plugin-config": "^1.3.3", "@jbrowse/plugin-data-management": "^1.3.3", "@jbrowse/plugin-dotplot-view": "^1.3.3", - "@jbrowse/plugin-filtering": "^1.3.3", "@jbrowse/plugin-gff3": "^1.3.3", "@jbrowse/plugin-grid-bookmark": "^1.3.3", "@jbrowse/plugin-hic": "^1.3.3", diff --git a/products/jbrowse-desktop/src/corePlugins.ts b/products/jbrowse-desktop/src/corePlugins.ts index 10a10fc123..bd4925966e 100644 --- a/products/jbrowse-desktop/src/corePlugins.ts +++ b/products/jbrowse-desktop/src/corePlugins.ts @@ -5,7 +5,6 @@ import CircularView from '@jbrowse/plugin-circular-view' import Config from '@jbrowse/plugin-config' import DataManagement from '@jbrowse/plugin-data-management' import DotplotView from '@jbrowse/plugin-dotplot-view' -import Filtering from '@jbrowse/plugin-filtering' import Gff3Tabix from '@jbrowse/plugin-gff3' import LegacyJBrowse from '@jbrowse/plugin-legacy-jbrowse' import LinearGenomeView from '@jbrowse/plugin-linear-genome-view' @@ -32,7 +31,6 @@ const corePlugins = [ Config, DataManagement, DotplotView, - Filtering, Gff3Tabix, LegacyJBrowse, LinearComparativeView, diff --git a/products/jbrowse-web/package.json b/products/jbrowse-web/package.json index 9f6e7f79c3..897cb8e5fe 100644 --- a/products/jbrowse-web/package.json +++ b/products/jbrowse-web/package.json @@ -23,7 +23,6 @@ "@jbrowse/plugin-config": "^1.3.3", "@jbrowse/plugin-data-management": "^1.3.3", "@jbrowse/plugin-dotplot-view": "^1.3.3", - "@jbrowse/plugin-filtering": "^1.3.3", "@jbrowse/plugin-gff3": "^1.3.3", "@jbrowse/plugin-grid-bookmark": "^1.3.3", "@jbrowse/plugin-hic": "^1.3.3", diff --git a/products/jbrowse-web/src/__snapshots__/jbrowseModel.test.ts.snap b/products/jbrowse-web/src/__snapshots__/jbrowseModel.test.ts.snap index e79230188f..014e0c5e0c 100644 --- a/products/jbrowse-web/src/__snapshots__/jbrowseModel.test.ts.snap +++ b/products/jbrowse-web/src/__snapshots__/jbrowseModel.test.ts.snap @@ -1027,73 +1027,6 @@ Object { "trackId": "lollipop_track", "type": "FeatureTrack", }, - Object { - "adapter": Object { - "adapterId": "DvufUT5OYV", - "features": Array [ - Object { - "end": 191, - "name": "Boris", - "note": "note for boris", - "refName": "ctgA", - "score": 200, - "start": 190, - "type": "foo", - "uniqueId": "one", - }, - Object { - "end": 192, - "name": "Theresa", - "note": "note for theresa", - "refName": "ctgA", - "score": 20, - "start": 191, - "type": "bar", - "uniqueId": "two", - }, - Object { - "end": 211, - "name": "Nigel", - "note": "note for nigel", - "refName": "ctgA", - "score": 300, - "start": 210, - "type": "baz", - "uniqueId": "three", - }, - Object { - "end": 221, - "name": "Geoffray", - "note": "note for geoffray", - "refName": "ctgA", - "score": 2, - "start": 220, - "type": "quux", - "uniqueId": "four", - }, - ], - "type": "FromConfigAdapter", - }, - "assemblyNames": Array [ - "volvox", - ], - "category": Array [ - "Miscellaneous", - ], - "displays": Array [ - Object { - "displayId": "filtering_track_linear", - "type": "LinearFilteringDisplay", - }, - Object { - "displayId": "filtering_track-LinearBasicDisplay", - "type": "LinearBasicDisplay", - }, - ], - "name": "FromConfig Track (defaults to LinearFilteringDisplay)", - "trackId": "filtering_track", - "type": "FeatureTrack", - }, Object { "adapter": Object { "bamLocation": Object { diff --git a/products/jbrowse-web/src/corePlugins.ts b/products/jbrowse-web/src/corePlugins.ts index 10a10fc123..bd4925966e 100644 --- a/products/jbrowse-web/src/corePlugins.ts +++ b/products/jbrowse-web/src/corePlugins.ts @@ -5,7 +5,6 @@ import CircularView from '@jbrowse/plugin-circular-view' import Config from '@jbrowse/plugin-config' import DataManagement from '@jbrowse/plugin-data-management' import DotplotView from '@jbrowse/plugin-dotplot-view' -import Filtering from '@jbrowse/plugin-filtering' import Gff3Tabix from '@jbrowse/plugin-gff3' import LegacyJBrowse from '@jbrowse/plugin-legacy-jbrowse' import LinearGenomeView from '@jbrowse/plugin-linear-genome-view' @@ -32,7 +31,6 @@ const corePlugins = [ Config, DataManagement, DotplotView, - Filtering, Gff3Tabix, LegacyJBrowse, LinearComparativeView, diff --git a/test_data/volvox/config.json b/test_data/volvox/config.json index 9b57020c4d..7a5c5eb0b3 100644 --- a/test_data/volvox/config.json +++ b/test_data/volvox/config.json @@ -650,68 +650,6 @@ } ] }, - { - "type": "FeatureTrack", - "trackId": "filtering_track", - "name": "FromConfig Track (defaults to LinearFilteringDisplay)", - "assemblyNames": ["volvox"], - "category": ["Miscellaneous"], - "adapter": { - "type": "FromConfigAdapter", - "adapterId": "DvufUT5OYV", - "features": [ - { - "uniqueId": "one", - "refName": "ctgA", - "start": 190, - "end": 191, - "type": "foo", - "score": 200, - "name": "Boris", - "note": "note for boris" - }, - { - "uniqueId": "two", - "refName": "ctgA", - "start": 191, - "end": 192, - "type": "bar", - "score": 20, - "name": "Theresa", - "note": "note for theresa" - }, - { - "uniqueId": "three", - "refName": "ctgA", - "start": 210, - "end": 211, - "type": "baz", - "score": 300, - "name": "Nigel", - "note": "note for nigel" - }, - { - "uniqueId": "four", - "refName": "ctgA", - "start": 220, - "end": 221, - "score": 2, - "type": "quux", - "name": "Geoffray", - "note": "note for geoffray" - } - ] - }, - "displays": [ - { - "type": "LinearFilteringDisplay", - "displayId": "filtering_track_linear", - "renderer": { - "type": "SvgFeatureRenderer" - } - } - ] - }, { "type": "AlignmentsTrack", "trackId": "volvox-long-reads-sv-bam",