react-msaview 6.2.3 → 6.3.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 (80) hide show
  1. package/bundle/index.js +104 -104
  2. package/bundle/index.js.map +4 -4
  3. package/dist/components/MSAViewer.d.ts +10 -1
  4. package/dist/components/MSAViewer.js +3 -1
  5. package/dist/components/MSAViewer.js.map +1 -1
  6. package/dist/components/minimap/Minimap.js +1 -1
  7. package/dist/components/minimap/Minimap.js.map +1 -1
  8. package/dist/components/minimap/MinimapSVG.js +2 -2
  9. package/dist/components/minimap/MinimapSVG.js.map +1 -1
  10. package/dist/components/msa/MSAMouseoverCanvas.js +4 -2
  11. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
  12. package/dist/components/msa/msaRaster.d.ts +5 -4
  13. package/dist/components/msa/msaRaster.js +10 -6
  14. package/dist/components/msa/msaRaster.js.map +1 -1
  15. package/dist/components/msa/renderHighlights.d.ts +31 -0
  16. package/dist/components/msa/renderHighlights.js +49 -0
  17. package/dist/components/msa/renderHighlights.js.map +1 -0
  18. package/dist/components/msa/renderMSAMouseover.d.ts +3 -1
  19. package/dist/components/msa/renderMSAMouseover.js +11 -1
  20. package/dist/components/msa/renderMSAMouseover.js.map +1 -1
  21. package/dist/components/tracks/drawTracks.js +4 -0
  22. package/dist/components/tracks/drawTracks.js.map +1 -1
  23. package/dist/components/tree/renderTreeCanvas.js +31 -0
  24. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  25. package/dist/exportFileName.d.ts +6 -0
  26. package/dist/exportFileName.js +15 -0
  27. package/dist/exportFileName.js.map +1 -0
  28. package/dist/headlessRenderEnv.d.ts +4 -1
  29. package/dist/headlessRenderEnv.js +6 -3
  30. package/dist/headlessRenderEnv.js.map +1 -1
  31. package/dist/index.d.ts +2 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/model.d.ts +172 -9
  34. package/dist/model.js +134 -3
  35. package/dist/model.js.map +1 -1
  36. package/dist/renderToSvg.js +30 -6
  37. package/dist/renderToSvg.js.map +1 -1
  38. package/dist/svgTestUtil.d.ts +1662 -0
  39. package/dist/svgTestUtil.js +28 -0
  40. package/dist/svgTestUtil.js.map +1 -0
  41. package/dist/types.d.ts +33 -0
  42. package/dist/umd.d.ts +1 -0
  43. package/dist/umd.js +3 -0
  44. package/dist/umd.js.map +1 -1
  45. package/dist/util.d.ts +1 -0
  46. package/dist/util.js +7 -0
  47. package/dist/util.js.map +1 -1
  48. package/dist/version.d.ts +1 -1
  49. package/dist/version.js +1 -1
  50. package/package.json +3 -3
  51. package/src/columnTracks.test.ts +97 -0
  52. package/src/components/MSAViewer.tsx +13 -0
  53. package/src/components/minimap/Minimap.tsx +1 -1
  54. package/src/components/minimap/MinimapSVG.tsx +2 -2
  55. package/src/components/msa/MSAMouseoverCanvas.tsx +4 -2
  56. package/src/components/msa/msaRaster.ts +10 -6
  57. package/src/components/msa/renderHighlights.ts +86 -0
  58. package/src/components/msa/renderMSAMouseover.ts +14 -0
  59. package/src/components/tracks/drawTracks.ts +4 -0
  60. package/src/components/tree/renderTreeCanvas.ts +56 -0
  61. package/src/exportFileName.test.ts +40 -0
  62. package/src/exportFileName.ts +20 -0
  63. package/src/headlessRenderEnv.ts +20 -11
  64. package/src/highlights.test.ts +70 -0
  65. package/src/impgRender.test.tsx +2 -4
  66. package/src/index.ts +4 -0
  67. package/src/model.ts +162 -10
  68. package/src/renderColumnTracksSvg.test.tsx +108 -0
  69. package/src/renderDomainsSvg.test.tsx +25 -10
  70. package/src/renderHighlightsSvg.test.tsx +85 -0
  71. package/src/renderMinimapSvg.test.tsx +6 -13
  72. package/src/renderRasterSvg.test.tsx +21 -93
  73. package/src/renderSequenceLogoSvg.test.tsx +4 -17
  74. package/src/renderToSvg.test.tsx +7 -21
  75. package/src/renderToSvg.tsx +32 -6
  76. package/src/svgTestUtil.ts +40 -0
  77. package/src/types.ts +39 -0
  78. package/src/umd.ts +3 -0
  79. package/src/util.ts +8 -0
  80. package/src/version.ts +1 -1
