@jbrowse/plugin-linear-genome-view 4.0.2 → 4.0.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/Tooltip.js +1 -1
- package/esm/BaseLinearDisplay/model.d.ts +9 -0
- package/esm/BaseLinearDisplay/model.js +3 -3
- package/esm/BaseLinearDisplay/util.d.ts +1 -0
- package/esm/BaseLinearDisplay/util.js +11 -1
- package/esm/LinearBareDisplay/model.d.ts +9 -0
- package/esm/LinearBasicDisplay/model.d.ts +14 -1
- package/esm/LinearFeatureDisplay/model.d.ts +14 -1
- package/esm/LinearFeatureDisplay/model.js +31 -1
- package/esm/LinearGenomeView/components/HeaderRegionWidth.js +2 -2
- package/esm/LinearGenomeView/components/HeaderZoomControls.js +5 -5
- package/esm/LinearGenomeView/components/MiniControls.js +3 -3
- package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +4 -2
- package/esm/LinearGenomeView/components/Rubberband.js +3 -3
- package/esm/LinearGenomeView/components/Scalebar.d.ts +1 -1
- package/esm/LinearGenomeView/components/Scalebar.js +3 -4
- package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +126 -4
- package/esm/LinearGenomeView/components/TrackLabel.d.ts +1 -1
- package/esm/LinearGenomeView/components/TrackLabel.js +3 -4
- package/esm/LinearGenomeView/components/TracksContainer.js +2 -2
- package/esm/LinearGenomeView/components/useRangeSelect.d.ts +1 -1
- package/esm/LinearGenomeView/components/useRangeSelect.js +28 -4
- package/esm/LinearGenomeView/model.d.ts +11 -2
- package/esm/LinearGenomeView/model.js +48 -16
- package/esm/LinearGenomeView/util.d.ts +6 -2
- package/esm/LinearGenomeView/util.js +17 -18
- package/esm/index.d.ts +9 -0
- package/package.json +3 -3
|
@@ -11,7 +11,7 @@ const Tooltip = observer(function Tooltip({ model, clientMouseCoord, }) {
|
|
|
11
11
|
const { featureUnderMouse, featureIdUnderMouse, mouseoverExtraInformation } = model;
|
|
12
12
|
const x = clientMouseCoord[0] + 15;
|
|
13
13
|
const y = clientMouseCoord[1];
|
|
14
|
-
const contents = useMemo(() => featureUnderMouse
|
|
14
|
+
const contents = useMemo(() => featureUnderMouse && mouseoverExtraInformation
|
|
15
15
|
? getConf(model, 'mouseover', {
|
|
16
16
|
feature: featureUnderMouse,
|
|
17
17
|
mouseoverExtraInformation,
|
|
@@ -139,6 +139,7 @@ export declare const BaseLinearDisplay: import("@jbrowse/mobx-state-tree").IMode
|
|
|
139
139
|
}> | null;
|
|
140
140
|
readonly adapterConfig: any;
|
|
141
141
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
142
|
+
readonly isMinimized: boolean;
|
|
142
143
|
readonly parentDisplay: any;
|
|
143
144
|
readonly effectiveRpcDriverName: any;
|
|
144
145
|
} & {
|
|
@@ -195,6 +196,7 @@ export declare const BaseLinearDisplay: import("@jbrowse/mobx-state-tree").IMode
|
|
|
195
196
|
}> | null;
|
|
196
197
|
readonly adapterConfig: any;
|
|
197
198
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
199
|
+
readonly isMinimized: boolean;
|
|
198
200
|
readonly parentDisplay: any;
|
|
199
201
|
readonly effectiveRpcDriverName: any;
|
|
200
202
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -248,6 +250,7 @@ export declare const BaseLinearDisplay: import("@jbrowse/mobx-state-tree").IMode
|
|
|
248
250
|
}> | null;
|
|
249
251
|
readonly adapterConfig: any;
|
|
250
252
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
253
|
+
readonly isMinimized: boolean;
|
|
251
254
|
readonly parentDisplay: any;
|
|
252
255
|
readonly effectiveRpcDriverName: any;
|
|
253
256
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -529,6 +532,7 @@ export declare const BaseLinearDisplay: import("@jbrowse/mobx-state-tree").IMode
|
|
|
529
532
|
}> | null;
|
|
530
533
|
readonly adapterConfig: any;
|
|
531
534
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
535
|
+
readonly isMinimized: boolean;
|
|
532
536
|
readonly parentDisplay: any;
|
|
533
537
|
readonly effectiveRpcDriverName: any;
|
|
534
538
|
} & {
|
|
@@ -585,6 +589,7 @@ export declare const BaseLinearDisplay: import("@jbrowse/mobx-state-tree").IMode
|
|
|
585
589
|
}> | null;
|
|
586
590
|
readonly adapterConfig: any;
|
|
587
591
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
592
|
+
readonly isMinimized: boolean;
|
|
588
593
|
readonly parentDisplay: any;
|
|
589
594
|
readonly effectiveRpcDriverName: any;
|
|
590
595
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -638,6 +643,7 @@ export declare const BaseLinearDisplay: import("@jbrowse/mobx-state-tree").IMode
|
|
|
638
643
|
}> | null;
|
|
639
644
|
readonly adapterConfig: any;
|
|
640
645
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
646
|
+
readonly isMinimized: boolean;
|
|
641
647
|
readonly parentDisplay: any;
|
|
642
648
|
readonly effectiveRpcDriverName: any;
|
|
643
649
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -864,6 +870,7 @@ export declare const BaseLinearDisplay: import("@jbrowse/mobx-state-tree").IMode
|
|
|
864
870
|
}> | null;
|
|
865
871
|
readonly adapterConfig: any;
|
|
866
872
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
873
|
+
readonly isMinimized: boolean;
|
|
867
874
|
readonly parentDisplay: any;
|
|
868
875
|
readonly effectiveRpcDriverName: any;
|
|
869
876
|
} & {
|
|
@@ -920,6 +927,7 @@ export declare const BaseLinearDisplay: import("@jbrowse/mobx-state-tree").IMode
|
|
|
920
927
|
}> | null;
|
|
921
928
|
readonly adapterConfig: any;
|
|
922
929
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
930
|
+
readonly isMinimized: boolean;
|
|
923
931
|
readonly parentDisplay: any;
|
|
924
932
|
readonly effectiveRpcDriverName: any;
|
|
925
933
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -973,6 +981,7 @@ export declare const BaseLinearDisplay: import("@jbrowse/mobx-state-tree").IMode
|
|
|
973
981
|
}> | null;
|
|
974
982
|
readonly adapterConfig: any;
|
|
975
983
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
984
|
+
readonly isMinimized: boolean;
|
|
976
985
|
readonly parentDisplay: any;
|
|
977
986
|
readonly effectiveRpcDriverName: any;
|
|
978
987
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -16,7 +16,7 @@ import FeatureDensityMixin from "./models/FeatureDensityMixin.js";
|
|
|
16
16
|
import TrackHeightMixin from "./models/TrackHeightMixin.js";
|
|
17
17
|
import configSchema from "./models/configSchema.js";
|
|
18
18
|
import BlockState from "./models/serverSideRenderedBlock.js";
|
|
19
|
-
import { fetchFeatureByIdRpc, findSubfeatureById, getTranscripts,
|
|
19
|
+
import { fetchFeatureByIdRpc, findSubfeatureById, getTranscripts, hasIntrons, } from "./util.js";
|
|
20
20
|
const Tooltip = lazy(() => import("./components/Tooltip.js"));
|
|
21
21
|
const CollapseIntronsDialog = lazy(() => import("./components/CollapseIntronsDialog/CollapseIntronsDialog.js"));
|
|
22
22
|
function stateModelFactory() {
|
|
@@ -321,7 +321,7 @@ function stateModelFactory() {
|
|
|
321
321
|
session.notify('Copied to clipboard', 'success');
|
|
322
322
|
},
|
|
323
323
|
},
|
|
324
|
-
...(
|
|
324
|
+
...(hasIntrons(transcripts)
|
|
325
325
|
? [
|
|
326
326
|
{
|
|
327
327
|
label: 'Collapse introns',
|
|
@@ -379,7 +379,7 @@ function stateModelFactory() {
|
|
|
379
379
|
afterAttach() {
|
|
380
380
|
addDisposer(self, autorun(function blockDefinitionsAutorun() {
|
|
381
381
|
try {
|
|
382
|
-
if (!isAlive(self)) {
|
|
382
|
+
if (!isAlive(self) || self.isMinimized) {
|
|
383
383
|
return;
|
|
384
384
|
}
|
|
385
385
|
const view = getContainingView(self);
|
|
@@ -11,5 +11,6 @@ export declare function fetchFeatureByIdRpc({ rpcManager, sessionId, trackId, re
|
|
|
11
11
|
export declare function findSubfeatureById(feature: Feature, targetId: string): Feature | undefined;
|
|
12
12
|
export declare function featureHasExonsOrCDS(feature: Feature): boolean;
|
|
13
13
|
export declare function hasExonsOrCDS(transcripts: Feature[]): boolean;
|
|
14
|
+
export declare function hasIntrons(transcripts: Feature[]): boolean;
|
|
14
15
|
export declare function getTranscripts(feature?: Feature): Feature[];
|
|
15
16
|
export declare function drawCanvasImageData(canvas: HTMLCanvasElement | null, imageData: ImageBitmap | undefined): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SimpleFeature } from '@jbrowse/core/util';
|
|
1
|
+
import { SimpleFeature, mergeIntervals } from '@jbrowse/core/util';
|
|
2
2
|
export async function fetchFeatureByIdRpc({ rpcManager, sessionId, trackId, rendererType, featureId, parentFeatureId, }) {
|
|
3
3
|
const lookupId = parentFeatureId || featureId;
|
|
4
4
|
const { feature: featureData } = (await rpcManager.call(sessionId, 'CoreGetFeatureDetails', {
|
|
@@ -38,6 +38,16 @@ export function featureHasExonsOrCDS(feature) {
|
|
|
38
38
|
export function hasExonsOrCDS(transcripts) {
|
|
39
39
|
return transcripts.some(t => featureHasExonsOrCDS(t));
|
|
40
40
|
}
|
|
41
|
+
export function hasIntrons(transcripts) {
|
|
42
|
+
const subs = transcripts.flatMap(transcript => transcript
|
|
43
|
+
.get('subfeatures')
|
|
44
|
+
?.filter((f) => f.get('type') === 'exon' || f.get('type') === 'CDS') ?? []);
|
|
45
|
+
if (subs.length < 2) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const merged = mergeIntervals(subs.map((f) => ({ start: f.get('start'), end: f.get('end') })), 0);
|
|
49
|
+
return merged.length > 1;
|
|
50
|
+
}
|
|
41
51
|
export function getTranscripts(feature) {
|
|
42
52
|
if (!feature) {
|
|
43
53
|
return [];
|
|
@@ -134,6 +134,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
134
134
|
}> | null;
|
|
135
135
|
readonly adapterConfig: any;
|
|
136
136
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
137
|
+
readonly isMinimized: boolean;
|
|
137
138
|
readonly parentDisplay: any;
|
|
138
139
|
readonly effectiveRpcDriverName: any;
|
|
139
140
|
} & {
|
|
@@ -190,6 +191,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
190
191
|
}> | null;
|
|
191
192
|
readonly adapterConfig: any;
|
|
192
193
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
194
|
+
readonly isMinimized: boolean;
|
|
193
195
|
readonly parentDisplay: any;
|
|
194
196
|
readonly effectiveRpcDriverName: any;
|
|
195
197
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -243,6 +245,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
243
245
|
}> | null;
|
|
244
246
|
readonly adapterConfig: any;
|
|
245
247
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
248
|
+
readonly isMinimized: boolean;
|
|
246
249
|
readonly parentDisplay: any;
|
|
247
250
|
readonly effectiveRpcDriverName: any;
|
|
248
251
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -524,6 +527,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
524
527
|
}> | null;
|
|
525
528
|
readonly adapterConfig: any;
|
|
526
529
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
530
|
+
readonly isMinimized: boolean;
|
|
527
531
|
readonly parentDisplay: any;
|
|
528
532
|
readonly effectiveRpcDriverName: any;
|
|
529
533
|
} & {
|
|
@@ -580,6 +584,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
580
584
|
}> | null;
|
|
581
585
|
readonly adapterConfig: any;
|
|
582
586
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
587
|
+
readonly isMinimized: boolean;
|
|
583
588
|
readonly parentDisplay: any;
|
|
584
589
|
readonly effectiveRpcDriverName: any;
|
|
585
590
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -633,6 +638,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
633
638
|
}> | null;
|
|
634
639
|
readonly adapterConfig: any;
|
|
635
640
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
641
|
+
readonly isMinimized: boolean;
|
|
636
642
|
readonly parentDisplay: any;
|
|
637
643
|
readonly effectiveRpcDriverName: any;
|
|
638
644
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -859,6 +865,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
859
865
|
}> | null;
|
|
860
866
|
readonly adapterConfig: any;
|
|
861
867
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
868
|
+
readonly isMinimized: boolean;
|
|
862
869
|
readonly parentDisplay: any;
|
|
863
870
|
readonly effectiveRpcDriverName: any;
|
|
864
871
|
} & {
|
|
@@ -915,6 +922,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
915
922
|
}> | null;
|
|
916
923
|
readonly adapterConfig: any;
|
|
917
924
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
925
|
+
readonly isMinimized: boolean;
|
|
918
926
|
readonly parentDisplay: any;
|
|
919
927
|
readonly effectiveRpcDriverName: any;
|
|
920
928
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -968,6 +976,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
968
976
|
}> | null;
|
|
969
977
|
readonly adapterConfig: any;
|
|
970
978
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
979
|
+
readonly isMinimized: boolean;
|
|
971
980
|
readonly parentDisplay: any;
|
|
972
981
|
readonly effectiveRpcDriverName: any;
|
|
973
982
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -147,6 +147,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
147
147
|
}> | null;
|
|
148
148
|
readonly adapterConfig: any;
|
|
149
149
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
150
|
+
readonly isMinimized: boolean;
|
|
150
151
|
readonly parentDisplay: any;
|
|
151
152
|
readonly effectiveRpcDriverName: any;
|
|
152
153
|
} & {
|
|
@@ -203,6 +204,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
203
204
|
}> | null;
|
|
204
205
|
readonly adapterConfig: any;
|
|
205
206
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
207
|
+
readonly isMinimized: boolean;
|
|
206
208
|
readonly parentDisplay: any;
|
|
207
209
|
readonly effectiveRpcDriverName: any;
|
|
208
210
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -256,6 +258,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
256
258
|
}> | null;
|
|
257
259
|
readonly adapterConfig: any;
|
|
258
260
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
261
|
+
readonly isMinimized: boolean;
|
|
259
262
|
readonly parentDisplay: any;
|
|
260
263
|
readonly effectiveRpcDriverName: any;
|
|
261
264
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -537,6 +540,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
537
540
|
}> | null;
|
|
538
541
|
readonly adapterConfig: any;
|
|
539
542
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
543
|
+
readonly isMinimized: boolean;
|
|
540
544
|
readonly parentDisplay: any;
|
|
541
545
|
readonly effectiveRpcDriverName: any;
|
|
542
546
|
} & {
|
|
@@ -593,6 +597,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
593
597
|
}> | null;
|
|
594
598
|
readonly adapterConfig: any;
|
|
595
599
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
600
|
+
readonly isMinimized: boolean;
|
|
596
601
|
readonly parentDisplay: any;
|
|
597
602
|
readonly effectiveRpcDriverName: any;
|
|
598
603
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -646,6 +651,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
646
651
|
}> | null;
|
|
647
652
|
readonly adapterConfig: any;
|
|
648
653
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
654
|
+
readonly isMinimized: boolean;
|
|
649
655
|
readonly parentDisplay: any;
|
|
650
656
|
readonly effectiveRpcDriverName: any;
|
|
651
657
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -872,6 +878,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
872
878
|
}> | null;
|
|
873
879
|
readonly adapterConfig: any;
|
|
874
880
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
881
|
+
readonly isMinimized: boolean;
|
|
875
882
|
readonly parentDisplay: any;
|
|
876
883
|
readonly effectiveRpcDriverName: any;
|
|
877
884
|
} & {
|
|
@@ -928,6 +935,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
928
935
|
}> | null;
|
|
929
936
|
readonly adapterConfig: any;
|
|
930
937
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
938
|
+
readonly isMinimized: boolean;
|
|
931
939
|
readonly parentDisplay: any;
|
|
932
940
|
readonly effectiveRpcDriverName: any;
|
|
933
941
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -981,6 +989,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
981
989
|
}> | null;
|
|
982
990
|
readonly adapterConfig: any;
|
|
983
991
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
992
|
+
readonly isMinimized: boolean;
|
|
984
993
|
readonly parentDisplay: any;
|
|
985
994
|
readonly effectiveRpcDriverName: any;
|
|
986
995
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -1087,7 +1096,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
1087
1096
|
} & {
|
|
1088
1097
|
featureUnderMouseVolatile: import("@jbrowse/core/util").Feature | undefined;
|
|
1089
1098
|
} & {
|
|
1090
|
-
readonly activeFilters:
|
|
1099
|
+
readonly activeFilters: string[];
|
|
1091
1100
|
readonly rendererTypeName: any;
|
|
1092
1101
|
readonly sequenceAdapter: any;
|
|
1093
1102
|
readonly showLabels: any;
|
|
@@ -1175,6 +1184,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
1175
1184
|
}> | null;
|
|
1176
1185
|
readonly adapterConfig: any;
|
|
1177
1186
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
1187
|
+
readonly isMinimized: boolean;
|
|
1178
1188
|
readonly parentDisplay: any;
|
|
1179
1189
|
readonly effectiveRpcDriverName: any;
|
|
1180
1190
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -1228,11 +1238,14 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
1228
1238
|
}> | null;
|
|
1229
1239
|
readonly adapterConfig: any;
|
|
1230
1240
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
1241
|
+
readonly isMinimized: boolean;
|
|
1231
1242
|
readonly parentDisplay: any;
|
|
1232
1243
|
readonly effectiveRpcDriverName: any;
|
|
1233
1244
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
1234
1245
|
};
|
|
1235
1246
|
trackMenuItems(): MenuItem[];
|
|
1247
|
+
} & {
|
|
1248
|
+
afterAttach(): void;
|
|
1236
1249
|
} & {
|
|
1237
1250
|
readonly geneGlyphMode: any;
|
|
1238
1251
|
readonly subfeatureLabels: any;
|
|
@@ -143,6 +143,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
143
143
|
}> | null;
|
|
144
144
|
readonly adapterConfig: any;
|
|
145
145
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
146
|
+
readonly isMinimized: boolean;
|
|
146
147
|
readonly parentDisplay: any;
|
|
147
148
|
readonly effectiveRpcDriverName: any;
|
|
148
149
|
} & {
|
|
@@ -199,6 +200,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
199
200
|
}> | null;
|
|
200
201
|
readonly adapterConfig: any;
|
|
201
202
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
203
|
+
readonly isMinimized: boolean;
|
|
202
204
|
readonly parentDisplay: any;
|
|
203
205
|
readonly effectiveRpcDriverName: any;
|
|
204
206
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -252,6 +254,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
252
254
|
}> | null;
|
|
253
255
|
readonly adapterConfig: any;
|
|
254
256
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
257
|
+
readonly isMinimized: boolean;
|
|
255
258
|
readonly parentDisplay: any;
|
|
256
259
|
readonly effectiveRpcDriverName: any;
|
|
257
260
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -533,6 +536,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
533
536
|
}> | null;
|
|
534
537
|
readonly adapterConfig: any;
|
|
535
538
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
539
|
+
readonly isMinimized: boolean;
|
|
536
540
|
readonly parentDisplay: any;
|
|
537
541
|
readonly effectiveRpcDriverName: any;
|
|
538
542
|
} & {
|
|
@@ -589,6 +593,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
589
593
|
}> | null;
|
|
590
594
|
readonly adapterConfig: any;
|
|
591
595
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
596
|
+
readonly isMinimized: boolean;
|
|
592
597
|
readonly parentDisplay: any;
|
|
593
598
|
readonly effectiveRpcDriverName: any;
|
|
594
599
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -642,6 +647,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
642
647
|
}> | null;
|
|
643
648
|
readonly adapterConfig: any;
|
|
644
649
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
650
|
+
readonly isMinimized: boolean;
|
|
645
651
|
readonly parentDisplay: any;
|
|
646
652
|
readonly effectiveRpcDriverName: any;
|
|
647
653
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -868,6 +874,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
868
874
|
}> | null;
|
|
869
875
|
readonly adapterConfig: any;
|
|
870
876
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
877
|
+
readonly isMinimized: boolean;
|
|
871
878
|
readonly parentDisplay: any;
|
|
872
879
|
readonly effectiveRpcDriverName: any;
|
|
873
880
|
} & {
|
|
@@ -924,6 +931,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
924
931
|
}> | null;
|
|
925
932
|
readonly adapterConfig: any;
|
|
926
933
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
934
|
+
readonly isMinimized: boolean;
|
|
927
935
|
readonly parentDisplay: any;
|
|
928
936
|
readonly effectiveRpcDriverName: any;
|
|
929
937
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -977,6 +985,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
977
985
|
}> | null;
|
|
978
986
|
readonly adapterConfig: any;
|
|
979
987
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
988
|
+
readonly isMinimized: boolean;
|
|
980
989
|
readonly parentDisplay: any;
|
|
981
990
|
readonly effectiveRpcDriverName: any;
|
|
982
991
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -1083,7 +1092,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
1083
1092
|
} & {
|
|
1084
1093
|
featureUnderMouseVolatile: Feature | undefined;
|
|
1085
1094
|
} & {
|
|
1086
|
-
readonly activeFilters:
|
|
1095
|
+
readonly activeFilters: string[];
|
|
1087
1096
|
readonly rendererTypeName: any;
|
|
1088
1097
|
readonly sequenceAdapter: any;
|
|
1089
1098
|
readonly showLabels: any;
|
|
@@ -1171,6 +1180,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
1171
1180
|
}> | null;
|
|
1172
1181
|
readonly adapterConfig: any;
|
|
1173
1182
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
1183
|
+
readonly isMinimized: boolean;
|
|
1174
1184
|
readonly parentDisplay: any;
|
|
1175
1185
|
readonly effectiveRpcDriverName: any;
|
|
1176
1186
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -1224,11 +1234,14 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
1224
1234
|
}> | null;
|
|
1225
1235
|
readonly adapterConfig: any;
|
|
1226
1236
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
1237
|
+
readonly isMinimized: boolean;
|
|
1227
1238
|
readonly parentDisplay: any;
|
|
1228
1239
|
readonly effectiveRpcDriverName: any;
|
|
1229
1240
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
1230
1241
|
};
|
|
1231
1242
|
trackMenuItems(): MenuItem[];
|
|
1243
|
+
} & {
|
|
1244
|
+
afterAttach(): void;
|
|
1232
1245
|
}, {
|
|
1233
1246
|
type: string;
|
|
1234
1247
|
} & Partial<import("@jbrowse/mobx-state-tree/dist/internal").ExtractCFromProps<{
|
|
@@ -3,8 +3,9 @@ import { ConfigurationReference, getConf, readConfObject, } from '@jbrowse/core/
|
|
|
3
3
|
import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
|
|
4
4
|
import { SimpleFeature, getSession } from '@jbrowse/core/util';
|
|
5
5
|
import { getRpcSessionId } from '@jbrowse/core/util/tracks';
|
|
6
|
-
import { cast, getParent, isAlive, types } from '@jbrowse/mobx-state-tree';
|
|
6
|
+
import { addDisposer, cast, getParent, isAlive, types, } from '@jbrowse/mobx-state-tree';
|
|
7
7
|
import VisibilityIcon from '@mui/icons-material/Visibility';
|
|
8
|
+
import { reaction } from 'mobx';
|
|
8
9
|
import { BaseLinearDisplay } from "../BaseLinearDisplay/index.js";
|
|
9
10
|
const SetMaxHeightDialog = lazy(() => import("./components/SetMaxHeightDialog.js"));
|
|
10
11
|
const AddFiltersDialog = lazy(() => import("./components/AddFiltersDialog.js"));
|
|
@@ -245,6 +246,35 @@ function stateModelFactory(configSchema) {
|
|
|
245
246
|
},
|
|
246
247
|
};
|
|
247
248
|
})
|
|
249
|
+
.actions(self => ({
|
|
250
|
+
afterAttach() {
|
|
251
|
+
addDisposer(self, reaction(() => self.featureIdUnderMouse, async (featureId) => {
|
|
252
|
+
if (!featureId) {
|
|
253
|
+
self.setFeatureUnderMouse(undefined);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const session = getSession(self);
|
|
257
|
+
const { rpcManager } = session;
|
|
258
|
+
const { parentTrack } = self;
|
|
259
|
+
try {
|
|
260
|
+
const sessionId = getRpcSessionId(self);
|
|
261
|
+
const { feature } = (await rpcManager.call(sessionId, 'CoreGetFeatureDetails', {
|
|
262
|
+
featureId,
|
|
263
|
+
sessionId,
|
|
264
|
+
trackInstanceId: parentTrack.id,
|
|
265
|
+
rendererType: self.rendererTypeName,
|
|
266
|
+
}));
|
|
267
|
+
if (isAlive(self) &&
|
|
268
|
+
feature &&
|
|
269
|
+
self.featureIdUnderMouse === featureId) {
|
|
270
|
+
self.setFeatureUnderMouse(new SimpleFeature(feature));
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
catch (e) {
|
|
274
|
+
}
|
|
275
|
+
}, { delay: 50, name: 'LinearFeatureDisplayMouseoverReaction' }));
|
|
276
|
+
},
|
|
277
|
+
}))
|
|
248
278
|
.postProcessSnapshot(snap => {
|
|
249
279
|
if (!snap) {
|
|
250
280
|
return snap;
|
|
@@ -12,7 +12,7 @@ const useStyles = makeStyles()({
|
|
|
12
12
|
});
|
|
13
13
|
const HeaderRegionWidth = observer(function HeaderRegionWidth({ model, }) {
|
|
14
14
|
const { classes } = useStyles();
|
|
15
|
-
const {
|
|
16
|
-
return (_jsx(Typography, { variant: "body2", color: "textSecondary", className: classes.bp, children:
|
|
15
|
+
const { effectiveTotalBpDisplayStr } = model;
|
|
16
|
+
return (_jsx(Typography, { variant: "body2", color: "textSecondary", className: classes.bp, children: effectiveTotalBpDisplayStr }));
|
|
17
17
|
});
|
|
18
18
|
export default HeaderRegionWidth;
|
|
@@ -26,13 +26,13 @@ function ValueLabelComponent(props) {
|
|
|
26
26
|
}
|
|
27
27
|
const HeaderZoomControls = observer(function HeaderZoomControls({ model, }) {
|
|
28
28
|
const { classes } = useStyles();
|
|
29
|
-
const { width, maxBpPerPx, minBpPerPx, bpPerPx } = model;
|
|
29
|
+
const { width, maxBpPerPx, minBpPerPx, bpPerPx, effectiveBpPerPx } = model;
|
|
30
30
|
const [value, setValue] = useState(-Math.log2(bpPerPx) * 100);
|
|
31
31
|
useEffect(() => {
|
|
32
|
-
setValue(-Math.log2(
|
|
33
|
-
}, [
|
|
34
|
-
const zoomInDisabled =
|
|
35
|
-
const zoomOutDisabled =
|
|
32
|
+
setValue(-Math.log2(effectiveBpPerPx) * 100);
|
|
33
|
+
}, [effectiveBpPerPx]);
|
|
34
|
+
const zoomInDisabled = effectiveBpPerPx <= minBpPerPx + 0.0001;
|
|
35
|
+
const zoomOutDisabled = effectiveBpPerPx >= maxBpPerPx - 0.0001;
|
|
36
36
|
return (_jsxs("div", { className: classes.container, children: [_jsx(Tooltip, { title: "Zoom out 2x", children: _jsx("span", { children: _jsx(IconButton, { "data-testid": "zoom_out", disabled: zoomOutDisabled, onClick: () => {
|
|
37
37
|
model.zoom(bpPerPx * 2);
|
|
38
38
|
}, children: _jsx(ZoomOut, {}) }) }) }), _jsx(Slider, { size: "small", className: classes.slider, value: value, min: -Math.log2(maxBpPerPx) * 100, max: -Math.log2(minBpPerPx) * 100, onChangeCommitted: () => model.zoomTo(2 ** (-value / 100)), valueLabelDisplay: "auto", valueLabelFormat: newValue => `Window size: ${getBpDisplayStr(2 ** (-newValue / 100) * width)}`, slots: {
|
|
@@ -20,12 +20,12 @@ const useStyles = makeStyles()(theme => ({
|
|
|
20
20
|
}));
|
|
21
21
|
const MiniControls = observer(function MiniControls({ model, }) {
|
|
22
22
|
const { classes } = useStyles();
|
|
23
|
-
const { id, bpPerPx, maxBpPerPx, minBpPerPx, hideHeader } = model;
|
|
23
|
+
const { id, bpPerPx, maxBpPerPx, minBpPerPx, hideHeader, effectiveBpPerPx } = model;
|
|
24
24
|
const { focusedViewId } = getSession(model);
|
|
25
25
|
return hideHeader ? (_jsx(Paper, { className: classes.background, children: _jsxs(Paper, { className: focusedViewId === id ? classes.focusedBackground : undefined, children: [_jsx(CascadingMenuButton, { menuItems: () => model.menuItems(), children: _jsx(ArrowDown, { fontSize: "small" }) }), _jsx(IconButton, { "data-testid": "zoom_out", onClick: () => {
|
|
26
26
|
model.zoom(bpPerPx * 2);
|
|
27
|
-
}, disabled:
|
|
27
|
+
}, disabled: effectiveBpPerPx >= maxBpPerPx - 0.0001, children: _jsx(ZoomOut, { fontSize: "small" }) }), _jsx(IconButton, { "data-testid": "zoom_in", onClick: () => {
|
|
28
28
|
model.zoom(bpPerPx / 2);
|
|
29
|
-
}, disabled:
|
|
29
|
+
}, disabled: effectiveBpPerPx <= minBpPerPx + 0.0001, children: _jsx(ZoomIn, { fontSize: "small" }) })] }) })) : null;
|
|
30
30
|
});
|
|
31
31
|
export default MiniControls;
|
|
@@ -2,11 +2,13 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { TextField } from '@mui/material';
|
|
3
3
|
export default function AutocompleteTextField({ TextFieldProps, inputBoxVal, params, setInputValue, setCurrentSearch, }) {
|
|
4
4
|
const { helperText, slotProps = {} } = TextFieldProps;
|
|
5
|
+
const { ref: inputRef, ...restInputProps } = params.InputProps;
|
|
6
|
+
const { InputProps: _InputProps, ...restParams } = params;
|
|
5
7
|
return (_jsx(TextField, { onBlur: () => {
|
|
6
8
|
setInputValue(inputBoxVal);
|
|
7
|
-
}, ...
|
|
9
|
+
}, ...restParams, ...TextFieldProps, inputRef: inputRef, size: "small", helperText: helperText, slotProps: {
|
|
8
10
|
input: {
|
|
9
|
-
...
|
|
11
|
+
...restInputProps,
|
|
10
12
|
...slotProps.input,
|
|
11
13
|
},
|
|
12
14
|
}, placeholder: "Search for location", onChange: e => {
|
|
@@ -17,10 +17,10 @@ const useStyles = makeStyles()({
|
|
|
17
17
|
const Rubberband = observer(function Rubberband({ model, ControlComponent = _jsx("div", {}), }) {
|
|
18
18
|
const ref = useRef(null);
|
|
19
19
|
const { classes } = useStyles();
|
|
20
|
-
const { stickyViewHeaders, rubberbandTop } = model;
|
|
20
|
+
const { stickyViewHeaders, rubberbandTop, isScalebarRefNameMenuOpen } = model;
|
|
21
21
|
const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, open, isClick, clickBpOffset, handleMenuItemClick, handleClose, mouseMove, mouseDown, mouseOut, } = useRangeSelect(ref, model);
|
|
22
|
-
return (_jsxs(_Fragment, { children: [guideX !== undefined ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberbandOn ? (_jsx(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: rubberbandTop, sticky: stickyViewHeaders })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
|
|
23
|
-
left: anchorPosition.clientX,
|
|
22
|
+
return (_jsxs(_Fragment, { children: [guideX !== undefined && !isScalebarRefNameMenuOpen ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberbandOn ? (_jsx(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: rubberbandTop, sticky: stickyViewHeaders })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
|
|
23
|
+
left: anchorPosition.clientX + 10,
|
|
24
24
|
top: anchorPosition.clientY,
|
|
25
25
|
}, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: isClick && clickBpOffset
|
|
26
26
|
? model.rubberbandClickMenuItems(clickBpOffset)
|
|
@@ -6,5 +6,5 @@ interface ScalebarProps {
|
|
|
6
6
|
style?: React.CSSProperties;
|
|
7
7
|
className?: string;
|
|
8
8
|
}
|
|
9
|
-
declare const Scalebar:
|
|
9
|
+
declare const Scalebar: ({ model, style, className, ...other }: ScalebarProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
export default Scalebar;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef } from 'react';
|
|
3
2
|
import { cx, makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
3
|
import { Paper } from '@mui/material';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
@@ -20,14 +19,14 @@ const useStyles = makeStyles()({
|
|
|
20
19
|
pointerEvents: 'none',
|
|
21
20
|
},
|
|
22
21
|
});
|
|
23
|
-
const Scalebar = observer(
|
|
22
|
+
const Scalebar = observer(function Scalebar({ model, style, className, ...other }) {
|
|
24
23
|
const { classes } = useStyles();
|
|
25
24
|
const { scaleFactor, staticBlocks, offsetPx } = model;
|
|
26
|
-
return (_jsxs(Paper, { "data-resizer": "true", className: cx(classes.container, className), variant: "outlined",
|
|
25
|
+
return (_jsxs(Paper, { "data-resizer": "true", className: cx(classes.container, className), variant: "outlined", style: { ...style, '--offset-px': `${offsetPx}px` }, ...other, children: [_jsx(Gridlines, { model: model, offset: 1 }), _jsx("div", { className: classes.zoomContainer, style: {
|
|
27
26
|
transform: scaleFactor !== 1 ? `scaleX(${scaleFactor})` : undefined,
|
|
28
27
|
}, children: _jsx("div", { className: classes.scalebar, style: {
|
|
29
28
|
transform: `translateX(calc(${staticBlocks.offsetPx}px - var(--offset-px) - 1px))`,
|
|
30
29
|
width: staticBlocks.totalWidthPx,
|
|
31
30
|
}, children: _jsx(ScalebarCoordinateLabels, { model: model }) }) }), _jsx(ScalebarRefNameLabels, { model: model })] }));
|
|
32
|
-
})
|
|
31
|
+
});
|
|
33
32
|
export default Scalebar;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Menu } from '@jbrowse/core/ui';
|
|
2
4
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
3
5
|
import { observer } from 'mobx-react';
|
|
4
6
|
const useStyles = makeStyles()(theme => ({
|
|
@@ -11,6 +13,12 @@ const useStyles = makeStyles()(theme => ({
|
|
|
11
13
|
lineHeight: 'normal',
|
|
12
14
|
zIndex: 1,
|
|
13
15
|
background: theme.palette.background.paper,
|
|
16
|
+
cursor: 'pointer',
|
|
17
|
+
overflow: 'hidden',
|
|
18
|
+
whiteSpace: 'nowrap',
|
|
19
|
+
'&:hover': {
|
|
20
|
+
background: theme.palette.grey[300],
|
|
21
|
+
},
|
|
14
22
|
},
|
|
15
23
|
b0: {
|
|
16
24
|
left: 0,
|
|
@@ -20,6 +28,10 @@ const useStyles = makeStyles()(theme => ({
|
|
|
20
28
|
const ScalebarRefNameLabels = observer(function ScalebarRefNameLabels({ model, }) {
|
|
21
29
|
const { classes, cx } = useStyles();
|
|
22
30
|
const { staticBlocks, offsetPx, scalebarDisplayPrefix } = model;
|
|
31
|
+
const [menuState, setMenuState] = useState();
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
model.setIsScalebarRefNameMenuOpen(!!menuState);
|
|
34
|
+
}, [model, menuState]);
|
|
23
35
|
let lastLeftBlock = staticBlocks.blocks.findIndex(b => b.type === 'ContentBlock');
|
|
24
36
|
if (lastLeftBlock < 0) {
|
|
25
37
|
lastLeftBlock = 0;
|
|
@@ -31,16 +43,126 @@ const ScalebarRefNameLabels = observer(function ScalebarRefNameLabels({ model, }
|
|
|
31
43
|
});
|
|
32
44
|
const val = scalebarDisplayPrefix();
|
|
33
45
|
const b0 = staticBlocks.blocks[0];
|
|
46
|
+
const regionEndPx = new Map();
|
|
47
|
+
for (const block of staticBlocks.blocks) {
|
|
48
|
+
if (block.type === 'ContentBlock' && block.regionNumber !== undefined) {
|
|
49
|
+
const endPx = block.offsetPx + block.widthPx;
|
|
50
|
+
const current = regionEndPx.get(block.regionNumber);
|
|
51
|
+
if (current === undefined || endPx > current) {
|
|
52
|
+
regionEndPx.set(block.regionNumber, endPx);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
34
56
|
return (_jsxs(_Fragment, { children: [b0?.type !== 'ContentBlock' && val ? (_jsx("span", { className: cx(classes.b0, classes.refLabel), children: val })) : null, staticBlocks.map((block, index) => {
|
|
35
|
-
const { offsetPx: blockOffsetPx, isLeftEndOfDisplayedRegion, key, type, refName, } = block;
|
|
57
|
+
const { offsetPx: blockOffsetPx, isLeftEndOfDisplayedRegion, key, type, refName, regionNumber, } = block;
|
|
36
58
|
const last = index === lastLeftBlock;
|
|
59
|
+
const regEndPx = regionNumber !== undefined ? regionEndPx.get(regionNumber) : undefined;
|
|
60
|
+
const labelStartPx = last ? offsetPx : blockOffsetPx;
|
|
61
|
+
const maxWidth = regEndPx !== undefined ? regEndPx - labelStartPx - 2 : undefined;
|
|
62
|
+
const minLabelWidth = 20;
|
|
63
|
+
const hasEnoughSpace = maxWidth === undefined || maxWidth >= minLabelWidth;
|
|
37
64
|
return type === 'ContentBlock' &&
|
|
38
|
-
(isLeftEndOfDisplayedRegion || last)
|
|
65
|
+
(isLeftEndOfDisplayedRegion || last) &&
|
|
66
|
+
hasEnoughSpace ? (_jsxs("span", { style: {
|
|
39
67
|
left: last
|
|
40
68
|
? 'max(0px, calc(-1 * var(--offset-px)))'
|
|
41
69
|
: `calc(${blockOffsetPx}px - var(--offset-px) - 1px)`,
|
|
42
70
|
paddingLeft: last ? 0 : 1,
|
|
43
|
-
|
|
44
|
-
|
|
71
|
+
maxWidth: maxWidth !== undefined && maxWidth > 0 ? maxWidth : undefined,
|
|
72
|
+
}, className: classes.refLabel, "data-testid": `refLabel-${refName}`, onMouseDown: () => {
|
|
73
|
+
model.setScalebarRefNameClickPending(true);
|
|
74
|
+
}, onClick: event => {
|
|
75
|
+
model.setScalebarRefNameClickPending(false);
|
|
76
|
+
setMenuState({
|
|
77
|
+
anchorEl: event.currentTarget,
|
|
78
|
+
refName,
|
|
79
|
+
regionNumber: regionNumber,
|
|
80
|
+
});
|
|
81
|
+
}, children: [last && val ? `${val}:` : '', refName] }, `refLabel-${key}-${index}`)) : null;
|
|
82
|
+
}), menuState ? (_jsx(RefNameMenu, { model: model, menuState: menuState, onClose: () => {
|
|
83
|
+
setMenuState(undefined);
|
|
84
|
+
} })) : null] }));
|
|
45
85
|
});
|
|
86
|
+
function RefNameMenu({ model, menuState, onClose, }) {
|
|
87
|
+
const { displayedRegions } = model;
|
|
88
|
+
const { refName, regionNumber } = menuState;
|
|
89
|
+
const numRegions = displayedRegions.length;
|
|
90
|
+
function moveRegion(fromIndex, toIndex) {
|
|
91
|
+
const regions = [...displayedRegions];
|
|
92
|
+
const [removed] = regions.splice(fromIndex, 1);
|
|
93
|
+
regions.splice(toIndex, 0, removed);
|
|
94
|
+
model.setDisplayedRegions(regions);
|
|
95
|
+
}
|
|
96
|
+
function removeRegion(index) {
|
|
97
|
+
const regions = displayedRegions.filter((_, i) => i !== index);
|
|
98
|
+
model.setDisplayedRegions(regions);
|
|
99
|
+
}
|
|
100
|
+
const actionItems = [
|
|
101
|
+
...(regionNumber > 0
|
|
102
|
+
? [
|
|
103
|
+
{
|
|
104
|
+
label: 'Move left',
|
|
105
|
+
onClick: () => {
|
|
106
|
+
moveRegion(regionNumber, regionNumber - 1);
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
]
|
|
110
|
+
: []),
|
|
111
|
+
...(regionNumber < numRegions - 1
|
|
112
|
+
? [
|
|
113
|
+
{
|
|
114
|
+
label: 'Move right',
|
|
115
|
+
onClick: () => {
|
|
116
|
+
moveRegion(regionNumber, regionNumber + 1);
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
]
|
|
120
|
+
: []),
|
|
121
|
+
...(numRegions > 2 && regionNumber > 0
|
|
122
|
+
? [
|
|
123
|
+
{
|
|
124
|
+
label: 'Move to far left',
|
|
125
|
+
onClick: () => {
|
|
126
|
+
moveRegion(regionNumber, 0);
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
]
|
|
130
|
+
: []),
|
|
131
|
+
...(numRegions > 2 && regionNumber < numRegions - 1
|
|
132
|
+
? [
|
|
133
|
+
{
|
|
134
|
+
label: 'Move to far right',
|
|
135
|
+
onClick: () => {
|
|
136
|
+
moveRegion(regionNumber, numRegions - 1);
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
]
|
|
140
|
+
: []),
|
|
141
|
+
{
|
|
142
|
+
label: 'Remove this region from view',
|
|
143
|
+
onClick: () => {
|
|
144
|
+
removeRegion(regionNumber);
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
];
|
|
148
|
+
return (_jsx(Menu, { anchorEl: menuState.anchorEl, open: true, onClose: onClose, onMenuItemClick: (_, callback) => {
|
|
149
|
+
callback();
|
|
150
|
+
onClose();
|
|
151
|
+
}, menuItems: [
|
|
152
|
+
{
|
|
153
|
+
label: `Focus on ${refName}`,
|
|
154
|
+
onClick: () => {
|
|
155
|
+
model.navTo({ refName });
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
...(numRegions > 1
|
|
159
|
+
? [
|
|
160
|
+
{
|
|
161
|
+
label: 'Actions',
|
|
162
|
+
subMenu: actionItems,
|
|
163
|
+
},
|
|
164
|
+
]
|
|
165
|
+
: []),
|
|
166
|
+
] }));
|
|
167
|
+
}
|
|
46
168
|
export default ScalebarRefNameLabels;
|
|
@@ -3,5 +3,5 @@ interface Props {
|
|
|
3
3
|
track: BaseTrackModel;
|
|
4
4
|
className?: string;
|
|
5
5
|
}
|
|
6
|
-
declare const TrackLabel:
|
|
6
|
+
declare const TrackLabel: ({ track, className }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
7
|
export default TrackLabel;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef } from 'react';
|
|
3
2
|
import { SanitizedHTML } from '@jbrowse/core/ui';
|
|
4
3
|
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
5
4
|
import { getTrackName } from '@jbrowse/core/util/tracks';
|
|
@@ -27,17 +26,17 @@ const useStyles = makeStyles()(theme => ({
|
|
|
27
26
|
padding: theme.spacing(1),
|
|
28
27
|
},
|
|
29
28
|
}));
|
|
30
|
-
const TrackLabel = observer(
|
|
29
|
+
const TrackLabel = observer(function TrackLabel({ track, className }) {
|
|
31
30
|
const { classes } = useStyles();
|
|
32
31
|
const view = getContainingView(track);
|
|
33
32
|
const session = getSession(track);
|
|
34
33
|
const { minimized } = track;
|
|
35
34
|
const trackId = track.trackId;
|
|
36
35
|
const trackName = getTrackName(track.configuration, session);
|
|
37
|
-
return (_jsxs(Paper, {
|
|
36
|
+
return (_jsxs(Paper, { className: cx(className, classes.root), onClick: event => {
|
|
38
37
|
event.stopPropagation();
|
|
39
38
|
}, children: [_jsx(TrackLabelDragHandle, { track: track, trackId: trackId, view: view }), _jsx(IconButton, { onClick: () => view.hideTrack(trackId), className: classes.iconButton, title: "close this track", children: _jsx(CloseIcon, { fontSize: "small" }) }), _jsx(Typography, { variant: "body1", component: "span", className: classes.trackName, children: _jsx(SanitizedHTML, { html: [trackName, minimized ? '(minimized)' : '']
|
|
40
39
|
.filter(f => !!f)
|
|
41
40
|
.join(' ') }) }), _jsx(TrackLabelMenu, { track: track })] }));
|
|
42
|
-
})
|
|
41
|
+
});
|
|
43
42
|
export default TrackLabel;
|
|
@@ -25,7 +25,7 @@ const TracksContainer = observer(function TracksContainer({ children, model, })
|
|
|
25
25
|
const { classes } = useStyles();
|
|
26
26
|
const { pluginManager } = getEnv(model);
|
|
27
27
|
const { mouseDown: mouseDown1, mouseUp } = useSideScroll(model);
|
|
28
|
-
const { stickyViewHeaders, rubberbandTop, showGridlines, showCenterLine } = model;
|
|
28
|
+
const { stickyViewHeaders, rubberbandTop, showGridlines, showCenterLine, isScalebarRefNameMenuOpen, } = model;
|
|
29
29
|
const ref = useRef(null);
|
|
30
30
|
const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, open, isClick, clickBpOffset, handleMenuItemClick, handleClose, mouseMove, mouseDown: mouseDown2, } = useRangeSelect(ref, model, true);
|
|
31
31
|
useWheelScroll(ref, model);
|
|
@@ -33,7 +33,7 @@ const TracksContainer = observer(function TracksContainer({ children, model, })
|
|
|
33
33
|
return (_jsxs("div", { ref: ref, "data-testid": "tracksContainer", className: classes.tracksContainer, style: { '--offset-px': `${model.offsetPx}px` }, onMouseDown: event => {
|
|
34
34
|
mouseDown1(event);
|
|
35
35
|
mouseDown2(event);
|
|
36
|
-
}, onMouseMove: mouseMove, onMouseUp: mouseUp, children: [showGridlines ? _jsx(Gridlines, { model: model }) : null, _jsx(Suspense, { fallback: null, children: showCenterLine ? _jsx(CenterLine, { model: model }) : null }), guideX !== undefined ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberbandOn ? (_jsx(Suspense, { fallback: null, children: _jsx(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: rubberbandTop, sticky: stickyViewHeaders }) })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
|
|
36
|
+
}, onMouseMove: mouseMove, onMouseUp: mouseUp, children: [showGridlines ? _jsx(Gridlines, { model: model }) : null, _jsx(Suspense, { fallback: null, children: showCenterLine ? _jsx(CenterLine, { model: model }) : null }), guideX !== undefined && !isScalebarRefNameMenuOpen ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberbandOn ? (_jsx(Suspense, { fallback: null, children: _jsx(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: rubberbandTop, sticky: stickyViewHeaders }) })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
|
|
37
37
|
left: anchorPosition.clientX,
|
|
38
38
|
top: anchorPosition.clientY,
|
|
39
39
|
}, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: isClick && clickBpOffset
|
|
@@ -47,6 +47,7 @@ export declare function useRangeSelect(ref: React.RefObject<HTMLDivElement | nul
|
|
|
47
47
|
end: number;
|
|
48
48
|
reversed?: boolean;
|
|
49
49
|
} | undefined;
|
|
50
|
+
guideX: number | undefined;
|
|
50
51
|
rubberbandOn: boolean;
|
|
51
52
|
mouseDown: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
52
53
|
mouseMove: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
@@ -79,6 +80,5 @@ export declare function useRangeSelect(ref: React.RefObject<HTMLDivElement | nul
|
|
|
79
80
|
numOfBpSelected: number;
|
|
80
81
|
width: number;
|
|
81
82
|
left: number;
|
|
82
|
-
guideX?: undefined;
|
|
83
83
|
};
|
|
84
84
|
export {};
|
|
@@ -10,6 +10,7 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
10
10
|
setAnchorPosition(undefined);
|
|
11
11
|
setStartX(undefined);
|
|
12
12
|
setCurrentX(undefined);
|
|
13
|
+
setGuideX(undefined);
|
|
13
14
|
}, []);
|
|
14
15
|
useEffect(() => {
|
|
15
16
|
function computeOffsets(offsetX) {
|
|
@@ -34,19 +35,30 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
34
35
|
const { clientX, clientY } = event;
|
|
35
36
|
const offsetX = getRelativeX(event, ref.current);
|
|
36
37
|
const isClick = Math.abs(offsetX - startX) <= 3;
|
|
38
|
+
if (isClick && model.scalebarRefNameClickPending) {
|
|
39
|
+
setStartX(undefined);
|
|
40
|
+
setCurrentX(undefined);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (!isClick && model.scalebarRefNameClickPending) {
|
|
44
|
+
model.setScalebarRefNameClickPending(false);
|
|
45
|
+
}
|
|
37
46
|
setAnchorPosition({
|
|
38
47
|
offsetX,
|
|
39
48
|
clientX,
|
|
40
49
|
clientY,
|
|
41
50
|
isClick,
|
|
42
51
|
});
|
|
43
|
-
if (
|
|
52
|
+
if (isClick) {
|
|
53
|
+
setGuideX(offsetX);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
44
56
|
const args = computeOffsets(offsetX);
|
|
45
57
|
if (args) {
|
|
46
58
|
model.setOffsets(args.leftOffset, args.rightOffset);
|
|
47
59
|
}
|
|
60
|
+
setGuideX(undefined);
|
|
48
61
|
}
|
|
49
|
-
setGuideX(undefined);
|
|
50
62
|
}
|
|
51
63
|
}
|
|
52
64
|
if (mouseDragging) {
|
|
@@ -63,6 +75,9 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
63
75
|
if (shiftOnly && !event.shiftKey) {
|
|
64
76
|
return;
|
|
65
77
|
}
|
|
78
|
+
if (model.isScalebarRefNameMenuOpen) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
66
81
|
event.preventDefault();
|
|
67
82
|
event.stopPropagation();
|
|
68
83
|
const relativeX = getRelativeX(event, ref.current);
|
|
@@ -70,7 +85,13 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
70
85
|
setCurrentX(relativeX);
|
|
71
86
|
}
|
|
72
87
|
function mouseMove(event) {
|
|
73
|
-
if (
|
|
88
|
+
if (anchorPosition?.isClick === false) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (mouseDragging) {
|
|
92
|
+
setGuideX(undefined);
|
|
93
|
+
}
|
|
94
|
+
else if (shiftOnly) {
|
|
74
95
|
if (event.shiftKey) {
|
|
75
96
|
setGuideX(getRelativeX(event, ref.current));
|
|
76
97
|
}
|
|
@@ -83,7 +104,9 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
83
104
|
}
|
|
84
105
|
}
|
|
85
106
|
function mouseOut() {
|
|
86
|
-
|
|
107
|
+
if (!anchorPosition?.isClick) {
|
|
108
|
+
setGuideX(undefined);
|
|
109
|
+
}
|
|
87
110
|
}
|
|
88
111
|
function handleMenuItemClick(_, callback) {
|
|
89
112
|
callback();
|
|
@@ -118,6 +141,7 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
118
141
|
open,
|
|
119
142
|
isClick,
|
|
120
143
|
clickBpOffset,
|
|
144
|
+
guideX,
|
|
121
145
|
rubberbandOn: !isClick,
|
|
122
146
|
mouseDown,
|
|
123
147
|
mouseMove,
|
|
@@ -46,11 +46,14 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
46
46
|
lastTrackDragY: undefined | number;
|
|
47
47
|
volatileError: unknown;
|
|
48
48
|
scaleFactor: number;
|
|
49
|
+
targetBpPerPx: number | undefined;
|
|
49
50
|
trackRefs: Record<string, HTMLDivElement>;
|
|
50
51
|
coarseDynamicBlocks: BaseBlock[];
|
|
51
52
|
coarseTotalBp: number;
|
|
52
53
|
leftOffset: undefined | BpOffset;
|
|
53
54
|
rightOffset: undefined | BpOffset;
|
|
55
|
+
isScalebarRefNameMenuOpen: boolean;
|
|
56
|
+
scalebarRefNameClickPending: boolean;
|
|
54
57
|
} & {
|
|
55
58
|
readonly pinnedTracks: any[];
|
|
56
59
|
readonly unpinnedTracks: any[];
|
|
@@ -104,6 +107,8 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
104
107
|
setShowCytobands(flag: boolean): void;
|
|
105
108
|
setWidth(newWidth: number): void;
|
|
106
109
|
setError(error: unknown): void;
|
|
110
|
+
setIsScalebarRefNameMenuOpen(isOpen: boolean): void;
|
|
111
|
+
setScalebarRefNameClickPending(pending: boolean): void;
|
|
107
112
|
setHideHeader(b: boolean): void;
|
|
108
113
|
setHideHeaderOverview(b: boolean): void;
|
|
109
114
|
setHideNoTracksActive(b: boolean): void;
|
|
@@ -143,6 +148,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
143
148
|
setDraggingTrackId(idx?: string): void;
|
|
144
149
|
setLastTrackDragY(y: number): void;
|
|
145
150
|
setScaleFactor(factor: number): void;
|
|
151
|
+
setTargetBpPerPx(target: number | undefined): void;
|
|
146
152
|
clearView(): void;
|
|
147
153
|
setInit(arg?: InitState): void;
|
|
148
154
|
exportSvg(opts?: ExportSvgOptions): Promise<void>;
|
|
@@ -164,6 +170,9 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
164
170
|
readonly visibleLocStrings: string;
|
|
165
171
|
readonly coarseVisibleLocStrings: string;
|
|
166
172
|
readonly coarseTotalBpDisplayStr: string;
|
|
173
|
+
readonly effectiveBpPerPx: number;
|
|
174
|
+
readonly effectiveTotalBp: number;
|
|
175
|
+
readonly effectiveTotalBpDisplayStr: string;
|
|
167
176
|
} & {
|
|
168
177
|
setCoarseDynamicBlocks(blocks: BlockSet): void;
|
|
169
178
|
} & {
|
|
@@ -175,8 +184,8 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
175
184
|
}): Promise<void>;
|
|
176
185
|
navToLocation(parsedLocString: ParsedLocString, assemblyName?: string, grow?: number): Promise<void>;
|
|
177
186
|
navToLocations(regions: ParsedLocString[], assemblyName?: string, grow?: number): Promise<void>;
|
|
178
|
-
navTo(query: NavLocation): void;
|
|
179
|
-
navToMultiple(locations: NavLocation[]): void;
|
|
187
|
+
navTo(query: NavLocation, grow?: number): void;
|
|
188
|
+
navToMultiple(locations: NavLocation[], grow?: number): void;
|
|
180
189
|
} & {
|
|
181
190
|
rubberBandMenuItems(): MenuItem[];
|
|
182
191
|
bpToPx({ refName, coord, regionNumber, }: {
|
|
@@ -19,7 +19,7 @@ import MiniControls from "./components/MiniControls.js";
|
|
|
19
19
|
import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT, INTER_REGION_PADDING_WIDTH, RESIZE_HANDLE_HEIGHT, SCALE_BAR_HEIGHT, } from "./consts.js";
|
|
20
20
|
import { setupKeyboardHandler } from "./keyboardHandler.js";
|
|
21
21
|
import { buildMenuItems, buildRubberBandMenuItems, buildRubberbandClickMenuItems, rewriteOnClicks, } from "./menuItems.js";
|
|
22
|
-
import { calculateVisibleLocStrings, generateLocations, parseLocStrings, } from "./util.js";
|
|
22
|
+
import { calculateVisibleLocStrings, expandRegion, generateLocations, parseLocStrings, } from "./util.js";
|
|
23
23
|
const SearchResultsDialog = lazy(() => import("./components/SearchResultsDialog.js"));
|
|
24
24
|
export function stateModelFactory(pluginManager) {
|
|
25
25
|
return types
|
|
@@ -50,11 +50,14 @@ export function stateModelFactory(pluginManager) {
|
|
|
50
50
|
lastTrackDragY: undefined,
|
|
51
51
|
volatileError: undefined,
|
|
52
52
|
scaleFactor: 1,
|
|
53
|
+
targetBpPerPx: undefined,
|
|
53
54
|
trackRefs: {},
|
|
54
55
|
coarseDynamicBlocks: [],
|
|
55
56
|
coarseTotalBp: 0,
|
|
56
57
|
leftOffset: undefined,
|
|
57
58
|
rightOffset: undefined,
|
|
59
|
+
isScalebarRefNameMenuOpen: false,
|
|
60
|
+
scalebarRefNameClickPending: false,
|
|
58
61
|
}))
|
|
59
62
|
.views(self => ({
|
|
60
63
|
get pinnedTracks() {
|
|
@@ -292,6 +295,12 @@ export function stateModelFactory(pluginManager) {
|
|
|
292
295
|
setError(error) {
|
|
293
296
|
self.volatileError = error;
|
|
294
297
|
},
|
|
298
|
+
setIsScalebarRefNameMenuOpen(isOpen) {
|
|
299
|
+
self.isScalebarRefNameMenuOpen = isOpen;
|
|
300
|
+
},
|
|
301
|
+
setScalebarRefNameClickPending(pending) {
|
|
302
|
+
self.scalebarRefNameClickPending = pending;
|
|
303
|
+
},
|
|
295
304
|
setHideHeader(b) {
|
|
296
305
|
self.hideHeader = b;
|
|
297
306
|
},
|
|
@@ -493,6 +502,9 @@ export function stateModelFactory(pluginManager) {
|
|
|
493
502
|
setScaleFactor(factor) {
|
|
494
503
|
self.scaleFactor = factor;
|
|
495
504
|
},
|
|
505
|
+
setTargetBpPerPx(target) {
|
|
506
|
+
self.targetBpPerPx = target;
|
|
507
|
+
},
|
|
496
508
|
clearView() {
|
|
497
509
|
this.setDisplayedRegions([]);
|
|
498
510
|
self.tracks.clear();
|
|
@@ -523,17 +535,21 @@ export function stateModelFactory(pluginManager) {
|
|
|
523
535
|
let cancelLastAnimation = () => { };
|
|
524
536
|
function zoom(targetBpPerPx) {
|
|
525
537
|
cancelLastAnimation();
|
|
526
|
-
self.
|
|
527
|
-
self.
|
|
528
|
-
|
|
529
|
-
|
|
538
|
+
const intendedFactor = targetBpPerPx / self.bpPerPx;
|
|
539
|
+
const effectiveBase = self.targetBpPerPx ?? self.bpPerPx;
|
|
540
|
+
let effectiveTarget = effectiveBase * intendedFactor;
|
|
541
|
+
effectiveTarget = Math.max(self.minBpPerPx, Math.min(self.maxBpPerPx, effectiveTarget));
|
|
542
|
+
const currentTarget = self.targetBpPerPx ?? self.bpPerPx;
|
|
543
|
+
if (effectiveTarget === currentTarget) {
|
|
530
544
|
return;
|
|
531
545
|
}
|
|
532
|
-
|
|
533
|
-
const
|
|
534
|
-
|
|
546
|
+
self.setTargetBpPerPx(effectiveTarget);
|
|
547
|
+
const targetScaleFactor = self.bpPerPx / effectiveTarget;
|
|
548
|
+
const [animate, cancelAnimation] = springAnimate(self.scaleFactor, targetScaleFactor, self.setScaleFactor, () => {
|
|
549
|
+
self.zoomTo(effectiveTarget);
|
|
535
550
|
self.setScaleFactor(1);
|
|
536
|
-
|
|
551
|
+
self.setTargetBpPerPx(undefined);
|
|
552
|
+
}, 0, 1000, 50);
|
|
537
553
|
cancelLastAnimation = cancelAnimation;
|
|
538
554
|
animate();
|
|
539
555
|
}
|
|
@@ -597,6 +613,15 @@ export function stateModelFactory(pluginManager) {
|
|
|
597
613
|
get coarseTotalBpDisplayStr() {
|
|
598
614
|
return getBpDisplayStr(self.coarseTotalBp);
|
|
599
615
|
},
|
|
616
|
+
get effectiveBpPerPx() {
|
|
617
|
+
return self.targetBpPerPx ?? self.bpPerPx;
|
|
618
|
+
},
|
|
619
|
+
get effectiveTotalBp() {
|
|
620
|
+
return this.effectiveBpPerPx * self.width;
|
|
621
|
+
},
|
|
622
|
+
get effectiveTotalBpDisplayStr() {
|
|
623
|
+
return getBpDisplayStr(this.effectiveTotalBp);
|
|
624
|
+
},
|
|
600
625
|
};
|
|
601
626
|
})
|
|
602
627
|
.actions(self => ({
|
|
@@ -666,10 +691,10 @@ export function stateModelFactory(pluginManager) {
|
|
|
666
691
|
self.showAllRegions();
|
|
667
692
|
}
|
|
668
693
|
},
|
|
669
|
-
navTo(query) {
|
|
670
|
-
this.navToMultiple([query]);
|
|
694
|
+
navTo(query, grow) {
|
|
695
|
+
this.navToMultiple([query], grow);
|
|
671
696
|
},
|
|
672
|
-
navToMultiple(locations) {
|
|
697
|
+
navToMultiple(locations, grow) {
|
|
673
698
|
if (locations.some(l => l.start !== undefined && l.end !== undefined && l.start > l.end)) {
|
|
674
699
|
throw new Error('found start greater than end');
|
|
675
700
|
}
|
|
@@ -694,14 +719,21 @@ export function stateModelFactory(pluginManager) {
|
|
|
694
719
|
if (!lastRegion) {
|
|
695
720
|
throw new Error(`could not find a region with refName "${lastRefName}"`);
|
|
696
721
|
}
|
|
697
|
-
|
|
722
|
+
let firstStart = firstLocation.start === undefined
|
|
698
723
|
? firstRegion.start
|
|
699
724
|
: firstLocation.start;
|
|
700
|
-
|
|
701
|
-
|
|
725
|
+
let firstEnd = firstLocation.end === undefined ? firstRegion.end : firstLocation.end;
|
|
726
|
+
let lastStart = lastLocation.start === undefined
|
|
702
727
|
? lastRegion.start
|
|
703
728
|
: lastLocation.start;
|
|
704
|
-
|
|
729
|
+
let lastEnd = lastLocation.end === undefined ? lastRegion.end : lastLocation.end;
|
|
730
|
+
if (grow) {
|
|
731
|
+
const expanded = expandRegion(firstStart, lastEnd, grow, firstRegion.start, lastRegion.end);
|
|
732
|
+
firstStart = expanded.start;
|
|
733
|
+
firstEnd = expanded.end;
|
|
734
|
+
lastStart = expanded.start;
|
|
735
|
+
lastEnd = expanded.end;
|
|
736
|
+
}
|
|
705
737
|
const firstIndex = self.displayedRegions.findIndex(r => firstRefName === r.refName &&
|
|
706
738
|
firstStart >= r.start &&
|
|
707
739
|
firstStart <= r.end &&
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { AssemblyManager, ParsedLocString } from '@jbrowse/core/util';
|
|
2
2
|
import type { BaseBlock } from '@jbrowse/core/util/blockTypes';
|
|
3
|
+
export declare function expandRegion(start: number, end: number, grow: number, minBound?: number, maxBound?: number): {
|
|
4
|
+
start: number;
|
|
5
|
+
end: number;
|
|
6
|
+
};
|
|
3
7
|
export declare function chooseGridPitch(scale: number, minMajorPitchPx: number, minMinorPitchPx: number): {
|
|
4
8
|
majorPitch: number;
|
|
5
9
|
minorPitch: number;
|
|
@@ -17,9 +21,9 @@ export declare function generateLocations({ regions, assemblyManager, assemblyNa
|
|
|
17
21
|
}): Promise<{
|
|
18
22
|
assemblyName: string;
|
|
19
23
|
parentRegion: import("@jbrowse/core/assemblyManager/assembly").BasicRegion;
|
|
24
|
+
start?: number;
|
|
25
|
+
end?: number;
|
|
20
26
|
refName: string;
|
|
21
|
-
start?: number | undefined;
|
|
22
|
-
end?: number | undefined;
|
|
23
27
|
reversed?: boolean | undefined;
|
|
24
28
|
}[]>;
|
|
25
29
|
export declare function parseLocStrings(input: string, assemblyName: string, isValidRefName: (str: string, assemblyName: string) => boolean): ParsedLocString[];
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { assembleLocString, parseLocString } from '@jbrowse/core/util';
|
|
2
|
+
export function expandRegion(start, end, grow, minBound = 0, maxBound = Infinity) {
|
|
3
|
+
const len = end - start;
|
|
4
|
+
const margin = len * grow;
|
|
5
|
+
return {
|
|
6
|
+
start: Math.max(minBound, start - margin),
|
|
7
|
+
end: Math.min(maxBound, end + margin),
|
|
8
|
+
};
|
|
9
|
+
}
|
|
2
10
|
export function chooseGridPitch(scale, minMajorPitchPx, minMinorPitchPx) {
|
|
3
11
|
scale = Math.abs(scale);
|
|
4
12
|
const minMajorPitchBp = minMajorPitchPx * scale;
|
|
@@ -74,24 +82,15 @@ export async function generateLocations({ regions, assemblyManager, assemblyName
|
|
|
74
82
|
throw new Error(`Could not find refName ${refName} in ${asmName}`);
|
|
75
83
|
}
|
|
76
84
|
const { start, end } = region;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
return {
|
|
90
|
-
...region,
|
|
91
|
-
assemblyName: asmName,
|
|
92
|
-
parentRegion,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
85
|
+
const expanded = grow && start !== undefined && end !== undefined
|
|
86
|
+
? expandRegion(start, end, grow)
|
|
87
|
+
: undefined;
|
|
88
|
+
return {
|
|
89
|
+
...region,
|
|
90
|
+
...(expanded ? { start: expanded.start, end: expanded.end } : {}),
|
|
91
|
+
assemblyName: asmName,
|
|
92
|
+
parentRegion,
|
|
93
|
+
};
|
|
95
94
|
}));
|
|
96
95
|
}
|
|
97
96
|
export function parseLocStrings(input, assemblyName, isValidRefName) {
|
package/esm/index.d.ts
CHANGED
|
@@ -139,6 +139,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
139
139
|
}> | null;
|
|
140
140
|
readonly adapterConfig: any;
|
|
141
141
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
142
|
+
readonly isMinimized: boolean;
|
|
142
143
|
readonly parentDisplay: any;
|
|
143
144
|
readonly effectiveRpcDriverName: any;
|
|
144
145
|
} & {
|
|
@@ -195,6 +196,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
195
196
|
}> | null;
|
|
196
197
|
readonly adapterConfig: any;
|
|
197
198
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
199
|
+
readonly isMinimized: boolean;
|
|
198
200
|
readonly parentDisplay: any;
|
|
199
201
|
readonly effectiveRpcDriverName: any;
|
|
200
202
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -248,6 +250,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
248
250
|
}> | null;
|
|
249
251
|
readonly adapterConfig: any;
|
|
250
252
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
253
|
+
readonly isMinimized: boolean;
|
|
251
254
|
readonly parentDisplay: any;
|
|
252
255
|
readonly effectiveRpcDriverName: any;
|
|
253
256
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -529,6 +532,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
529
532
|
}> | null;
|
|
530
533
|
readonly adapterConfig: any;
|
|
531
534
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
535
|
+
readonly isMinimized: boolean;
|
|
532
536
|
readonly parentDisplay: any;
|
|
533
537
|
readonly effectiveRpcDriverName: any;
|
|
534
538
|
} & {
|
|
@@ -585,6 +589,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
585
589
|
}> | null;
|
|
586
590
|
readonly adapterConfig: any;
|
|
587
591
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
592
|
+
readonly isMinimized: boolean;
|
|
588
593
|
readonly parentDisplay: any;
|
|
589
594
|
readonly effectiveRpcDriverName: any;
|
|
590
595
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -638,6 +643,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
638
643
|
}> | null;
|
|
639
644
|
readonly adapterConfig: any;
|
|
640
645
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
646
|
+
readonly isMinimized: boolean;
|
|
641
647
|
readonly parentDisplay: any;
|
|
642
648
|
readonly effectiveRpcDriverName: any;
|
|
643
649
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
|
@@ -864,6 +870,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
864
870
|
}> | null;
|
|
865
871
|
readonly adapterConfig: any;
|
|
866
872
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
873
|
+
readonly isMinimized: boolean;
|
|
867
874
|
readonly parentDisplay: any;
|
|
868
875
|
readonly effectiveRpcDriverName: any;
|
|
869
876
|
} & {
|
|
@@ -920,6 +927,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
920
927
|
}> | null;
|
|
921
928
|
readonly adapterConfig: any;
|
|
922
929
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
930
|
+
readonly isMinimized: boolean;
|
|
923
931
|
readonly parentDisplay: any;
|
|
924
932
|
readonly effectiveRpcDriverName: any;
|
|
925
933
|
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
@@ -973,6 +981,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
973
981
|
}> | null;
|
|
974
982
|
readonly adapterConfig: any;
|
|
975
983
|
readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
|
|
984
|
+
readonly isMinimized: boolean;
|
|
976
985
|
readonly parentDisplay: any;
|
|
977
986
|
readonly effectiveRpcDriverName: any;
|
|
978
987
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-linear-genome-view",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.4",
|
|
4
4
|
"description": "JBrowse 2 linear genome view",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"file-saver-es": "^2.0.5",
|
|
29
29
|
"mobx": "^6.15.0",
|
|
30
30
|
"mobx-react": "^9.2.1",
|
|
31
|
-
"@jbrowse/
|
|
32
|
-
"@jbrowse/core": "^4.0.
|
|
31
|
+
"@jbrowse/core": "^4.0.4",
|
|
32
|
+
"@jbrowse/product-core": "^4.0.4"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": ">=18.0.0",
|