@jbrowse/plugin-linear-genome-view 2.9.0 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/BaseLinearDisplay/components/Tooltip.js +18 -50
  2. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +4 -16
  3. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +8 -1
  4. package/dist/LinearBareDisplay/model.d.ts +8 -11
  5. package/dist/LinearBareDisplay/model.js +2 -1
  6. package/dist/LinearBasicDisplay/model.d.ts +30 -33
  7. package/dist/LinearBasicDisplay/model.js +3 -0
  8. package/dist/LinearGenomeView/components/Cytobands.d.ts +18 -6
  9. package/dist/LinearGenomeView/components/Cytobands.js +8 -2
  10. package/dist/LinearGenomeView/components/OverviewScalebar.d.ts +0 -8
  11. package/dist/LinearGenomeView/components/OverviewScalebar.js +23 -55
  12. package/dist/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +9 -0
  13. package/dist/LinearGenomeView/components/OverviewScalebarPolygon.js +46 -0
  14. package/dist/LinearGenomeView/components/TracksContainer.js +1 -1
  15. package/dist/LinearGenomeView/model.d.ts +6 -1
  16. package/dist/LinearGenomeView/model.js +3 -0
  17. package/dist/LinearGenomeView/svgcomponents/SVGHeader.js +2 -2
  18. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +0 -7
  19. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +11 -13
  20. package/dist/LinearGenomeView/svgcomponents/util.d.ts +8 -0
  21. package/dist/LinearGenomeView/svgcomponents/util.js +9 -0
  22. package/dist/index.d.ts +110 -37
  23. package/dist/index.js +3 -2
  24. package/esm/BaseLinearDisplay/components/Tooltip.js +16 -28
  25. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +4 -16
  26. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +8 -1
  27. package/esm/LinearBareDisplay/model.d.ts +8 -11
  28. package/esm/LinearBareDisplay/model.js +2 -1
  29. package/esm/LinearBasicDisplay/model.d.ts +30 -33
  30. package/esm/LinearBasicDisplay/model.js +3 -0
  31. package/esm/LinearGenomeView/components/Cytobands.d.ts +18 -6
  32. package/esm/LinearGenomeView/components/Cytobands.js +8 -2
  33. package/esm/LinearGenomeView/components/OverviewScalebar.d.ts +0 -8
  34. package/esm/LinearGenomeView/components/OverviewScalebar.js +23 -53
  35. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +9 -0
  36. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +41 -0
  37. package/esm/LinearGenomeView/components/TracksContainer.js +1 -1
  38. package/esm/LinearGenomeView/model.d.ts +6 -1
  39. package/esm/LinearGenomeView/model.js +3 -0
  40. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +2 -2
  41. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +0 -7
  42. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +9 -10
  43. package/esm/LinearGenomeView/svgcomponents/util.d.ts +8 -0
  44. package/esm/LinearGenomeView/svgcomponents/util.js +5 -0
  45. package/esm/index.d.ts +110 -37
  46. package/esm/index.js +2 -1
  47. package/package.json +4 -6
@@ -15,7 +15,14 @@ import FeatureDensityMixin from './FeatureDensityMixin';
15
15
  /**
16
16
  * #stateModel BaseLinearDisplay
17
17
  * #category display
18
- * extends `BaseDisplay`
18
+ *
19
+ * BaseLinearDisplay is used as the basis for many linear genome view tracks.
20
+ * It is block based, and can use 'static blocks' or 'dynamic blocks'
21
+ *
22
+ * extends
23
+ * - [BaseDisplay](../basedisplay)
24
+ * - [TrackHeightMixin](../trackheightmixin)
25
+ * - [FeatureDensityMixin](../featuredensitymixin)
19
26
  */
