@jbrowse/plugin-canvas 4.0.0

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 (78) hide show
  1. package/LICENSE +201 -0
  2. package/esm/CanvasFeatureRenderer/CanvasFeatureRenderer.d.ts +6 -0
  3. package/esm/CanvasFeatureRenderer/CanvasFeatureRenderer.js +30 -0
  4. package/esm/CanvasFeatureRenderer/CanvasFeatureRendering.d.ts +17 -0
  5. package/esm/CanvasFeatureRenderer/CanvasFeatureRendering.js +192 -0
  6. package/esm/CanvasFeatureRenderer/configSchema.d.ts +136 -0
  7. package/esm/CanvasFeatureRenderer/configSchema.js +152 -0
  8. package/esm/CanvasFeatureRenderer/configSchema2.d.ts +136 -0
  9. package/esm/CanvasFeatureRenderer/configSchema2.js +5 -0
  10. package/esm/CanvasFeatureRenderer/doAll.d.ts +21 -0
  11. package/esm/CanvasFeatureRenderer/doAll.js +42 -0
  12. package/esm/CanvasFeatureRenderer/drawChevrons.d.ts +1 -0
  13. package/esm/CanvasFeatureRenderer/drawChevrons.js +25 -0
  14. package/esm/CanvasFeatureRenderer/drawFeature.d.ts +3 -0
  15. package/esm/CanvasFeatureRenderer/drawFeature.js +27 -0
  16. package/esm/CanvasFeatureRenderer/filterSubparts.d.ts +5 -0
  17. package/esm/CanvasFeatureRenderer/filterSubparts.js +92 -0
  18. package/esm/CanvasFeatureRenderer/floatingLabels.d.ts +23 -0
  19. package/esm/CanvasFeatureRenderer/floatingLabels.js +65 -0
  20. package/esm/CanvasFeatureRenderer/glyphs/box.d.ts +2 -0
  21. package/esm/CanvasFeatureRenderer/glyphs/box.js +87 -0
  22. package/esm/CanvasFeatureRenderer/glyphs/cds.d.ts +2 -0
  23. package/esm/CanvasFeatureRenderer/glyphs/cds.js +93 -0
  24. package/esm/CanvasFeatureRenderer/glyphs/childGlyphs.d.ts +5 -0
  25. package/esm/CanvasFeatureRenderer/glyphs/childGlyphs.js +18 -0
  26. package/esm/CanvasFeatureRenderer/glyphs/glyphUtils.d.ts +14 -0
  27. package/esm/CanvasFeatureRenderer/glyphs/glyphUtils.js +125 -0
  28. package/esm/CanvasFeatureRenderer/glyphs/index.d.ts +9 -0
  29. package/esm/CanvasFeatureRenderer/glyphs/index.js +29 -0
  30. package/esm/CanvasFeatureRenderer/glyphs/matureProteinRegion.d.ts +2 -0
  31. package/esm/CanvasFeatureRenderer/glyphs/matureProteinRegion.js +121 -0
  32. package/esm/CanvasFeatureRenderer/glyphs/processed.d.ts +2 -0
  33. package/esm/CanvasFeatureRenderer/glyphs/processed.js +53 -0
  34. package/esm/CanvasFeatureRenderer/glyphs/repeatRegion.d.ts +2 -0
  35. package/esm/CanvasFeatureRenderer/glyphs/repeatRegion.js +104 -0
  36. package/esm/CanvasFeatureRenderer/glyphs/segments.d.ts +2 -0
  37. package/esm/CanvasFeatureRenderer/glyphs/segments.js +65 -0
  38. package/esm/CanvasFeatureRenderer/glyphs/subfeatures.d.ts +2 -0
  39. package/esm/CanvasFeatureRenderer/glyphs/subfeatures.js +132 -0
  40. package/esm/CanvasFeatureRenderer/index.d.ts +3 -0
  41. package/esm/CanvasFeatureRenderer/index.js +23 -0
  42. package/esm/CanvasFeatureRenderer/labelUtils.d.ts +9 -0
  43. package/esm/CanvasFeatureRenderer/labelUtils.js +35 -0
  44. package/esm/CanvasFeatureRenderer/layout/index.d.ts +3 -0
  45. package/esm/CanvasFeatureRenderer/layout/index.js +3 -0
  46. package/esm/CanvasFeatureRenderer/layout/layoutFeature.d.ts +14 -0
  47. package/esm/CanvasFeatureRenderer/layout/layoutFeature.js +40 -0
  48. package/esm/CanvasFeatureRenderer/layout/layoutFeatures.d.ts +13 -0
  49. package/esm/CanvasFeatureRenderer/layout/layoutFeatures.js +59 -0
  50. package/esm/CanvasFeatureRenderer/layout/layoutUtils.d.ts +19 -0
  51. package/esm/CanvasFeatureRenderer/layout/layoutUtils.js +129 -0
  52. package/esm/CanvasFeatureRenderer/makeImageData.d.ts +14 -0
  53. package/esm/CanvasFeatureRenderer/makeImageData.js +90 -0
  54. package/esm/CanvasFeatureRenderer/peptides/aggregateAminoAcids.d.ts +8 -0
  55. package/esm/CanvasFeatureRenderer/peptides/aggregateAminoAcids.js +45 -0
  56. package/esm/CanvasFeatureRenderer/peptides/drawCDSBackground.d.ts +16 -0
  57. package/esm/CanvasFeatureRenderer/peptides/drawCDSBackground.js +24 -0
  58. package/esm/CanvasFeatureRenderer/peptides/drawPeptidesOnCDS.d.ts +15 -0
  59. package/esm/CanvasFeatureRenderer/peptides/drawPeptidesOnCDS.js +28 -0
  60. package/esm/CanvasFeatureRenderer/peptides/index.d.ts +5 -0
  61. package/esm/CanvasFeatureRenderer/peptides/index.js +5 -0
  62. package/esm/CanvasFeatureRenderer/peptides/peptideUtils.d.ts +5 -0
  63. package/esm/CanvasFeatureRenderer/peptides/peptideUtils.js +129 -0
  64. package/esm/CanvasFeatureRenderer/peptides/prepareAminoAcidData.d.ts +9 -0
  65. package/esm/CanvasFeatureRenderer/peptides/prepareAminoAcidData.js +5 -0
  66. package/esm/CanvasFeatureRenderer/renderConfig.d.ts +26 -0
  67. package/esm/CanvasFeatureRenderer/renderConfig.js +35 -0
  68. package/esm/CanvasFeatureRenderer/types.d.ts +97 -0
  69. package/esm/CanvasFeatureRenderer/types.js +1 -0
  70. package/esm/CanvasFeatureRenderer/util.d.ts +22 -0
  71. package/esm/CanvasFeatureRenderer/util.js +50 -0
  72. package/esm/CanvasFeatureRenderer/zoomThresholds.d.ts +4 -0
  73. package/esm/CanvasFeatureRenderer/zoomThresholds.js +8 -0
  74. package/esm/glyphs/index.d.ts +2 -0
  75. package/esm/glyphs/index.js +2 -0
  76. package/esm/index.d.ts +6 -0
  77. package/esm/index.js +10 -0
  78. package/package.json +53 -0