@@ -65,8 +65,11 @@ export class HeadlessDOMPoint {
65
65
  * average for layout and, more usefully, exactly predictable: a caller can
66
66
  * compute the width a renderer will see rather than hardcoding a number
67
67
  * measured from one machine's fonts.
68
+ *
69
+ * `contextExtras` adds to the context a test hands out -- the raster test
70
+ * supplies the ImageData methods that make the export take its image path.
68
71
  */
69
- export function installHeadlessRenderEnv(win = globalThis) {
72
+ export function installHeadlessRenderEnv(win = globalThis, contextExtras = {}) {
70
73
  const g = globalThis;
71
74
  g.DOMMatrix = HeadlessDOMMatrix;
72
75
  g.DOMPoint = HeadlessDOMPoint;
@@ -74,7 +77,7 @@ export function installHeadlessRenderEnv(win = globalThis) {
74
77
  .HTMLCanvasElement;
75
78
  canvas.prototype.getContext = function () {
76
79
  let font = '10px sans-serif';
77
- return {
80
+ return Object.assign({
78
81
  get font() {
79
82
  return font;
80
83
  },
@@ -84,7 +87,7 @@ export function installHeadlessRenderEnv(win = globalThis) {
84
87
  measureText: (t) => ({
85
88
  width: t.length * (Number.parseFloat(font) || 10) * CHAR_WIDTH_RATIO,
86
89
  }),
87
- };
90
+ }, contextExtras);
88
91
  };
89
92
  }
90
93
  /** the per-character width factor `measureText` above reports */
@@ -1 +1 @@
1
- {"version":3,"file":"headlessRenderEnv.js","sourceRoot":"","sources":["../src/headlessRenderEnv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,iBAAiB;IAC5B,CAAC,CAAQ;IACT,CAAC,CAAQ;IACT,CAAC,CAAQ;IACT,CAAC,CAAQ;IACT,CAAC,CAAQ;IACT,CAAC,CAAQ;IAET,YAAY,IAAe;QACzB,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,CAAA;QAC7D,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;IACZ,CAAC;IAED,QAAQ,CAAC,CAAoB;QAC3B,OAAO,IAAI,iBAAiB,CAAC;YAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;SACrC,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,CAAC,CAAS,EAAE,CAAC,GAAG,CAAC;QACxB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACjE,CAAC;IAED,KAAK,CAAC,CAAS,EAAE,CAAC,GAAG,CAAC;QACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACjE,CAAC;CACF;AAED,MAAM,OAAO,gBAAgB;IAElB,CAAC;IACD,CAAC;IAFV,YACS,CAAC,GAAG,CAAC,EACL,CAAC,GAAG,CAAC;iBADL,CAAC;iBACD,CAAC;IACP,CAAC;IAEJ,eAAe,CAAC,CAAoB;QAClC,OAAO,IAAI,gBAAgB,CACzB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EACjC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAClC,CAAA;IACH,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAG,GAAY,UAAU;IAChE,MAAM,CAAC,GAAG,UAAqC,CAAA;IAC/C,CAAC,CAAC,SAAS,GAAG,iBAAiB,CAAA;IAC/B,CAAC,CAAC,QAAQ,GAAG,gBAAgB,CAAA;IAC7B,MAAM,MAAM,GAAI,GAAuD;SACpE,iBAAiB,CAAA;IACpB,MAAM,CAAC,SAAS,CAAC,UAAU,GAAG;QAC5B,IAAI,IAAI,GAAG,iBAAiB,CAAA;QAC5B,OAAO;YACL,IAAI,IAAI;gBACN,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,IAAI,CAAC,CAAS;gBAChB,IAAI,GAAG,CAAC,CAAA;YACV,CAAC;YACD,WAAW,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC;gBAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,gBAAgB;aACrE,CAAC;SACoC,CAAA;IAC1C,CAA6D,CAAA;AAC/D,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA"}
1
+ {"version":3,"file":"headlessRenderEnv.js","sourceRoot":"","sources":["../src/headlessRenderEnv.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { renderToSvg } from './renderToSvg.tsx';
2
+ export type { ExportSvgOptions } from './renderToSvg.tsx';
2
3
  export { CHAR_WIDTH_RATIO, installHeadlessRenderEnv, } from './headlessRenderEnv.ts';
3
4
  export { default as MSAView } from './components/Loading.tsx';
4
5
  export { default as MSAViewer } from './components/MSAViewer.tsx';
@@ -7,4 +8,4 @@ export type { MSAFormat, MSAParserType } from 'msa-parsers';
7
8
  export type { HierarchyNode } from './hierarchy.ts';
8
9
  export type { InterProScanResults } from 'msa-parsers';
9
10
  export type { ColumnCounts } from './columnCounts.ts';
10
- export type { Accession, Annotation, BasicTrack, BasicTrackModel, DomainBand, Node, NodeWithIds, NodeWithIdsAndLength, TextTrackModel, TidyDomainAnnotation, } from './types.ts';
11
+ export type { Accession, Annotation, BasicTrack, BasicTrackModel, ColumnTrackSpec, DomainBand, Highlight, Node, NodeWithIds, NodeWithIdsAndLength, ResolvedHighlight, TextTrackModel, TidyDomainAnnotation, } from './types.ts';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,yDAAyD;AACzD,+EAA+E;AAC/E,6EAA6E;AAC7E,gFAAgF;AAChF,0EAA0E;AAC1E,yEAAyE;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAmB,CAAA;AAC/C,8EAA8E;AAC9E,yDAAyD;AACzD,OAAO,EACL,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAA0B,CAAA;AAC7D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,2BAA4B,CAAA;AACjE,OAAO,EAAqB,OAAO,IAAI,SAAS,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,yDAAyD;AACzD,+EAA+E;AAC/E,6EAA6E;AAC7E,gFAAgF;AAChF,0EAA0E;AAC1E,yEAAyE;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAmB,CAAA;AAE/C,8EAA8E;AAC9E,yDAAyD;AACzD,OAAO,EACL,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAA0B,CAAA;AAC7D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,2BAA4B,CAAA;AACjE,OAAO,EAAqB,OAAO,IAAI,SAAS,EAAE,MAAM,YAAY,CAAA"}
package/dist/model.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { HierarchyNode } from './hierarchy.ts';
2
- import type { Annotation, BasicTrack, DomainBand, NodeWithIds, NodeWithIdsAndLength } from './types.ts';
2
+ import type { ExportSvgOptions } from './renderToSvg.tsx';
3
+ import type { Annotation, BasicTrack, ColumnTrackSpec, DomainBand, Highlight, NodeWithIds, NodeWithIdsAndLength, ResolvedHighlight } from './types.ts';
3
4
  import type { FileLocation as FileLocationType } from '@jbrowse/core/util/types';
4
5
  import type { Instance } from '@jbrowse/mobx-state-tree';
5
- import type { Theme } from '@mui/material';
6
6
  import type { InterProScanResults } from 'msa-parsers';
7
7
  /**
8
8
  * The snapshot properties reset() carries across a return to the import form:
@@ -55,7 +55,7 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
55
55
  colorSchemeName: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
56
56
  showColumnStats: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
57
57
  msaFormat: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<import("msa-parsers").MSAFormat>>;
58
- }, "allowedGappyness" | "colWidth" | "collapsed" | "currentAlignment" | "data" | "drawMsaLetters" | "featureFilters" | "gffFilehandle" | "height" | "hideGaps" | "highlightColumns" | "id" | "msaFilehandle" | "relativeTo" | "rowHeight" | "scrollX" | "scrollY" | "scrollZoom" | "showDomainLegend" | "showDomains" | "showOnly" | "subFeatureRows" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffTracks" | "type"> & {
58
+ }, "allowedGappyness" | "colWidth" | "collapsed" | "columnTracks" | "currentAlignment" | "data" | "drawMsaLetters" | "featureFilters" | "gffFilehandle" | "height" | "hideGaps" | "highlightColumns" | "highlights" | "id" | "msaFilehandle" | "relativeTo" | "rowHeight" | "scrollX" | "scrollY" | "scrollZoom" | "showDomainLegend" | "showDomains" | "showOnly" | "subFeatureRows" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffTracks" | "type"> & {
59
59
  /**
60
60
  * #property
61
61
  * id of view, randomly generated if not provided
@@ -541,6 +541,13 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
541
541
  * hidden-by-default track adds nothing to the shared URL.
542
542
  */
543
543
  turnedOffTracks: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IMapType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>>, [undefined]>;
544
+ /**
545
+ * #property
546
+ * tracks supplied as data rather than computed from the alignment:
547
+ * per-column values drawn as bars, or a per-column string drawn as a
548
+ * text track. See docs/layers.md
549
+ */
550
+ columnTracks: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<ColumnTrackSpec, ColumnTrackSpec, ColumnTrackSpec>>, [undefined]>;
544
551
  /**
545
552
  * #property
546
553
  * data from the loaded tree/msa/treeMetadata, generally loaded by
@@ -576,6 +583,14 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
576
583
  * in afterCreate.
577
584
  */
578
585
  highlightColumns: import("@jbrowse/mobx-state-tree").IType<number[] | undefined, number[] | undefined, number[] | undefined>;
586
+ /**
587
+ * #property
588
+ * labeled highlights in 1-based inclusive coordinates: a column span
589
+ * `{start, end}`, a residue span `{row, start, end}` of a named row,
590
+ * or a row set `{rows}`, each with an optional `label` and `color`.
591
+ * Persists in the snapshot, so a computed answer travels in the URL.
592
+ */
593
+ highlights: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<Highlight, Highlight, Highlight>>, [undefined]>;
579
594
  }, {
580
595
  queueOfDialogs: [import("@jbrowse/core/util").DialogComponentType, any][];
581
596
  } & {
@@ -766,6 +781,10 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
766
781
  * in-repo caller, so do not flag it as dead code — it is public API.
767
782
  */
768
783
  setHighlightedColumns(columns?: number[]): void;
784
+ /**
785
+ * #action
786
+ */
787
+ setHighlights(highlights: Highlight[]): void;
769
788
  /**
770
789
  * #action
771
790
  * toggle the annotation overlay on the alignment
@@ -1229,6 +1248,10 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
1229
1248
  * #action
1230
1249
  */
1231
1250
  setScrollX(n: number): void;
1251
+ /**
1252
+ * #action
1253
+ */
1254
+ setColumnTracks(tracks: ColumnTrackSpec[]): void;
1232
1255
  /**
1233
1256
  * #action
1234
1257
  */
@@ -1265,6 +1288,19 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
1265
1288
  * #getter
1266
1289
  */
1267
1290
  readonly adapterTrackModels: BasicTrack[];
1291
+ /**
1292
+ * #getter
1293
+ * a data track's values or string, projected from its row's residues
1294
+ * onto alignment columns when it names a row
1295
+ */
1296
+ readonly columnTrackContent: Map<string, {
1297
+ values?: number[];
1298
+ data?: string;
1299
+ }>;
1300
+ /**
1301
+ * #getter
1302
+ */
1303
+ readonly columnTrackModels: BasicTrack[];
1268
1304
  /**
1269
1305
  * #getter
1270
1306
  */
@@ -1454,6 +1490,14 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
1454
1490
  start: number;
1455
1491
  end: number;
1456
1492
  }[];
1493
+ /**
1494
+ * #getter
1495
+ * `highlights` projected onto what is on screen: residue spans go
1496
+ * through the named row's gap structure, column spans through the
1497
+ * hidden-column list, and a span that lands entirely on hidden columns
1498
+ * is dropped. Row names that match no row are ignored.
1499
+ */
1500
+ readonly resolvedHighlights: ResolvedHighlight[];
1457
1501
  /**
1458
1502
  * #getter
1459
1503
  * per-column summary statistics for the hovered column: consensus residue
@@ -1507,12 +1551,7 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
1507
1551
  /**
1508
1552
  * #action
1509
1553
  */
1510
- exportSVG(opts: {
1511
- theme: Theme;
1512
- includeMinimap?: boolean;
1513
- includeTracks?: boolean;
1514
- exportType: 'entire' | 'viewport';
1515
- }): Promise<void>;
1554
+ exportSVG(opts: ExportSvgOptions): Promise<void>;
1516
1555
  initFilter(arg: string): void;
1517
1556
  setFilter(arg: string, flag: boolean): void;
1518
1557
  /**
@@ -1541,6 +1580,129 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
1541
1580
  drawTree: boolean;
1542
1581
  drawNodeBubbles: boolean;
1543
1582
  autoTreeAreaWidth: boolean;
1583
+ columnTracks: ColumnTrackSpec[];
1584
+ id: string;
1585
+ showDomains: boolean;
1586
+ showDomainLegend: boolean;
1587
+ hideGaps: boolean;
1588
+ allowedGappyness: number;
1589
+ subFeatureRows: boolean;
1590
+ type: "MsaView";
1591
+ drawMsaLetters: boolean;
1592
+ scrollZoom: boolean;
1593
+ height: number;
1594
+ rowHeight: number;
1595
+ scrollY: number;
1596
+ scrollX: number;
1597
+ colWidth: number;
1598
+ treeFilehandle: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1599
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"LocalPathLocation">;
1600
+ localPath: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1601
+ }> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1602
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"BlobLocation">;
1603
+ name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1604
+ blobId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1605
+ }> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1606
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"FileHandleLocation">;
1607
+ name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1608
+ handleId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1609
+ }> | {
1610
+ locationType: "UriLocation";
1611
+ uri: string;
1612
+ internetAccountId: string | undefined;
1613
+ internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1614
+ internetAccountType: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1615
+ authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
1616
+ }> | undefined;
1617
+ } | undefined;
1618
+ msaFilehandle: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1619
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"LocalPathLocation">;
1620
+ localPath: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1621
+ }> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1622
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"BlobLocation">;
1623
+ name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1624
+ blobId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1625
+ }> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1626
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"FileHandleLocation">;
1627
+ name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1628
+ handleId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1629
+ }> | {
1630
+ locationType: "UriLocation";
1631
+ uri: string;
1632
+ internetAccountId: string | undefined;
1633
+ internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1634
+ internetAccountType: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1635
+ authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
1636
+ }> | undefined;
1637
+ } | undefined;
1638
+ treeMetadataFilehandle: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1639
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"LocalPathLocation">;
1640
+ localPath: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1641
+ }> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1642
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"BlobLocation">;
1643
+ name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1644
+ blobId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1645
+ }> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1646
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"FileHandleLocation">;
1647
+ name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1648
+ handleId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1649
+ }> | {
1650
+ locationType: "UriLocation";
1651
+ uri: string;
1652
+ internetAccountId: string | undefined;
1653
+ internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1654
+ internetAccountType: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1655
+ authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
1656
+ }> | undefined;
1657
+ } | undefined;
1658
+ gffFilehandle: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1659
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"LocalPathLocation">;
1660
+ localPath: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1661
+ }> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1662
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"BlobLocation">;
1663
+ name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1664
+ blobId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1665
+ }> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1666
+ locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"FileHandleLocation">;
1667
+ name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1668
+ handleId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1669
+ }> | {
1670
+ locationType: "UriLocation";
1671
+ uri: string;
1672
+ internetAccountId: string | undefined;
1673
+ internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
1674
+ internetAccountType: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
1675
+ authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
1676
+ }> | undefined;
1677
+ } | undefined;
1678
+ currentAlignment: number;
1679
+ collapsed: string[];
1680
+ showOnly: string | undefined;
1681
+ turnedOffTracks: import("mobx").IKeyValueMap<boolean>;
1682
+ featureFilters: import("mobx").IKeyValueMap<boolean>;
1683
+ relativeTo: string | undefined;
1684
+ highlightColumns: number[] | undefined;
1685
+ highlights: Highlight[];
1686
+ data: {
1687
+ tree?: string | undefined;
1688
+ msa?: string | undefined;
1689
+ treeMetadata?: string | undefined;
1690
+ gff?: string | undefined;
1691
+ };
1692
+ } | {
1693
+ bgColor: boolean;
1694
+ colorSchemeName: string;
1695
+ showColumnStats: boolean;
1696
+ msaFormat: import("msa-parsers").MSAFormat | undefined;
1697
+ drawLabels: boolean;
1698
+ labelsAlignRight: boolean;
1699
+ treeAreaWidth: number;
1700
+ treeWidth: number;
1701
+ showBranchLen: boolean;
1702
+ drawTree: boolean;
1703
+ drawNodeBubbles: boolean;
1704
+ autoTreeAreaWidth: boolean;
1705
+ columnTracks?: undefined;
1544
1706
  id: string;
1545
1707
  showDomains: boolean;
1546
1708
  showDomainLegend: boolean;
@@ -1642,6 +1804,7 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
1642
1804
  featureFilters: import("mobx").IKeyValueMap<boolean>;
1643
1805
  relativeTo: string | undefined;
1644
1806
  highlightColumns: number[] | undefined;
1807
+ highlights: Highlight[];
1645
1808
  data: {
1646
1809
  tree?: string | undefined;
1647
1810
  msa?: string | undefined;
package/dist/model.js CHANGED
@@ -12,6 +12,7 @@ import { columnCountsFromRows, letterOfResidueSlot } from './columnCounts.js';
12
12
  import TrackBlocks from './components/tracks/TrackBlocks.js';
13
13
  import { defaultAllowedGappyness, defaultColWidth, defaultColorSchemeName, defaultCurrentAlignment, defaultDrawMsaLetters, defaultHeight, defaultHideGaps, defaultRowHeight, defaultScrollX, defaultScrollY, defaultScrollZoom, defaultShowDomainLegend, defaultShowDomains, defaultSubFeatureRows, labelReferenceFontSize, maxCellSize, minColWidth, minLetterColWidth, minLetterRowHeight, minRowHeight, segmentFeatureTypes, segmentShades, } from './constants.js';
14
14
  import { createPaletteMap } from './createPaletteMap.js';
15
+ import { exportFileName } from './exportFileName.js';
15
16
  import { fetchTextWithProgress, isAbortError } from './fetchUtils.js';
16
17
  import { flatToTree } from './flatToTree.js';
17
18
  import { calcDepthToLeaf, clusterLayout, collapse, collapsedSubtreeMaxLength, find, findMaxBranchLen, forEachDescendant, hierarchy, leaves, links, maxLength, setBrLength, sort, sum as hierarchySum, } from './hierarchy.js';
@@ -27,7 +28,7 @@ import { globalColToVisibleCol, visibleColToGlobalCol, visibleColToSeqPosForRow,
27
28
  import { buildSeqPosIndex } from './seqPosToGlobalCol.js';
28
29
  import { maxBitsFor } from './sequenceLogo.js';
29
30
  import { stripDefault } from './stripDefault.js';
30
- import { computeRowInsertions, len, skipBlanks, transform } from './util.js';
31
+ import { computeRowInsertions, dropBlanks, len, skipBlanks, transform, } from './util.js';
31
32
  import { saveAs } from './vendor/fileSaver.js';
32
33
  function parseTreeText(text) {
33
34
  if (text.startsWith('BioTreeContainer')) {
@@ -39,6 +40,13 @@ function parseTreeText(text) {
39
40
  // conservation does and costs three times the vertical space, so it waits to be
40
41
  // asked for.
41
42
  const defaultOffTracks = new Set(['sequence-logo']);
43
+ // a data track over this size stays in the live model but leaves the snapshot,
44
+ // the same rule DataModel applies to an inline document
45
+ const maxColumnTrackSnapshotBytes = 50_000;
46
+ function smallColumnTracks(tracks) {
47
+ const kept = tracks?.filter(t => JSON.stringify(t).length <= maxColumnTrackSnapshotBytes);
48
+ return kept?.length ? { columnTracks: kept } : {};
49
+ }
42
50
  /**
43
51
  * The snapshot properties reset() carries across a return to the import form:
44
52
  * display preferences and layout, nothing derived from the loaded file.
@@ -221,6 +229,13 @@ function stateModelFactory() {
221
229
  * hidden-by-default track adds nothing to the shared URL.
222
230
  */
223
231
  turnedOffTracks: stripDefault(types.map(types.boolean), {}),
232
+ /**
233
+ * #property
234
+ * tracks supplied as data rather than computed from the alignment:
235
+ * per-column values drawn as bars, or a per-column string drawn as a
236
+ * text track. See docs/layers.md
237
+ */
238
+ columnTracks: stripDefault(types.array(types.frozen()), []),
224
239
  /**
225
240
  * #property
226
241
  * data from the loaded tree/msa/treeMetadata, generally loaded by
@@ -248,6 +263,14 @@ function stateModelFactory() {
248
263
  * in afterCreate.
249
264
  */
250
265
  highlightColumns: types.frozen(),
266
+ /**
267
+ * #property
268
+ * labeled highlights in 1-based inclusive coordinates: a column span
269
+ * `{start, end}`, a residue span `{row, start, end}` of a named row,
270
+ * or a row set `{rows}`, each with an optional `label` and `color`.
271
+ * Persists in the snapshot, so a computed answer travels in the URL.
272
+ */
273
+ highlights: stripDefault(types.array(types.frozen()), []),
251
274
  }))
252
275
  .volatile(() => ({
253
276
  /**
@@ -435,6 +458,12 @@ function stateModelFactory() {
435
458
  setHighlightedColumns(columns) {
436
459
  self.highlightedColumns = columns;
437
460
  },
461
+ /**
462
+ * #action
463
+ */
464
+ setHighlights(highlights) {
465
+ self.highlights.replace(highlights);
466
+ },
438
467
  /**
439
468
  * #action
440
469
  * toggle the annotation overlay on the alignment
@@ -1305,6 +1334,12 @@ function stateModelFactory() {
1305
1334
  setScrollX(n) {
1306
1335
  self.scrollX = clamp(n, self.maxScrollX, 0);
1307
1336
  },
1337
+ /**
1338
+ * #action
1339
+ */
1340
+ setColumnTracks(tracks) {
1341
+ self.columnTracks.replace(tracks);
1342
+ },
1308
1343
  /**
1309
1344
  * #action
1310
1345
  */
@@ -1398,6 +1433,59 @@ function stateModelFactory() {
1398
1433
  ReactComponent: TrackBlocks,
1399
1434
  }));
1400
1435
  },
1436
+ /**
1437
+ * #getter
1438
+ * a data track's values or string, projected from its row's residues
1439
+ * onto alignment columns when it names a row
1440
+ */
1441
+ get columnTrackContent() {
1442
+ const { MSA, blanks, hideGapsEffective } = self;
1443
+ const width = MSA?.getWidth() ?? 0;
1444
+ const project = (track, items, fill) => {
1445
+ if (!track.row) {
1446
+ return items;
1447
+ }
1448
+ const out = Array.from({ length: width }, () => fill);
1449
+ const index = self.seqPosGlobalColIndex.get(track.row);
1450
+ items.forEach((item, seqPos) => {
1451
+ const col = index?.[seqPos];
1452
+ if (col !== undefined) {
1453
+ out[col] = item;
1454
+ }
1455
+ });
1456
+ return out;
1457
+ };
1458
+ const skip = (items) => hideGapsEffective ? dropBlanks(blanks, items) : items;
1459
+ return new Map(self.columnTracks.map(track => {
1460
+ if (track.kind === 'bar') {
1461
+ const max = track.max ?? 1;
1462
+ const values = skip(project(track, track.values ?? [], 0)).map(v => Math.min(1, Math.max(0, v / max)));
1463
+ return [track.id, { values }];
1464
+ }
1465
+ const data = skip(project(track, (track.data ?? '').split(''), ' '));
1466
+ return [track.id, { data: data.join('') }];
1467
+ }));
1468
+ },
1469
+ /**
1470
+ * #getter
1471
+ */
1472
+ get columnTrackModels() {
1473
+ return self.columnTracks.map(track => ({
1474
+ model: {
1475
+ id: track.id,
1476
+ name: track.name,
1477
+ kind: track.kind,
1478
+ height: track.height ??
1479
+ (track.kind === 'bar'
1480
+ ? self.conservationTrackHeight
1481
+ : self.rowHeight),
1482
+ barColor: track.color,
1483
+ customColorScheme: track.colors,
1484
+ data: this.columnTrackContent.get(track.id)?.data,
1485
+ },
1486
+ ReactComponent: TrackBlocks,
1487
+ }));
1488
+ },
1401
1489
  /**
1402
1490
  * #getter
1403
1491
  */
@@ -1424,6 +1512,7 @@ function stateModelFactory() {
1424
1512
  };
1425
1513
  return [
1426
1514
  ...this.adapterTrackModels,
1515
+ ...this.columnTrackModels,
1427
1516
  ...[
1428
1517
  conservationTrack,
1429
1518
  ...(self.sequenceType === 'amino'
@@ -1771,6 +1860,47 @@ function stateModelFactory() {
1771
1860
  }
1772
1861
  return runs;
1773
1862
  },
1863
+ /**
1864
+ * #getter
1865
+ * `highlights` projected onto what is on screen: residue spans go
1866
+ * through the named row's gap structure, column spans through the
1867
+ * hidden-column list, and a span that lands entirely on hidden columns
1868
+ * is dropped. Row names that match no row are ignored.
1869
+ */
1870
+ get resolvedHighlights() {
1871
+ const { blanks, rowNamesSet, rowMap } = self;
1872
+ const toVisible = (globalCol) => {
1873
+ const visible = self.globalColToVisibleCol(globalCol);
1874
+ return visible ?? visibleColsBefore(blanks, globalCol);
1875
+ };
1876
+ return self.highlights.flatMap(({ row, rows, start, end, label, color }) => {
1877
+ const base = { label, color };
1878
+ if (rows) {
1879
+ const rowIndices = rows
1880
+ .map(name => rowNamesSet.get(name))
1881
+ .filter(notEmpty);
1882
+ return rowIndices.length ? [{ ...base, rowIndices }] : [];
1883
+ }
1884
+ if (start === undefined || end === undefined) {
1885
+ return [];
1886
+ }
1887
+ let startGlobal = start - 1;
1888
+ let endGlobal = end - 1;
1889
+ if (row !== undefined) {
1890
+ if (!rowMap.has(row)) {
1891
+ return [];
1892
+ }
1893
+ startGlobal = self.seqPosToGlobalCol(row, start - 1);
1894
+ endGlobal = self.seqPosToGlobalCol(row, end - 1);
1895
+ }
1896
+ const startCol = toVisible(startGlobal);
1897
+ const endVisible = self.globalColToVisibleCol(endGlobal);
1898
+ const endCol = endVisible ?? visibleColsBefore(blanks, endGlobal) - 1;
1899
+ return startCol <= endCol
1900
+ ? [{ ...base, startCol, endCol, rowIndices: [] }]
1901
+ : [];
1902
+ });
1903
+ },
1774
1904
  /**
1775
1905
  * #getter
1776
1906
  * per-column summary statistics for the hovered column: consensus residue
@@ -1860,7 +1990,7 @@ function stateModelFactory() {
1860
1990
  const { renderToSvg } = await import('./renderToSvg.js');
1861
1991
  const html = await renderToSvg(self, opts);
1862
1992
  const blob = new Blob([html], { type: 'image/svg+xml' });
1863
- saveAs(blob, 'image.svg');
1993
+ saveAs(blob, exportFileName(self.msaFilehandle, 'svg'));
1864
1994
  },
1865
1995
  initFilter(arg) {
1866
1996
  if (!self.featureFilters.has(arg)) {
@@ -2096,11 +2226,12 @@ function stateModelFactory() {
2096
2226
  }));
2097
2227
  },
2098
2228
  }))
2099
- .postProcessSnapshot(({ data, ...rest }) => ({
2229
+ .postProcessSnapshot(({ data, columnTracks, ...rest }) => ({
2100
2230
  // per-property defaults are stripped by the stripDefault helper; the only thing
2101
2231
  // it can't express is this cross-field rule: drop inline tree/msa/metadata
2102
2232
  // when a sibling filehandle can refetch them, keeping sessions/URLs small
2103
2233
  ...rest,
2234
+ ...smallColumnTracks(columnTracks),
2104
2235
  data: {
2105
2236
  ...(rest.treeFilehandle ? {} : { tree: data.tree }),
2106
2237
  ...(rest.msaFilehandle ? {} : { msa: data.msa }),