20
27
  function stateModelFactory() {
21
28
  return types
@@ -3,7 +3,8 @@ import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
3
3
  /**
4
4
  * #stateModel LinearBareDisplay
5
5
  * #category display
6
- * extends `BaseLinearDisplay`
6
+ * extends
7
+ * - [BaseLinearDisplay](../baselineardisplay)
7
8
  */
8
9
  export declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): import("mobx-state-tree").IModelType<{
9
10
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
@@ -76,9 +77,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
76
77
  type: string;
77
78
  defaultValue: number;
78
79
  description: string;
79
- }; /**
80
- * #getter
81
- */
80
+ };
82
81
  mouseover: {
83
82
  type: string;
84
83
  description: string;
@@ -98,9 +97,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
98
97
  }, {
99
98
  rendererTypeName: string;
100
99
  error: unknown;
101
- message: string | undefined; /**
102
- * #property
103
- */
100
+ message: string | undefined;
104
101
  } & {
105
102
  readonly RenderingComponent: import("react").FC<{
106
103
  model: {
@@ -160,7 +157,9 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
160
157
  } & {
161
158
  readonly height: number;
162
159
  } & {
163
- setScrollTop(scrollTop: number): void;
160
+ setScrollTop(scrollTop: number): void; /**
161
+ * #method
162
+ */
164
163
  setHeight(displayHeight: number): number;
165
164
  resizeHeight(distance: number): number;
166
165
  } & {
@@ -303,9 +302,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
303
302
  type: string;
304
303
  defaultValue: number;
305
304
  description: string;
306
- }; /**
307
- * #getter
308
- */
305
+ };
309
306
  mouseover: {
310
307
  type: string;
311
308
  description: string;
@@ -5,7 +5,8 @@ import { BaseLinearDisplay } from '../BaseLinearDisplay';
5
5
  /**
6
6
  * #stateModel LinearBareDisplay
7
7
  * #category display
8
- * extends `BaseLinearDisplay`
8
+ * extends
9
+ * - [BaseLinearDisplay](../baselineardisplay)
9
10
  */
10
11
  export function stateModelFactory(configSchema) {
11
12
  return types
@@ -7,6 +7,9 @@ import { Instance } from 'mobx-state-tree';
7
7
  * #category display
8
8
  * used by `FeatureTrack`, has simple settings like "show/hide feature labels",
9
9
  * etc.
10
+ *
11
+ * extends
12
+ * - [BaseLinearDisplay](../baselineardisplay)
10
13
  */
11
14
  declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): import("mobx-state-tree").IModelType<{
12
15
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
@@ -34,7 +37,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
34
37
  isLeftEndOfDisplayedRegion: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
35
38
  isRightEndOfDisplayedRegion: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
36
39
  }, {
37
- renderInProgress: AbortController | undefined;
40
+ renderInProgress: AbortController | undefined; /**
41
+ * #property
42
+ */
38
43
  filled: boolean;
39
44
  reactElement: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
40
45
  features: Map<string, import("@jbrowse/core/util").Feature> | undefined;
@@ -52,9 +57,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
52
57
  afterAttach(): void;
53
58
  setStatus(message: string): void;
54
59
  setLoading(abortController: AbortController): void;
55
- setMessage(messageText: string): void; /**
56
- * #method
57
- */
60
+ setMessage(messageText: string): void;
58
61
  setRendered(props: {
59
62
  reactElement: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
60
63
  features: Map<string, import("@jbrowse/core/util").Feature>;
@@ -81,15 +84,11 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
81
84
  type: string;
82
85
  defaultValue: number;
83
86
  description: string;
84
- }; /**
85
- * #property
86
- */
87
+ };
87
88
  mouseover: {
88
89
  type: string;
89
90
  description: string;
90
- defaultValue: string; /**
91
- * #property
92
- */
91
+ defaultValue: string;
93
92
  contextVariable: string[];
94
93
  };
95
94
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
@@ -127,9 +126,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
127
126
  model: {
128
127
  id: string;
129
128
  type: string;
130
- rpcDriverName: string | undefined; /**
131
- * #property
132
- */
129
+ rpcDriverName: string | undefined;
133
130
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
134
131
  rendererTypeName: string;
135
132
  error: unknown;
@@ -160,13 +157,14 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
160
157
  type: import("mobx-state-tree").ISimpleType<string>;
161
158
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
162
159
  }, {
163
- rendererTypeName: string; /**
164
- * #action
165
- */
160
+ rendererTypeName: string;
166
161
  error: unknown;
167
162
  message: string | undefined;
168
163
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
169
164
  }> | null;
165
+ /**
166
+ * #action
167
+ */
170
168
  readonly adapterConfig: any;
171
169
  readonly parentTrack: any;
172
170
  renderProps(): any;
@@ -195,10 +193,11 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
195
193
  } & {
196
194
  readonly currentBytesRequested: number;
197
195
  readonly currentFeatureScreenDensity: number;
198
- readonly maxFeatureScreenDensity: any;
199
- readonly featureDensityStatsReady: boolean; /**
196
+ /**
200
197
  * #getter
201
198
  */
199
+ readonly maxFeatureScreenDensity: any;
200
+ readonly featureDensityStatsReady: boolean;
202
201
  readonly maxAllowableBytes: number;
203
202
  } & {
204
203
  afterAttach(): void;
@@ -219,9 +218,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
219
218
  featureIdUnderMouse: string | undefined;
220
219
  contextMenuFeature: import("@jbrowse/core/util").Feature | undefined;
221
220
  } & {
222
- readonly blockType: "dynamicBlocks" | "staticBlocks"; /**
223
- * #getter
224
- */
221
+ readonly blockType: "dynamicBlocks" | "staticBlocks";
225
222
  readonly blockDefinitions: import("@jbrowse/core/util/blockTypes").BlockSet;
226
223
  } & {
227
224
  readonly renderDelay: number;
@@ -278,7 +275,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
278
275
  readonly rendererConfig: {
279
276
  [x: string]: any;
280
277
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
281
- setSubschema(slotName: string, data: unknown): any;
278
+ setSubschema(slotName: string, data: unknown): any; /**
279
+ * #property
280
+ */
282
281
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
283
282
  } & {
284
283
  /**
@@ -305,7 +304,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
305
304
  config: {
306
305
  [x: string]: any;
307
306
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
308
- setSubschema(slotName: string, data: unknown): any;
307
+ setSubschema(slotName: string, data: unknown): any; /**
308
+ * #property
309
+ */
309
310
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
310
311
  };
311
312
  /**
@@ -340,7 +341,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
340
341
  isLeftEndOfDisplayedRegion: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
341
342
  isRightEndOfDisplayedRegion: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
342
343
  }, {
343
- renderInProgress: AbortController | undefined;
344
+ renderInProgress: AbortController | undefined; /**
345
+ * #property
346
+ */
344
347
  filled: boolean;
345
348
  reactElement: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
346
349
  features: Map<string, import("@jbrowse/core/util").Feature> | undefined;
@@ -358,9 +361,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
358
361
  afterAttach(): void;
359
362
  setStatus(message: string): void;
360
363
  setLoading(abortController: AbortController): void;
361
- setMessage(messageText: string): void; /**
362
- * #method
363
- */
364
+ setMessage(messageText: string): void;
364
365
  setRendered(props: {
365
366
  reactElement: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
366
367
  features: Map<string, import("@jbrowse/core/util").Feature>;
@@ -387,15 +388,11 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
387
388
  type: string;
388
389
  defaultValue: number;
389
390
  description: string;
390
- }; /**
391
- * #property
392
- */
391
+ };
393
392
  mouseover: {
394
393
  type: string;
395
394
  description: string;
396
- defaultValue: string; /**
397
- * #property
398
- */
395
+ defaultValue: string;
399
396
  contextVariable: string[];
400
397
  };
401
398
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
@@ -12,6 +12,9 @@ const SetMaxHeightDlg = lazy(() => import('./components/SetMaxHeight'));
12
12
  * #category display
13
13
  * used by `FeatureTrack`, has simple settings like "show/hide feature labels",
14
14
  * etc.
15
+ *
16
+ * extends
17
+ * - [BaseLinearDisplay](../baselineardisplay)
15
18
  */
16
19
  function stateModelFactory(configSchema) {
17
20
  return types
@@ -53,11 +53,17 @@ declare const Cytobands: ({ overview, block, assembly, }: {
53
53
  load(): Promise<void>;
54
54
  loadPre(): Promise<void>;
55
55
  } & {
56
- getAdapterMapEntry(adapterConf: unknown, options: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<import("@jbrowse/core/assemblyManager/assembly").RefNameMap>;
57
- getRefNameMapForAdapter(adapterConf: unknown, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
56
+ getAdapterMapEntry(adapterConf: {
57
+ [x: string]: unknown;
58
+ }, options: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<import("@jbrowse/core/assemblyManager/assembly").RefNameMap>;
59
+ getRefNameMapForAdapter(adapterConf: {
60
+ [x: string]: unknown;
61
+ }, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
58
62
  [x: string]: string | undefined;
59
63
  }>;
60
- getReverseRefNameMapForAdapter(adapterConf: unknown, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
64
+ getReverseRefNameMapForAdapter(adapterConf: {
65
+ [x: string]: unknown;
66
+ }, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
61
67
  [x: string]: string | undefined;
62
68
  }>;
63
69
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
@@ -109,11 +115,17 @@ declare const Cytobands: ({ overview, block, assembly, }: {
109
115
  load(): Promise<void>;
110
116
  loadPre(): Promise<void>;
111
117
  } & {
112
- getAdapterMapEntry(adapterConf: unknown, options: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<import("@jbrowse/core/assemblyManager/assembly").RefNameMap>;
113
- getRefNameMapForAdapter(adapterConf: unknown, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
118
+ getAdapterMapEntry(adapterConf: {
119
+ [x: string]: unknown;
120
+ }, options: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<import("@jbrowse/core/assemblyManager/assembly").RefNameMap>;
121
+ getRefNameMapForAdapter(adapterConf: {
122
+ [x: string]: unknown;
123
+ }, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
114
124
  [x: string]: string | undefined;
115
125
  }>;
116
- getReverseRefNameMapForAdapter(adapterConf: unknown, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
126
+ getReverseRefNameMapForAdapter(adapterConf: {
127
+ [x: string]: unknown;
128
+ }, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
117
129
  [x: string]: string | undefined;
118
130
  }>;
119
131
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>) | undefined;
@@ -66,10 +66,16 @@ const Cytobands = observer(function ({ overview, block, assembly, }) {
66
66
  const c = colorMap[type];
67
67
  if (type === 'acen' && !centromereSeen) {
68
68
  centromereSeen = true; // the next acen entry is drawn with different right triangle
69
- return React.createElement("polygon", { key: k, points: leftTriangle(s, 0, w, h), fill: c });
69
+ const tri = reversed
70
+ ? rightTriangle(s - w, 0, w, h)
71
+ : leftTriangle(s, 0, w, h);
72
+ return React.createElement("polygon", { key: k, points: tri, fill: c });
70
73
  }
71
74
  else if (type === 'acen' && centromereSeen) {
72
- return React.createElement("polygon", { key: k, points: rightTriangle(s, 0, w, h), fill: c });
75
+ const tri = reversed
76
+ ? leftTriangle(s - w, 0, w, h)
77
+ : rightTriangle(s, 0, w, h);
78
+ return React.createElement("polygon", { key: k, points: tri, fill: c });
73
79
  }
74
80
  else if (lcap === index) {
75
81
  return React.createElement("path", { key: k, d: leftRoundedRect(l, 0, w, h, 8), fill: c });
@@ -1,16 +1,8 @@
1
1
  import React from 'react';
2
- import { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel';
3
2
  import { LinearGenomeViewModel } from '..';
4
- declare const Polygon: ({ model, overview, useOffset, }: {
5
- model: LGV;
6
- overview: Base1DViewModel;
7
- useOffset?: boolean | undefined;
8
- }) => React.JSX.Element | null;
9
3
  type LGV = LinearGenomeViewModel;
10
4
  declare const OverviewScalebar: ({ model, children, }: {
11
5
  model: LGV;
12
6
  children: React.ReactNode;
13
7
  }) => React.JSX.Element;
14
- export { Polygon };
15
- export { default as Cytobands } from './Cytobands';
16
8
  export default OverviewScalebar;
@@ -9,9 +9,10 @@ import { ContentBlock } from '@jbrowse/core/util/blockTypes';
9
9
  // locals
10
10
  import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT, } from '..';
11
11
  import { chooseGridPitch } from '../util';
12
+ import { getCytobands } from './util';
12
13
  import OverviewRubberband from './OverviewRubberband';
13
14
  import Cytobands from './Cytobands';
14
- import { getCytobands } from './util';
15
+ import OverviewScalebarPolygon from './OverviewScalebarPolygon';
15
16
  const wholeSeqSpacer = 2;
16
17
  const useStyles = makeStyles()(theme => ({
17
18
  scalebar: {
@@ -65,55 +66,14 @@ const useStyles = makeStyles()(theme => ({
65
66
  position: 'absolute',
66
67
  },
67
68
  }));
68
- const Polygon = observer(function ({ model, overview, useOffset = true, }) {
69
- const theme = useTheme();
70
- const multiplier = Number(useOffset);
71
- const { interRegionPaddingWidth, offsetPx, dynamicBlocks, cytobandOffset } = model;
72
- const { contentBlocks, totalWidthPxWithoutBorders } = dynamicBlocks;
73
- const { tertiary, primary } = theme.palette;
74
- const polygonColor = tertiary ? tertiary.light : primary.light;
75
- // catches possible null from at's below
76
- if (!contentBlocks.length) {
77
- return null;
78
- }
79
- const first = contentBlocks.at(0);
80
- const last = contentBlocks.at(-1);
81
- const topLeft = (overview.bpToPx({
82
- ...first,
83
- coord: first.reversed ? first.end : first.start,
84
- }) || 0) +
85
- cytobandOffset * multiplier;
86
- const topRight = (overview.bpToPx({
87
- ...last,
88
- coord: last.reversed ? last.start : last.end,
89
- }) || 0) +
90
- cytobandOffset * multiplier;
91
- const startPx = Math.max(0, -offsetPx);
92
- const endPx = startPx +
93
- totalWidthPxWithoutBorders +
94
- (contentBlocks.length * interRegionPaddingWidth) / 2;
95
- const points = [
96
- [startPx, HEADER_BAR_HEIGHT],
97
- [endPx, HEADER_BAR_HEIGHT],
98
- [topRight, 0],
99
- [topLeft, 0],
100
- ];
101
- return (React.createElement("polygon", { points: points.toString(), fill: alpha(polygonColor, 0.3), stroke: alpha(polygonColor, 0.8) }));
102
- });
103
69
  const OverviewBox = observer(function ({ scale, model, block, overview, }) {
104
70
  const { classes, cx } = useStyles();
105
71
  const theme = useTheme();
106
72
  const { cytobandOffset, showCytobands } = model;
107
- const { start, end, reversed, refName, assemblyName } = block;
108
- const { majorPitch } = chooseGridPitch(scale, 120, 15);
73
+ const { reversed, refName, assemblyName } = block;
109
74
  const { assemblyManager } = getSession(model);
110
75
  const assembly = assemblyManager.get(assemblyName);
111
76
  const refNameColor = assembly === null || assembly === void 0 ? void 0 : assembly.getRefNameColor(refName);
112
- const tickLabels = [];
113
- for (let i = 0; i < Math.floor((end - start) / majorPitch); i++) {
114
- const offsetLabel = (i + 1) * majorPitch;
115
- tickLabels.push(reversed ? end - offsetLabel : start + offsetLabel);
116
- }
117
77
  const canDisplayCytobands = showCytobands && getCytobands(assembly, block.refName).length;
118
78
  return (React.createElement("div", null,
119
79
  React.createElement(Typography, { style: {
@@ -131,16 +91,28 @@ const OverviewBox = observer(function ({ scale, model, block, overview, }) {
131
91
  width: block.widthPx,
132
92
  borderColor: refNameColor,
133
93
  } },
134
- !canDisplayCytobands
135
- ? tickLabels.map((tickLabel, labelIdx) => (React.createElement(Typography, { key: `${JSON.stringify(block)}-${tickLabel}-${labelIdx}`, className: classes.scalebarLabel, variant: "body2", style: {
136
- left: ((labelIdx + 1) * majorPitch) / scale,
137
- pointerEvents: 'none',
138
- color: refNameColor,
139
- } }, getTickDisplayStr(tickLabel, overview.bpPerPx))))
140
- : null,
94
+ !canDisplayCytobands ? (React.createElement(TickLabels, { model: model, overview: overview, scale: scale, block: block })) : null,
141
95
  canDisplayCytobands ? (React.createElement("svg", { style: { width: '100%' } },
142
96
  React.createElement(Cytobands, { overview: overview, assembly: assembly, block: block }))) : null)));
143
97
  });
98
+ const TickLabels = observer(function ({ block, scale, overview, model, }) {
99
+ const { classes } = useStyles();
100
+ const { start, end, reversed, refName, assemblyName } = block;
101
+ const { majorPitch } = chooseGridPitch(scale, 120, 15);
102
+ const { assemblyManager } = getSession(model);
103
+ const assembly = assemblyManager.get(assemblyName);
104
+ const refNameColor = assembly === null || assembly === void 0 ? void 0 : assembly.getRefNameColor(refName);
105
+ const tickLabels = [];
106
+ for (let i = 0; i < Math.floor((end - start) / majorPitch); i++) {
107
+ const offsetLabel = (i + 1) * majorPitch;
108
+ tickLabels.push(reversed ? end - offsetLabel : start + offsetLabel);
109
+ }
110
+ return tickLabels.map((tickLabel, labelIdx) => (React.createElement(Typography, { key: `${JSON.stringify(block)}-${tickLabel}-${labelIdx}`, className: classes.scalebarLabel, variant: "body2", style: {
111
+ left: ((labelIdx + 1) * majorPitch) / scale,
112
+ pointerEvents: 'none',
113
+ color: refNameColor,
114
+ } }, getTickDisplayStr(tickLabel, overview.bpPerPx))));
115
+ });
144
116
  const Scalebar = observer(function ({ model, scale, overview, }) {
145
117
  const { classes } = useStyles();
146
118
  const theme = useTheme();
@@ -205,9 +177,7 @@ const OverviewScalebar = observer(function ({ model, children, }) {
205
177
  React.createElement(OverviewRubberband, { model: model, overview: overview, ControlComponent: React.createElement(Scalebar, { model: model, overview: overview, scale: scale }) }),
206
178
  React.createElement("div", { className: classes.overview },
207
179
  React.createElement("svg", { height: HEADER_BAR_HEIGHT, className: classes.overviewSvg },
208
- React.createElement(Polygon, { model: model, overview: overview })),
180
+ React.createElement(OverviewScalebarPolygon, { model: model, overview: overview })),
209
181
  children)));
210
182
  });
211
- export { Polygon };
212
- export { default as Cytobands } from './Cytobands';
213
183
  export default OverviewScalebar;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel';
3
+ import { LinearGenomeViewModel } from '..';
4
+ declare const OverviewScalebarPolygon: ({ model, overview, useOffset, }: {
5
+ model: LinearGenomeViewModel;
6
+ overview: Base1DViewModel;
7
+ useOffset?: boolean | undefined;
8
+ }) => React.JSX.Element | null;
9
+ export default OverviewScalebarPolygon;
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import { useTheme, alpha } from '@mui/material';
3
+ import { observer } from 'mobx-react';
4
+ // locals
5
+ import { HEADER_BAR_HEIGHT } from '..';
6
+ const OverviewScalebarPolygon = observer(function ({ model, overview, useOffset = true, }) {
7
+ const theme = useTheme();
8
+ const multiplier = Number(useOffset);
9
+ const { interRegionPaddingWidth, offsetPx, dynamicBlocks, cytobandOffset } = model;
10
+ const { contentBlocks, totalWidthPxWithoutBorders } = dynamicBlocks;
11
+ const { tertiary, primary } = theme.palette;
12
+ const polygonColor = tertiary ? tertiary.light : primary.light;
13
+ // catches possible null from at's below
14
+ if (!contentBlocks.length) {
15
+ return null;
16
+ }
17
+ const first = contentBlocks.at(0);
18
+ const last = contentBlocks.at(-1);
19
+ const topLeft = (overview.bpToPx({
20
+ ...first,
21
+ coord: first.reversed ? first.end : first.start,
22
+ }) || 0) +
23
+ cytobandOffset * multiplier;
24
+ const topRight = (overview.bpToPx({
25
+ ...last,
26
+ coord: last.reversed ? last.start : last.end,
27
+ }) || 0) +
28
+ cytobandOffset * multiplier;
29
+ const startPx = Math.max(0, -offsetPx);
30
+ const endPx = startPx +
31
+ totalWidthPxWithoutBorders +
32
+ (contentBlocks.length * interRegionPaddingWidth) / 2;
33
+ const points = [
34
+ [startPx, HEADER_BAR_HEIGHT],
35
+ [endPx, HEADER_BAR_HEIGHT],
36
+ [topRight, 0],
37
+ [topLeft, 0],
38
+ ];
39
+ return (React.createElement("polygon", { points: points.toString(), fill: alpha(polygonColor, 0.3), stroke: alpha(polygonColor, 0.8) }));
40
+ });
41
+ export default OverviewScalebarPolygon;
@@ -2,6 +2,7 @@ import React, { useRef } from 'react';
2
2
  import { makeStyles } from 'tss-react/mui';
3
3
  import { observer } from 'mobx-react';
4
4
  import { Menu } from '@jbrowse/core/ui';
5
+ import { getEnv } from '@jbrowse/core/util';
5
6
  // local utils
6
7
  import { SCALE_BAR_HEIGHT } from '..';
7
8
  import { useSideScroll, useRangeSelect, useWheelScroll } from './hooks';
@@ -12,7 +13,6 @@ import Gridlines from './Gridlines';
12
13
  import CenterLine from './CenterLine';
13
14
  import VerticalGuide from './VerticalGuide';
14
15
  import RubberbandSpan from './RubberbandSpan';
15
- import { getEnv } from '@jbrowse/core/util';
16
16
  const useStyles = makeStyles()({
17
17
  tracksContainer: {
18
18
  position: 'relative',
@@ -21,7 +21,9 @@ export interface BpOffset {
21
21
  export interface ExportSvgOptions {
22
22
  rasterizeLayers?: boolean;
23
23
  filename?: string;
24
- Wrapper?: React.FC<any>;
24
+ Wrapper?: React.FC<{
25
+ children: React.ReactNode;
26
+ }>;
25
27
  fontSize?: number;
26
28
  rulerHeight?: number;
27
29
  textHeight?: number;
@@ -47,6 +49,9 @@ export declare const WIDGET_HEIGHT = 32;
47
49
  /**
48
50
  * #stateModel LinearGenomeView
49
51
  * #category view
52
+ *
53
+ * extends
54
+ * - [BaseViewModel](../baseviewmodel)
50
55
  */
51
56
  export declare function stateModelFactory(pluginManager: PluginManager): import("mobx-state-tree").IModelType<{
52
57
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
@@ -54,6 +54,9 @@ export const WIDGET_HEIGHT = 32;
54
54
  /**
55
55
  * #stateModel LinearGenomeView
56
56
  * #category view
57
+ *
58
+ * extends
59
+ * - [BaseViewModel](../baseviewmodel)
57
60
  */
58
61
  export function stateModelFactory(pluginManager) {
59
62
  return types
@@ -5,9 +5,9 @@ import { useTheme } from '@mui/material';
5
5
  // locals
6
6
  import { HEADER_OVERVIEW_HEIGHT } from '..';
7
7
  import Cytobands from '../components/Cytobands';
8
- import { Polygon } from '../components/OverviewScalebar';
9
8
  import SVGRuler from './SVGRuler';
10
9
  import SVGScalebar from './SVGScalebar';
10
+ import OverviewScalebarPolygon from '../components/OverviewScalebarPolygon';
11
11
  export default function SVGHeader({ model, fontSize, cytobandHeight, rulerHeight, }) {
12
12
  const { width, assemblyNames, showCytobands, displayedRegions } = model;
13
13
  const { assemblyManager } = getSession(model);
@@ -44,7 +44,7 @@ export default function SVGHeader({ model, fontSize, cytobandHeight, rulerHeight
44
44
  React.createElement(Cytobands, { overview: overview, assembly: assembly, block: block }),
45
45
  React.createElement("rect", { stroke: "red", fill: "rgb(255,0,0,0.1)", width: Math.max(lastOverviewPx - firstOverviewPx, 0.5), height: HEADER_OVERVIEW_HEIGHT - 1, x: firstOverviewPx, y: 0.5 }),
46
46
  React.createElement("g", { transform: `translate(0,${HEADER_OVERVIEW_HEIGHT})` },
47
- React.createElement(Polygon, { overview: overview, model: model, useOffset: false })))) : null,
47
+ React.createElement(OverviewScalebarPolygon, { overview: overview, model: model, useOffset: false })))) : null,
48
48
  React.createElement("g", { transform: `translate(0 ${fontSize + y})` },
49
49
  React.createElement(SVGScalebar, { model: model, fontSize: fontSize })),
50
50
  React.createElement("g", { transform: `translate(0 ${rulerHeight + y})` },
@@ -1,12 +1,5 @@
1
1
  import { LinearGenomeViewModel, ExportSvgOptions } from '..';
2
2
  type LGV = LinearGenomeViewModel;
3
- interface Display {
4
- height: number;
5
- }
6
- interface Track {
7
- displays: Display[];
8
- }
9
- export declare function totalHeight(tracks: Track[], textHeight: number, trackLabels: string): number;
10
3
  export declare function renderToSvg(model: LGV, opts: ExportSvgOptions): Promise<string>;
11
4
  export { default as SVGRuler } from './SVGRuler';
12
5
  export { default as SVGTracks } from './SVGTracks';
@@ -1,25 +1,24 @@
1
1
  /* eslint-disable react-refresh/only-export-components */
2
2
  import React from 'react';
3
- import { renderToStaticMarkup } from 'react-dom/server';
4
3
  import { when } from 'mobx';
5
- import { getSession, max, measureText, sum } from '@jbrowse/core/util';
4
+ import { getSession, max, measureText, renderToStaticMarkup, } from '@jbrowse/core/util';
6
5
  import { ThemeProvider } from '@mui/material';
7
6
  import { createJBrowseTheme } from '@jbrowse/core/ui';
7
+ import { getTrackName } from '@jbrowse/core/util/tracks';
8
+ import { getRoot } from 'mobx-state-tree';
8
9
  import SVGBackground from './SVGBackground';
9
10
  import SVGTracks from './SVGTracks';
10
11
  import SVGHeader from './SVGHeader';
11
- import { getTrackName } from '@jbrowse/core/util/tracks';
12
- export function totalHeight(tracks, textHeight, trackLabels) {
13
- return sum(tracks.map(t => t.displays[0].height +
14
- (['none', 'left'].includes(trackLabels) ? 0 : textHeight)));
15
- }
12
+ import { totalHeight } from './util';
16
13
  // render LGV to SVG
17
14
  export async function renderToSvg(model, opts) {
18
- var _a;
19
15
  await when(() => model.initialized);
20
16
  const { textHeight = 18, headerHeight = 40, rulerHeight = 50, fontSize = 13, cytobandHeight = 100, trackLabels = 'offset', themeName = 'default', Wrapper = ({ children }) => React.createElement(React.Fragment, null, children), } = opts;
21
17
  const session = getSession(model);
22
- const theme = (_a = session.allThemes) === null || _a === void 0 ? void 0 : _a.call(session)[themeName];
18
+ const { allThemes } = session;
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ const { createRootFn } = getRoot(model);
21
+ const theme = allThemes === null || allThemes === void 0 ? void 0 : allThemes()[themeName];
23
22
  const { width, tracks, showCytobands } = model;
24
23
  const shift = 50;
25
24
  const c = +showCytobands * cytobandHeight;
@@ -41,7 +40,7 @@ export async function renderToSvg(model, opts) {
41
40
  React.createElement("g", { transform: `translate(${shift} 0)` },
42
41
  React.createElement("g", { transform: `translate(${trackLabelOffset})` },
43
42
  React.createElement(SVGHeader, { model: model, fontSize: fontSize, rulerHeight: rulerHeight, cytobandHeight: cytobandHeight })),
44
- React.createElement(SVGTracks, { textHeight: textHeight, fontSize: fontSize, model: model, displayResults: displayResults, offset: offset, trackLabels: trackLabels, trackLabelOffset: trackLabelOffset }))))));
43
+ React.createElement(SVGTracks, { textHeight: textHeight, fontSize: fontSize, model: model, displayResults: displayResults, offset: offset, trackLabels: trackLabels, trackLabelOffset: trackLabelOffset }))))), createRootFn);
45
44
  }
46
45
  export { default as SVGRuler } from './SVGRuler';
47
46
  export { default as SVGTracks } from './SVGTracks';
@@ -0,0 +1,8 @@
1
+ interface Display {
2
+ height: number;
3
+ }
4
+ interface Track {
5
+ displays: Display[];
6
+ }
7
+ export declare function totalHeight(tracks: Track[], textHeight: number, trackLabels: string): number;
8
+ export {};
@@ -0,0 +1,5 @@
1
+ import { sum } from '@jbrowse/core/util';
2
+ export function totalHeight(tracks, textHeight, trackLabels) {
3
+ return sum(tracks.map(t => t.displays[0].height +
4
+ (['none', 'left'].includes(trackLabels) ? 0 : textHeight)));
5
+ }