@@ -0,0 +1,152 @@
1
+ import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
+ import { types } from '@jbrowse/mobx-state-tree';
3
+ function x() { }
4
+ const CanvasFeatureRenderer = ConfigurationSchema('CanvasFeatureRenderer', {
5
+ color1: {
6
+ type: 'color',
7
+ description: 'the main color of each feature',
8
+ defaultValue: 'goldenrod',
9
+ contextVariable: ['feature'],
10
+ },
11
+ color2: {
12
+ type: 'color',
13
+ description: 'the secondary color of each feature, used for connecting lines, etc',
14
+ defaultValue: '#f0f',
15
+ contextVariable: ['feature'],
16
+ },
17
+ color3: {
18
+ type: 'color',
19
+ description: 'the tertiary color of each feature, often used for contrasting fills, like on UTRs',
20
+ defaultValue: '#357089',
21
+ contextVariable: ['feature'],
22
+ },
23
+ outline: {
24
+ type: 'color',
25
+ description: 'the outline for features',
26
+ defaultValue: '',
27
+ contextVariable: ['feature'],
28
+ },
29
+ height: {
30
+ type: 'number',
31
+ description: 'height in pixels of the main body of each feature',
32
+ defaultValue: 10,
33
+ contextVariable: ['feature'],
34
+ },
35
+ showLabels: {
36
+ type: 'boolean',
37
+ defaultValue: true,
38
+ },
39
+ showDescriptions: {
40
+ type: 'boolean',
41
+ defaultValue: true,
42
+ },
43
+ subfeatureLabels: {
44
+ type: 'stringEnum',
45
+ model: types.enumeration('subfeatureLabels', [
46
+ 'none',
47
+ 'below',
48
+ 'overlay',
49
+ ]),
50
+ description: 'subfeature label display: "none" hides labels, "below" reserves extra space, "overlay" draws on top of feature',
51
+ defaultValue: 'none',
52
+ },
53
+ mouseover: {
54
+ type: 'string',
55
+ description: 'the mouseover tooltip label for features. Available variables: feature (the feature object), label (evaluated name), description (evaluated description)',
56
+ defaultValue: `jexl:get(feature,'_mouseover') || get(feature,'_mouseOver') || (label && description ? label + '<br/>' + description : (label || description || ''))`,
57
+ contextVariable: ['feature', 'label', 'description'],
58
+ },
59
+ subfeatureMouseover: {
60
+ type: 'string',
61
+ description: 'the mouseover tooltip label for subfeatures (e.g. transcripts). Available variables: feature (the subfeature object)',
62
+ defaultValue: `jexl:get(feature,'name') || get(feature,'id')`,
63
+ contextVariable: ['feature'],
64
+ },
65
+ labels: ConfigurationSchema('CanvasFeatureLabels', {
66
+ name: {
67
+ type: 'string',
68
+ description: 'the primary name of the feature to show, if space is available',
69
+ defaultValue: `jexl:get(feature,'name') || get(feature,'id')`,
70
+ contextVariable: ['feature'],
71
+ },
72
+ nameColor: {
73
+ type: 'color',
74
+ description: 'the color of the name label, if shown',
75
+ defaultValue: '#f0f',
76
+ contextVariable: ['feature'],
77
+ },
78
+ description: {
79
+ type: 'string',
80
+ description: 'the text description to show, if space is available',
81
+ defaultValue: `jexl:get(feature,'note') || get(feature,'description')`,
82
+ contextVariable: ['feature'],
83
+ },
84
+ descriptionColor: {
85
+ type: 'color',
86
+ description: 'the color of the description, if shown',
87
+ defaultValue: 'blue',
88
+ contextVariable: ['feature'],
89
+ },
90
+ fontSize: {
91
+ type: 'number',
92
+ description: 'height in pixels of the text to use for names and descriptions',
93
+ defaultValue: 12,
94
+ contextVariable: ['feature'],
95
+ },
96
+ }),
97
+ displayMode: {
98
+ type: 'stringEnum',
99
+ model: types.enumeration('displayMode', [
100
+ 'normal',
101
+ 'compact',
102
+ 'reducedRepresentation',
103
+ 'collapse',
104
+ ]),
105
+ description: 'Alternative display modes',
106
+ defaultValue: 'normal',
107
+ },
108
+ maxFeatureGlyphExpansion: {
109
+ type: 'number',
110
+ description: "maximum number of pixels on each side of a feature's bounding coordinates that a glyph is allowed to use",
111
+ defaultValue: 500,
112
+ },
113
+ maxHeight: {
114
+ type: 'integer',
115
+ description: 'the maximum height to be used in a rendering',
116
+ defaultValue: 5000,
117
+ },
118
+ subParts: {
119
+ type: 'string',
120
+ description: 'subparts for a glyph',
121
+ defaultValue: 'CDS,UTR,five_prime_UTR,three_prime_UTR',
122
+ },
123
+ impliedUTRs: {
124
+ type: 'boolean',
125
+ description: 'imply UTR from the exon and CDS differences',
126
+ defaultValue: false,
127
+ },
128
+ transcriptTypes: {
129
+ type: 'stringArray',
130
+ defaultValue: ['mRNA', 'transcript', 'primary_transcript'],
131
+ },
132
+ containerTypes: {
133
+ type: 'stringArray',
134
+ defaultValue: ['proteoform_orf'],
135
+ },
136
+ geneGlyphMode: {
137
+ type: 'stringEnum',
138
+ model: types.enumeration('geneGlyphMode', [
139
+ 'all',
140
+ 'longest',
141
+ 'longestCoding',
142
+ ]),
143
+ description: 'Gene glyph display mode: "all" shows all transcripts, "longest" shows only the longest transcript, "longestCoding" shows only the longest coding transcript',
144
+ defaultValue: 'all',
145
+ },
146
+ displayDirectionalChevrons: {
147
+ type: 'boolean',
148
+ description: 'Display directional chevrons on intron lines to indicate strand direction',
149
+ defaultValue: true,
150
+ },
151
+ }, { explicitlyTyped: true });
152
+ export default CanvasFeatureRenderer;
@@ -0,0 +1,136 @@
1
+ declare const SvgFeatureRenderer: import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{}, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{
2
+ color1: {
3
+ type: string;
4
+ description: string;
5
+ defaultValue: string;
6
+ contextVariable: string[];
7
+ };
8
+ color2: {
9
+ type: string;
10
+ description: string;
11
+ defaultValue: string;
12
+ contextVariable: string[];
13
+ };
14
+ color3: {
15
+ type: string;
16
+ description: string;
17
+ defaultValue: string;
18
+ contextVariable: string[];
19
+ };
20
+ outline: {
21
+ type: string;
22
+ description: string;
23
+ defaultValue: string;
24
+ contextVariable: string[];
25
+ };
26
+ height: {
27
+ type: string;
28
+ description: string;
29
+ defaultValue: number;
30
+ contextVariable: string[];
31
+ };
32
+ showLabels: {
33
+ type: string;
34
+ defaultValue: boolean;
35
+ };
36
+ showDescriptions: {
37
+ type: string;
38
+ defaultValue: boolean;
39
+ };
40
+ subfeatureLabels: {
41
+ type: string;
42
+ model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
43
+ description: string;
44
+ defaultValue: string;
45
+ };
46
+ mouseover: {
47
+ type: string;
48
+ description: string;
49
+ defaultValue: string;
50
+ contextVariable: string[];
51
+ };
52
+ subfeatureMouseover: {
53
+ type: string;
54
+ description: string;
55
+ defaultValue: string;
56
+ contextVariable: string[];
57
+ };
58
+ labels: import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{
59
+ name: {
60
+ type: string;
61
+ description: string;
62
+ defaultValue: string;
63
+ contextVariable: string[];
64
+ };
65
+ nameColor: {
66
+ type: string;
67
+ description: string;
68
+ defaultValue: string;
69
+ contextVariable: string[];
70
+ };
71
+ description: {
72
+ type: string;
73
+ description: string;
74
+ defaultValue: string;
75
+ contextVariable: string[];
76
+ };
77
+ descriptionColor: {
78
+ type: string;
79
+ description: string;
80
+ defaultValue: string;
81
+ contextVariable: string[];
82
+ };
83
+ fontSize: {
84
+ type: string;
85
+ description: string;
86
+ defaultValue: number;
87
+ contextVariable: string[];
88
+ };
89
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<undefined, undefined>>;
90
+ displayMode: {
91
+ type: string;
92
+ model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
93
+ description: string;
94
+ defaultValue: string;
95
+ };
96
+ maxFeatureGlyphExpansion: {
97
+ type: string;
98
+ description: string;
99
+ defaultValue: number;
100
+ };
101
+ maxHeight: {
102
+ type: string;
103
+ description: string;
104
+ defaultValue: number;
105
+ };
106
+ subParts: {
107
+ type: string;
108
+ description: string;
109
+ defaultValue: string;
110
+ };
111
+ impliedUTRs: {
112
+ type: string;
113
+ description: string;
114
+ defaultValue: boolean;
115
+ };
116
+ transcriptTypes: {
117
+ type: string;
118
+ defaultValue: string[];
119
+ };
120
+ containerTypes: {
121
+ type: string;
122
+ defaultValue: string[];
123
+ };
124
+ geneGlyphMode: {
125
+ type: string;
126
+ model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
127
+ description: string;
128
+ defaultValue: string;
129
+ };
130
+ displayDirectionalChevrons: {
131
+ type: string;
132
+ description: string;
133
+ defaultValue: boolean;
134
+ };
135
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<undefined, undefined>>, undefined>>;
136
+ export default SvgFeatureRenderer;
@@ -0,0 +1,5 @@
1
+ import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
+ import configSchema from "./configSchema.js";
3
+ function x() { }
4
+ const SvgFeatureRenderer = ConfigurationSchema('SvgFeatureRenderer', {}, { explicitlyTyped: true, baseConfiguration: configSchema });
5
+ export default SvgFeatureRenderer;
@@ -0,0 +1,21 @@
1
+ import type PluginManager from '@jbrowse/core/PluginManager';
2
+ import type { RenderArgsDeserialized } from '@jbrowse/core/pluggableElementTypes/renderers/BoxRendererType';
3
+ import type { Feature } from '@jbrowse/core/util';
4
+ import type { BaseLayout } from '@jbrowse/core/util/layouts';
5
+ export declare function doAll({ layout, features, renderProps, pluginManager, }: {
6
+ pluginManager: PluginManager;
7
+ layout: BaseLayout<unknown>;
8
+ features: Map<string, Feature>;
9
+ renderProps: RenderArgsDeserialized;
10
+ }): Promise<{
11
+ flatbush: ArrayBufferLike;
12
+ items: import("./types.ts").FlatbushItem[];
13
+ subfeatureFlatbush: ArrayBufferLike;
14
+ subfeatureInfos: import("./types.ts").SubfeatureInfo[];
15
+ } & ({
16
+ canvasRecordedData: Record<string, unknown>;
17
+ } | {
18
+ imageData: ImageBitmap;
19
+ } | {
20
+ html: string;
21
+ })>;
@@ -0,0 +1,42 @@
1
+ import { renderToAbstractCanvas, updateStatus } from '@jbrowse/core/util';
2
+ import { layoutFeatures } from "./layout/layoutFeatures.js";
3
+ import { makeImageData } from "./makeImageData.js";
4
+ import { fetchPeptideData } from "./peptides/peptideUtils.js";
5
+ import { createRenderConfigContext } from "./renderConfig.js";
6
+ export async function doAll({ layout, features, renderProps, pluginManager, }) {
7
+ const { statusCallback = () => { }, regions, bpPerPx, config } = renderProps;
8
+ const region = regions[0];
9
+ const width = Math.max(1, (region.end - region.start) / bpPerPx);
10
+ const configContext = createRenderConfigContext(config);
11
+ const layoutRecords = await updateStatus('Computing feature layout', statusCallback, async () => {
12
+ return layoutFeatures({
13
+ features,
14
+ bpPerPx,
15
+ region,
16
+ configContext,
17
+ layout,
18
+ pluginManager,
19
+ });
20
+ });
21
+ const height = Math.max(1, layout.getTotalHeight());
22
+ const peptideDataMap = await updateStatus('Fetching peptide data', statusCallback, async () => {
23
+ return fetchPeptideData(pluginManager, renderProps, features);
24
+ });
25
+ return updateStatus('Rendering features', statusCallback, async () => {
26
+ return renderToAbstractCanvas(width, height, renderProps, ctx => makeImageData({
27
+ ctx,
28
+ layoutRecords,
29
+ canvasWidth: width,
30
+ renderArgs: {
31
+ ...renderProps,
32
+ features,
33
+ layout,
34
+ displayMode: configContext.displayMode,
35
+ peptideDataMap,
36
+ colorByCDS: renderProps.colorByCDS,
37
+ pluginManager,
38
+ },
39
+ configContext,
40
+ }));
41
+ });
42
+ }
@@ -0,0 +1 @@
1
+ export declare function drawChevrons(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, strand: number, color: string, spacing?: number, size?: number): void;
@@ -0,0 +1,25 @@
1
+ export function drawChevrons(ctx, x, y, width, strand, color, spacing = 40, size = 4) {
2
+ if (strand === 0 || width < spacing) {
3
+ return;
4
+ }
5
+ ctx.strokeStyle = color;
6
+ ctx.lineWidth = 0.5;
7
+ ctx.beginPath();
8
+ const halfSize = size / 2;
9
+ const numChevrons = Math.floor(width / spacing);
10
+ const startOffset = (width - numChevrons * spacing) / 2 + spacing / 2;
11
+ for (let i = 0; i < numChevrons; i++) {
12
+ const cx = x + startOffset + i * spacing;
13
+ if (strand === 1) {
14
+ ctx.moveTo(cx - halfSize, y - halfSize);
15
+ ctx.lineTo(cx + halfSize, y);
16
+ ctx.lineTo(cx - halfSize, y + halfSize);
17
+ }
18
+ else {
19
+ ctx.moveTo(cx + halfSize, y - halfSize);
20
+ ctx.lineTo(cx - halfSize, y);
21
+ ctx.lineTo(cx + halfSize, y + halfSize);
22
+ }
23
+ }
24
+ ctx.stroke();
25
+ }
@@ -0,0 +1,3 @@
1
+ import type { DrawContext, FeatureLayout } from './types.ts';
2
+ import type PluginManager from '@jbrowse/core/PluginManager';
3
+ export declare function drawFeature(ctx: CanvasRenderingContext2D, layout: FeatureLayout, drawContext: DrawContext, pluginManager?: PluginManager): void;
@@ -0,0 +1,27 @@
1
+ import { boxGlyph, builtinGlyphs, findPluggableGlyph } from "./glyphs/index.js";
2
+ const glyphMap = Object.fromEntries(builtinGlyphs.map(g => [g.type, g]));
3
+ export function drawFeature(ctx, layout, drawContext, pluginManager) {
4
+ const pluggableGlyph = findPluggableGlyph(layout.feature, pluginManager);
5
+ if (pluggableGlyph) {
6
+ pluggableGlyph.draw({
7
+ ctx,
8
+ feature: layout.feature,
9
+ featureLayout: layout,
10
+ region: drawContext.region,
11
+ bpPerPx: drawContext.bpPerPx,
12
+ config: drawContext.configContext.config,
13
+ theme: drawContext.theme,
14
+ reversed: drawContext.region.reversed ?? false,
15
+ topLevel: true,
16
+ canvasWidth: drawContext.canvasWidth,
17
+ });
18
+ return;
19
+ }
20
+ const glyph = glyphMap[layout.glyphType];
21
+ if (glyph) {
22
+ glyph.draw(ctx, layout, drawContext);
23
+ }
24
+ else {
25
+ boxGlyph.draw(ctx, layout, drawContext);
26
+ }
27
+ }
@@ -0,0 +1,5 @@
1
+ import { type Feature } from '@jbrowse/core/util';
2
+ import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
+ export declare function filterSubpart(feature: Feature, config: AnyConfigurationModel): boolean;
4
+ export declare function makeUTRs(parent: Feature, subs: Feature[]): Feature[];
5
+ export declare function getSubparts(f: Feature, config: AnyConfigurationModel): Feature[];
@@ -0,0 +1,92 @@
1
+ import { readConfObject } from '@jbrowse/core/configuration';
2
+ import { SimpleFeature } from '@jbrowse/core/util';
3
+ import { isUTR } from "./util.js";
4
+ function makeSubpartsFilter(confKey, config) {
5
+ const filter = readConfObject(config, confKey);
6
+ const ret = typeof filter === 'string' ? filter.split(/\s*,\s*/) : filter;
7
+ const lowerRet = new Set(ret.map(t => t.toLowerCase()));
8
+ return (feature) => lowerRet.has(feature.get('type').toLowerCase());
9
+ }
10
+ export function filterSubpart(feature, config) {
11
+ return makeSubpartsFilter('subParts', config)(feature);
12
+ }
13
+ export function makeUTRs(parent, subs) {
14
+ const subparts = [...subs];
15
+ let codeStart = Number.POSITIVE_INFINITY;
16
+ let codeEnd = Number.NEGATIVE_INFINITY;
17
+ let haveLeftUTR;
18
+ let haveRightUTR;
19
+ const exons = [];
20
+ for (const subpart of subparts) {
21
+ const type = subpart.get('type');
22
+ if (/^cds/i.test(type)) {
23
+ if (codeStart > subpart.get('start')) {
24
+ codeStart = subpart.get('start');
25
+ }
26
+ if (codeEnd < subpart.get('end')) {
27
+ codeEnd = subpart.get('end');
28
+ }
29
+ }
30
+ else if (/exon/i.test(type)) {
31
+ exons.push(subpart);
32
+ }
33
+ else if (isUTR(subpart)) {
34
+ haveLeftUTR = subpart.get('start') === parent.get('start');
35
+ haveRightUTR = subpart.get('end') === parent.get('end');
36
+ }
37
+ }
38
+ if (!(exons.length &&
39
+ codeStart < Number.POSITIVE_INFINITY &&
40
+ codeEnd > Number.NEGATIVE_INFINITY)) {
41
+ return subparts;
42
+ }
43
+ exons.sort((a, b) => a.get('start') - b.get('start'));
44
+ const strand = parent.get('strand');
45
+ let start;
46
+ let end;
47
+ if (!haveLeftUTR) {
48
+ for (const [i, exon] of exons.entries()) {
49
+ start = exon.get('start');
50
+ if (start >= codeStart) {
51
+ break;
52
+ }
53
+ end = Math.min(codeStart, exon.get('end'));
54
+ const type = strand >= 0 ? 'five_prime_UTR' : 'three_prime_UTR';
55
+ subparts.unshift(new SimpleFeature({
56
+ parent,
57
+ id: `${parent.id()}_${type}_${i}`,
58
+ data: { start, end, strand, type },
59
+ }));
60
+ }
61
+ }
62
+ if (!haveRightUTR) {
63
+ for (let i = exons.length - 1; i >= 0; i--) {
64
+ end = exons[i].get('end');
65
+ if (end <= codeEnd) {
66
+ break;
67
+ }
68
+ start = Math.max(codeEnd, exons[i].get('start'));
69
+ const type = strand >= 0 ? 'three_prime_UTR' : 'five_prime_UTR';
70
+ subparts.push(new SimpleFeature({
71
+ parent,
72
+ id: `${parent.id()}_${type}_${i}`,
73
+ data: { start, end, strand, type },
74
+ }));
75
+ }
76
+ }
77
+ return subparts;
78
+ }
79
+ export function getSubparts(f, config) {
80
+ let c = f.get('subfeatures');
81
+ if (!c || c.length === 0) {
82
+ return [];
83
+ }
84
+ const hasUTRs = c.some(child => isUTR(child));
85
+ const isTranscript = ['mRNA', 'transcript'].includes(f.get('type'));
86
+ const impliedUTRs = !hasUTRs && isTranscript;
87
+ if (impliedUTRs || readConfObject(config, 'impliedUTRs')) {
88
+ c = makeUTRs(f, c);
89
+ }
90
+ const subpartFilter = makeSubpartsFilter('subParts', config);
91
+ return c.filter(subpartFilter);
92
+ }
@@ -0,0 +1,23 @@
1
+ import type { RenderConfigContext } from './renderConfig.ts';
2
+ import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
+ import type { Feature } from '@jbrowse/core/util';
4
+ import type { FloatingLabelData } from '@jbrowse/plugin-linear-genome-view';
5
+ export declare function createFeatureFloatingLabels({ feature, config, configContext, nameColor, descriptionColor, name: rawName, description: rawDescription, }: {
6
+ feature: Feature;
7
+ config: AnyConfigurationModel;
8
+ configContext: RenderConfigContext;
9
+ nameColor: string;
10
+ descriptionColor: string;
11
+ name: string;
12
+ description: string;
13
+ }): FloatingLabelData[];
14
+ export declare function createTranscriptFloatingLabel({ displayLabel, featureHeight, subfeatureLabels, color, parentFeatureId, subfeatureId, tooltip, }: {
15
+ displayLabel: string;
16
+ featureHeight: number;
17
+ subfeatureLabels: string;
18
+ color: string;
19
+ parentFeatureId: string;
20
+ subfeatureId: string;
21
+ tooltip: string;
22
+ }): FloatingLabelData | null;
23
+ export { type FloatingLabelData } from '@jbrowse/plugin-linear-genome-view';
@@ -0,0 +1,65 @@
1
+ import { measureText } from '@jbrowse/core/util';
2
+ import { readCachedConfig } from "./renderConfig.js";
3
+ import { truncateLabel } from "./util.js";
4
+ const FLOATING_LABEL_FONT_SIZE = 11;
5
+ export function createFeatureFloatingLabels({ feature, config, configContext, nameColor, descriptionColor, name: rawName, description: rawDescription, }) {
6
+ const { showLabels, showDescriptions, fontHeight } = configContext;
7
+ const name = truncateLabel(rawName);
8
+ const description = truncateLabel(rawDescription);
9
+ const shouldShowLabel = /\S/.test(name) && showLabels;
10
+ const shouldShowDescription = /\S/.test(description) && showDescriptions;
11
+ if (!shouldShowLabel && !shouldShowDescription) {
12
+ return [];
13
+ }
14
+ const actualFontHeight = readCachedConfig(fontHeight, config, ['labels', 'fontSize'], feature);
15
+ const floatingLabels = [];
16
+ if (shouldShowLabel && shouldShowDescription) {
17
+ floatingLabels.push({
18
+ text: name,
19
+ relativeY: 0,
20
+ color: nameColor,
21
+ textWidth: measureText(name, FLOATING_LABEL_FONT_SIZE),
22
+ }, {
23
+ text: description,
24
+ relativeY: actualFontHeight,
25
+ color: descriptionColor,
26
+ textWidth: measureText(description, FLOATING_LABEL_FONT_SIZE),
27
+ });
28
+ }
29
+ else if (shouldShowLabel) {
30
+ floatingLabels.push({
31
+ text: name,
32
+ relativeY: 0,
33
+ color: nameColor,
34
+ textWidth: measureText(name, FLOATING_LABEL_FONT_SIZE),
35
+ });
36
+ }
37
+ else if (shouldShowDescription) {
38
+ floatingLabels.push({
39
+ text: description,
40
+ relativeY: 0,
41
+ color: descriptionColor,
42
+ textWidth: measureText(description, FLOATING_LABEL_FONT_SIZE),
43
+ });
44
+ }
45
+ return floatingLabels;
46
+ }
47
+ export function createTranscriptFloatingLabel({ displayLabel, featureHeight, subfeatureLabels, color, parentFeatureId, subfeatureId, tooltip, }) {
48
+ if (!displayLabel) {
49
+ return null;
50
+ }
51
+ const truncatedName = truncateLabel(displayLabel);
52
+ const isOverlay = subfeatureLabels === 'overlay';
53
+ const relativeY = isOverlay ? 2 - featureHeight : 0;
54
+ return {
55
+ text: truncatedName,
56
+ relativeY,
57
+ color,
58
+ textWidth: measureText(truncatedName, FLOATING_LABEL_FONT_SIZE),
59
+ isOverlay,
60
+ parentFeatureId,
61
+ subfeatureId,
62
+ tooltip,
63
+ };
64
+ }
65
+ export {} from '@jbrowse/plugin-linear-genome-view';
@@ -0,0 +1,2 @@
1
+ import type { Glyph } from '../types.ts';
2
+ export declare const boxGlyph: Glyph;