@jbrowse/plugin-linear-genome-view 4.1.3 → 4.1.4
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.
- package/esm/BaseLinearDisplay/components/FloatingLabels.js +3 -4
- package/esm/BaseLinearDisplay/components/LoadingOverlay.d.ts +2 -1
- package/esm/BaseLinearDisplay/components/LoadingOverlay.js +2 -2
- package/esm/BaseLinearDisplay/components/NonBlockCanvasDisplayComponent.d.ts +1 -0
- package/esm/BaseLinearDisplay/components/NonBlockCanvasDisplayComponent.js +2 -2
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.d.ts +1 -0
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +1 -1
- package/esm/BaseLinearDisplay/components/util.d.ts +8 -8
- package/esm/BaseLinearDisplay/components/util.js +25 -35
- package/esm/BaseLinearDisplay/model.d.ts +18 -8
- package/esm/BaseLinearDisplay/models/SvgFloatingLabels.d.ts +8 -0
- package/esm/BaseLinearDisplay/models/SvgFloatingLabels.js +19 -0
- package/esm/BaseLinearDisplay/models/configSchema.d.ts +2 -2
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +2 -0
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +3 -0
- package/esm/BaseLinearDisplay/models/util.d.ts +0 -13
- package/esm/BaseLinearDisplay/renderSvg.js +8 -4
- package/esm/BaseLinearDisplay/types.d.ts +0 -4
- package/esm/BasicTrack/configSchema.d.ts +8 -8
- package/esm/FeatureTrack/configSchema.d.ts +8 -8
- package/esm/LinearBareDisplay/configSchema.d.ts +3 -3
- package/esm/LinearBareDisplay/model.d.ts +18 -8
- package/esm/LinearBasicDisplay/configSchema.d.ts +3 -3
- package/esm/LinearBasicDisplay/model.d.ts +18 -8
- package/esm/LinearFeatureDisplay/configSchema.d.ts +3 -3
- package/esm/LinearFeatureDisplay/model.d.ts +22 -10
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +18 -6
- package/esm/LinearGenomeView/components/SearchResultsTable.js +2 -7
- package/esm/LinearGenomeView/lazyDialogs.d.ts +23 -0
- package/esm/LinearGenomeView/lazyDialogs.js +5 -0
- package/esm/LinearGenomeView/menuItems.js +1 -5
- package/esm/LinearGenomeView/model.d.ts +2 -1
- package/esm/LinearGenomeView/model.js +64 -13
- package/esm/LinearGenomeView/types.d.ts +1 -0
- package/esm/index.d.ts +23 -12
- package/esm/index.js +1 -0
- package/esm/searchUtils.js +4 -1
- package/package.json +5 -5
- package/esm/BaseLinearDisplay/models/calculateLabelPositions.d.ts +0 -24
- package/esm/BaseLinearDisplay/models/calculateLabelPositions.js +0 -60
- package/esm/BaseLinearDisplay/models/renderSvg.d.ts +0 -3
- package/esm/BaseLinearDisplay/models/renderSvg.js +0 -55
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const ReturnToImportFormDialog: import("react").LazyExoticComponent<({ model, handleClose, }: {
|
|
2
|
+
model: {
|
|
3
|
+
clearView: () => void;
|
|
4
|
+
};
|
|
5
|
+
handleClose: () => void;
|
|
6
|
+
}) => import("react/jsx-runtime").JSX.Element>;
|
|
7
|
+
export declare const SequenceSearchDialog: import("react").LazyExoticComponent<({ model, handleClose, }: {
|
|
8
|
+
model: {
|
|
9
|
+
assemblyNames: string[];
|
|
10
|
+
showTrack: (trackId: string) => void;
|
|
11
|
+
};
|
|
12
|
+
handleClose: () => void;
|
|
13
|
+
}) => import("react/jsx-runtime").JSX.Element>;
|
|
14
|
+
export declare const ExportSvgDialog: import("react").LazyExoticComponent<typeof import("./components/ExportSvgDialog.tsx").default>;
|
|
15
|
+
export declare const GetSequenceDialog: import("react").LazyExoticComponent<({ model, handleClose, }: {
|
|
16
|
+
model: {
|
|
17
|
+
leftOffset?: import("./types.ts").BpOffset;
|
|
18
|
+
rightOffset?: import("./types.ts").BpOffset;
|
|
19
|
+
getSelectedRegions: (left?: import("./types.ts").BpOffset, right?: import("./types.ts").BpOffset) => import("@jbrowse/core/util").Region[];
|
|
20
|
+
setOffsets: (left?: import("./types.ts").BpOffset, right?: import("./types.ts").BpOffset) => void;
|
|
21
|
+
};
|
|
22
|
+
handleClose: () => void;
|
|
23
|
+
}) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { lazy } from 'react';
|
|
2
|
+
export const ReturnToImportFormDialog = lazy(() => import('@jbrowse/core/ui/ReturnToImportFormDialog'));
|
|
3
|
+
export const SequenceSearchDialog = lazy(() => import("./components/SequenceSearchDialog.js"));
|
|
4
|
+
export const ExportSvgDialog = lazy(() => import("./components/ExportSvgDialog.js"));
|
|
5
|
+
export const GetSequenceDialog = lazy(() => import("./components/GetSequenceDialog.js"));
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { lazy } from 'react';
|
|
2
1
|
import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons';
|
|
3
2
|
import { getSession, isSessionWithAddTracks, toLocale, } from '@jbrowse/core/util';
|
|
4
3
|
import CenterFocusStrongIcon from '@mui/icons-material/CenterFocusStrong';
|
|
@@ -12,10 +11,7 @@ import SearchIcon from '@mui/icons-material/Search';
|
|
|
12
11
|
import SyncAltIcon from '@mui/icons-material/SyncAlt';
|
|
13
12
|
import VisibilityIcon from '@mui/icons-material/Visibility';
|
|
14
13
|
import ZoomInIcon from '@mui/icons-material/ZoomIn';
|
|
15
|
-
|
|
16
|
-
const SequenceSearchDialog = lazy(() => import("./components/SequenceSearchDialog.js"));
|
|
17
|
-
const ExportSvgDialog = lazy(() => import("./components/ExportSvgDialog.js"));
|
|
18
|
-
const GetSequenceDialog = lazy(() => import("./components/GetSequenceDialog.js"));
|
|
14
|
+
import { ExportSvgDialog, GetSequenceDialog, ReturnToImportFormDialog, SequenceSearchDialog, } from "./lazyDialogs.js";
|
|
19
15
|
function toLocaleRounded(n) {
|
|
20
16
|
return toLocale(Math.round(n));
|
|
21
17
|
}
|
|
@@ -86,6 +86,8 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
86
86
|
readonly trackHeightsWithResizeHandles: number;
|
|
87
87
|
readonly height: number;
|
|
88
88
|
readonly totalBp: number;
|
|
89
|
+
getNonElidedRegionCount(bpPerPx: number): number;
|
|
90
|
+
getInterRegionPaddingPx(bpPerPx: number): number;
|
|
89
91
|
readonly maxBpPerPx: number;
|
|
90
92
|
readonly minBpPerPx: number;
|
|
91
93
|
readonly error: unknown;
|
|
@@ -144,7 +146,6 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
144
146
|
end: number;
|
|
145
147
|
}[];
|
|
146
148
|
horizontalScroll(distance: number): number;
|
|
147
|
-
center(): void;
|
|
148
149
|
showAllRegions(): void;
|
|
149
150
|
showAllRegionsInAssembly(assemblyName?: string): void;
|
|
150
151
|
setDraggingTrackId(idx?: string): void;
|
|
@@ -21,6 +21,9 @@ import { setupKeyboardHandler } from "./keyboardHandler.js";
|
|
|
21
21
|
import { buildMenuItems, buildRubberBandMenuItems, buildRubberbandClickMenuItems, rewriteOnClicks, } from "./menuItems.js";
|
|
22
22
|
import { calculateVisibleLocStrings, expandRegion, generateLocations, parseLocStrings, } from "./util.js";
|
|
23
23
|
const SearchResultsDialog = lazy(() => import("./components/SearchResultsDialog.js"));
|
|
24
|
+
function getCenteredOffsetPx(contentPx, viewportPx) {
|
|
25
|
+
return Math.round(contentPx / 2 - viewportPx / 2);
|
|
26
|
+
}
|
|
24
27
|
export function stateModelFactory(pluginManager) {
|
|
25
28
|
return types
|
|
26
29
|
.compose('LinearGenomeView', BaseViewModel, types.model({
|
|
@@ -201,8 +204,29 @@ export function stateModelFactory(pluginManager) {
|
|
|
201
204
|
get totalBp() {
|
|
202
205
|
return sum(self.displayedRegions.map(r => r.end - r.start));
|
|
203
206
|
},
|
|
207
|
+
getNonElidedRegionCount(bpPerPx) {
|
|
208
|
+
if (bpPerPx <= 0) {
|
|
209
|
+
return self.displayedRegions.length;
|
|
210
|
+
}
|
|
211
|
+
return self.displayedRegions.filter(r => (r.end - r.start) / bpPerPx >= self.minimumBlockWidth).length;
|
|
212
|
+
},
|
|
213
|
+
getInterRegionPaddingPx(bpPerPx) {
|
|
214
|
+
const nonElidedCount = this.getNonElidedRegionCount(bpPerPx);
|
|
215
|
+
const numPaddings = Math.max(0, nonElidedCount - 1);
|
|
216
|
+
return numPaddings * self.interRegionPaddingWidth;
|
|
217
|
+
},
|
|
204
218
|
get maxBpPerPx() {
|
|
205
|
-
|
|
219
|
+
if (this.totalBp === 0 || self.width === 0) {
|
|
220
|
+
return 1;
|
|
221
|
+
}
|
|
222
|
+
const naiveBpPerPx = this.totalBp / (self.width * 0.9);
|
|
223
|
+
const totalPaddingPx = this.getInterRegionPaddingPx(naiveBpPerPx);
|
|
224
|
+
const targetWidth = self.width * 0.9;
|
|
225
|
+
const availableForBp = targetWidth - totalPaddingPx;
|
|
226
|
+
if (availableForBp <= 0) {
|
|
227
|
+
return naiveBpPerPx;
|
|
228
|
+
}
|
|
229
|
+
return this.totalBp / availableForBp;
|
|
206
230
|
},
|
|
207
231
|
get minBpPerPx() {
|
|
208
232
|
return 1 / 50;
|
|
@@ -238,7 +262,11 @@ export function stateModelFactory(pluginManager) {
|
|
|
238
262
|
return -self.width + rightPadding;
|
|
239
263
|
},
|
|
240
264
|
get displayedRegionsTotalPx() {
|
|
241
|
-
|
|
265
|
+
if (self.bpPerPx === 0) {
|
|
266
|
+
return 0;
|
|
267
|
+
}
|
|
268
|
+
const totalPaddingPx = this.getInterRegionPaddingPx(self.bpPerPx);
|
|
269
|
+
return this.totalBp / self.bpPerPx + totalPaddingPx;
|
|
242
270
|
},
|
|
243
271
|
renderProps() {
|
|
244
272
|
return {
|
|
@@ -462,17 +490,9 @@ export function stateModelFactory(pluginManager) {
|
|
|
462
490
|
const newOffsetPx = self.scrollTo(self.offsetPx + distance);
|
|
463
491
|
return newOffsetPx - oldOffsetPx;
|
|
464
492
|
},
|
|
465
|
-
center() {
|
|
466
|
-
const numPaddings = Math.max(0, self.displayedRegions.length - 1);
|
|
467
|
-
const totalPaddingPx = numPaddings * self.interRegionPaddingWidth;
|
|
468
|
-
const totalContentPx = self.totalBp / self.bpPerPx + totalPaddingPx;
|
|
469
|
-
const centerPx = totalContentPx / 2;
|
|
470
|
-
const targetOffsetPx = Math.round(centerPx - self.width / 2);
|
|
471
|
-
self.scrollTo(targetOffsetPx);
|
|
472
|
-
},
|
|
473
493
|
showAllRegions() {
|
|
474
494
|
self.bpPerPx = clamp(self.maxBpPerPx, self.minBpPerPx, self.maxBpPerPx);
|
|
475
|
-
|
|
495
|
+
self.scrollTo(getCenteredOffsetPx(self.displayedRegionsTotalPx, self.width));
|
|
476
496
|
},
|
|
477
497
|
showAllRegionsInAssembly(assemblyName) {
|
|
478
498
|
const session = getSession(self);
|
|
@@ -492,7 +512,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
492
512
|
}
|
|
493
513
|
this.setDisplayedRegions(regions);
|
|
494
514
|
self.zoomTo(self.maxBpPerPx);
|
|
495
|
-
|
|
515
|
+
self.scrollTo(getCenteredOffsetPx(self.displayedRegionsTotalPx, self.width));
|
|
496
516
|
},
|
|
497
517
|
setDraggingTrackId(idx) {
|
|
498
518
|
self.draggingTrackId = idx;
|
|
@@ -522,7 +542,38 @@ export function stateModelFactory(pluginManager) {
|
|
|
522
542
|
const { renderToSvg } = await import("./svgcomponents/SVGLinearGenomeView.js");
|
|
523
543
|
const html = await renderToSvg(self, opts);
|
|
524
544
|
const { saveAs } = await import('file-saver-es');
|
|
525
|
-
|
|
545
|
+
if (opts.format === 'png') {
|
|
546
|
+
const img = new Image();
|
|
547
|
+
const svgBlob = new Blob([html], { type: 'image/svg+xml' });
|
|
548
|
+
const url = URL.createObjectURL(svgBlob);
|
|
549
|
+
await new Promise((resolve, reject) => {
|
|
550
|
+
img.onload = () => {
|
|
551
|
+
const canvas = document.createElement('canvas');
|
|
552
|
+
canvas.width = img.width;
|
|
553
|
+
canvas.height = img.height;
|
|
554
|
+
const ctx = canvas.getContext('2d');
|
|
555
|
+
ctx.drawImage(img, 0, 0);
|
|
556
|
+
URL.revokeObjectURL(url);
|
|
557
|
+
canvas.toBlob(blob => {
|
|
558
|
+
if (blob) {
|
|
559
|
+
saveAs(blob, opts.filename || 'image.png');
|
|
560
|
+
resolve();
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
reject(new Error(`Failed to create PNG. The image may be too large (${img.width}x${img.height}). Try reducing the view size or use SVG format.`));
|
|
564
|
+
}
|
|
565
|
+
}, 'image/png');
|
|
566
|
+
};
|
|
567
|
+
img.onerror = () => {
|
|
568
|
+
URL.revokeObjectURL(url);
|
|
569
|
+
reject(new Error('Failed to load SVG for PNG conversion'));
|
|
570
|
+
};
|
|
571
|
+
img.src = url;
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
saveAs(new Blob([html], { type: 'image/svg+xml' }), opts.filename || 'image.svg');
|
|
576
|
+
}
|
|
526
577
|
},
|
|
527
578
|
}))
|
|
528
579
|
.actions(self => {
|
package/esm/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
41
41
|
statusMessage?: string;
|
|
42
42
|
reactElement?: React.ReactElement;
|
|
43
43
|
isRenderingPending?: boolean;
|
|
44
|
+
displayHeight?: number;
|
|
44
45
|
};
|
|
45
46
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
46
47
|
renderProps: any;
|
|
@@ -59,10 +60,11 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
59
60
|
beforeDestroy(): void;
|
|
60
61
|
} & {
|
|
61
62
|
readonly statusMessage: any;
|
|
63
|
+
readonly displayHeight: number | undefined;
|
|
62
64
|
} & {
|
|
63
65
|
afterAttach(): void;
|
|
64
66
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
65
|
-
configuration: import("
|
|
67
|
+
configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
66
68
|
maxFeatureScreenDensity: {
|
|
67
69
|
type: string;
|
|
68
70
|
description: string;
|
|
@@ -89,7 +91,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
89
91
|
description: string;
|
|
90
92
|
defaultValue: never[];
|
|
91
93
|
};
|
|
92
|
-
}, import("
|
|
94
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
93
95
|
showLegend: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>>;
|
|
94
96
|
showTooltips: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>>;
|
|
95
97
|
}, {
|
|
@@ -380,6 +382,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
380
382
|
statusMessage?: string;
|
|
381
383
|
reactElement?: React.ReactElement;
|
|
382
384
|
isRenderingPending?: boolean;
|
|
385
|
+
displayHeight?: number;
|
|
383
386
|
};
|
|
384
387
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
385
388
|
renderProps: any;
|
|
@@ -398,6 +401,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
398
401
|
beforeDestroy(): void;
|
|
399
402
|
} & {
|
|
400
403
|
readonly statusMessage: any;
|
|
404
|
+
readonly displayHeight: number | undefined;
|
|
401
405
|
} & {
|
|
402
406
|
afterAttach(): void;
|
|
403
407
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>> & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IMapType<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -424,6 +428,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
424
428
|
statusMessage?: string;
|
|
425
429
|
reactElement?: React.ReactElement;
|
|
426
430
|
isRenderingPending?: boolean;
|
|
431
|
+
displayHeight?: number;
|
|
427
432
|
};
|
|
428
433
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
429
434
|
renderProps: any;
|
|
@@ -442,6 +447,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
442
447
|
beforeDestroy(): void;
|
|
443
448
|
} & {
|
|
444
449
|
readonly statusMessage: any;
|
|
450
|
+
readonly displayHeight: number | undefined;
|
|
445
451
|
} & {
|
|
446
452
|
afterAttach(): void;
|
|
447
453
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>>;
|
|
@@ -455,7 +461,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
455
461
|
[x: string]: any;
|
|
456
462
|
} & import("@jbrowse/mobx-state-tree/dist/internal").NonEmptyObject & any & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>);
|
|
457
463
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>);
|
|
458
|
-
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("
|
|
464
|
+
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
459
465
|
maxFeatureScreenDensity: {
|
|
460
466
|
type: string;
|
|
461
467
|
description: string;
|
|
@@ -482,7 +488,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
482
488
|
description: string;
|
|
483
489
|
defaultValue: never[];
|
|
484
490
|
};
|
|
485
|
-
}, import("
|
|
491
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>>;
|
|
486
492
|
showLegend: boolean | undefined;
|
|
487
493
|
showTooltips: boolean | undefined;
|
|
488
494
|
} & import("@jbrowse/mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
@@ -772,6 +778,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
772
778
|
statusMessage?: string;
|
|
773
779
|
reactElement?: React.ReactElement;
|
|
774
780
|
isRenderingPending?: boolean;
|
|
781
|
+
displayHeight?: number;
|
|
775
782
|
};
|
|
776
783
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
777
784
|
renderProps: any;
|
|
@@ -790,10 +797,11 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
790
797
|
beforeDestroy(): void;
|
|
791
798
|
} & {
|
|
792
799
|
readonly statusMessage: any;
|
|
800
|
+
readonly displayHeight: number | undefined;
|
|
793
801
|
} & {
|
|
794
802
|
afterAttach(): void;
|
|
795
803
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
796
|
-
configuration: import("
|
|
804
|
+
configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
797
805
|
maxFeatureScreenDensity: {
|
|
798
806
|
type: string;
|
|
799
807
|
description: string;
|
|
@@ -820,7 +828,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
820
828
|
description: string;
|
|
821
829
|
defaultValue: never[];
|
|
822
830
|
};
|
|
823
|
-
}, import("
|
|
831
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
824
832
|
showLegend: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>>;
|
|
825
833
|
showTooltips: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>>;
|
|
826
834
|
}, {
|
|
@@ -1119,6 +1127,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
1119
1127
|
statusMessage?: string;
|
|
1120
1128
|
reactElement?: React.ReactElement;
|
|
1121
1129
|
isRenderingPending?: boolean;
|
|
1130
|
+
displayHeight?: number;
|
|
1122
1131
|
};
|
|
1123
1132
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
1124
1133
|
renderProps: any;
|
|
@@ -1137,10 +1146,11 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
1137
1146
|
beforeDestroy(): void;
|
|
1138
1147
|
} & {
|
|
1139
1148
|
readonly statusMessage: any;
|
|
1149
|
+
readonly displayHeight: number | undefined;
|
|
1140
1150
|
} & {
|
|
1141
1151
|
afterAttach(): void;
|
|
1142
1152
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
1143
|
-
configuration: import("
|
|
1153
|
+
configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
1144
1154
|
maxFeatureScreenDensity: {
|
|
1145
1155
|
type: string;
|
|
1146
1156
|
description: string;
|
|
@@ -1167,7 +1177,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
1167
1177
|
description: string;
|
|
1168
1178
|
defaultValue: never[];
|
|
1169
1179
|
};
|
|
1170
|
-
}, import("
|
|
1180
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
1171
1181
|
showLegend: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>>;
|
|
1172
1182
|
showTooltips: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>>;
|
|
1173
1183
|
}>>, {
|
|
@@ -1181,7 +1191,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
1181
1191
|
showLegend: boolean | undefined;
|
|
1182
1192
|
showTooltips: boolean | undefined;
|
|
1183
1193
|
}>;
|
|
1184
|
-
baseLinearDisplayConfigSchema: import("
|
|
1194
|
+
baseLinearDisplayConfigSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
1185
1195
|
maxFeatureScreenDensity: {
|
|
1186
1196
|
type: string;
|
|
1187
1197
|
description: string;
|
|
@@ -1208,7 +1218,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
1208
1218
|
description: string;
|
|
1209
1219
|
defaultValue: never[];
|
|
1210
1220
|
};
|
|
1211
|
-
}, import("
|
|
1221
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
1212
1222
|
SearchBox: ({ model, showHelp, }: {
|
|
1213
1223
|
showHelp?: boolean;
|
|
1214
1224
|
model: import("./index.ts").LinearGenomeViewModel;
|
|
@@ -1220,13 +1230,13 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
1220
1230
|
model: import("./index.ts").LinearGenomeViewModel;
|
|
1221
1231
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
1222
1232
|
};
|
|
1223
|
-
configurationSchema: import("
|
|
1233
|
+
configurationSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
1224
1234
|
trackLabels: {
|
|
1225
1235
|
type: string;
|
|
1226
1236
|
defaultValue: string;
|
|
1227
1237
|
model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1228
1238
|
};
|
|
1229
|
-
}, import("
|
|
1239
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
1230
1240
|
install(pluginManager: PluginManager): void;
|
|
1231
1241
|
configure(pluginManager: PluginManager): void;
|
|
1232
1242
|
}
|
|
@@ -1235,6 +1245,7 @@ export { configSchemaFactory as linearBareDisplayConfigSchemaFactory, stateModel
|
|
|
1235
1245
|
export { BaseLinearDisplay, BaseLinearDisplayComponent, BlockMsg, FeatureDensityMixin, FloatingLegend, NonBlockCanvasDisplayComponent, NonBlockCanvasDisplayMixin, SVGLegend, TooLargeMessage, TrackHeightMixin, baseLinearDisplayConfigSchema, calculateSvgLegendWidth, createSubfeatureLabelMetadata, drawCanvasImageData, } from './BaseLinearDisplay/index.ts';
|
|
1236
1246
|
export type { NonBlockCanvasDisplayMixinType, NonBlockCanvasDisplayModel, } from './BaseLinearDisplay/index.ts';
|
|
1237
1247
|
export { type LinearGenomeViewModel, type LinearGenomeViewStateModel, RefNameAutocomplete, SearchBox, } from './LinearGenomeView/index.ts';
|
|
1248
|
+
export { fetchResults } from './searchUtils.ts';
|
|
1238
1249
|
export type { BpOffset, ExportSvgOptions, HighlightType, InitState, NavLocation, VolatileGuide, } from './LinearGenomeView/types.ts';
|
|
1239
1250
|
export { SVGGridlines, SVGRuler, SVGTracks, renderToSvg, } from './LinearGenomeView/svgcomponents/SVGLinearGenomeView.tsx';
|
|
1240
1251
|
export { totalHeight } from './LinearGenomeView/svgcomponents/util.ts';
|
package/esm/index.js
CHANGED
|
@@ -55,6 +55,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
55
55
|
export { configSchemaFactory as linearBareDisplayConfigSchemaFactory, stateModelFactory as linearBareDisplayStateModelFactory, } from "./LinearBareDisplay/index.js";
|
|
56
56
|
export { BaseLinearDisplay, BaseLinearDisplayComponent, BlockMsg, FeatureDensityMixin, FloatingLegend, NonBlockCanvasDisplayComponent, NonBlockCanvasDisplayMixin, SVGLegend, TooLargeMessage, TrackHeightMixin, baseLinearDisplayConfigSchema, calculateSvgLegendWidth, createSubfeatureLabelMetadata, drawCanvasImageData, } from "./BaseLinearDisplay/index.js";
|
|
57
57
|
export { RefNameAutocomplete, SearchBox, } from "./LinearGenomeView/index.js";
|
|
58
|
+
export { fetchResults } from "./searchUtils.js";
|
|
58
59
|
export { SVGGridlines, SVGRuler, SVGTracks, renderToSvg, } from "./LinearGenomeView/svgcomponents/SVGLinearGenomeView.js";
|
|
59
60
|
export { totalHeight } from "./LinearGenomeView/svgcomponents/util.js";
|
|
60
61
|
export { configSchema as linearBasicDisplayConfigSchemaFactory, modelFactory as linearBasicDisplayModelFactory, } from "./LinearBasicDisplay/index.js";
|
package/esm/searchUtils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
|
|
2
|
-
import { dedupe, getSession } from '@jbrowse/core/util';
|
|
2
|
+
import { dedupe, getEnv, getSession } from '@jbrowse/core/util';
|
|
3
3
|
export async function navToOption({ option, model, assemblyName, }) {
|
|
4
4
|
const location = option.getLocation();
|
|
5
5
|
const trackId = option.getTrackId();
|
|
@@ -9,6 +9,9 @@ export async function navToOption({ option, model, assemblyName, }) {
|
|
|
9
9
|
model.showTrack(trackId);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
const session = getSession(model);
|
|
13
|
+
const { pluginManager } = getEnv(session);
|
|
14
|
+
await pluginManager.evaluateAsyncExtensionPoint('LinearGenomeView-searchResultSelected', undefined, { session, result: option, model, assemblyName });
|
|
12
15
|
}
|
|
13
16
|
export async function handleSelectedRegion({ input, model, assembly, }) {
|
|
14
17
|
const allRefs = assembly.allRefNamesWithLowerCase || [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-linear-genome-view",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "JBrowse 2 linear genome view",
|
|
6
6
|
"keywords": [
|
|
@@ -22,15 +22,15 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@jbrowse/mobx-state-tree": "^5.5.0",
|
|
25
|
-
"@mui/icons-material": "^7.3.
|
|
26
|
-
"@mui/material": "^7.3.
|
|
25
|
+
"@mui/icons-material": "^7.3.8",
|
|
26
|
+
"@mui/material": "^7.3.8",
|
|
27
27
|
"@types/file-saver-es": "^2.0.3",
|
|
28
28
|
"copy-to-clipboard": "^3.3.3",
|
|
29
29
|
"file-saver-es": "^2.0.5",
|
|
30
30
|
"mobx": "^6.15.0",
|
|
31
31
|
"mobx-react": "^9.2.1",
|
|
32
|
-
"@jbrowse/product-core": "^4.1.
|
|
33
|
-
"@jbrowse/core": "^4.1.
|
|
32
|
+
"@jbrowse/product-core": "^4.1.4",
|
|
33
|
+
"@jbrowse/core": "^4.1.4"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"react": ">=18.0.0",
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { LinearGenomeViewModel } from '../../LinearGenomeView/index.ts';
|
|
2
|
-
import type { BaseLinearDisplayModel } from '../model.ts';
|
|
3
|
-
import type { Assembly } from '@jbrowse/core/assemblyManager/assembly';
|
|
4
|
-
export interface RenderProps {
|
|
5
|
-
rendererType: any;
|
|
6
|
-
renderArgs: Record<string, any>;
|
|
7
|
-
renderProps: Record<string, any>;
|
|
8
|
-
displayError: unknown;
|
|
9
|
-
rpcManager: {
|
|
10
|
-
call: (...args: unknown[]) => void;
|
|
11
|
-
};
|
|
12
|
-
cannotBeRenderedReason: string;
|
|
13
|
-
}
|
|
14
|
-
export interface LabelData {
|
|
15
|
-
key: string;
|
|
16
|
-
label: string;
|
|
17
|
-
description: string;
|
|
18
|
-
leftPos: number;
|
|
19
|
-
topPos: number;
|
|
20
|
-
}
|
|
21
|
-
export interface ErrorProps {
|
|
22
|
-
displayError: string;
|
|
23
|
-
}
|
|
24
|
-
export declare function calculateLabelPositions(model: BaseLinearDisplayModel, view: LinearGenomeViewModel, assembly: Assembly | undefined, offsetPx: number): LabelData[];
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { clamp, measureText } from '@jbrowse/core/util';
|
|
2
|
-
export function calculateLabelPositions(model, view, assembly, offsetPx) {
|
|
3
|
-
if (!assembly) {
|
|
4
|
-
return [];
|
|
5
|
-
}
|
|
6
|
-
const fontSize = 11;
|
|
7
|
-
const result = [];
|
|
8
|
-
for (const [key, val] of model.layoutFeatures.entries()) {
|
|
9
|
-
if (!val?.[4]) {
|
|
10
|
-
continue;
|
|
11
|
-
}
|
|
12
|
-
const [left, , right, bottom, feature] = val;
|
|
13
|
-
const { refName, description, label, totalLayoutWidth } = feature;
|
|
14
|
-
if (!label) {
|
|
15
|
-
continue;
|
|
16
|
-
}
|
|
17
|
-
const r0 = assembly.getCanonicalRefName2(refName);
|
|
18
|
-
const px1 = view.bpToPx({
|
|
19
|
-
refName: r0,
|
|
20
|
-
coord: left,
|
|
21
|
-
})?.offsetPx;
|
|
22
|
-
const px2 = view.bpToPx({
|
|
23
|
-
refName: r0,
|
|
24
|
-
coord: right,
|
|
25
|
-
})?.offsetPx;
|
|
26
|
-
if (px1 === undefined) {
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
const leftPx = px2 !== undefined ? Math.min(px1, px2) : px1;
|
|
30
|
-
const rightPx = px2 !== undefined ? Math.max(px1, px2) : px1;
|
|
31
|
-
const labelWidth = getCachedMeasureText(label, fontSize);
|
|
32
|
-
const effectiveRightPx = totalLayoutWidth !== undefined ? leftPx + totalLayoutWidth : rightPx;
|
|
33
|
-
const leftPos = clamp(0, leftPx - offsetPx, effectiveRightPx - offsetPx - labelWidth);
|
|
34
|
-
const topPos = bottom - 14 * (+!!description + +!!label);
|
|
35
|
-
result.push({
|
|
36
|
-
key,
|
|
37
|
-
label,
|
|
38
|
-
description: description || '',
|
|
39
|
-
leftPos,
|
|
40
|
-
topPos,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
return result;
|
|
44
|
-
}
|
|
45
|
-
const textMeasureCache = new Map();
|
|
46
|
-
function getCachedMeasureText(text, fontSize) {
|
|
47
|
-
const key = `${text}:${fontSize}`;
|
|
48
|
-
let width = textMeasureCache.get(key);
|
|
49
|
-
if (width === undefined) {
|
|
50
|
-
width = measureText(text, fontSize);
|
|
51
|
-
if (textMeasureCache.size > 500) {
|
|
52
|
-
const firstKey = textMeasureCache.keys().next().value;
|
|
53
|
-
if (firstKey) {
|
|
54
|
-
textMeasureCache.delete(firstKey);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
textMeasureCache.set(key, width);
|
|
58
|
-
}
|
|
59
|
-
return width;
|
|
60
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { BaseLinearDisplayModel } from '../model.ts';
|
|
2
|
-
import type { ExportSvgDisplayOptions } from '../types.ts';
|
|
3
|
-
export declare function renderBaseLinearDisplaySvg(self: BaseLinearDisplayModel, opts: ExportSvgDisplayOptions): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment } from 'react';
|
|
3
|
-
import { ReactRendering, getContainingView, getSession, } from '@jbrowse/core/util';
|
|
4
|
-
import { calculateLabelPositions } from "./calculateLabelPositions.js";
|
|
5
|
-
import BlockState, { renderBlockData } from "./serverSideRenderedBlock.js";
|
|
6
|
-
import { getId } from "./util.js";
|
|
7
|
-
import { ErrorBox } from "../../LinearGenomeView/SVGErrorBox.js";
|
|
8
|
-
export async function renderBaseLinearDisplaySvg(self, opts) {
|
|
9
|
-
const { height, id } = self;
|
|
10
|
-
const { overrideHeight } = opts;
|
|
11
|
-
const view = getContainingView(self);
|
|
12
|
-
const { offsetPx: viewOffsetPx, roundedDynamicBlocks, width } = view;
|
|
13
|
-
if (self.error) {
|
|
14
|
-
return _jsx(ErrorBox, { error: self.error, width: width, height: height });
|
|
15
|
-
}
|
|
16
|
-
const renderings = await Promise.all(roundedDynamicBlocks.map(async (block) => {
|
|
17
|
-
const blockState = BlockState.create({
|
|
18
|
-
key: block.key,
|
|
19
|
-
region: block,
|
|
20
|
-
});
|
|
21
|
-
const cannotBeRenderedReason = self.regionCannotBeRenderedText(block) ||
|
|
22
|
-
self.regionCannotBeRendered(block);
|
|
23
|
-
if (cannotBeRenderedReason) {
|
|
24
|
-
return [
|
|
25
|
-
block,
|
|
26
|
-
{
|
|
27
|
-
reactElement: (_jsxs(_Fragment, { children: [_jsx("rect", { x: 0, y: 0, width: width, height: 20, fill: "#aaa" }), _jsx("text", { x: 0, y: 15, children: cannotBeRenderedReason })] })),
|
|
28
|
-
},
|
|
29
|
-
];
|
|
30
|
-
}
|
|
31
|
-
const { rpcManager, renderArgs, renderProps, renderingProps, rendererType, } = renderBlockData(blockState, self);
|
|
32
|
-
return [
|
|
33
|
-
block,
|
|
34
|
-
await rendererType.renderInClient(rpcManager, {
|
|
35
|
-
...renderArgs,
|
|
36
|
-
...renderProps,
|
|
37
|
-
renderingProps,
|
|
38
|
-
exportSVG: opts,
|
|
39
|
-
theme: opts.theme || renderProps.theme,
|
|
40
|
-
}),
|
|
41
|
-
];
|
|
42
|
-
}));
|
|
43
|
-
const { assemblyManager } = getSession(self);
|
|
44
|
-
const { offsetPx } = view;
|
|
45
|
-
const assemblyName = view.assemblyNames[0];
|
|
46
|
-
const assembly = assemblyName ? assemblyManager.get(assemblyName) : undefined;
|
|
47
|
-
const labelData = calculateLabelPositions(self, view, assembly, offsetPx);
|
|
48
|
-
const labelsClipId = getId(id, 'labels');
|
|
49
|
-
return (_jsxs(_Fragment, { children: [renderings.map(([block, rendering], index) => {
|
|
50
|
-
const { offsetPx, widthPx } = block;
|
|
51
|
-
const offset = offsetPx - viewOffsetPx;
|
|
52
|
-
const clipid = getId(id, index);
|
|
53
|
-
return (_jsxs(Fragment, { children: [_jsx("defs", { children: _jsx("clipPath", { id: clipid, children: _jsx("rect", { x: 0, y: 0, width: widthPx, height: overrideHeight || height }) }) }), _jsx("g", { transform: `translate(${offset} 0)`, children: _jsx("g", { clipPath: `url(#${clipid})`, children: _jsx(ReactRendering, { rendering: rendering }) }) })] }, `frag-${index}`));
|
|
54
|
-
}), _jsx("defs", { children: _jsx("clipPath", { id: labelsClipId, children: _jsx("rect", { x: 0, y: 0, width: width, height: overrideHeight || height }) }) }), _jsx("g", { clipPath: `url(#${labelsClipId})`, children: labelData.map(({ key, label, description, leftPos, topPos }) => (_jsxs("g", { transform: `translate(${leftPos}, ${topPos})`, children: [_jsx("text", { x: 0, y: 11, fontSize: 11, fill: "currentColor", style: { pointerEvents: 'none' }, children: label }), description ? (_jsx("text", { x: 0, y: 25, fontSize: 11, fill: "blue", style: { pointerEvents: 'none' }, children: description })) : null] }, `label-${key}`))) })] }));
|
|
55
|
-
}
|