jbrowse-plugin-mafviewer 1.0.1 → 1.0.3

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.
@@ -1,17 +1,18 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@jbrowse/core/Plugin'), require('@jbrowse/core/pluggableElementTypes'), require('@jbrowse/core/configuration'), require('@jbrowse/core/data_adapters/BaseAdapter'), require('mobx-state-tree'), require('@jbrowse/core/util'), require('@jbrowse/core/util/rxjs'), require('react'), require('mobx-react'), require('@jbrowse/core/ui'), require('@mui/material'), require('tss-react/mui')) :
3
- typeof define === 'function' && define.amd ? define(['exports', '@jbrowse/core/Plugin', '@jbrowse/core/pluggableElementTypes', '@jbrowse/core/configuration', '@jbrowse/core/data_adapters/BaseAdapter', 'mobx-state-tree', '@jbrowse/core/util', '@jbrowse/core/util/rxjs', 'react', 'mobx-react', '@jbrowse/core/ui', '@mui/material', 'tss-react/mui'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.JBrowsePluginMafViewer = {}, global.JBrowseExports["@jbrowse/core/Plugin"], global.JBrowseExports["@jbrowse/core/pluggableElementTypes"], global.JBrowseExports["@jbrowse/core/configuration"], global.JBrowseExports["@jbrowse/core/data_adapters/BaseAdapter"], global.JBrowseExports["mobx-state-tree"], global.JBrowseExports["@jbrowse/core/util"], global.JBrowseExports["@jbrowse/core/util/rxjs"], global.JBrowseExports.react, global.JBrowseExports["mobx-react"], global.JBrowseExports["@jbrowse/core/ui"], global.JBrowseExports["@mui/material"], global.JBrowseExports["tss-react/mui"]));
5
- })(this, (function (exports, Plugin, pluggableElementTypes, configuration, BaseAdapter, mobxStateTree, util, rxjs, React, mobxReact, ui, material, mui) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@jbrowse/core/Plugin'), require('@jbrowse/core/pluggableElementTypes'), require('@jbrowse/core/configuration'), require('@jbrowse/core/data_adapters/BaseAdapter'), require('mobx-state-tree'), require('@jbrowse/core/util'), require('@jbrowse/core/util/rxjs'), require('react'), require('mobx-react'), require('@mui/material'), require('@jbrowse/core/ui'), require('tss-react/mui')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', '@jbrowse/core/Plugin', '@jbrowse/core/pluggableElementTypes', '@jbrowse/core/configuration', '@jbrowse/core/data_adapters/BaseAdapter', 'mobx-state-tree', '@jbrowse/core/util', '@jbrowse/core/util/rxjs', 'react', 'mobx-react', '@mui/material', '@jbrowse/core/ui', 'tss-react/mui'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.JBrowsePluginMafViewer = {}, global.JBrowseExports["@jbrowse/core/Plugin"], global.JBrowseExports["@jbrowse/core/pluggableElementTypes"], global.JBrowseExports["@jbrowse/core/configuration"], global.JBrowseExports["@jbrowse/core/data_adapters/BaseAdapter"], global.JBrowseExports["mobx-state-tree"], global.JBrowseExports["@jbrowse/core/util"], global.JBrowseExports["@jbrowse/core/util/rxjs"], global.JBrowseExports.react, global.JBrowseExports["mobx-react"], global.JBrowseExports["@mui/material"], global.JBrowseExports["@jbrowse/core/ui"], global.JBrowseExports["tss-react/mui"]));
5
+ })(this, (function (exports, Plugin, pluggableElementTypes, configuration, BaseAdapter, mobxStateTree, util, rxjs, React, mobxReact, material, ui, mui) { 'use strict';
6
6
 
7
- var version = "1.0.1";
7
+ var version = "1.0.3";
8
8
 
9
9
  const configSchema$2 = configuration.ConfigurationSchema('BigMafAdapter', {
10
10
  /**
11
11
  * #slot
12
12
  */
13
13
  samples: {
14
- type: 'stringArray',
14
+ type: 'frozen',
15
+ description: 'string[] or {id:string,label:string,color?:string}[]',
15
16
  defaultValue: [],
16
17
  },
17
18
  /**
@@ -737,29 +738,54 @@
737
738
 
738
739
  function configSchemaF(pluginManager) {
739
740
  const LinearGenomePlugin = pluginManager.getPlugin('LinearGenomeViewPlugin');
740
- // @ts-expect-error
741
- const { linearBasicDisplayConfigSchemaFactory } = LinearGenomePlugin.exports;
741
+ const { baseLinearDisplayConfigSchema } = LinearGenomePlugin.exports;
742
742
  return configuration.ConfigurationSchema('LinearMafDisplay', {
743
743
  /**
744
744
  * #slot
745
745
  */
746
746
  renderer: pluginManager.pluggableConfigSchemaType('renderer'),
747
747
  }, {
748
- baseConfiguration: linearBasicDisplayConfigSchemaFactory(pluginManager),
748
+ baseConfiguration: baseLinearDisplayConfigSchema,
749
749
  explicitlyTyped: true,
750
750
  });
751
751
  }
752
752
 
753
+ const useStyles$1 = mui.makeStyles()({
754
+ root: {
755
+ width: 500,
756
+ },
757
+ });
758
+ const SetRowHeightDialog = mobxReact.observer(function (props) {
759
+ const { model, handleClose } = props;
760
+ const { classes } = useStyles$1();
761
+ const [rowHeight, setRowHeight] = React.useState(`${model.rowHeight}`);
762
+ const [rowProportion, setRowProportion] = React.useState(`${model.rowProportion}`);
763
+ return (React.createElement(ui.Dialog, { open: true, onClose: handleClose, title: "Filter options" },
764
+ React.createElement(material.DialogContent, { className: classes.root },
765
+ React.createElement(material.Typography, null, "Set row height and the proportion of the row height to use for drawing each row"),
766
+ React.createElement(material.TextField, { value: rowHeight, onChange: event => setRowHeight(event.target.value), placeholder: "Enter row height" }),
767
+ React.createElement(material.TextField, { value: rowProportion, onChange: event => setRowProportion(event.target.value), placeholder: "Enter row proportion" }),
768
+ React.createElement(material.DialogActions, null,
769
+ React.createElement(material.Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, onClick: () => {
770
+ model.setRowProportion(+rowProportion);
771
+ model.setRowHeight(+rowHeight);
772
+ handleClose();
773
+ } }, "Submit"),
774
+ React.createElement(material.Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel")))));
775
+ });
776
+
777
+ function isStrs(array) {
778
+ return typeof array[0] === 'string';
779
+ }
753
780
  /**
754
781
  * #stateModel LinearMafDisplay
755
782
  * extends LinearBasicDisplay
756
783
  */
757
784
  function stateModelFactory(configSchema, pluginManager) {
758
785
  const LinearGenomePlugin = pluginManager.getPlugin('LinearGenomeViewPlugin');
759
- // @ts-expect-error
760
- const { linearBasicDisplayModelFactory } = LinearGenomePlugin.exports;
786
+ const { BaseLinearDisplay } = LinearGenomePlugin.exports;
761
787
  return mobxStateTree.types
762
- .compose('LinearMafDisplay', linearBasicDisplayModelFactory(configSchema), mobxStateTree.types.model({
788
+ .compose('LinearMafDisplay', BaseLinearDisplay, mobxStateTree.types.model({
763
789
  /**
764
790
  * #property
765
791
  */
@@ -768,23 +794,44 @@
768
794
  * #property
769
795
  */
770
796
  configuration: configuration.ConfigurationReference(configSchema),
797
+ /**
798
+ * #property
799
+ */
800
+ rowHeight: 15,
801
+ /**
802
+ * #property
803
+ */
804
+ rowProportion: 0.8,
771
805
  }))
772
806
  .volatile(() => ({
773
807
  prefersOffset: true,
774
808
  }))
775
- .views(self => ({
809
+ .actions(self => ({
776
810
  /**
777
- * #getter
811
+ * #action
778
812
  */
779
- get samples() {
780
- const r = self.adapterConfig.samples;
781
- return r.map(elt => ({ name: elt, color: undefined }));
813
+ setRowHeight(n) {
814
+ self.rowHeight = n;
782
815
  },
816
+ /**
817
+ * #action
818
+ */
819
+ setRowProportion(n) {
820
+ self.rowProportion = n;
821
+ },
822
+ }))
823
+ .views(self => ({
783
824
  /**
784
825
  * #getter
785
826
  */
786
- get rowHeight() {
787
- return 20;
827
+ get samples() {
828
+ const r = self.adapterConfig.samples;
829
+ if (isStrs(r)) {
830
+ return r.map(elt => ({ id: elt, label: elt, color: undefined }));
831
+ }
832
+ else {
833
+ return r;
834
+ }
788
835
  },
789
836
  /**
790
837
  * #getter
@@ -805,7 +852,7 @@
805
852
  },
806
853
  }))
807
854
  .views(self => {
808
- const { renderProps: superRenderProps } = self;
855
+ const { trackMenuItems: superTrackMenuItems, renderProps: superRenderProps, } = self;
809
856
  return {
810
857
  /**
811
858
  * #method
@@ -813,10 +860,29 @@
813
860
  renderProps() {
814
861
  return {
815
862
  ...superRenderProps(),
863
+ config: self.rendererConfig,
816
864
  samples: self.samples,
817
865
  rowHeight: self.rowHeight,
866
+ rowProportion: self.rowProportion,
818
867
  };
819
868
  },
869
+ /**
870
+ * #method
871
+ */
872
+ trackMenuItems() {
873
+ return [
874
+ ...superTrackMenuItems(),
875
+ {
876
+ label: 'Set row height',
877
+ onClick: () => {
878
+ util.getSession(self).queueDialog(handleClose => [
879
+ SetRowHeightDialog,
880
+ { model: self, handleClose },
881
+ ]);
882
+ },
883
+ },
884
+ ];
885
+ },
820
886
  };
821
887
  })
822
888
  .actions(self => {
@@ -827,7 +893,6 @@
827
893
  */
828
894
  async renderSvg(opts) {
829
895
  const { renderSvg } = await Promise.resolve().then(function () { return renderSvg$1; });
830
- // @ts-expect-error
831
896
  return renderSvg(self, opts, superRenderSvg);
832
897
  },
833
898
  };
@@ -841,18 +906,14 @@
841
906
 
842
907
  const ColorLegend = mobxReact.observer(function ({ model, labelWidth, }) {
843
908
  const { samples, rowHeight } = model;
844
- const svgFontSize = Math.min(rowHeight, 12);
845
- const canDisplayLabel = rowHeight > 11;
846
- const colorBoxWidth = 15;
847
- const legendWidth = labelWidth + colorBoxWidth + 5;
848
- const extraOffset = 0;
849
- return samples ? (React.createElement(React.Fragment, null, samples.map((source, idx) => {
850
- const boxHeight = Math.min(20, rowHeight);
851
- return (React.createElement(React.Fragment, { key: `${source.name}-${idx}` },
852
- source.color ? (React.createElement(RectBg, { y: idx * rowHeight + 1, x: extraOffset, width: colorBoxWidth, height: boxHeight, color: source.color })) : null,
853
- React.createElement(RectBg, { y: idx * rowHeight + 1, x: extraOffset, width: legendWidth, height: boxHeight }),
854
- canDisplayLabel ? (React.createElement("text", { y: idx * rowHeight + 13, x: extraOffset + colorBoxWidth + 2, fontSize: svgFontSize }, source.name)) : null));
855
- }))) : null;
909
+ const svgFontSize = Math.min(rowHeight, 10);
910
+ const canDisplayLabel = rowHeight >= 10;
911
+ const boxHeight = Math.min(20, rowHeight);
912
+ return samples ? (React.createElement(React.Fragment, null,
913
+ samples.map((sample, idx) => (React.createElement(RectBg, { key: `${sample.id}-${idx}`, y: idx * rowHeight + 1, x: 0, width: labelWidth + 5, height: boxHeight, color: sample.color }))),
914
+ canDisplayLabel
915
+ ? samples.map((sample, idx) => (React.createElement("text", { key: `${sample.id}-${idx}`, y: idx * rowHeight + 14, x: 2, fontSize: svgFontSize }, sample.label)))
916
+ : null)) : null;
856
917
  });
857
918
 
858
919
  const Wrapper = mobxReact.observer(function ({ children, model, exportSVG, }) {
@@ -875,10 +936,10 @@
875
936
  const { model } = props;
876
937
  const { rowHeight, samples } = model;
877
938
  const svgFontSize = Math.min(rowHeight, 12);
878
- const canDisplayLabel = rowHeight > 11;
939
+ const canDisplayLabel = rowHeight >= 10;
879
940
  const minWidth = 20;
880
941
  const labelWidth = Math.max(...(samples
881
- .map(s => util.measureText(s, svgFontSize))
942
+ .map(s => util.measureText(s.label, svgFontSize))
882
943
  .map(width => (canDisplayLabel ? width : minWidth)) || [0]));
883
944
  return (React.createElement(Wrapper, { ...props },
884
945
  React.createElement(ColorLegend, { model: model, labelWidth: labelWidth })));
@@ -917,20 +978,6 @@
917
978
  explicitlyTyped: true,
918
979
  });
919
980
 
920
- function getCorrectionFactor(scale) {
921
- if (scale >= 1) {
922
- return 0.6;
923
- }
924
- else if (scale >= 0.2) {
925
- return 0.05;
926
- }
927
- else if (scale >= 0.02) {
928
- return 0.03;
929
- }
930
- else {
931
- return 0.02;
932
- }
933
- }
934
981
  function getContrastBaseMap(theme) {
935
982
  return Object.fromEntries(Object.entries(getColorBaseMap(theme)).map(([key, value]) => [
936
983
  key,
@@ -947,16 +994,18 @@
947
994
  };
948
995
  }
949
996
  function makeImageData({ ctx, renderArgs, }) {
950
- const { regions, bpPerPx, rowHeight, theme: configTheme, samples, } = renderArgs;
997
+ const { regions, bpPerPx, rowHeight, theme: configTheme, samples, rowProportion, } = renderArgs;
951
998
  const [region] = regions;
952
999
  const features = renderArgs.features;
953
1000
  const h = rowHeight;
954
1001
  const theme = ui.createJBrowseTheme(configTheme);
955
1002
  const colorForBase = getColorBaseMap(theme);
956
1003
  const contrastForBase = getContrastBaseMap(theme);
957
- const sampleToRowMap = new Map(samples.map((s, i) => [s.name, i]));
1004
+ const sampleToRowMap = new Map(samples.map((s, i) => [s.id, i]));
958
1005
  const scale = 1 / bpPerPx;
959
- const correctionFactor = getCorrectionFactor(bpPerPx);
1006
+ const f = 0.4;
1007
+ const h2 = h * rowProportion;
1008
+ const offset = h2 / 2;
960
1009
  // sample as alignments
961
1010
  ctx.font = 'bold 10px Courier New,monospace';
962
1011
  for (const feature of features.values()) {
@@ -966,63 +1015,117 @@
966
1015
  for (const [sample, val] of Object.entries(vals)) {
967
1016
  const origAlignment = val.data;
968
1017
  const alignment = origAlignment.toLowerCase();
969
- // gaps
970
- ctx.beginPath();
971
- ctx.fillStyle = 'black';
972
- const offset0 = (5 / 12) * h;
973
- const h6 = h / 6;
974
1018
  const row = sampleToRowMap.get(sample);
975
1019
  if (row === undefined) {
976
1020
  throw new Error(`unknown sample encountered: ${sample}`);
977
1021
  }
978
1022
  const t = h * row;
979
- for (let i = 0; i < alignment.length; i++) {
980
- const l = leftPx + scale * i;
981
- if (alignment[i] === '-') {
982
- ctx.rect(l, offset0 + t, scale + correctionFactor, h6);
1023
+ // gaps
1024
+ ctx.beginPath();
1025
+ ctx.fillStyle = 'black';
1026
+ for (let i = 0, o = 0; i < alignment.length; i++) {
1027
+ if (seq[i] !== '-') {
1028
+ if (alignment[i] === '-') {
1029
+ const l = leftPx + scale * o;
1030
+ ctx.moveTo(l, t + h2);
1031
+ ctx.lineTo(l + scale + f, t + h2);
1032
+ }
1033
+ o++;
983
1034
  }
984
1035
  }
985
- ctx.fill();
986
- const offset = (1 / 4) * h;
987
- const h2 = h / 2;
1036
+ ctx.stroke();
988
1037
  // matches
989
1038
  ctx.beginPath();
990
1039
  ctx.fillStyle = 'lightgrey';
991
- for (let i = 0; i < alignment.length; i++) {
992
- const c = alignment[i];
993
- const l = leftPx + scale * i;
994
- if (seq[i] === c && c !== '-') {
995
- ctx.rect(l, offset + t, scale + correctionFactor, h2);
1040
+ for (let i = 0, o = 0; i < alignment.length; i++) {
1041
+ if (seq[i] !== '-') {
1042
+ const c = alignment[i];
1043
+ const l = leftPx + scale * o;
1044
+ if (seq[i] === c && c !== '-') {
1045
+ ctx.rect(l, offset + t, scale + f, h2);
1046
+ }
1047
+ o++;
996
1048
  }
997
1049
  }
998
1050
  ctx.fill();
999
1051
  // mismatches
1000
- for (let i = 0; i < alignment.length; i++) {
1052
+ for (let i = 0, o = 0; i < alignment.length; i++) {
1001
1053
  const c = alignment[i];
1002
- if (seq[i] !== c && c !== '-') {
1003
- const l = leftPx + scale * i;
1004
- ctx.fillStyle =
1005
- colorForBase[c] ?? 'purple';
1006
- ctx.fillRect(l, offset + t, scale + correctionFactor, h2);
1054
+ if (seq[i] !== '-') {
1055
+ if (seq[i] !== c && c !== '-') {
1056
+ const l = leftPx + scale * o;
1057
+ ctx.fillStyle =
1058
+ colorForBase[c] ?? 'purple';
1059
+ ctx.fillRect(l, offset + t, scale + f, h2);
1060
+ }
1061
+ o++;
1007
1062
  }
1008
1063
  }
1009
1064
  // font
1010
1065
  const charSize = { w: 10 };
1011
1066
  if (scale >= charSize.w) {
1012
- for (let i = 0; i < alignment.length; i++) {
1013
- const l = leftPx + scale * i;
1014
- const offset = (scale - charSize.w) / 2 + 1;
1015
- const c = alignment[i];
1016
- if (seq[i] !== c && c !== '-') {
1017
- ctx.fillStyle = contrastForBase[c] ?? 'black';
1018
- ctx.fillText(origAlignment[i], l + offset, h2 + t + 3);
1067
+ for (let i = 0, o = 0; i < alignment.length; i++) {
1068
+ if (seq[i] !== '-') {
1069
+ const l = leftPx + scale * o;
1070
+ const offset = (scale - charSize.w) / 2 + 1;
1071
+ const c = alignment[i];
1072
+ if (seq[i] !== c && c !== '-') {
1073
+ ctx.fillStyle = contrastForBase[c] ?? 'black';
1074
+ ctx.fillText(origAlignment[i], l + offset, h2 + t + 3);
1075
+ }
1076
+ o++;
1019
1077
  }
1020
1078
  }
1021
1079
  }
1022
1080
  }
1023
1081
  }
1082
+ // second pass for insertions, has slightly improved look since the
1083
+ // insertions are always 'on top' of the other features
1084
+ for (const feature of features.values()) {
1085
+ const [leftPx] = util.featureSpanPx(feature, region, bpPerPx);
1086
+ const vals = feature.get('alignments');
1087
+ const seq = feature.get('seq').toLowerCase();
1088
+ for (const [sample, val] of Object.entries(vals)) {
1089
+ const origAlignment = val.data;
1090
+ const alignment = origAlignment.toLowerCase();
1091
+ const row = sampleToRowMap.get(sample);
1092
+ if (row === undefined) {
1093
+ throw new Error(`unknown sample encountered: ${sample}`);
1094
+ }
1095
+ const t = h * row;
1096
+ ctx.beginPath();
1097
+ ctx.fillStyle = 'purple';
1098
+ for (let i = 0, o = 0; i < alignment.length; i++) {
1099
+ let ins = '';
1100
+ while (seq[i] === '-') {
1101
+ if (alignment[i] !== '-') {
1102
+ ins += alignment[i];
1103
+ }
1104
+ i++;
1105
+ }
1106
+ if (ins.length) {
1107
+ const l = leftPx + scale * o - 2;
1108
+ ctx.rect(l, offset + t, 2, h2);
1109
+ ctx.rect(l - 2, offset + t, 6, 1);
1110
+ ctx.rect(l - 2, offset + t + h2, 6, 1);
1111
+ }
1112
+ o++;
1113
+ }
1114
+ ctx.fill();
1115
+ }
1116
+ }
1024
1117
  }
1025
1118
  class LinearMafRenderer extends pluggableElementTypes.FeatureRendererType {
1119
+ getExpandedRegion(region) {
1120
+ const { start, end } = region;
1121
+ const bpExpansion = 1;
1122
+ return {
1123
+ // xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
1124
+ ...region,
1125
+ start: Math.floor(Math.max(start - bpExpansion, 0)),
1126
+ end: Math.ceil(end + bpExpansion),
1127
+ };
1128
+ }
1026
1129
  async render(renderProps) {
1027
1130
  const { regions, bpPerPx, samples, rowHeight } = renderProps;
1028
1131
  const [region] = regions;
@@ -1069,7 +1172,8 @@
1069
1172
  * #slot
1070
1173
  */
1071
1174
  samples: {
1072
- type: 'stringArray',
1175
+ type: 'frozen',
1176
+ description: 'string[] or {id:string,label:string,color?:string}[]',
1073
1177
  defaultValue: [],
1074
1178
  },
1075
1179
  /**
@@ -1124,6 +1228,10 @@
1124
1228
  const { adapter } = await this.setup();
1125
1229
  return adapter.getRefNames();
1126
1230
  }
1231
+ async getHeader() {
1232
+ const { adapter } = await this.setup();
1233
+ return adapter.getHeader();
1234
+ }
1127
1235
  getFeatures(query) {
1128
1236
  return rxjs.ObservableCreate(async (observer) => {
1129
1237
  const { adapter } = await this.setup();
@@ -1131,31 +1239,29 @@
1131
1239
  for (const feature of features) {
1132
1240
  const data = feature.get('field5').split(',');
1133
1241
  const alignments = {};
1134
- const main = data[0];
1135
- const aln = main.split(':')[5];
1136
1242
  const alns = data.map(elt => elt.split(':')[5]);
1137
- const alns2 = data.map(() => '');
1243
+ // const aln = alns[0]
1244
+ // const alns2 = data.map(() => '')
1138
1245
  // remove extraneous data in other alignments
1139
1246
  // reason being: cannot represent missing data in main species that are in others)
1140
- for (let i = 0, o = 0; i < aln.length; i++, o++) {
1141
- if (aln[i] !== '-') {
1142
- for (let j = 0; j < data.length; j++) {
1143
- alns2[j] += alns[j][i];
1144
- }
1145
- }
1146
- }
1247
+ // for (let i = 0; i < aln.length; i++) {
1248
+ // if (aln[i] !== '-') {
1249
+ // for (let j = 0; j < data.length; j++) {
1250
+ // alns2[j] += alns[j][i]
1251
+ // }
1252
+ // }
1253
+ // }
1147
1254
  for (let j = 0; j < data.length; j++) {
1148
1255
  const elt = data[j];
1149
1256
  const ad = elt.split(':');
1150
- const org = ad[0].split('.')[0];
1151
- const chr = ad[0].split('.')[1];
1257
+ const [org, chr] = ad[0].split('.');
1152
1258
  alignments[org] = {
1153
- chr: chr,
1259
+ chr,
1154
1260
  start: +ad[1],
1155
1261
  srcSize: +ad[2],
1156
1262
  strand: ad[3] === '-' ? -1 : 1,
1157
1263
  unknown: +ad[4],
1158
- data: alns2[j],
1264
+ data: alns[j],
1159
1265
  };
1160
1266
  }
1161
1267
  observer.next(new util.SimpleFeature({
@@ -1166,8 +1272,8 @@
1166
1272
  refName: feature.get('refName'),
1167
1273
  name: feature.get('name'),
1168
1274
  score: feature.get('score'),
1169
- alignments: alignments,
1170
- seq: alns2[0],
1275
+ alignments,
1276
+ seq: alns[0],
1171
1277
  },
1172
1278
  }));
1173
1279
  }
@@ -1286,15 +1392,21 @@
1286
1392
  MafTabixAdapterF(pluginManager);
1287
1393
  MafAddTrackWorkflowF(pluginManager);
1288
1394
  }
1289
- configure(pluginManager) { }
1395
+ configure(_pluginManager) { }
1290
1396
  }
1291
1397
 
1292
1398
  async function renderSvg(self, opts, superRenderSvg) {
1293
- const { offsetPx } = util.getContainingView(self);
1399
+ const { height } = self;
1400
+ const { offsetPx, width } = util.getContainingView(self);
1401
+ const clipid = `mafclip-${self.id}`;
1294
1402
  return (React.createElement(React.Fragment, null,
1295
- React.createElement("g", { id: "snpcov" }, await superRenderSvg(opts)),
1296
- React.createElement("g", { transform: `translate(${Math.max(-offsetPx, 0)})` },
1297
- React.createElement(YScaleBars, { model: self, orientation: "left", exportSVG: true }))));
1403
+ React.createElement("defs", null,
1404
+ React.createElement("clipPath", { id: clipid },
1405
+ React.createElement("rect", { x: 0, y: 0, width: width, height: height }))),
1406
+ React.createElement("g", { clipPath: `url(#${clipid})` },
1407
+ React.createElement("g", { id: "snpcov" }, await superRenderSvg(opts)),
1408
+ React.createElement("g", { transform: `translate(${Math.max(-offsetPx, 0)})` },
1409
+ React.createElement(YScaleBars, { model: self, orientation: "left", exportSVG: true })))));
1298
1410
  }
1299
1411
 
1300
1412
  var renderSvg$1 = {