@apollo-annotation/jbrowse-plugin-apollo 0.3.3 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +317 -227
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +316 -226
- package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.development.js +316 -226
- package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
- package/package.json +4 -4
- package/src/FeatureDetailsWidget/model.ts +0 -2
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +20 -1
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +232 -117
- package/src/LinearApolloDisplay/stateModel/base.ts +15 -1
- package/src/LinearApolloDisplay/stateModel/layouts.ts +84 -85
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +9 -4
- package/src/LinearApolloDisplay/stateModel/rendering.ts +3 -2
- package/src/OntologyManager/index.ts +22 -0
package/dist/index.esm.js
CHANGED
|
@@ -10,7 +10,7 @@ import { getSnapshot, getParent, getRoot, types, addDisposer, flow, cast, isAliv
|
|
|
10
10
|
import { io } from 'socket.io-client';
|
|
11
11
|
import gff from '@gmod/gff';
|
|
12
12
|
import LinkIcon from '@mui/icons-material/Link';
|
|
13
|
-
import { DialogTitle, IconButton, DialogContent, DialogContentText, Select, MenuItem, TextField, FormControl, FormLabel, RadioGroup, FormControlLabel, Radio, Box, Typography, FormGroup, Checkbox, DialogActions, Button, Autocomplete, InputLabel, TableContainer, Paper, Table, TableHead, TableRow, TableCell, TableBody, Grid2, Tooltip, Chip, useTheme, FormHelperText, SvgIcon, Divider, Menu, InputAdornment as InputAdornment$1, alpha, Alert, Avatar } from '@mui/material';
|
|
13
|
+
import { DialogTitle, IconButton, DialogContent, DialogContentText, Select, MenuItem, TextField, FormControl, FormLabel, RadioGroup, FormControlLabel, Radio, Box, Typography, FormGroup, Checkbox, DialogActions, Button, Autocomplete, InputLabel, TableContainer, Paper, Table, TableHead, TableRow, TableCell, TableBody, Grid2, Tooltip, Chip, useTheme, FormHelperText, SvgIcon, Divider, Menu, InputAdornment as InputAdornment$1, alpha, CircularProgress, Alert, Avatar } from '@mui/material';
|
|
14
14
|
import InputAdornment from '@mui/material/InputAdornment';
|
|
15
15
|
import LinearProgress from '@mui/material/LinearProgress';
|
|
16
16
|
import ObjectID from 'bson-objectid';
|
|
@@ -50,7 +50,7 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
|
50
50
|
import ErrorIcon from '@mui/icons-material/Error';
|
|
51
51
|
import SaveIcon from '@mui/icons-material/Save';
|
|
52
52
|
|
|
53
|
-
var version = "0.3.
|
|
53
|
+
var version = "0.3.4";
|
|
54
54
|
|
|
55
55
|
const ApolloConfigSchema = ConfigurationSchema('ApolloInternetAccount', {
|
|
56
56
|
baseURL: {
|
|
@@ -1246,6 +1246,7 @@ const OntologyRecordType = types
|
|
|
1246
1246
|
})
|
|
1247
1247
|
.volatile((_self) => ({
|
|
1248
1248
|
dataStore: undefined,
|
|
1249
|
+
startedEquivalentTypeRequests: new Set(),
|
|
1249
1250
|
}))
|
|
1250
1251
|
.actions((self) => ({
|
|
1251
1252
|
/** does nothing, just used to access the model to force its lifecycle hooks to run */
|
|
@@ -1269,12 +1270,33 @@ const OntologyRecordType = types
|
|
|
1269
1270
|
if (!self.dataStore) {
|
|
1270
1271
|
return;
|
|
1271
1272
|
}
|
|
1273
|
+
if (self.startedEquivalentTypeRequests.has(type)) {
|
|
1274
|
+
return;
|
|
1275
|
+
}
|
|
1276
|
+
self.startedEquivalentTypeRequests.add(type);
|
|
1272
1277
|
const terms = (yield self.dataStore.getTermsWithLabelOrSynonym(type));
|
|
1273
1278
|
const equivalents = terms
|
|
1274
1279
|
.map((term) => term.lbl)
|
|
1275
1280
|
.filter((term) => term != undefined);
|
|
1276
1281
|
self.setEquivalentTypes(type, equivalents);
|
|
1277
1282
|
}),
|
|
1283
|
+
}))
|
|
1284
|
+
.actions((self) => ({
|
|
1285
|
+
afterCreate() {
|
|
1286
|
+
autorun((reaction) => {
|
|
1287
|
+
if (!self.dataStore) {
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
void self.loadEquivalentTypes('gene');
|
|
1291
|
+
void self.loadEquivalentTypes('transcript');
|
|
1292
|
+
void self.loadEquivalentTypes('CDS');
|
|
1293
|
+
void self.loadEquivalentTypes('mRNA');
|
|
1294
|
+
reaction.dispose();
|
|
1295
|
+
});
|
|
1296
|
+
},
|
|
1297
|
+
setEquivalentTypes(type, equivalentTypes) {
|
|
1298
|
+
self.equivalentTypes.set(type, equivalentTypes);
|
|
1299
|
+
},
|
|
1278
1300
|
}))
|
|
1279
1301
|
.views((self) => ({
|
|
1280
1302
|
isTypeOf(queryType, typeOf) {
|
|
@@ -5777,7 +5799,6 @@ const ApolloTranscriptDetailsModel = types
|
|
|
5777
5799
|
})),
|
|
5778
5800
|
assembly: types.string,
|
|
5779
5801
|
refName: types.string,
|
|
5780
|
-
changeManager: types.frozen(),
|
|
5781
5802
|
})
|
|
5782
5803
|
.volatile(() => ({
|
|
5783
5804
|
tryReload: undefined,
|
|
@@ -6787,6 +6808,7 @@ function baseModelFactory(_pluginManager, configSchema) {
|
|
|
6787
6808
|
table: false,
|
|
6788
6809
|
heightPreConfig: types.maybe(types.refinement('displayHeight', types.number, (n) => n >= minDisplayHeight)),
|
|
6789
6810
|
filteredFeatureTypes: types.array(types.string),
|
|
6811
|
+
loadingState: false,
|
|
6790
6812
|
})
|
|
6791
6813
|
.views((self) => {
|
|
6792
6814
|
const { configuration, renderProps: superRenderProps } = self;
|
|
@@ -6819,6 +6841,9 @@ function baseModelFactory(_pluginManager, configSchema) {
|
|
|
6819
6841
|
}
|
|
6820
6842
|
return 300;
|
|
6821
6843
|
},
|
|
6844
|
+
get loading() {
|
|
6845
|
+
return self.loadingState;
|
|
6846
|
+
},
|
|
6822
6847
|
}))
|
|
6823
6848
|
.views((self) => ({
|
|
6824
6849
|
get rendererTypeName() {
|
|
@@ -6904,6 +6929,9 @@ function baseModelFactory(_pluginManager, configSchema) {
|
|
|
6904
6929
|
updateFilteredFeatureTypes(types) {
|
|
6905
6930
|
self.filteredFeatureTypes = cast(types);
|
|
6906
6931
|
},
|
|
6932
|
+
setLoading(loading) {
|
|
6933
|
+
self.loadingState = loading;
|
|
6934
|
+
},
|
|
6907
6935
|
}))
|
|
6908
6936
|
.views((self) => {
|
|
6909
6937
|
const { filteredFeatureTypes, trackMenuItems: superTrackMenuItems } = self;
|
|
@@ -6974,7 +7002,14 @@ function baseModelFactory(_pluginManager, configSchema) {
|
|
|
6974
7002
|
if (!self.lgv.initialized || self.regionCannotBeRendered()) {
|
|
6975
7003
|
return;
|
|
6976
7004
|
}
|
|
6977
|
-
|
|
7005
|
+
self.setLoading(true);
|
|
7006
|
+
void self.session.apolloDataStore
|
|
7007
|
+
.loadFeatures(self.regions)
|
|
7008
|
+
.then(() => {
|
|
7009
|
+
setTimeout(() => {
|
|
7010
|
+
self.setLoading(false);
|
|
7011
|
+
}, 1000);
|
|
7012
|
+
});
|
|
6978
7013
|
if (self.lgv.bpPerPx <= 3) {
|
|
6979
7014
|
void self.session.apolloDataStore.loadRefSeq(self.regions);
|
|
6980
7015
|
}
|
|
@@ -7403,7 +7438,6 @@ function draw$1(ctx, feature, row, stateModel, displayedRegionIndex) {
|
|
|
7403
7438
|
const displayedRegion = displayedRegions[displayedRegionIndex];
|
|
7404
7439
|
const { refName, reversed } = displayedRegion;
|
|
7405
7440
|
const rowHeight = apolloRowHeight;
|
|
7406
|
-
const exonHeight = Math.round(0.6 * rowHeight);
|
|
7407
7441
|
const cdsHeight = Math.round(0.9 * rowHeight);
|
|
7408
7442
|
const { children, min, strand } = feature;
|
|
7409
7443
|
if (!children) {
|
|
@@ -7437,27 +7471,20 @@ function draw$1(ctx, feature, row, stateModel, displayedRegionIndex) {
|
|
|
7437
7471
|
currentRow += 1;
|
|
7438
7472
|
continue;
|
|
7439
7473
|
}
|
|
7440
|
-
const { children:
|
|
7441
|
-
if (!
|
|
7474
|
+
const { children: transcriptChildren } = transcript;
|
|
7475
|
+
if (!transcriptChildren) {
|
|
7442
7476
|
continue;
|
|
7443
7477
|
}
|
|
7444
|
-
|
|
7445
|
-
|
|
7478
|
+
const cdsCount = getCDSCount(transcript, featureTypeOntology);
|
|
7479
|
+
for (const [, childFeature] of transcriptChildren) {
|
|
7480
|
+
if (!featureTypeOntology.isTypeOf(childFeature.type, 'CDS')) {
|
|
7446
7481
|
continue;
|
|
7447
7482
|
}
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
const widthPx = transcript.length / bpPerPx;
|
|
7454
|
-
const startPx = reversed ? minX - widthPx : minX;
|
|
7455
|
-
const height = Math.round((currentRow + 1 / 2) * rowHeight) + row * rowHeight;
|
|
7456
|
-
ctx.strokeStyle = theme?.palette.text.primary ?? 'black';
|
|
7457
|
-
ctx.beginPath();
|
|
7458
|
-
ctx.moveTo(startPx, height);
|
|
7459
|
-
ctx.lineTo(startPx + widthPx, height);
|
|
7460
|
-
ctx.stroke();
|
|
7483
|
+
drawLine(ctx, stateModel, displayedRegionIndex, row, transcript, currentRow);
|
|
7484
|
+
currentRow += 1;
|
|
7485
|
+
}
|
|
7486
|
+
if (cdsCount === 0) {
|
|
7487
|
+
drawLine(ctx, stateModel, displayedRegionIndex, row, transcript, currentRow);
|
|
7461
7488
|
currentRow += 1;
|
|
7462
7489
|
}
|
|
7463
7490
|
}
|
|
@@ -7471,83 +7498,125 @@ function draw$1(ctx, feature, row, stateModel, displayedRegionIndex) {
|
|
|
7471
7498
|
currentRow += 1;
|
|
7472
7499
|
continue;
|
|
7473
7500
|
}
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
for (const [, exon] of childrenOfTranscript) {
|
|
7480
|
-
if (!featureTypeOntology.isTypeOf(exon.type, 'exon')) {
|
|
7501
|
+
const cdsCount = getCDSCount(child, featureTypeOntology);
|
|
7502
|
+
if (cdsCount != 0) {
|
|
7503
|
+
for (const cdsRow of child.cdsLocations) {
|
|
7504
|
+
const { _id, children: transcriptChildren } = child;
|
|
7505
|
+
if (!transcriptChildren) {
|
|
7481
7506
|
continue;
|
|
7482
7507
|
}
|
|
7483
|
-
const
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
const
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
const
|
|
7503
|
-
const
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
ctx.
|
|
7508
|
+
for (const [, exon] of transcriptChildren) {
|
|
7509
|
+
if (!featureTypeOntology.isTypeOf(exon.type, 'exon')) {
|
|
7510
|
+
continue;
|
|
7511
|
+
}
|
|
7512
|
+
drawExon(ctx, stateModel, displayedRegionIndex, row, exon, currentRow, strand, forwardFill, backwardFill);
|
|
7513
|
+
}
|
|
7514
|
+
for (const cds of cdsRow) {
|
|
7515
|
+
const cdsWidthPx = (cds.max - cds.min) / bpPerPx;
|
|
7516
|
+
const minX = (lgv.bpToPx({
|
|
7517
|
+
refName,
|
|
7518
|
+
coord: cds.min,
|
|
7519
|
+
regionNumber: displayedRegionIndex,
|
|
7520
|
+
})?.offsetPx ?? 0) - offsetPx;
|
|
7521
|
+
const cdsStartPx = reversed ? minX - cdsWidthPx : minX;
|
|
7522
|
+
ctx.fillStyle = theme?.palette.text.primary ?? 'black';
|
|
7523
|
+
const cdsTop = (row + currentRow) * rowHeight + (rowHeight - cdsHeight) / 2;
|
|
7524
|
+
ctx.fillRect(cdsStartPx, cdsTop, cdsWidthPx, cdsHeight);
|
|
7525
|
+
if (cdsWidthPx > 2) {
|
|
7526
|
+
ctx.clearRect(cdsStartPx + 1, cdsTop + 1, cdsWidthPx - 2, cdsHeight - 2);
|
|
7527
|
+
const frame = getFrame(cds.min, cds.max, child.strand ?? 1, cds.phase);
|
|
7528
|
+
const frameColor = theme?.palette.framesCDS.at(frame)?.main;
|
|
7529
|
+
const cdsColorCode = frameColor ?? 'rgb(171,71,188)';
|
|
7530
|
+
ctx.fillStyle =
|
|
7531
|
+
apolloSelectedFeature && _id === apolloSelectedFeature._id
|
|
7532
|
+
? 'rgb(0,0,0)'
|
|
7533
|
+
: cdsColorCode;
|
|
7534
|
+
ctx.fillStyle = cdsColorCode;
|
|
7535
|
+
ctx.fillRect(cdsStartPx + 1, cdsTop + 1, cdsWidthPx - 2, cdsHeight - 2);
|
|
7536
|
+
if (forwardFill && backwardFill && strand) {
|
|
7537
|
+
const reversal = reversed ? -1 : 1;
|
|
7538
|
+
const [topFill, bottomFill] = strand * reversal === 1
|
|
7539
|
+
? [forwardFill, backwardFill]
|
|
7540
|
+
: [backwardFill, forwardFill];
|
|
7541
|
+
ctx.fillStyle = topFill;
|
|
7542
|
+
ctx.fillRect(cdsStartPx + 1, cdsTop + 1, cdsWidthPx - 2, (cdsHeight - 2) / 2);
|
|
7543
|
+
ctx.fillStyle = bottomFill;
|
|
7544
|
+
ctx.fillRect(cdsStartPx + 1, cdsTop + (cdsHeight - 2) / 2, cdsWidthPx - 2, (cdsHeight - 2) / 2);
|
|
7545
|
+
}
|
|
7510
7546
|
}
|
|
7511
7547
|
}
|
|
7548
|
+
currentRow += 1;
|
|
7512
7549
|
}
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
const cdsStartPx = reversed ? minX - cdsWidthPx : minX;
|
|
7521
|
-
ctx.fillStyle = theme?.palette.text.primary ?? 'black';
|
|
7522
|
-
const cdsTop = (row + currentRow) * rowHeight + (rowHeight - cdsHeight) / 2;
|
|
7523
|
-
ctx.fillRect(cdsStartPx, cdsTop, cdsWidthPx, cdsHeight);
|
|
7524
|
-
if (cdsWidthPx > 2) {
|
|
7525
|
-
ctx.clearRect(cdsStartPx + 1, cdsTop + 1, cdsWidthPx - 2, cdsHeight - 2);
|
|
7526
|
-
const frame = getFrame(cds.min, cds.max, child.strand ?? 1, cds.phase);
|
|
7527
|
-
const frameColor = theme?.palette.framesCDS.at(frame)?.main;
|
|
7528
|
-
const cdsColorCode = frameColor ?? 'rgb(171,71,188)';
|
|
7529
|
-
ctx.fillStyle =
|
|
7530
|
-
apolloSelectedFeature && _id === apolloSelectedFeature._id
|
|
7531
|
-
? 'rgb(0,0,0)'
|
|
7532
|
-
: cdsColorCode;
|
|
7533
|
-
ctx.fillStyle = cdsColorCode;
|
|
7534
|
-
ctx.fillRect(cdsStartPx + 1, cdsTop + 1, cdsWidthPx - 2, cdsHeight - 2);
|
|
7535
|
-
if (forwardFill && backwardFill && strand) {
|
|
7536
|
-
const reversal = reversed ? -1 : 1;
|
|
7537
|
-
const [topFill, bottomFill] = strand * reversal === 1
|
|
7538
|
-
? [forwardFill, backwardFill]
|
|
7539
|
-
: [backwardFill, forwardFill];
|
|
7540
|
-
ctx.fillStyle = topFill;
|
|
7541
|
-
ctx.fillRect(cdsStartPx + 1, cdsTop + 1, cdsWidthPx - 2, (cdsHeight - 2) / 2);
|
|
7542
|
-
ctx.fillStyle = bottomFill;
|
|
7543
|
-
ctx.fillRect(cdsStartPx + 1, cdsTop + (cdsHeight - 2) / 2, cdsWidthPx - 2, (cdsHeight - 2) / 2);
|
|
7544
|
-
}
|
|
7550
|
+
}
|
|
7551
|
+
const { children: transcriptChildren } = child;
|
|
7552
|
+
// Draw exons for non-coding genes
|
|
7553
|
+
if (cdsCount === 0 && transcriptChildren) {
|
|
7554
|
+
for (const [, exon] of transcriptChildren) {
|
|
7555
|
+
if (!featureTypeOntology.isTypeOf(exon.type, 'exon')) {
|
|
7556
|
+
continue;
|
|
7545
7557
|
}
|
|
7558
|
+
drawExon(ctx, stateModel, displayedRegionIndex, row, exon, currentRow, strand, forwardFill, backwardFill);
|
|
7546
7559
|
}
|
|
7547
7560
|
currentRow += 1;
|
|
7548
7561
|
}
|
|
7549
7562
|
}
|
|
7550
7563
|
}
|
|
7564
|
+
function drawExon(ctx, stateModel, displayedRegionIndex, row, exon, currentRow, strand, forwardFill, backwardFill) {
|
|
7565
|
+
const { apolloRowHeight, lgv, session, theme } = stateModel;
|
|
7566
|
+
const { bpPerPx, displayedRegions, offsetPx } = lgv;
|
|
7567
|
+
const displayedRegion = displayedRegions[displayedRegionIndex];
|
|
7568
|
+
const { refName, reversed } = displayedRegion;
|
|
7569
|
+
const { apolloSelectedFeature } = session;
|
|
7570
|
+
const minX = (lgv.bpToPx({
|
|
7571
|
+
refName,
|
|
7572
|
+
coord: exon.min,
|
|
7573
|
+
regionNumber: displayedRegionIndex,
|
|
7574
|
+
})?.offsetPx ?? 0) - offsetPx;
|
|
7575
|
+
const widthPx = exon.length / bpPerPx;
|
|
7576
|
+
const startPx = reversed ? minX - widthPx : minX;
|
|
7577
|
+
const top = (row + currentRow) * apolloRowHeight;
|
|
7578
|
+
const exonHeight = Math.round(0.6 * apolloRowHeight);
|
|
7579
|
+
const exonTop = top + (apolloRowHeight - exonHeight) / 2;
|
|
7580
|
+
ctx.fillStyle = theme?.palette.text.primary ?? 'black';
|
|
7581
|
+
ctx.fillRect(startPx, exonTop, widthPx, exonHeight);
|
|
7582
|
+
if (widthPx > 2) {
|
|
7583
|
+
ctx.clearRect(startPx + 1, exonTop + 1, widthPx - 2, exonHeight - 2);
|
|
7584
|
+
ctx.fillStyle =
|
|
7585
|
+
apolloSelectedFeature && exon._id === apolloSelectedFeature._id
|
|
7586
|
+
? 'rgb(0,0,0)'
|
|
7587
|
+
: 'rgb(211,211,211)';
|
|
7588
|
+
ctx.fillRect(startPx + 1, exonTop + 1, widthPx - 2, exonHeight - 2);
|
|
7589
|
+
if (forwardFill && backwardFill && strand) {
|
|
7590
|
+
const reversal = reversed ? -1 : 1;
|
|
7591
|
+
const [topFill, bottomFill] = strand * reversal === 1
|
|
7592
|
+
? [forwardFill, backwardFill]
|
|
7593
|
+
: [backwardFill, forwardFill];
|
|
7594
|
+
ctx.fillStyle = topFill;
|
|
7595
|
+
ctx.fillRect(startPx + 1, exonTop + 1, widthPx - 2, (exonHeight - 2) / 2);
|
|
7596
|
+
ctx.fillStyle = bottomFill;
|
|
7597
|
+
ctx.fillRect(startPx + 1, exonTop + 1 + (exonHeight - 2) / 2, widthPx - 2, (exonHeight - 2) / 2);
|
|
7598
|
+
}
|
|
7599
|
+
}
|
|
7600
|
+
}
|
|
7601
|
+
function drawLine(ctx, stateModel, displayedRegionIndex, row, transcript, currentRow) {
|
|
7602
|
+
const { apolloRowHeight, lgv, theme } = stateModel;
|
|
7603
|
+
const { bpPerPx, displayedRegions, offsetPx } = lgv;
|
|
7604
|
+
const displayedRegion = displayedRegions[displayedRegionIndex];
|
|
7605
|
+
const { refName, reversed } = displayedRegion;
|
|
7606
|
+
const minX = (lgv.bpToPx({
|
|
7607
|
+
refName,
|
|
7608
|
+
coord: transcript.min,
|
|
7609
|
+
regionNumber: displayedRegionIndex,
|
|
7610
|
+
})?.offsetPx ?? 0) - offsetPx;
|
|
7611
|
+
const widthPx = transcript.length / bpPerPx;
|
|
7612
|
+
const startPx = reversed ? minX - widthPx : minX;
|
|
7613
|
+
const height = Math.round((currentRow + 1 / 2) * apolloRowHeight) + row * apolloRowHeight;
|
|
7614
|
+
ctx.strokeStyle = theme?.palette.text.primary ?? 'black';
|
|
7615
|
+
ctx.beginPath();
|
|
7616
|
+
ctx.moveTo(startPx, height);
|
|
7617
|
+
ctx.lineTo(startPx + widthPx, height);
|
|
7618
|
+
ctx.stroke();
|
|
7619
|
+
}
|
|
7551
7620
|
function drawDragPreview$1(stateModel, overlayCtx) {
|
|
7552
7621
|
const { apolloDragging, apolloRowHeight, lgv, theme } = stateModel;
|
|
7553
7622
|
const { bpPerPx, displayedRegions, offsetPx } = lgv;
|
|
@@ -7631,6 +7700,22 @@ function getFeatureFromLayout$1(feature, bp, row, featureTypeOntology) {
|
|
|
7631
7700
|
}
|
|
7632
7701
|
return feature;
|
|
7633
7702
|
}
|
|
7703
|
+
function getCDSCount(feature, featureTypeOntology) {
|
|
7704
|
+
const { children, type } = feature;
|
|
7705
|
+
if (!children) {
|
|
7706
|
+
return 0;
|
|
7707
|
+
}
|
|
7708
|
+
const isMrna = featureTypeOntology.isTypeOf(type, 'mRNA');
|
|
7709
|
+
let cdsCount = 0;
|
|
7710
|
+
if (isMrna) {
|
|
7711
|
+
for (const [, child] of children) {
|
|
7712
|
+
if (featureTypeOntology.isTypeOf(child.type, 'CDS')) {
|
|
7713
|
+
cdsCount += 1;
|
|
7714
|
+
}
|
|
7715
|
+
}
|
|
7716
|
+
}
|
|
7717
|
+
return cdsCount;
|
|
7718
|
+
}
|
|
7634
7719
|
function getRowCount$1(feature, featureTypeOntology, _bpPerPx) {
|
|
7635
7720
|
const { children, type } = feature;
|
|
7636
7721
|
if (!children) {
|
|
@@ -7640,12 +7725,12 @@ function getRowCount$1(feature, featureTypeOntology, _bpPerPx) {
|
|
|
7640
7725
|
let rowCount = 0;
|
|
7641
7726
|
if (isTranscript) {
|
|
7642
7727
|
for (const [, child] of children) {
|
|
7643
|
-
|
|
7644
|
-
if (isCds) {
|
|
7728
|
+
if (featureTypeOntology.isTypeOf(child.type, 'CDS')) {
|
|
7645
7729
|
rowCount += 1;
|
|
7646
7730
|
}
|
|
7647
7731
|
}
|
|
7648
|
-
return
|
|
7732
|
+
// return 1 if there are no CDSs for non coding genes
|
|
7733
|
+
return rowCount === 0 ? 1 : rowCount;
|
|
7649
7734
|
}
|
|
7650
7735
|
for (const [, child] of children) {
|
|
7651
7736
|
rowCount += getRowCount$1(child, featureTypeOntology);
|
|
@@ -7689,6 +7774,9 @@ function featuresForRow$1(feature, featureTypeOntology) {
|
|
|
7689
7774
|
for (const cds of cdss) {
|
|
7690
7775
|
features.push([cds, ...exons, child, feature]);
|
|
7691
7776
|
}
|
|
7777
|
+
if (cdss.length === 0) {
|
|
7778
|
+
features.push([...exons, child, feature]);
|
|
7779
|
+
}
|
|
7692
7780
|
}
|
|
7693
7781
|
return features;
|
|
7694
7782
|
}
|
|
@@ -7936,49 +8024,39 @@ const genericChildGlyph = {
|
|
|
7936
8024
|
};
|
|
7937
8025
|
|
|
7938
8026
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
8027
|
+
function getRowsForFeature(startingRow, rowCount, filledRowLocations) {
|
|
8028
|
+
const rowsForFeature = [];
|
|
8029
|
+
for (let i = startingRow; i < startingRow + rowCount; i++) {
|
|
8030
|
+
const row = filledRowLocations.get(i);
|
|
8031
|
+
if (row) {
|
|
8032
|
+
rowsForFeature.push(row);
|
|
8033
|
+
}
|
|
8034
|
+
}
|
|
8035
|
+
return rowsForFeature;
|
|
8036
|
+
}
|
|
8037
|
+
function canPlaceFeatureInRows(rowsForFeature, feature) {
|
|
8038
|
+
for (const rowForFeature of rowsForFeature) {
|
|
8039
|
+
for (const [rowStart, rowEnd] of rowForFeature) {
|
|
8040
|
+
if (doesIntersect2(feature.min, feature.max, rowStart, rowEnd) ||
|
|
8041
|
+
doesIntersect2(rowStart, rowEnd, feature.min, feature.max)) {
|
|
8042
|
+
return false;
|
|
8043
|
+
}
|
|
8044
|
+
}
|
|
8045
|
+
}
|
|
8046
|
+
return true;
|
|
8047
|
+
}
|
|
7939
8048
|
function layoutsModelFactory(pluginManager, configSchema) {
|
|
7940
8049
|
const BaseLinearApolloDisplay = baseModelFactory(pluginManager, configSchema);
|
|
7941
8050
|
return BaseLinearApolloDisplay.named('LinearApolloDisplayLayouts')
|
|
7942
8051
|
.props({
|
|
7943
|
-
|
|
8052
|
+
cleanupBoundary: 200_000,
|
|
7944
8053
|
})
|
|
7945
8054
|
.volatile(() => ({
|
|
7946
8055
|
seenFeatures: observable.map(),
|
|
7947
8056
|
}))
|
|
7948
8057
|
.views((self) => ({
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
return self.lgv.displayedRegions.map((region) => {
|
|
7952
|
-
const assembly = assemblyManager.get(region.assemblyName);
|
|
7953
|
-
let min;
|
|
7954
|
-
let max;
|
|
7955
|
-
const { end, refName, start } = region;
|
|
7956
|
-
for (const [, feature] of self.seenFeatures) {
|
|
7957
|
-
if (refName !== assembly?.getCanonicalRefName(feature.refSeq) ||
|
|
7958
|
-
!doesIntersect2(start, end, feature.min, feature.max) ||
|
|
7959
|
-
feature.length > self.featuresMinMaxLimit ||
|
|
7960
|
-
(self.filteredFeatureTypes.length > 0 &&
|
|
7961
|
-
!self.filteredFeatureTypes.includes(feature.type))) {
|
|
7962
|
-
continue;
|
|
7963
|
-
}
|
|
7964
|
-
if (min === undefined) {
|
|
7965
|
-
({ min } = feature);
|
|
7966
|
-
}
|
|
7967
|
-
if (max === undefined) {
|
|
7968
|
-
({ max } = feature);
|
|
7969
|
-
}
|
|
7970
|
-
if (feature.minWithChildren < min) {
|
|
7971
|
-
({ min } = feature);
|
|
7972
|
-
}
|
|
7973
|
-
if (feature.maxWithChildren > max) {
|
|
7974
|
-
({ max } = feature);
|
|
7975
|
-
}
|
|
7976
|
-
}
|
|
7977
|
-
if (min !== undefined && max !== undefined) {
|
|
7978
|
-
return [min, max];
|
|
7979
|
-
}
|
|
7980
|
-
return;
|
|
7981
|
-
});
|
|
8058
|
+
getAnnotationFeatureById(id) {
|
|
8059
|
+
return self.seenFeatures.get(id);
|
|
7982
8060
|
},
|
|
7983
8061
|
getGlyph(feature) {
|
|
7984
8062
|
if (this.looksLikeGene(feature)) {
|
|
@@ -8008,11 +8086,7 @@ function layoutsModelFactory(pluginManager, configSchema) {
|
|
|
8008
8086
|
if (!grandChildren?.size) {
|
|
8009
8087
|
return false;
|
|
8010
8088
|
}
|
|
8011
|
-
|
|
8012
|
-
const hasExon = [...grandChildren.values()].some((grandchild) => featureTypeOntology.isTypeOf(grandchild.type, 'exon'));
|
|
8013
|
-
if (hasCDS && hasExon) {
|
|
8014
|
-
return true;
|
|
8015
|
-
}
|
|
8089
|
+
return [...grandChildren.values()].some((grandchild) => featureTypeOntology.isTypeOf(grandchild.type, 'exon'));
|
|
8016
8090
|
}
|
|
8017
8091
|
}
|
|
8018
8092
|
return false;
|
|
@@ -8029,15 +8103,11 @@ function layoutsModelFactory(pluginManager, configSchema) {
|
|
|
8029
8103
|
.views((self) => ({
|
|
8030
8104
|
get featureLayouts() {
|
|
8031
8105
|
const { assemblyManager } = self.session;
|
|
8032
|
-
return self.lgv.displayedRegions.map((region
|
|
8106
|
+
return self.lgv.displayedRegions.map((region) => {
|
|
8033
8107
|
const assembly = assemblyManager.get(region.assemblyName);
|
|
8034
8108
|
const featureLayout = new Map();
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
return featureLayout;
|
|
8038
|
-
}
|
|
8039
|
-
const [min, max] = minMax;
|
|
8040
|
-
const rows = [];
|
|
8109
|
+
// Track the occupied coordinates in each row
|
|
8110
|
+
const filledRowLocations = new Map();
|
|
8041
8111
|
const { end, refName, start } = region;
|
|
8042
8112
|
for (const [id, feature] of self.seenFeatures.entries()) {
|
|
8043
8113
|
if (!isAlive(feature)) {
|
|
@@ -8060,42 +8130,23 @@ function layoutsModelFactory(pluginManager, configSchema) {
|
|
|
8060
8130
|
let startingRow = 0;
|
|
8061
8131
|
let placed = false;
|
|
8062
8132
|
while (!placed) {
|
|
8063
|
-
let rowsForFeature =
|
|
8133
|
+
let rowsForFeature = getRowsForFeature(startingRow, rowCount, filledRowLocations);
|
|
8064
8134
|
if (rowsForFeature.length < rowCount) {
|
|
8065
8135
|
for (let i = 0; i < rowCount - rowsForFeature.length; i++) {
|
|
8066
|
-
const newRowNumber =
|
|
8067
|
-
|
|
8136
|
+
const newRowNumber = filledRowLocations.size;
|
|
8137
|
+
filledRowLocations.set(newRowNumber, []);
|
|
8068
8138
|
featureLayout.set(newRowNumber, []);
|
|
8069
8139
|
}
|
|
8070
|
-
rowsForFeature =
|
|
8140
|
+
rowsForFeature = getRowsForFeature(startingRow, rowCount, filledRowLocations);
|
|
8071
8141
|
}
|
|
8072
|
-
if (rowsForFeature
|
|
8073
|
-
.map((rowForFeature) => {
|
|
8074
|
-
// zero-length features are allowed in the spec
|
|
8075
|
-
const featureMax = feature.max - feature.min === 0
|
|
8076
|
-
? feature.min + 1
|
|
8077
|
-
: feature.max;
|
|
8078
|
-
let start = feature.min - min, end = featureMax - min;
|
|
8079
|
-
if (feature.min - min < 0) {
|
|
8080
|
-
start = 0;
|
|
8081
|
-
end = featureMax - feature.min;
|
|
8082
|
-
}
|
|
8083
|
-
return rowForFeature.slice(start, end).some(Boolean);
|
|
8084
|
-
})
|
|
8085
|
-
.some(Boolean)) {
|
|
8142
|
+
if (!canPlaceFeatureInRows(rowsForFeature, feature)) {
|
|
8086
8143
|
startingRow += 1;
|
|
8087
8144
|
continue;
|
|
8088
8145
|
}
|
|
8089
8146
|
for (let rowNum = startingRow; rowNum < startingRow + rowCount; rowNum++) {
|
|
8090
|
-
|
|
8091
|
-
let start = feature.min - min, end = feature.max - min;
|
|
8092
|
-
if (feature.min - min < 0) {
|
|
8093
|
-
start = 0;
|
|
8094
|
-
end = feature.max - feature.min;
|
|
8095
|
-
}
|
|
8096
|
-
row.fill(true, start, end);
|
|
8147
|
+
filledRowLocations.get(rowNum)?.push([feature.min, feature.max]);
|
|
8097
8148
|
const layoutRow = featureLayout.get(rowNum);
|
|
8098
|
-
layoutRow?.push([rowNum - startingRow, feature]);
|
|
8149
|
+
layoutRow?.push([rowNum - startingRow, feature._id]);
|
|
8099
8150
|
}
|
|
8100
8151
|
placed = true;
|
|
8101
8152
|
}
|
|
@@ -8108,12 +8159,16 @@ function layoutsModelFactory(pluginManager, configSchema) {
|
|
|
8108
8159
|
const { featureTypeOntology } = self.session.apolloDataStore.ontologyManager;
|
|
8109
8160
|
for (const [idx, layout] of featureLayouts.entries()) {
|
|
8110
8161
|
for (const [layoutRowNum, layoutRow] of layout) {
|
|
8111
|
-
for (const [featureRowNum,
|
|
8162
|
+
for (const [featureRowNum, layoutFeatureId] of layoutRow) {
|
|
8112
8163
|
if (featureRowNum !== 0) {
|
|
8113
8164
|
// Same top-level feature in all feature rows, so only need to
|
|
8114
8165
|
// check the first one
|
|
8115
8166
|
continue;
|
|
8116
8167
|
}
|
|
8168
|
+
const layoutFeature = self.getAnnotationFeatureById(layoutFeatureId);
|
|
8169
|
+
if (!layoutFeature) {
|
|
8170
|
+
continue;
|
|
8171
|
+
}
|
|
8117
8172
|
if (feature._id === layoutFeature._id) {
|
|
8118
8173
|
return {
|
|
8119
8174
|
layoutIndex: idx,
|
|
@@ -8153,6 +8208,23 @@ function layoutsModelFactory(pluginManager, configSchema) {
|
|
|
8153
8208
|
if (!self.lgv.initialized || self.regionCannotBeRendered()) {
|
|
8154
8209
|
return;
|
|
8155
8210
|
}
|
|
8211
|
+
// Clear out features that are no longer in the view and out of the cleanup boundary
|
|
8212
|
+
// cleanup boundary + region boundary + cleanup boundary
|
|
8213
|
+
for (const [id, feature] of self.seenFeatures.entries()) {
|
|
8214
|
+
let shouldKeep = false;
|
|
8215
|
+
for (const region of self.regions) {
|
|
8216
|
+
const extendedStart = region.start - self.cleanupBoundary;
|
|
8217
|
+
const extendedEnd = region.end + self.cleanupBoundary;
|
|
8218
|
+
if (doesIntersect2(extendedStart, extendedEnd, feature.min, feature.max)) {
|
|
8219
|
+
shouldKeep = true;
|
|
8220
|
+
break;
|
|
8221
|
+
}
|
|
8222
|
+
}
|
|
8223
|
+
if (!shouldKeep) {
|
|
8224
|
+
self.deleteSeenFeature(id);
|
|
8225
|
+
}
|
|
8226
|
+
}
|
|
8227
|
+
// Add features that are in the current view
|
|
8156
8228
|
for (const region of self.regions) {
|
|
8157
8229
|
const assembly = self.session.apolloDataStore.assemblies.get(region.assemblyName);
|
|
8158
8230
|
const ref = assembly?.getByRefName(region.refName);
|
|
@@ -8426,8 +8498,9 @@ function renderingModelFactory(pluginManager, configSchema) {
|
|
|
8426
8498
|
for (const [idx, featureLayout] of featureLayouts.entries()) {
|
|
8427
8499
|
const displayedRegion = displayedRegions[idx];
|
|
8428
8500
|
for (const [row, featureLayoutRow] of featureLayout.entries()) {
|
|
8429
|
-
for (const [featureRow,
|
|
8430
|
-
|
|
8501
|
+
for (const [featureRow, featureId] of featureLayoutRow) {
|
|
8502
|
+
const feature = self.getAnnotationFeatureById(featureId);
|
|
8503
|
+
if (featureRow > 0 || !feature) {
|
|
8431
8504
|
continue;
|
|
8432
8505
|
}
|
|
8433
8506
|
if (!doesIntersect2(displayedRegion.start, displayedRegion.end, feature.min, feature.max)) {
|
|
@@ -8508,11 +8581,18 @@ function mouseEventsModelIntermediateFactory(pluginManager, configSchema) {
|
|
|
8508
8581
|
if (!layoutRow) {
|
|
8509
8582
|
return mousePosition;
|
|
8510
8583
|
}
|
|
8511
|
-
const foundFeature = layoutRow.find((f) =>
|
|
8584
|
+
const foundFeature = layoutRow.find((f) => {
|
|
8585
|
+
const feature = self.getAnnotationFeatureById(f[1]);
|
|
8586
|
+
return feature && bp >= feature.min && bp <= feature.max;
|
|
8587
|
+
});
|
|
8512
8588
|
if (!foundFeature) {
|
|
8513
8589
|
return mousePosition;
|
|
8514
8590
|
}
|
|
8515
|
-
const [featureRow,
|
|
8591
|
+
const [featureRow, topLevelFeatureId] = foundFeature;
|
|
8592
|
+
const topLevelFeature = self.getAnnotationFeatureById(topLevelFeatureId);
|
|
8593
|
+
if (!topLevelFeature) {
|
|
8594
|
+
return mousePosition;
|
|
8595
|
+
}
|
|
8516
8596
|
const glyph = self.getGlyph(topLevelFeature);
|
|
8517
8597
|
const { featureTypeOntology } = self.session.apolloDataStore.ontologyManager;
|
|
8518
8598
|
if (!featureTypeOntology) {
|
|
@@ -8796,11 +8876,18 @@ const useStyles$1 = makeStyles()((theme) => ({
|
|
|
8796
8876
|
color: theme.palette.warning.light,
|
|
8797
8877
|
backgroundColor: theme.palette.warning.contrastText,
|
|
8798
8878
|
},
|
|
8879
|
+
loading: {
|
|
8880
|
+
position: 'absolute',
|
|
8881
|
+
right: theme.spacing(3),
|
|
8882
|
+
zIndex: 10,
|
|
8883
|
+
pointerEvents: 'none',
|
|
8884
|
+
textAlign: 'right',
|
|
8885
|
+
},
|
|
8799
8886
|
}));
|
|
8800
8887
|
const LinearApolloDisplay = observer(function LinearApolloDisplay(props) {
|
|
8801
8888
|
const theme = useTheme();
|
|
8802
8889
|
const { model } = props;
|
|
8803
|
-
const { apolloRowHeight, contextMenuItems: getContextMenuItems, cursor, featuresHeight, isShown, onMouseDown, onMouseLeave, onMouseMove, onMouseUp, regionCannotBeRendered, session, setCanvas, setCollaboratorCanvas, setOverlayCanvas, setSeqTrackCanvas, setSeqTrackOverlayCanvas, setTheme, } = model;
|
|
8890
|
+
const { loading, apolloRowHeight, contextMenuItems: getContextMenuItems, cursor, featuresHeight, isShown, onMouseDown, onMouseLeave, onMouseMove, onMouseUp, regionCannotBeRendered, session, setCanvas, setCollaboratorCanvas, setOverlayCanvas, setSeqTrackCanvas, setSeqTrackOverlayCanvas, setTheme, } = model;
|
|
8804
8891
|
const { classes } = useStyles$1();
|
|
8805
8892
|
const lgv = getContainingView(model);
|
|
8806
8893
|
useEffect(() => {
|
|
@@ -8840,65 +8927,68 @@ const LinearApolloDisplay = observer(function LinearApolloDisplay(props) {
|
|
|
8840
8927
|
setContextCoord(coord);
|
|
8841
8928
|
setContextMenuItems(getContextMenuItems(coord));
|
|
8842
8929
|
}
|
|
8843
|
-
} },
|
|
8844
|
-
React__default.createElement(
|
|
8845
|
-
React__default.createElement("
|
|
8846
|
-
|
|
8847
|
-
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
assembly.
|
|
8866
|
-
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
|
|
8880
|
-
|
|
8881
|
-
|
|
8882
|
-
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
8888
|
-
|
|
8889
|
-
|
|
8890
|
-
|
|
8891
|
-
|
|
8892
|
-
|
|
8893
|
-
|
|
8894
|
-
|
|
8895
|
-
}, TransitionProps: {
|
|
8896
|
-
onExit: () => {
|
|
8930
|
+
} },
|
|
8931
|
+
loading ? (React__default.createElement("div", { className: classes.loading },
|
|
8932
|
+
React__default.createElement(CircularProgress, { size: "18px" }))) : null,
|
|
8933
|
+
message ? (React__default.createElement(Alert, { severity: "warning", classes: { message: classes.ellipses } },
|
|
8934
|
+
React__default.createElement(Tooltip, { title: message },
|
|
8935
|
+
React__default.createElement("div", null, message)))) : (
|
|
8936
|
+
// Promise.resolve() in these 3 callbacks is to avoid infinite rendering loop
|
|
8937
|
+
// https://github.com/mobxjs/mobx/issues/3728#issuecomment-1715400931
|
|
8938
|
+
React__default.createElement(React__default.Fragment, null,
|
|
8939
|
+
React__default.createElement("canvas", { ref: async (node) => {
|
|
8940
|
+
await Promise.resolve();
|
|
8941
|
+
setCollaboratorCanvas(node);
|
|
8942
|
+
}, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, className: classes.canvas, "data-testid": "collaboratorCanvas" }),
|
|
8943
|
+
React__default.createElement("canvas", { ref: async (node) => {
|
|
8944
|
+
await Promise.resolve();
|
|
8945
|
+
setCanvas(node);
|
|
8946
|
+
}, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, className: classes.canvas, "data-testid": "canvas" }),
|
|
8947
|
+
React__default.createElement("canvas", { ref: async (node) => {
|
|
8948
|
+
await Promise.resolve();
|
|
8949
|
+
setOverlayCanvas(node);
|
|
8950
|
+
}, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, className: classes.canvas, style: { cursor: cursor ?? 'default' }, "data-testid": "overlayCanvas" }),
|
|
8951
|
+
lgv.displayedRegions.flatMap((region, idx) => {
|
|
8952
|
+
const assembly = assemblyManager.get(region.assemblyName);
|
|
8953
|
+
return [...session.apolloDataStore.checkResults.values()]
|
|
8954
|
+
.filter((checkResult) => assembly?.isValidRefName(checkResult.refSeq) &&
|
|
8955
|
+
assembly.getCanonicalRefName(checkResult.refSeq) ===
|
|
8956
|
+
region.refName &&
|
|
8957
|
+
doesIntersect2(region.start, region.end, checkResult.start, checkResult.end))
|
|
8958
|
+
.map((checkResult) => {
|
|
8959
|
+
const left = (lgv.bpToPx({
|
|
8960
|
+
refName: region.refName,
|
|
8961
|
+
coord: checkResult.start,
|
|
8962
|
+
regionNumber: idx,
|
|
8963
|
+
})?.offsetPx ?? 0) - lgv.offsetPx;
|
|
8964
|
+
const [feature] = checkResult.ids;
|
|
8965
|
+
if (!feature) {
|
|
8966
|
+
return null;
|
|
8967
|
+
}
|
|
8968
|
+
const { topLevelFeature } = feature;
|
|
8969
|
+
const row = parent
|
|
8970
|
+
? model.getFeatureLayoutPosition(topLevelFeature)
|
|
8971
|
+
?.layoutRow ?? 0
|
|
8972
|
+
: 0;
|
|
8973
|
+
const top = row * apolloRowHeight;
|
|
8974
|
+
const height = apolloRowHeight;
|
|
8975
|
+
return (React__default.createElement(Tooltip, { key: checkResult._id, title: checkResult.message },
|
|
8976
|
+
React__default.createElement(Avatar, { className: classes.avatar, style: { top, left, height, width: height } },
|
|
8977
|
+
React__default.createElement(ErrorIcon, null))));
|
|
8978
|
+
});
|
|
8979
|
+
}),
|
|
8980
|
+
React__default.createElement(Menu$1, { open: contextMenuItems.length > 0, onMenuItemClick: (_, callback) => {
|
|
8981
|
+
callback();
|
|
8897
8982
|
setContextMenuItems([]);
|
|
8898
|
-
},
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8983
|
+
}, onClose: () => {
|
|
8984
|
+
setContextMenuItems([]);
|
|
8985
|
+
}, TransitionProps: {
|
|
8986
|
+
onExit: () => {
|
|
8987
|
+
setContextMenuItems([]);
|
|
8988
|
+
},
|
|
8989
|
+
}, anchorReference: "anchorPosition", anchorPosition: contextCoord
|
|
8990
|
+
? { top: contextCoord[1], left: contextCoord[0] }
|
|
8991
|
+
: undefined, style: { zIndex: theme.zIndex.tooltip }, menuItems: contextMenuItems }))))));
|
|
8902
8992
|
});
|
|
8903
8993
|
|
|
8904
8994
|
const TrackLines = observer(function TrackLines({ model, }) {
|