igv 2.11.0 → 2.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dist/igv.esm.js +632 -606
- package/dist/igv.esm.min.js +9 -9
- package/dist/igv.esm.min.js.map +1 -1
- package/dist/igv.js +641 -588
- package/dist/igv.min.js +6 -6
- package/dist/igv.min.js.map +1 -1
- package/package.json +4 -4
package/dist/igv.js
CHANGED
|
@@ -17943,7 +17943,7 @@
|
|
|
17943
17943
|
* @constructor
|
|
17944
17944
|
*/
|
|
17945
17945
|
|
|
17946
|
-
class FeatureCache {
|
|
17946
|
+
class FeatureCache$1 {
|
|
17947
17947
|
constructor(featureList, genome, range) {
|
|
17948
17948
|
featureList = featureList || [];
|
|
17949
17949
|
this.treeMap = this.buildTreeMap(featureList, genome);
|
|
@@ -19385,7 +19385,7 @@
|
|
|
19385
19385
|
}
|
|
19386
19386
|
|
|
19387
19387
|
function embedCSS$2() {
|
|
19388
|
-
var css = '.igv-ui-popover {\n cursor: default;\n position: absolute;\n z-index: 2048;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: 1px;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n background-color: white; }\n .igv-ui-popover > div:first-child {\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee; }\n .igv-ui-popover > div:first-child > div:first-child {\n margin-left: 4px; }\n .igv-ui-popover > div:first-child > div:last-child {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F; }\n .igv-ui-popover > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444; }\n .igv-ui-popover > div:last-child {\n overflow-y: auto;\n overflow-x: hidden;\n max-height: 400px;\n max-width: 800px;\n background-color: white; }\n .igv-ui-popover > div:last-child > div {\n -webkit-user-select: all;\n /* Chrome/Safari */\n -moz-user-select: all;\n /* Firefox */\n margin-left: 4px;\n margin-right: 4px;\n min-width: 220px;\n overflow-x: hidden;\n text-overflow: ellipsis;\n white-space: nowrap; }\n .igv-ui-popover > div:last-child > div > span {\n font-weight: bolder; }\n .igv-ui-popover > div:last-child hr {\n width: 100%; }\n\n.igv-ui-alert-dialog-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n top: 50%;\n left: 50%;\n width: 400px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n outline: none;\n font-family: \"Open Sans\", sans-serif;\n font-size: 15px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center; }\n .igv-ui-alert-dialog-container > div:first-child {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee; }\n .igv-ui-alert-dialog-container > div:first-child div:first-child {\n padding-left: 8px; }\n .igv-ui-alert-dialog-container .igv-ui-alert-dialog-body {\n color: #373737;\n width: 100%;\n height: calc(100% - 24px - 64px);\n overflow-y: scroll; }\n .igv-ui-alert-dialog-container .igv-ui-alert-dialog-body .igv-ui-alert-dialog-body-copy {\n cursor: pointer;\n margin: 16px;\n width: auto;\n height: auto;\n overflow-wrap: break-word;\n word-break: break-word;\n -webkit-user-select: all;\n -moz-user-select: all;\n -ms-user-select: all;\n user-select: all;\n background-color: white;\n border: unset; }\n .igv-ui-alert-dialog-container > div:last-child {\n width: 100%;\n margin-bottom: 10px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center; }\n .igv-ui-alert-dialog-container > div:last-child div {\n margin: unset;\n width: 40px;\n height: 30px;\n line-height: 30px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n border-color: #2B81AF;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF; }\n .igv-ui-alert-dialog-container > div:last-child div:hover {\n cursor: pointer;\n border-color: #25597f;\n background-color: #25597f; }\n\n.igv-ui-color-swatch {\n position: relative;\n box-sizing: content-box;\n display: flex;\n flex-flow: row;\n flex-wrap: wrap;\n justify-content: center;\n align-items: center;\n width: 32px;\n height: 32px;\n border-style: solid;\n border-width: 2px;\n border-color: white;\n border-radius: 4px; }\n\n.igv-ui-color-swatch:hover {\n border-color: dimgray; }\n\n.igv-ui-colorpicker-menu-close-button {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 32px;\n margin-top: 4px;\n margin-bottom: 4px;\n padding-right: 8px; }\n .igv-ui-colorpicker-menu-close-button i.fa {\n display: block;\n margin-left: 4px;\n margin-right: 4px;\n color: #5f5f5f; }\n .igv-ui-colorpicker-menu-close-button i.fa:hover,\n .igv-ui-colorpicker-menu-close-button i.fa:focus,\n .igv-ui-colorpicker-menu-close-button i.fa:active {\n cursor: pointer;\n color: #0f0f0f; }\n\n.igv-ui-generic-dialog-container {\n box-sizing: content-box;\n position: fixed;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n font-size: 16px; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f; }\n\n.igv-ui-generic-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center; }\n .igv-ui-generic-container div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd; }\n .igv-ui-generic-container div:first-child div {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px; }\n\n.igv-ui-dialog {\n z-index: 2048;\n position: fixed;\n width: fit-content;\n height: fit-content;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n background-color: white;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400; }\n .igv-ui-dialog .igv-ui-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee; }\n .igv-ui-dialog .igv-ui-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F; }\n .igv-ui-dialog .igv-ui-dialog-header div:hover {\n cursor: pointer;\n color: #444; }\n .igv-ui-dialog .igv-ui-dialog-one-liner {\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin: 8px;\n overflow-wrap: break-word;\n background-color: white;\n font-weight: bold; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel {\n width: 100%;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel div {\n margin: 16px;\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child {\n background-color: #5ea4e0; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child {\n background-color: #c4c4c4; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f; }\n .igv-ui-dialog .igv-ui-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center; }\n .igv-ui-dialog .igv-ui-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF; }\n .igv-ui-dialog .igv-ui-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f; }\n\n.igv-ui-panel, .igv-ui-panel-column, .igv-ui-panel-row {\n z-index: 2048;\n background-color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start; }\n\n.igv-ui-panel-column {\n display: flex;\n flex-direction: column; }\n\n.igv-ui-panel-row {\n display: flex;\n flex-direction: row; }\n\n.igv-ui-textbox {\n background-color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start; }\n\n/*# sourceMappingURL=igv-ui.css.map */\n';
|
|
19388
|
+
var css = '.igv-ui-popover {\n cursor: default;\n position: absolute;\n z-index: 2048;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: 1px;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n background-color: white; }\n .igv-ui-popover > div:first-child {\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee; }\n .igv-ui-popover > div:first-child > div:first-child {\n margin-left: 4px; }\n .igv-ui-popover > div:first-child > div:last-child {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F; }\n .igv-ui-popover > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444; }\n .igv-ui-popover > div:last-child {\n overflow-y: auto;\n overflow-x: hidden;\n max-height: 400px;\n max-width: 800px;\n background-color: white; }\n .igv-ui-popover > div:last-child > div {\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n user-select: text;\n margin-left: 4px;\n margin-right: 4px;\n min-width: 220px;\n overflow-x: hidden;\n text-overflow: ellipsis;\n white-space: nowrap; }\n .igv-ui-popover > div:last-child > div > span {\n font-weight: bolder; }\n .igv-ui-popover > div:last-child hr {\n width: 100%; }\n\n.igv-ui-alert-dialog-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n top: 50%;\n left: 50%;\n width: 400px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n outline: none;\n font-family: \"Open Sans\", sans-serif;\n font-size: 15px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center; }\n .igv-ui-alert-dialog-container > div:first-child {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee; }\n .igv-ui-alert-dialog-container > div:first-child div:first-child {\n padding-left: 8px; }\n .igv-ui-alert-dialog-container .igv-ui-alert-dialog-body {\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n user-select: text;\n color: #373737;\n width: 100%;\n height: calc(100% - 24px - 64px);\n overflow-y: scroll; }\n .igv-ui-alert-dialog-container .igv-ui-alert-dialog-body .igv-ui-alert-dialog-body-copy {\n margin: 16px;\n width: auto;\n height: auto;\n overflow-wrap: break-word;\n word-break: break-word;\n background-color: white;\n border: unset; }\n .igv-ui-alert-dialog-container > div:last-child {\n width: 100%;\n margin-bottom: 10px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center; }\n .igv-ui-alert-dialog-container > div:last-child div {\n margin: unset;\n width: 40px;\n height: 30px;\n line-height: 30px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n border-color: #2B81AF;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF; }\n .igv-ui-alert-dialog-container > div:last-child div:hover {\n cursor: pointer;\n border-color: #25597f;\n background-color: #25597f; }\n\n.igv-ui-color-swatch {\n position: relative;\n box-sizing: content-box;\n display: flex;\n flex-flow: row;\n flex-wrap: wrap;\n justify-content: center;\n align-items: center;\n width: 32px;\n height: 32px;\n border-style: solid;\n border-width: 2px;\n border-color: white;\n border-radius: 4px; }\n\n.igv-ui-color-swatch:hover {\n border-color: dimgray; }\n\n.igv-ui-colorpicker-menu-close-button {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 32px;\n margin-top: 4px;\n margin-bottom: 4px;\n padding-right: 8px; }\n .igv-ui-colorpicker-menu-close-button i.fa {\n display: block;\n margin-left: 4px;\n margin-right: 4px;\n color: #5f5f5f; }\n .igv-ui-colorpicker-menu-close-button i.fa:hover,\n .igv-ui-colorpicker-menu-close-button i.fa:focus,\n .igv-ui-colorpicker-menu-close-button i.fa:active {\n cursor: pointer;\n color: #0f0f0f; }\n\n.igv-ui-generic-dialog-container {\n box-sizing: content-box;\n position: fixed;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n font-size: 16px; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF; }\n .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f; }\n\n.igv-ui-generic-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center; }\n .igv-ui-generic-container > div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd; }\n .igv-ui-generic-container > div:first-child > div {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px; }\n\n.igv-ui-dialog {\n z-index: 2048;\n position: fixed;\n width: fit-content;\n height: fit-content;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n background-color: white;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400; }\n .igv-ui-dialog .igv-ui-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee; }\n .igv-ui-dialog .igv-ui-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F; }\n .igv-ui-dialog .igv-ui-dialog-header div:hover {\n cursor: pointer;\n color: #444; }\n .igv-ui-dialog .igv-ui-dialog-one-liner {\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin: 8px;\n overflow-wrap: break-word;\n background-color: white;\n font-weight: bold; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel {\n width: 100%;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel div {\n margin: 16px;\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child {\n background-color: #5ea4e0; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child {\n background-color: #c4c4c4; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f; }\n .igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f; }\n .igv-ui-dialog .igv-ui-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center; }\n .igv-ui-dialog .igv-ui-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF; }\n .igv-ui-dialog .igv-ui-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f; }\n\n.igv-ui-panel, .igv-ui-panel-column, .igv-ui-panel-row {\n z-index: 2048;\n background-color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start; }\n\n.igv-ui-panel-column {\n display: flex;\n flex-direction: column; }\n\n.igv-ui-panel-row {\n display: flex;\n flex-direction: row; }\n\n.igv-ui-textbox {\n background-color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start; }\n\n/*# sourceMappingURL=igv-ui.css.map */\n';
|
|
19389
19389
|
var style = document.createElement('style');
|
|
19390
19390
|
style.setAttribute('type', 'text/css');
|
|
19391
19391
|
style.innerHTML = css;
|
|
@@ -19911,7 +19911,7 @@
|
|
|
19911
19911
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19912
19912
|
* THE SOFTWARE.
|
|
19913
19913
|
*/
|
|
19914
|
-
const knownFileExtensions = new Set(["narrowpeak", "broadpeak", "regionpeak", "peaks", "bedgraph", "wig", "gff3", "gff", "gtf", "fusionjuncspan", "refflat", "seg", "aed", "bed", "vcf", "bb", "bigbed", "bw", "bigwig", "bam", "tdf", "refgene", "genepred", "genepredext", "bedpe", "bp", "snp", "rmsk", "cram", "gwas", "maf", "mut"]);
|
|
19914
|
+
const knownFileExtensions = new Set(["narrowpeak", "broadpeak", "regionpeak", "peaks", "bedgraph", "wig", "gff3", "gff", "gtf", "fusionjuncspan", "refflat", "seg", "aed", "bed", "vcf", "bb", "bigbed", "biginteract", "bw", "bigwig", "bam", "tdf", "refgene", "genepred", "genepredext", "bedpe", "bp", "snp", "rmsk", "cram", "gwas", "maf", "mut"]);
|
|
19915
19915
|
/**
|
|
19916
19916
|
* Return a custom format object with the given name.
|
|
19917
19917
|
* @param name
|
|
@@ -20043,6 +20043,7 @@
|
|
|
20043
20043
|
case "bed":
|
|
20044
20044
|
case "bigbed":
|
|
20045
20045
|
case "bb":
|
|
20046
|
+
case "biginteract":
|
|
20046
20047
|
return "bedtype";
|
|
20047
20048
|
|
|
20048
20049
|
default:
|
|
@@ -20732,14 +20733,13 @@
|
|
|
20732
20733
|
console.log('Viewport - draw(drawConfiguration, features, roiFeatures)');
|
|
20733
20734
|
}
|
|
20734
20735
|
|
|
20735
|
-
checkContentHeight() {
|
|
20736
|
+
checkContentHeight(features) {
|
|
20736
20737
|
let track = this.trackView.track;
|
|
20738
|
+
features = features || this.cachedFeatures;
|
|
20737
20739
|
|
|
20738
20740
|
if ("FILL" === track.displayMode) {
|
|
20739
20741
|
this.setContentHeight(this.$viewport.height());
|
|
20740
20742
|
} else if (typeof track.computePixelHeight === 'function') {
|
|
20741
|
-
let features = this.cachedFeatures;
|
|
20742
|
-
|
|
20743
20743
|
if (features && features.length > 0) {
|
|
20744
20744
|
let requiredContentHeight = track.computePixelHeight(features);
|
|
20745
20745
|
let currentContentHeight = this.$content.height();
|
|
@@ -20759,7 +20759,7 @@
|
|
|
20759
20759
|
// Maximum height of a canvas is ~32,000 pixels on Chrome, possibly smaller on other platforms
|
|
20760
20760
|
contentHeight = Math.min(contentHeight, 32000);
|
|
20761
20761
|
this.$content.height(contentHeight);
|
|
20762
|
-
if (this.
|
|
20762
|
+
if (this.canvas._data) this.canvas._data.invalidate = true;
|
|
20763
20763
|
}
|
|
20764
20764
|
|
|
20765
20765
|
isLoading() {
|
|
@@ -20774,8 +20774,6 @@
|
|
|
20774
20774
|
|
|
20775
20775
|
setWidth(width) {
|
|
20776
20776
|
this.$viewport.width(width);
|
|
20777
|
-
this.canvas.style.width = `${width}px`;
|
|
20778
|
-
this.canvas.setAttribute('width', width);
|
|
20779
20777
|
}
|
|
20780
20778
|
|
|
20781
20779
|
getWidth() {
|
|
@@ -23060,7 +23058,7 @@
|
|
|
23060
23058
|
}
|
|
23061
23059
|
};
|
|
23062
23060
|
|
|
23063
|
-
const _version = "2.11.
|
|
23061
|
+
const _version = "2.11.1";
|
|
23064
23062
|
|
|
23065
23063
|
function version$1() {
|
|
23066
23064
|
return _version;
|
|
@@ -23577,16 +23575,20 @@
|
|
|
23577
23575
|
|
|
23578
23576
|
checkZoomIn() {
|
|
23579
23577
|
const showZoomInNotice = () => {
|
|
23580
|
-
const referenceFrame = this.referenceFrame;
|
|
23581
|
-
|
|
23582
23578
|
if (this.referenceFrame.chr.toLowerCase() === "all" && !this.trackView.track.supportsWholeGenome()) {
|
|
23583
23579
|
return true;
|
|
23584
23580
|
} else {
|
|
23585
23581
|
const visibilityWindow = this.trackView.track.visibilityWindow;
|
|
23586
|
-
return visibilityWindow !== undefined && visibilityWindow > 0 && referenceFrame.bpPerPixel * this.$viewport.width() > visibilityWindow;
|
|
23582
|
+
return visibilityWindow !== undefined && visibilityWindow > 0 && this.referenceFrame.bpPerPixel * this.$viewport.width() > visibilityWindow;
|
|
23587
23583
|
}
|
|
23588
23584
|
};
|
|
23589
23585
|
|
|
23586
|
+
if (this.trackView.track && "sequence" === this.trackView.track.type && this.referenceFrame.bpPerPixel > 1) {
|
|
23587
|
+
if (this.canvas) ;
|
|
23588
|
+
|
|
23589
|
+
return false;
|
|
23590
|
+
}
|
|
23591
|
+
|
|
23590
23592
|
if (!this.viewIsReady()) {
|
|
23591
23593
|
return false;
|
|
23592
23594
|
}
|
|
@@ -23596,7 +23598,8 @@
|
|
|
23596
23598
|
// Out of visibility window
|
|
23597
23599
|
if (this.canvas) {
|
|
23598
23600
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
23599
|
-
this.
|
|
23601
|
+
this.canvas._data = undefined;
|
|
23602
|
+
this.featureCache = undefined;
|
|
23600
23603
|
}
|
|
23601
23604
|
|
|
23602
23605
|
this.$zoomInNotice.show();
|
|
@@ -23615,14 +23618,17 @@
|
|
|
23615
23618
|
|
|
23616
23619
|
return true;
|
|
23617
23620
|
}
|
|
23621
|
+
/**
|
|
23622
|
+
* Adjust the canvas to the current genomic state.
|
|
23623
|
+
*/
|
|
23624
|
+
|
|
23618
23625
|
|
|
23619
23626
|
shift() {
|
|
23620
|
-
const
|
|
23621
|
-
const referenceFrame = self.referenceFrame;
|
|
23627
|
+
const referenceFrame = this.referenceFrame;
|
|
23622
23628
|
|
|
23623
|
-
if (
|
|
23624
|
-
const pixelOffset = Math.round((
|
|
23625
|
-
|
|
23629
|
+
if (this.canvas && this.canvas._data && this.canvas._data.chr === this.referenceFrame.chr && this.canvas._data.bpPerPixel === referenceFrame.bpPerPixel) {
|
|
23630
|
+
const pixelOffset = Math.round((this.canvas._data.startBP - referenceFrame.start) / referenceFrame.bpPerPixel);
|
|
23631
|
+
this.canvas.style.left = pixelOffset + "px";
|
|
23626
23632
|
}
|
|
23627
23633
|
}
|
|
23628
23634
|
|
|
@@ -23648,9 +23654,10 @@
|
|
|
23648
23654
|
this.startSpinner();
|
|
23649
23655
|
|
|
23650
23656
|
try {
|
|
23651
|
-
const
|
|
23657
|
+
const track = this.trackView.track;
|
|
23658
|
+
const features = await this.getFeatures(track, chr, bpStart, bpEnd, referenceFrame.bpPerPixel);
|
|
23652
23659
|
let roiFeatures = [];
|
|
23653
|
-
const roi = mergeArrays(this.browser.roi,
|
|
23660
|
+
const roi = mergeArrays(this.browser.roi, track.roi);
|
|
23654
23661
|
|
|
23655
23662
|
if (roi) {
|
|
23656
23663
|
for (let r of roi) {
|
|
@@ -23662,11 +23669,13 @@
|
|
|
23662
23669
|
}
|
|
23663
23670
|
}
|
|
23664
23671
|
|
|
23665
|
-
|
|
23672
|
+
const mr = track && ("wig" === track.type || "merged" === track.type); // wig tracks are potentially multiresolution (e.g. bigwig)
|
|
23673
|
+
|
|
23674
|
+
this.featureCache = new FeatureCache(chr, bpStart, bpEnd, referenceFrame.bpPerPixel, features, roiFeatures, mr);
|
|
23666
23675
|
this.loading = false;
|
|
23667
23676
|
this.hideMessage();
|
|
23668
23677
|
this.stopSpinner();
|
|
23669
|
-
return this.
|
|
23678
|
+
return this.featureCache;
|
|
23670
23679
|
} catch (error) {
|
|
23671
23680
|
// Track might have been removed during load
|
|
23672
23681
|
if (this.trackView && this.trackView.disposed !== true) {
|
|
@@ -23679,30 +23688,34 @@
|
|
|
23679
23688
|
this.stopSpinner();
|
|
23680
23689
|
}
|
|
23681
23690
|
}
|
|
23691
|
+
/**
|
|
23692
|
+
* Repaint the canvas for the current genomic state.
|
|
23693
|
+
*
|
|
23694
|
+
* @returns {Promise<void>}
|
|
23695
|
+
*/
|
|
23682
23696
|
|
|
23683
|
-
|
|
23684
|
-
|
|
23697
|
+
|
|
23698
|
+
repaint() {
|
|
23699
|
+
if (undefined === this.featureCache) {
|
|
23685
23700
|
return;
|
|
23686
23701
|
}
|
|
23687
23702
|
|
|
23688
23703
|
let {
|
|
23689
23704
|
features,
|
|
23690
|
-
roiFeatures
|
|
23691
|
-
|
|
23692
|
-
|
|
23693
|
-
endBP
|
|
23694
|
-
} = this.tile; // const isWGV = GenomeUtils.isWholeGenomeView(this.browser.referenceFrameList[0].chr)
|
|
23705
|
+
roiFeatures
|
|
23706
|
+
} = this.featureCache; //this.tile.bpPerPixel = this.referenceFrame.bpPerPixel
|
|
23707
|
+
// const isWGV = GenomeUtils.isWholeGenomeView(this.browser.referenceFrameList[0].chr)
|
|
23695
23708
|
|
|
23696
23709
|
const isWGV = GenomeUtils.isWholeGenomeView(this.referenceFrame.chr);
|
|
23697
23710
|
let pixelWidth;
|
|
23711
|
+
const startBP = this.featureCache.startBP;
|
|
23712
|
+
const endBP = this.featureCache.endBP;
|
|
23713
|
+
let bpPerPixel = this.referenceFrame.bpPerPixel;
|
|
23698
23714
|
|
|
23699
23715
|
if (isWGV) {
|
|
23700
|
-
bpPerPixel = this.referenceFrame.end / this.$viewport.width();
|
|
23701
|
-
startBP = 0;
|
|
23702
|
-
endBP = this.referenceFrame.end;
|
|
23703
23716
|
pixelWidth = this.$viewport.width();
|
|
23704
23717
|
} else {
|
|
23705
|
-
pixelWidth =
|
|
23718
|
+
pixelWidth = 3 * this.$viewport.width();
|
|
23706
23719
|
} // For deep tracks we paint a canvas == 3*viewportHeight centered on the current vertical scroll position
|
|
23707
23720
|
|
|
23708
23721
|
|
|
@@ -23755,21 +23768,33 @@
|
|
|
23755
23768
|
viewport: this,
|
|
23756
23769
|
viewportWidth: this.$viewport.width()
|
|
23757
23770
|
};
|
|
23758
|
-
this.draw(drawConfiguration, features, roiFeatures);
|
|
23759
|
-
|
|
23771
|
+
this.draw(drawConfiguration, features, roiFeatures); // Attach metadata to canvas
|
|
23772
|
+
|
|
23773
|
+
newCanvas._data = {
|
|
23774
|
+
chr: this.referenceFrame.chr,
|
|
23775
|
+
startBP,
|
|
23776
|
+
endBP,
|
|
23777
|
+
bpPerPixel,
|
|
23760
23778
|
top: canvasTop,
|
|
23761
23779
|
bottom: canvasTop + pixelHeight
|
|
23762
23780
|
};
|
|
23763
23781
|
|
|
23764
|
-
if (this
|
|
23765
|
-
this
|
|
23782
|
+
if (this.canvas) {
|
|
23783
|
+
$$1(this.canvas).remove();
|
|
23766
23784
|
}
|
|
23767
23785
|
|
|
23768
|
-
this.$canvas = $$1(newCanvas);
|
|
23769
|
-
this.$content.append(this.$canvas);
|
|
23770
23786
|
this.canvas = newCanvas;
|
|
23771
23787
|
this.ctx = ctx;
|
|
23788
|
+
this.$content.append($$1(newCanvas));
|
|
23772
23789
|
}
|
|
23790
|
+
/**
|
|
23791
|
+
* Draw the associated track.
|
|
23792
|
+
*
|
|
23793
|
+
* @param drawConfiguration
|
|
23794
|
+
* @param features
|
|
23795
|
+
* @param roiFeatures
|
|
23796
|
+
*/
|
|
23797
|
+
|
|
23773
23798
|
|
|
23774
23799
|
draw(drawConfiguration, features, roiFeatures) {
|
|
23775
23800
|
// console.log(`${ Date.now() } viewport draw(). track ${ this.trackView.track.type }. content-css-top ${ this.$content.css('top') }. canvas-top ${ drawConfiguration.pixelTop }.`)
|
|
@@ -23784,51 +23809,6 @@
|
|
|
23784
23809
|
r.track.draw(drawConfiguration);
|
|
23785
23810
|
}
|
|
23786
23811
|
}
|
|
23787
|
-
} // TODO: Nolonger used. Will discard
|
|
23788
|
-
|
|
23789
|
-
|
|
23790
|
-
async toSVG(tile) {
|
|
23791
|
-
// Nothing to do if zoomInNotice is active
|
|
23792
|
-
if (this.$zoomInNotice && this.$zoomInNotice.is(":visible")) {
|
|
23793
|
-
return;
|
|
23794
|
-
}
|
|
23795
|
-
|
|
23796
|
-
const referenceFrame = this.referenceFrame;
|
|
23797
|
-
const bpPerPixel = tile.bpPerPixel;
|
|
23798
|
-
const features = tile.features;
|
|
23799
|
-
const roiFeatures = tile.roiFeatures;
|
|
23800
|
-
const pixelWidth = this.$viewport.width();
|
|
23801
|
-
const pixelHeight = this.$viewport.height();
|
|
23802
|
-
const bpStart = referenceFrame.start;
|
|
23803
|
-
const bpEnd = referenceFrame.start + pixelWidth * referenceFrame.bpPerPixel;
|
|
23804
|
-
const ctx$1 = new ctx({
|
|
23805
|
-
// svg
|
|
23806
|
-
width: pixelWidth,
|
|
23807
|
-
height: pixelHeight,
|
|
23808
|
-
viewbox: {
|
|
23809
|
-
x: 0,
|
|
23810
|
-
y: -this.$content.position().top,
|
|
23811
|
-
width: pixelWidth,
|
|
23812
|
-
height: pixelHeight
|
|
23813
|
-
}
|
|
23814
|
-
});
|
|
23815
|
-
const drawConfiguration = {
|
|
23816
|
-
viewport: this,
|
|
23817
|
-
context: ctx$1,
|
|
23818
|
-
top: -this.$content.position().top,
|
|
23819
|
-
pixelTop: 0,
|
|
23820
|
-
// for compatibility with canvas draw
|
|
23821
|
-
pixelWidth,
|
|
23822
|
-
pixelHeight,
|
|
23823
|
-
bpStart,
|
|
23824
|
-
bpEnd,
|
|
23825
|
-
bpPerPixel,
|
|
23826
|
-
referenceFrame: this.referenceFrame,
|
|
23827
|
-
selection: this.selection,
|
|
23828
|
-
viewportWidth: pixelWidth
|
|
23829
|
-
};
|
|
23830
|
-
this.draw(drawConfiguration, features, roiFeatures);
|
|
23831
|
-
return ctx$1.getSerializedSvg(true);
|
|
23832
23812
|
}
|
|
23833
23813
|
|
|
23834
23814
|
containsPosition(chr, position) {
|
|
@@ -23843,9 +23823,10 @@
|
|
|
23843
23823
|
return this.loading;
|
|
23844
23824
|
}
|
|
23845
23825
|
|
|
23846
|
-
|
|
23826
|
+
savePNG() {
|
|
23847
23827
|
if (!this.ctx) return;
|
|
23848
|
-
const
|
|
23828
|
+
const canvasMetadata = this.canvas._data;
|
|
23829
|
+
const canvasTop = canvasMetadata ? canvasMetadata.top : 0;
|
|
23849
23830
|
const devicePixelRatio = window.devicePixelRatio;
|
|
23850
23831
|
const w = this.$viewport.width() * devicePixelRatio;
|
|
23851
23832
|
const h = this.$viewport.height() * devicePixelRatio;
|
|
@@ -23967,23 +23948,22 @@
|
|
|
23967
23948
|
viewportWidth: width,
|
|
23968
23949
|
selection: this.selection
|
|
23969
23950
|
};
|
|
23970
|
-
const features = this.
|
|
23971
|
-
const roiFeatures = this.
|
|
23951
|
+
const features = this.featureCache ? this.featureCache.features : [];
|
|
23952
|
+
const roiFeatures = this.featureCache ? this.featureCache.roiFeatures : undefined;
|
|
23972
23953
|
this.draw(config, features, roiFeatures);
|
|
23973
23954
|
context.restore();
|
|
23974
23955
|
}
|
|
23975
23956
|
|
|
23976
|
-
|
|
23977
|
-
return this.
|
|
23957
|
+
get cachedFeatures() {
|
|
23958
|
+
return this.featureCache ? this.featureCache.features : [];
|
|
23978
23959
|
}
|
|
23979
23960
|
|
|
23980
23961
|
async getFeatures(track, chr, start, end, bpPerPixel) {
|
|
23981
|
-
if (this.
|
|
23982
|
-
return this.
|
|
23962
|
+
if (this.featureCache && this.featureCache.containsRange(chr, start, end, bpPerPixel)) {
|
|
23963
|
+
return this.featureCache.features;
|
|
23983
23964
|
} else if (typeof track.getFeatures === "function") {
|
|
23984
23965
|
const features = await track.getFeatures(chr, start, end, bpPerPixel, this);
|
|
23985
|
-
this.
|
|
23986
|
-
this.checkContentHeight();
|
|
23966
|
+
this.checkContentHeight(features);
|
|
23987
23967
|
return features;
|
|
23988
23968
|
} else {
|
|
23989
23969
|
return undefined;
|
|
@@ -24263,11 +24243,6 @@
|
|
|
24263
24243
|
const viewportCoords = translateMouseCoordinates$1(event, viewport.contentDiv);
|
|
24264
24244
|
const canvasCoords = translateMouseCoordinates$1(event, viewport.canvas);
|
|
24265
24245
|
const genomicLocation = referenceFrame.start + referenceFrame.toBP(viewportCoords.x);
|
|
24266
|
-
|
|
24267
|
-
if (undefined === genomicLocation || null === viewport.tile) {
|
|
24268
|
-
return undefined;
|
|
24269
|
-
}
|
|
24270
|
-
|
|
24271
24246
|
return {
|
|
24272
24247
|
event,
|
|
24273
24248
|
viewport,
|
|
@@ -24321,22 +24296,28 @@
|
|
|
24321
24296
|
return rows.join('');
|
|
24322
24297
|
}
|
|
24323
24298
|
|
|
24324
|
-
|
|
24325
|
-
|
|
24326
|
-
|
|
24327
|
-
|
|
24328
|
-
|
|
24329
|
-
|
|
24330
|
-
|
|
24331
|
-
|
|
24299
|
+
class FeatureCache {
|
|
24300
|
+
constructor(chr, tileStart, tileEnd, bpPerPixel, features, roiFeatures, multiresolution) {
|
|
24301
|
+
this.chr = chr;
|
|
24302
|
+
this.startBP = tileStart;
|
|
24303
|
+
this.endBP = tileEnd;
|
|
24304
|
+
this.bpPerPixel = bpPerPixel;
|
|
24305
|
+
this.features = features;
|
|
24306
|
+
this.roiFeatures = roiFeatures;
|
|
24307
|
+
this.multiresolution = multiresolution;
|
|
24308
|
+
}
|
|
24332
24309
|
|
|
24333
|
-
|
|
24334
|
-
|
|
24335
|
-
|
|
24310
|
+
containsRange(chr, start, end, bpPerPixel) {
|
|
24311
|
+
// For multi-resolution tracks allow for a 2X change in bpPerPixel
|
|
24312
|
+
const r = this.multiresolution ? this.bpPerPixel / bpPerPixel : 1;
|
|
24313
|
+
return start >= this.startBP && end <= this.endBP && chr === this.chr && r > 0.5 && r < 2;
|
|
24314
|
+
}
|
|
24336
24315
|
|
|
24337
|
-
|
|
24338
|
-
|
|
24339
|
-
|
|
24316
|
+
overlapsRange(chr, start, end) {
|
|
24317
|
+
return this.chr === chr && end >= this.startBP && start <= this.endBP;
|
|
24318
|
+
}
|
|
24319
|
+
|
|
24320
|
+
}
|
|
24340
24321
|
/**
|
|
24341
24322
|
* Merge 2 arrays. a and/or b can be undefined. If both are undefined, return undefined
|
|
24342
24323
|
* @param a An array or undefined
|
|
@@ -25480,6 +25461,18 @@
|
|
|
25480
25461
|
return true; // By definition
|
|
25481
25462
|
}
|
|
25482
25463
|
|
|
25464
|
+
isMateMapped() {
|
|
25465
|
+
return true; // By definition
|
|
25466
|
+
}
|
|
25467
|
+
|
|
25468
|
+
isProperPair() {
|
|
25469
|
+
return this.firstAlignment.isProperPair();
|
|
25470
|
+
}
|
|
25471
|
+
|
|
25472
|
+
get tlen() {
|
|
25473
|
+
return Math.abs(this.firstAlignment.fragmentLength);
|
|
25474
|
+
}
|
|
25475
|
+
|
|
25483
25476
|
firstOfPairStrand() {
|
|
25484
25477
|
if (this.firstAlignment.isFirstOfPair()) {
|
|
25485
25478
|
return this.firstAlignment.strand;
|
|
@@ -25846,7 +25839,15 @@
|
|
|
25846
25839
|
*/
|
|
25847
25840
|
|
|
25848
25841
|
class AlignmentContainer {
|
|
25849
|
-
|
|
25842
|
+
// this.config.samplingWindowSize, this.config.samplingDepth,
|
|
25843
|
+
// this.config.pairsSupported, this.config.alleleFreqThreshold)
|
|
25844
|
+
constructor(chr, start, end, _ref) {
|
|
25845
|
+
let {
|
|
25846
|
+
samplingWindowSize,
|
|
25847
|
+
samplingDepth,
|
|
25848
|
+
pairsSupported,
|
|
25849
|
+
alleleFreqThreshold
|
|
25850
|
+
} = _ref;
|
|
25850
25851
|
this.chr = chr;
|
|
25851
25852
|
this.start = Math.floor(start);
|
|
25852
25853
|
this.end = Math.ceil(end);
|
|
@@ -25869,17 +25870,10 @@
|
|
|
25869
25870
|
// TODO -- pass this in
|
|
25870
25871
|
return alignment.isMapped() && !alignment.isFailsVendorQualityCheck();
|
|
25871
25872
|
};
|
|
25872
|
-
|
|
25873
|
-
this.pairedEndStats = new PairedEndStats();
|
|
25874
25873
|
}
|
|
25875
25874
|
|
|
25876
25875
|
push(alignment) {
|
|
25877
25876
|
if (this.filter(alignment) === false) return;
|
|
25878
|
-
|
|
25879
|
-
if (alignment.isPaired()) {
|
|
25880
|
-
this.pairedEndStats.push(alignment);
|
|
25881
|
-
}
|
|
25882
|
-
|
|
25883
25877
|
this.coverageMap.incCounts(alignment); // Count coverage before any downsampling
|
|
25884
25878
|
|
|
25885
25879
|
if (this.pairsSupported && this.downsampledReads.has(alignment.readName)) {
|
|
@@ -25908,7 +25902,6 @@
|
|
|
25908
25902
|
});
|
|
25909
25903
|
this.pairsCache = undefined;
|
|
25910
25904
|
this.downsampledReads = undefined;
|
|
25911
|
-
this.pairedEndStats.compute();
|
|
25912
25905
|
}
|
|
25913
25906
|
|
|
25914
25907
|
contains(chr, start, end) {
|
|
@@ -26203,62 +26196,6 @@
|
|
|
26203
26196
|
|
|
26204
26197
|
}
|
|
26205
26198
|
|
|
26206
|
-
class PairedEndStats {
|
|
26207
|
-
constructor(lowerPercentile, upperPercentile) {
|
|
26208
|
-
this.totalCount = 0;
|
|
26209
|
-
this.frCount = 0;
|
|
26210
|
-
this.rfCount = 0;
|
|
26211
|
-
this.ffCount = 0;
|
|
26212
|
-
this.sumF = 0;
|
|
26213
|
-
this.sumF2 = 0; //this.lp = lowerPercentile === undefined ? 0.005 : lowerPercentile;
|
|
26214
|
-
//this.up = upperPercentile === undefined ? 0.995 : upperPercentile;
|
|
26215
|
-
//this.digest = new Digest();
|
|
26216
|
-
}
|
|
26217
|
-
|
|
26218
|
-
push(alignment) {
|
|
26219
|
-
if (alignment.isProperPair()) {
|
|
26220
|
-
var fragmentLength = Math.abs(alignment.fragmentLength); //this.digest.push(fragmentLength);
|
|
26221
|
-
|
|
26222
|
-
this.sumF += fragmentLength;
|
|
26223
|
-
this.sumF2 += fragmentLength * fragmentLength;
|
|
26224
|
-
var po = alignment.pairOrientation;
|
|
26225
|
-
|
|
26226
|
-
if (typeof po === "string" && po.length === 4) {
|
|
26227
|
-
var tmp = '' + po.charAt(0) + po.charAt(2);
|
|
26228
|
-
|
|
26229
|
-
switch (tmp) {
|
|
26230
|
-
case 'FF':
|
|
26231
|
-
case 'RR':
|
|
26232
|
-
this.ffCount++;
|
|
26233
|
-
break;
|
|
26234
|
-
|
|
26235
|
-
case "FR":
|
|
26236
|
-
this.frCount++;
|
|
26237
|
-
break;
|
|
26238
|
-
|
|
26239
|
-
case "RF":
|
|
26240
|
-
this.rfCount++;
|
|
26241
|
-
}
|
|
26242
|
-
}
|
|
26243
|
-
|
|
26244
|
-
this.totalCount++;
|
|
26245
|
-
}
|
|
26246
|
-
}
|
|
26247
|
-
|
|
26248
|
-
compute() {
|
|
26249
|
-
if (this.totalCount > 100) {
|
|
26250
|
-
if (this.ffCount / this.totalCount > 0.9) this.orienation = "ff";else if (this.frCount / this.totalCount > 0.9) this.orienation = "fr";else if (this.rfCount / this.totalCount > 0.9) this.orienation = "rf";
|
|
26251
|
-
var fMean = this.sumF / this.totalCount;
|
|
26252
|
-
var stdDev = Math.sqrt((this.totalCount * this.sumF2 - this.sumF * this.sumF) / (this.totalCount * this.totalCount));
|
|
26253
|
-
this.lowerFragmentLength = fMean - 3 * stdDev;
|
|
26254
|
-
this.upperFragmentLength = fMean + 3 * stdDev; //this.lowerFragmentLength = this.digest.percentile(this.lp);
|
|
26255
|
-
//this.upperFragmentLength = this.digest.percentile(this.up);
|
|
26256
|
-
//this.digest = undefined;
|
|
26257
|
-
}
|
|
26258
|
-
}
|
|
26259
|
-
|
|
26260
|
-
}
|
|
26261
|
-
|
|
26262
26199
|
class SupplementaryAlignment {
|
|
26263
26200
|
constructor(rec) {
|
|
26264
26201
|
const tokens = rec.split(',');
|
|
@@ -27462,7 +27399,7 @@
|
|
|
27462
27399
|
const header = this.header;
|
|
27463
27400
|
const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr;
|
|
27464
27401
|
const qAlignments = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd);
|
|
27465
|
-
const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.
|
|
27402
|
+
const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config);
|
|
27466
27403
|
|
|
27467
27404
|
for (let a of qAlignments) {
|
|
27468
27405
|
alignmentContainer.push(a);
|
|
@@ -27489,13 +27426,13 @@
|
|
|
27489
27426
|
const alignments = [];
|
|
27490
27427
|
this.header = BamUtils.decodeBamHeader(data);
|
|
27491
27428
|
BamUtils.decodeBamRecords(data, this.header.size, alignments, this.header.chrNames);
|
|
27492
|
-
this.alignmentCache = new FeatureCache(alignments, this.genome);
|
|
27429
|
+
this.alignmentCache = new FeatureCache$1(alignments, this.genome);
|
|
27493
27430
|
}
|
|
27494
27431
|
|
|
27495
27432
|
fetchAlignments(chr, bpStart, bpEnd) {
|
|
27496
27433
|
const queryChr = this.header.chrAliasTable.hasOwnProperty(chr) ? this.header.chrAliasTable[chr] : chr;
|
|
27497
27434
|
const features = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd);
|
|
27498
|
-
const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.
|
|
27435
|
+
const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config);
|
|
27499
27436
|
|
|
27500
27437
|
for (let feature of features) {
|
|
27501
27438
|
alignmentContainer.push(feature);
|
|
@@ -28495,7 +28432,7 @@
|
|
|
28495
28432
|
const chrToIndex = await this.getChrIndex();
|
|
28496
28433
|
const queryChr = this.chrAliasTable.hasOwnProperty(chr) ? this.chrAliasTable[chr] : chr;
|
|
28497
28434
|
const chrId = chrToIndex[queryChr];
|
|
28498
|
-
const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config
|
|
28435
|
+
const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config);
|
|
28499
28436
|
|
|
28500
28437
|
if (chrId === undefined) {
|
|
28501
28438
|
return alignmentContainer;
|
|
@@ -28644,7 +28581,7 @@
|
|
|
28644
28581
|
|
|
28645
28582
|
async readAlignments(chr, start, end) {
|
|
28646
28583
|
if (!this.bamReaders.hasOwnProperty(chr)) {
|
|
28647
|
-
return new AlignmentContainer(chr, start, end);
|
|
28584
|
+
return new AlignmentContainer(chr, start, end, this.config);
|
|
28648
28585
|
} else {
|
|
28649
28586
|
let reader = this.bamReaders[chr];
|
|
28650
28587
|
const a = await reader.readAlignments(chr, start, end);
|
|
@@ -28716,7 +28653,7 @@
|
|
|
28716
28653
|
return igvxhr.loadString(url, buildOptions(self.config)).then(function (sam) {
|
|
28717
28654
|
var alignmentContainer;
|
|
28718
28655
|
header.chrToIndex[queryChr];
|
|
28719
|
-
alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, self.
|
|
28656
|
+
alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, self.config);
|
|
28720
28657
|
BamUtils.decodeSamRecords(sam, alignmentContainer, queryChr, bpStart, bpEnd, self.filter);
|
|
28721
28658
|
return alignmentContainer;
|
|
28722
28659
|
});
|
|
@@ -28926,7 +28863,7 @@
|
|
|
28926
28863
|
|
|
28927
28864
|
const ba = unbgzf(compressedData.buffer);
|
|
28928
28865
|
const chrIdx = this.header.chrToIndex[chr];
|
|
28929
|
-
const alignmentContainer = new AlignmentContainer(chr, start, end, this.
|
|
28866
|
+
const alignmentContainer = new AlignmentContainer(chr, start, end, this.config);
|
|
28930
28867
|
BamUtils.decodeBamRecords(ba, this.header.size, alignmentContainer, this.header.chrNames, chrIdx, start, end);
|
|
28931
28868
|
alignmentContainer.finish();
|
|
28932
28869
|
return alignmentContainer;
|
|
@@ -44464,7 +44401,7 @@
|
|
|
44464
44401
|
const header = await this.getHeader();
|
|
44465
44402
|
const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr;
|
|
44466
44403
|
const chrIdx = header.chrToIndex[queryChr];
|
|
44467
|
-
const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.
|
|
44404
|
+
const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config);
|
|
44468
44405
|
|
|
44469
44406
|
if (chrIdx === undefined) {
|
|
44470
44407
|
return alignmentContainer;
|
|
@@ -45073,7 +45010,7 @@
|
|
|
45073
45010
|
"pageSize": "10000"
|
|
45074
45011
|
},
|
|
45075
45012
|
decode: decodeGa4ghReads,
|
|
45076
|
-
results: new AlignmentContainer(chr, bpStart, bpEnd, self.
|
|
45013
|
+
results: new AlignmentContainer(chr, bpStart, bpEnd, self.config)
|
|
45077
45014
|
});
|
|
45078
45015
|
});
|
|
45079
45016
|
|
|
@@ -45380,7 +45317,6 @@
|
|
|
45380
45317
|
const genome = browser.genome;
|
|
45381
45318
|
this.config = config;
|
|
45382
45319
|
this.genome = genome;
|
|
45383
|
-
this.alignmentContainer = undefined;
|
|
45384
45320
|
|
|
45385
45321
|
if (isDataURL(config.url)) {
|
|
45386
45322
|
if ("cram" === config.format) {
|
|
@@ -45431,58 +45367,44 @@
|
|
|
45431
45367
|
}
|
|
45432
45368
|
|
|
45433
45369
|
setViewAsPairs(bool) {
|
|
45434
|
-
|
|
45435
|
-
if (this.viewAsPairs !== bool) {
|
|
45436
|
-
this.viewAsPairs = bool; // if (this.alignmentContainer) {
|
|
45437
|
-
// this.alignmentContainer.setViewAsPairs(bool);
|
|
45438
|
-
// }
|
|
45439
|
-
}
|
|
45370
|
+
this.viewAsPairs = bool;
|
|
45440
45371
|
}
|
|
45441
45372
|
|
|
45442
45373
|
setShowSoftClips(bool) {
|
|
45443
|
-
|
|
45444
|
-
this.showSoftClips = bool;
|
|
45445
|
-
}
|
|
45374
|
+
this.showSoftClips = bool;
|
|
45446
45375
|
}
|
|
45447
45376
|
|
|
45448
45377
|
async getAlignments(chr, bpStart, bpEnd) {
|
|
45449
45378
|
const genome = this.genome;
|
|
45450
45379
|
const showSoftClips = this.showSoftClips;
|
|
45380
|
+
const alignmentContainer = await this.bamReader.readAlignments(chr, bpStart, bpEnd);
|
|
45381
|
+
let alignments = alignmentContainer.alignments;
|
|
45451
45382
|
|
|
45452
|
-
if (this.
|
|
45453
|
-
|
|
45454
|
-
|
|
45455
|
-
|
|
45456
|
-
|
|
45457
|
-
|
|
45458
|
-
if (!this.viewAsPairs) {
|
|
45459
|
-
alignments = unpairAlignments([{
|
|
45460
|
-
alignments: alignments
|
|
45461
|
-
}]);
|
|
45462
|
-
}
|
|
45463
|
-
|
|
45464
|
-
const hasAlignments = alignments.length > 0;
|
|
45465
|
-
alignmentContainer.packedAlignmentRows = packAlignmentRows(alignments, alignmentContainer.start, alignmentContainer.end, showSoftClips);
|
|
45466
|
-
alignmentContainer.alignments = undefined; // Don't need to hold onto these anymore
|
|
45383
|
+
if (!this.viewAsPairs) {
|
|
45384
|
+
alignments = unpairAlignments([{
|
|
45385
|
+
alignments: alignments
|
|
45386
|
+
}]);
|
|
45387
|
+
}
|
|
45467
45388
|
|
|
45468
|
-
|
|
45389
|
+
const hasAlignments = alignments.length > 0;
|
|
45390
|
+
alignmentContainer.packedAlignmentRows = packAlignmentRows(alignments, alignmentContainer.start, alignmentContainer.end, showSoftClips);
|
|
45391
|
+
this.alignmentContainer = alignmentContainer;
|
|
45469
45392
|
|
|
45470
|
-
|
|
45471
|
-
|
|
45393
|
+
if (hasAlignments) {
|
|
45394
|
+
const sequence = await genome.sequence.getSequence(chr, alignmentContainer.start, alignmentContainer.end);
|
|
45472
45395
|
|
|
45473
|
-
|
|
45474
|
-
|
|
45396
|
+
if (sequence) {
|
|
45397
|
+
alignmentContainer.coverageMap.refSeq = sequence; // TODO -- fix this
|
|
45475
45398
|
|
|
45476
|
-
|
|
45399
|
+
alignmentContainer.sequence = sequence; // TODO -- fix this
|
|
45477
45400
|
|
|
45478
|
-
|
|
45479
|
-
|
|
45480
|
-
|
|
45481
|
-
}
|
|
45401
|
+
return alignmentContainer;
|
|
45402
|
+
} else {
|
|
45403
|
+
console.error("No sequence for: " + chr + ":" + alignmentContainer.start + "-" + alignmentContainer.end);
|
|
45482
45404
|
}
|
|
45483
|
-
|
|
45484
|
-
return alignmentContainer;
|
|
45485
45405
|
}
|
|
45406
|
+
|
|
45407
|
+
return alignmentContainer;
|
|
45486
45408
|
}
|
|
45487
45409
|
|
|
45488
45410
|
}
|
|
@@ -45827,7 +45749,7 @@
|
|
|
45827
45749
|
clickedFeatures(clickState, features) {
|
|
45828
45750
|
// We use the cached features rather than method to avoid async load. If the
|
|
45829
45751
|
// feature is not already loaded this won't work, but the user wouldn't be mousing over it either.
|
|
45830
|
-
if (!features) features = clickState.viewport.
|
|
45752
|
+
if (!features) features = clickState.viewport.cachedFeatures;
|
|
45831
45753
|
|
|
45832
45754
|
if (!features || features.length === 0) {
|
|
45833
45755
|
return [];
|
|
@@ -48466,52 +48388,119 @@
|
|
|
48466
48388
|
return regions;
|
|
48467
48389
|
}
|
|
48468
48390
|
|
|
48391
|
+
function sendChords(chords, track, refFrame, alpha) {
|
|
48392
|
+
const chordSetColor = IGVColor.addAlpha("all" === refFrame.chr ? track.color : getChrColor(refFrame.chr), alpha);
|
|
48393
|
+
const trackColor = IGVColor.addAlpha(track.color || 'rgb(0,0,255)', alpha); // name the chord set to include locus and filtering information
|
|
48394
|
+
|
|
48395
|
+
const encodedName = track.name.replaceAll(' ', '%20');
|
|
48396
|
+
const chordSetName = "all" === refFrame.chr ? encodedName : `${encodedName} ${refFrame.chr}:${refFrame.start}-${refFrame.end}`;
|
|
48397
|
+
track.browser.circularView.addChords(chords, {
|
|
48398
|
+
track: chordSetName,
|
|
48399
|
+
color: chordSetColor,
|
|
48400
|
+
trackColor: trackColor
|
|
48401
|
+
});
|
|
48402
|
+
}
|
|
48403
|
+
|
|
48469
48404
|
function createCircularView(el, browser) {
|
|
48470
48405
|
const circularView = new CircularView(el, {
|
|
48471
48406
|
onChordClick: (feature, chordTrack, pluginManager) => {
|
|
48472
48407
|
const f1 = feature.data;
|
|
48473
48408
|
const f2 = f1.mate;
|
|
48474
|
-
|
|
48475
|
-
|
|
48476
|
-
|
|
48477
|
-
|
|
48478
|
-
|
|
48479
|
-
|
|
48480
|
-
|
|
48481
|
-
|
|
48482
|
-
|
|
48483
|
-
|
|
48484
|
-
|
|
48485
|
-
|
|
48486
|
-
|
|
48487
|
-
|
|
48488
|
-
|
|
48489
|
-
|
|
48490
|
-
|
|
48491
|
-
|
|
48492
|
-
|
|
48493
|
-
})) {
|
|
48494
|
-
// add flanking
|
|
48495
|
-
l.start = Math.max(0, l.start - flanking);
|
|
48496
|
-
l.end += flanking;
|
|
48497
|
-
loci.push(l);
|
|
48409
|
+
addFrameForFeature(f1);
|
|
48410
|
+
addFrameForFeature(f2);
|
|
48411
|
+
|
|
48412
|
+
function addFrameForFeature(feature) {
|
|
48413
|
+
feature.chr = browser.genome.getChromosomeName(feature.refName);
|
|
48414
|
+
|
|
48415
|
+
for (let referenceFrame of browser.currentReferenceFrames()) {
|
|
48416
|
+
const l = Locus.fromLocusString(referenceFrame.getLocusString());
|
|
48417
|
+
|
|
48418
|
+
if (l.contains(feature)) {
|
|
48419
|
+
break;
|
|
48420
|
+
} else if (l.overlaps(feature)) {
|
|
48421
|
+
referenceFrame.extend(feature);
|
|
48422
|
+
break;
|
|
48423
|
+
} else {
|
|
48424
|
+
const flanking = 2000;
|
|
48425
|
+
const center = (feature.start + feature.end) / 2;
|
|
48426
|
+
browser.addMultiLocusPanel(feature.chr, center - flanking, center + flanking);
|
|
48427
|
+
break;
|
|
48498
48428
|
}
|
|
48499
48429
|
}
|
|
48500
|
-
} else {
|
|
48501
|
-
l1.start = Math.max(0, l1.start - flanking);
|
|
48502
|
-
l1.end += flanking;
|
|
48503
|
-
l2.start = Math.max(0, l2.start - flanking);
|
|
48504
|
-
l2.end += flanking;
|
|
48505
|
-
loci = [l1, l2];
|
|
48506
48430
|
}
|
|
48507
|
-
|
|
48508
|
-
const searchString = loci.map(l => l.getLocusString()).join(" ");
|
|
48509
|
-
browser.search(searchString);
|
|
48510
48431
|
}
|
|
48511
48432
|
});
|
|
48512
48433
|
return circularView;
|
|
48513
48434
|
}
|
|
48514
48435
|
|
|
48436
|
+
class PairedEndStats {
|
|
48437
|
+
constructor(alignments, _ref) {
|
|
48438
|
+
let {
|
|
48439
|
+
minTLENPercentile,
|
|
48440
|
+
maxTLENPercentile
|
|
48441
|
+
} = _ref;
|
|
48442
|
+
this.totalCount = 0;
|
|
48443
|
+
this.frCount = 0;
|
|
48444
|
+
this.rfCount = 0;
|
|
48445
|
+
this.ffCount = 0;
|
|
48446
|
+
this.sumF = 0;
|
|
48447
|
+
this.sumF2 = 0;
|
|
48448
|
+
this.lp = minTLENPercentile === undefined ? 0.1 : minTLENPercentile;
|
|
48449
|
+
this.up = maxTLENPercentile === undefined ? 99.5 : maxTLENPercentile;
|
|
48450
|
+
this.isizes = [];
|
|
48451
|
+
this.compute(alignments);
|
|
48452
|
+
}
|
|
48453
|
+
|
|
48454
|
+
compute(alignments) {
|
|
48455
|
+
for (let alignment of alignments) {
|
|
48456
|
+
if (alignment.isProperPair()) {
|
|
48457
|
+
var tlen = Math.abs(alignment.fragmentLength);
|
|
48458
|
+
this.sumF += tlen;
|
|
48459
|
+
this.sumF2 += tlen * tlen;
|
|
48460
|
+
this.isizes.push(tlen);
|
|
48461
|
+
var po = alignment.pairOrientation;
|
|
48462
|
+
|
|
48463
|
+
if (typeof po === "string" && po.length === 4) {
|
|
48464
|
+
var tmp = '' + po.charAt(0) + po.charAt(2);
|
|
48465
|
+
|
|
48466
|
+
switch (tmp) {
|
|
48467
|
+
case 'FF':
|
|
48468
|
+
case 'RR':
|
|
48469
|
+
this.ffCount++;
|
|
48470
|
+
break;
|
|
48471
|
+
|
|
48472
|
+
case "FR":
|
|
48473
|
+
this.frCount++;
|
|
48474
|
+
break;
|
|
48475
|
+
|
|
48476
|
+
case "RF":
|
|
48477
|
+
this.rfCount++;
|
|
48478
|
+
}
|
|
48479
|
+
}
|
|
48480
|
+
|
|
48481
|
+
this.totalCount++;
|
|
48482
|
+
}
|
|
48483
|
+
}
|
|
48484
|
+
|
|
48485
|
+
if (this.ffCount / this.totalCount > 0.9) this.orienation = "ff";else if (this.frCount / this.totalCount > 0.9) this.orienation = "fr";else if (this.rfCount / this.totalCount > 0.9) this.orienation = "rf";
|
|
48486
|
+
this.minTLEN = this.lp === 0 ? 0 : percentile(this.isizes, this.lp);
|
|
48487
|
+
this.maxTLEN = percentile(this.isizes, this.up); // var fMean = this.sumF / this.totalCount
|
|
48488
|
+
// var stdDev = Math.sqrt((this.totalCount * this.sumF2 - this.sumF * this.sumF) / (this.totalCount * this.totalCount))
|
|
48489
|
+
// this.minTLEN = fMean - 3 * stdDev
|
|
48490
|
+
// this.maxTLEN = fMean + 3 * stdDev
|
|
48491
|
+
}
|
|
48492
|
+
|
|
48493
|
+
}
|
|
48494
|
+
|
|
48495
|
+
function percentile(array, p) {
|
|
48496
|
+
if (array.length === 0) return undefined;
|
|
48497
|
+
var k = Math.floor(array.length * (p / 100));
|
|
48498
|
+
array.sort(function (a, b) {
|
|
48499
|
+
return a - b;
|
|
48500
|
+
});
|
|
48501
|
+
return array[k];
|
|
48502
|
+
}
|
|
48503
|
+
|
|
48515
48504
|
/*
|
|
48516
48505
|
* The MIT License (MIT)
|
|
48517
48506
|
*
|
|
@@ -48571,10 +48560,7 @@
|
|
|
48571
48560
|
this.showInsertions = false !== config.showInsertions;
|
|
48572
48561
|
this.showMismatches = false !== config.showMismatches;
|
|
48573
48562
|
this.color = config.color;
|
|
48574
|
-
this.coverageColor = config.coverageColor;
|
|
48575
|
-
this.minFragmentLength = config.minFragmentLength; // Optional, might be undefined
|
|
48576
|
-
|
|
48577
|
-
this.maxFragmentLength = config.maxFragmentLength || 1000; // The sort object can be an array in the case of multi-locus view, however if multiple sort positions
|
|
48563
|
+
this.coverageColor = config.coverageColor; // The sort object can be an array in the case of multi-locus view, however if multiple sort positions
|
|
48578
48564
|
// are present for a given reference frame the last one will take precedence
|
|
48579
48565
|
|
|
48580
48566
|
if (config.sort) {
|
|
@@ -48602,12 +48588,22 @@
|
|
|
48602
48588
|
return this._height;
|
|
48603
48589
|
}
|
|
48604
48590
|
|
|
48591
|
+
get minTemplateLength() {
|
|
48592
|
+
const configMinTLEN = this.config.minTLEN !== undefined ? this.config.minTLEN : this.config.minFragmentLength;
|
|
48593
|
+
return configMinTLEN !== undefined ? configMinTLEN : this._pairedEndStats ? this._pairedEndStats.minTLEN : 0;
|
|
48594
|
+
}
|
|
48595
|
+
|
|
48596
|
+
get maxTemplateLength() {
|
|
48597
|
+
const configMaxTLEN = this.config.maxTLEN !== undefined ? this.config.maxTLEN : this.config.maxFragmentLength;
|
|
48598
|
+
return configMaxTLEN !== undefined ? configMaxTLEN : this._pairedEndStats ? this._pairedEndStats.maxTLEN : 1000;
|
|
48599
|
+
}
|
|
48600
|
+
|
|
48605
48601
|
sort(options) {
|
|
48606
48602
|
options = this.assignSort(options);
|
|
48607
48603
|
|
|
48608
48604
|
for (let vp of this.trackView.viewports) {
|
|
48609
48605
|
if (vp.containsPosition(options.chr, options.position)) {
|
|
48610
|
-
const alignmentContainer = vp.
|
|
48606
|
+
const alignmentContainer = vp.cachedFeatures;
|
|
48611
48607
|
|
|
48612
48608
|
if (alignmentContainer) {
|
|
48613
48609
|
sortAlignmentRows(options, alignmentContainer);
|
|
@@ -48642,16 +48638,16 @@
|
|
|
48642
48638
|
async getFeatures(chr, bpStart, bpEnd, bpPerPixel, viewport) {
|
|
48643
48639
|
const alignmentContainer = await this.featureSource.getAlignments(chr, bpStart, bpEnd);
|
|
48644
48640
|
|
|
48645
|
-
if (alignmentContainer.
|
|
48646
|
-
|
|
48647
|
-
this.minFragmentLength = alignmentContainer.pairedEndStats.lowerFragmentLength;
|
|
48648
|
-
}
|
|
48641
|
+
if (alignmentContainer.paired && !this._pairedEndStats && !this.config.maxFragmentLength) {
|
|
48642
|
+
const pairedEndStats = new PairedEndStats(alignmentContainer.alignments, this.config);
|
|
48649
48643
|
|
|
48650
|
-
if (
|
|
48651
|
-
this.
|
|
48644
|
+
if (pairedEndStats.totalCount > 99) {
|
|
48645
|
+
this._pairedEndStats = pairedEndStats;
|
|
48652
48646
|
}
|
|
48653
48647
|
}
|
|
48654
48648
|
|
|
48649
|
+
alignmentContainer.alignments = undefined; // Don't need to hold onto these anymore
|
|
48650
|
+
|
|
48655
48651
|
const sort = this.sortObject;
|
|
48656
48652
|
|
|
48657
48653
|
if (sort) {
|
|
@@ -48756,7 +48752,7 @@
|
|
|
48756
48752
|
label: 'pair orientation'
|
|
48757
48753
|
});
|
|
48758
48754
|
colorByMenuItems.push({
|
|
48759
|
-
key: '
|
|
48755
|
+
key: 'tlen',
|
|
48760
48756
|
label: 'insert size (TLEN)'
|
|
48761
48757
|
});
|
|
48762
48758
|
colorByMenuItems.push({
|
|
@@ -48867,7 +48863,7 @@
|
|
|
48867
48863
|
this.trackView.repaintViews();
|
|
48868
48864
|
}
|
|
48869
48865
|
});
|
|
48870
|
-
} //
|
|
48866
|
+
} // Add chords to JBrowse circular view, if present
|
|
48871
48867
|
|
|
48872
48868
|
|
|
48873
48869
|
if (this.browser.circularView && true === this.browser.circularViewVisible && (this.alignmentTrack.hasPairs || this.alignmentTrack.hasSupplemental)) {
|
|
@@ -48877,26 +48873,9 @@
|
|
|
48877
48873
|
menuItems.push({
|
|
48878
48874
|
label: 'Add discordant pairs to circular view',
|
|
48879
48875
|
click: () => {
|
|
48880
|
-
const maxFragmentLength = this.maxFragmentLength;
|
|
48881
|
-
const inView = [];
|
|
48882
|
-
|
|
48883
48876
|
for (let viewport of this.trackView.viewports) {
|
|
48884
|
-
|
|
48885
|
-
const referenceFrame = viewport.referenceFrame;
|
|
48886
|
-
|
|
48887
|
-
if (a.end >= referenceFrame.start && a.start <= referenceFrame.end && a.mate && a.mate.chr && (a.mate.chr !== a.chr || Math.max(a.fragmentLength) > maxFragmentLength)) {
|
|
48888
|
-
inView.push(a);
|
|
48889
|
-
}
|
|
48890
|
-
}
|
|
48877
|
+
this.addPairedChordsForViewport(viewport);
|
|
48891
48878
|
}
|
|
48892
|
-
|
|
48893
|
-
this.browser.circularViewVisible = true;
|
|
48894
|
-
const chords = makePairedAlignmentChords(inView);
|
|
48895
|
-
const color = IGVColor.addAlpha(this.color || 'rgb(0,0,255)', 0.02);
|
|
48896
|
-
this.browser.circularView.addChords(chords, {
|
|
48897
|
-
track: this.name,
|
|
48898
|
-
color: color
|
|
48899
|
-
});
|
|
48900
48879
|
}
|
|
48901
48880
|
});
|
|
48902
48881
|
}
|
|
@@ -48905,25 +48884,9 @@
|
|
|
48905
48884
|
menuItems.push({
|
|
48906
48885
|
label: 'Add split reads to circular view',
|
|
48907
48886
|
click: () => {
|
|
48908
|
-
const inView = [];
|
|
48909
|
-
|
|
48910
48887
|
for (let viewport of this.trackView.viewports) {
|
|
48911
|
-
|
|
48912
|
-
const referenceFrame = viewport.referenceFrame;
|
|
48913
|
-
const sa = a.hasTag('SA');
|
|
48914
|
-
|
|
48915
|
-
if (a.end >= referenceFrame.start && a.start <= referenceFrame.end && sa) {
|
|
48916
|
-
inView.push(a);
|
|
48917
|
-
}
|
|
48918
|
-
}
|
|
48888
|
+
this.addSplitChordsForViewport(viewport);
|
|
48919
48889
|
}
|
|
48920
|
-
|
|
48921
|
-
const chords = makeSupplementalAlignmentChords(inView);
|
|
48922
|
-
const color = IGVColor.addAlpha(this.color || 'rgb(0,0,255)', 0.1);
|
|
48923
|
-
this.browser.circularView.addChords(chords, {
|
|
48924
|
-
track: this.name,
|
|
48925
|
-
color: color
|
|
48926
|
-
});
|
|
48927
48890
|
}
|
|
48928
48891
|
});
|
|
48929
48892
|
}
|
|
@@ -49042,7 +49005,7 @@
|
|
|
49042
49005
|
}
|
|
49043
49006
|
|
|
49044
49007
|
getCachedAlignmentContainers() {
|
|
49045
|
-
return this.trackView.viewports.map(vp => vp.
|
|
49008
|
+
return this.trackView.viewports.map(vp => vp.cachedFeatures);
|
|
49046
49009
|
}
|
|
49047
49010
|
|
|
49048
49011
|
get dataRange() {
|
|
@@ -49068,6 +49031,56 @@
|
|
|
49068
49031
|
set autoscale(autoscale) {
|
|
49069
49032
|
this.coverageTrack.autoscale = autoscale;
|
|
49070
49033
|
}
|
|
49034
|
+
/**
|
|
49035
|
+
* Add chords to the circular view for the given viewport, represented by its reference frame
|
|
49036
|
+
* @param refFrame
|
|
49037
|
+
*/
|
|
49038
|
+
|
|
49039
|
+
|
|
49040
|
+
addPairedChordsForViewport(viewport) {
|
|
49041
|
+
const maxTemplateLength = this.maxTemplateLength;
|
|
49042
|
+
const inView = [];
|
|
49043
|
+
const refFrame = viewport.referenceFrame;
|
|
49044
|
+
|
|
49045
|
+
for (let a of viewport.cachedFeatures.allAlignments()) {
|
|
49046
|
+
if (a.end >= refFrame.start && a.start <= refFrame.end && a.mate && a.mate.chr && (a.mate.chr !== a.chr || Math.max(a.fragmentLength) > maxTemplateLength)) {
|
|
49047
|
+
inView.push(a);
|
|
49048
|
+
}
|
|
49049
|
+
}
|
|
49050
|
+
|
|
49051
|
+
const chords = makePairedAlignmentChords(inView);
|
|
49052
|
+
sendChords(chords, this, refFrame, 0.02); // const chordSetColor = IGVColor.addAlpha("all" === refFrame.chr ? this.color : getChrColor(refFrame.chr), 0.02)
|
|
49053
|
+
// const trackColor = IGVColor.addAlpha(this.color || 'rgb(0,0,255)', 0.02)
|
|
49054
|
+
//
|
|
49055
|
+
// // name the chord set to include track name and locus
|
|
49056
|
+
// const encodedName = this.name.replaceAll(' ', '%20')
|
|
49057
|
+
// const chordSetName = "all" === refFrame.chr ? encodedName :
|
|
49058
|
+
// `${encodedName} (${refFrame.chr}:${refFrame.start}-${refFrame.end}`
|
|
49059
|
+
// this.browser.circularView.addChords(chords, {name: chordSetName, color: chordSetColor, trackColor: trackColor})
|
|
49060
|
+
}
|
|
49061
|
+
|
|
49062
|
+
addSplitChordsForViewport(viewport) {
|
|
49063
|
+
const inView = [];
|
|
49064
|
+
const refFrame = viewport.referenceFrame;
|
|
49065
|
+
|
|
49066
|
+
for (let a of viewport.cachedFeatures.allAlignments()) {
|
|
49067
|
+
const sa = a.hasTag('SA');
|
|
49068
|
+
|
|
49069
|
+
if (a.end >= refFrame.start && a.start <= refFrame.end && sa) {
|
|
49070
|
+
inView.push(a);
|
|
49071
|
+
}
|
|
49072
|
+
}
|
|
49073
|
+
|
|
49074
|
+
const chords = makeSupplementalAlignmentChords(inView);
|
|
49075
|
+
sendChords(chords, this, refFrame, 0.02); // const chordSetColor = IGVColor.addAlpha("all" === refFrame.chr ? this.color : getChrColor(refFrame.chr), 0.02)
|
|
49076
|
+
// const trackColor = IGVColor.addAlpha(this.color || 'rgb(0,0,255)', 0.02)
|
|
49077
|
+
//
|
|
49078
|
+
// // name the chord set to include track name and locus
|
|
49079
|
+
// const encodedName = this.name.replaceAll(' ', '%20')
|
|
49080
|
+
// const chordSetName = "all" === refFrame.chr ? encodedName :
|
|
49081
|
+
// `${encodedName} (${refFrame.chr}:${refFrame.start}-${refFrame.end}`
|
|
49082
|
+
// this.browser.circularView.addChords(chords, {name: chordSetName, color: chordSetColor, trackColor: trackColor})
|
|
49083
|
+
}
|
|
49071
49084
|
|
|
49072
49085
|
}
|
|
49073
49086
|
|
|
@@ -49178,7 +49191,7 @@
|
|
|
49178
49191
|
}
|
|
49179
49192
|
|
|
49180
49193
|
getClickedObject(clickState) {
|
|
49181
|
-
let features = clickState.viewport.
|
|
49194
|
+
let features = clickState.viewport.cachedFeatures;
|
|
49182
49195
|
if (!features || features.length === 0) return;
|
|
49183
49196
|
const genomicLocation = Math.floor(clickState.genomicLocation);
|
|
49184
49197
|
const coverageMap = features.coverageMap;
|
|
@@ -49264,14 +49277,14 @@
|
|
|
49264
49277
|
this.deletionColor = config.deletionColor || "black";
|
|
49265
49278
|
this.skippedColor = config.skippedColor || "rgb(150, 170, 170)";
|
|
49266
49279
|
this.pairConnectorColor = config.pairConnectorColor;
|
|
49267
|
-
this.
|
|
49268
|
-
this.
|
|
49280
|
+
this.smallTLENColor = config.smallTLENColor || config.smallFragmentLengthColor || "rgb(0, 0, 150)";
|
|
49281
|
+
this.largeTLENColor = config.largeTLENColor || config.largeFragmentLengthColor || "rgb(200, 0, 0)";
|
|
49269
49282
|
this.pairOrientation = config.pairOrienation || 'fr';
|
|
49270
49283
|
this.pairColors = {};
|
|
49271
49284
|
this.pairColors["RL"] = config.rlColor || "rgb(0, 150, 0)";
|
|
49272
49285
|
this.pairColors["RR"] = config.rrColor || "rgb(20, 50, 200)";
|
|
49273
49286
|
this.pairColors["LL"] = config.llColor || "rgb(0, 150, 150)";
|
|
49274
|
-
this.colorBy = config.colorBy || "
|
|
49287
|
+
this.colorBy = config.colorBy || "unexpectedPair";
|
|
49275
49288
|
this.colorByTag = config.colorByTag ? config.colorByTag.toUpperCase() : undefined;
|
|
49276
49289
|
this.bamColorTag = config.bamColorTag === undefined ? "YC" : config.bamColorTag;
|
|
49277
49290
|
this.hideSmallIndels = config.hideSmallIndels;
|
|
@@ -49626,7 +49639,7 @@
|
|
|
49626
49639
|
direction: direction
|
|
49627
49640
|
};
|
|
49628
49641
|
this.parent.sortObject = newSortObject;
|
|
49629
|
-
sortAlignmentRows(newSortObject, viewport.
|
|
49642
|
+
sortAlignmentRows(newSortObject, viewport.cachedFeatures);
|
|
49630
49643
|
viewport.repaint();
|
|
49631
49644
|
};
|
|
49632
49645
|
|
|
@@ -49678,7 +49691,7 @@
|
|
|
49678
49691
|
};
|
|
49679
49692
|
this.sortByTag = tag;
|
|
49680
49693
|
this.parent.sortObject = newSortObject;
|
|
49681
|
-
sortAlignmentRows(newSortObject, viewport.
|
|
49694
|
+
sortAlignmentRows(newSortObject, viewport.cachedFeatures);
|
|
49682
49695
|
viewport.repaint();
|
|
49683
49696
|
}
|
|
49684
49697
|
}
|
|
@@ -49702,8 +49715,12 @@
|
|
|
49702
49715
|
const referenceFrame = clickState.viewport.referenceFrame;
|
|
49703
49716
|
|
|
49704
49717
|
if (this.browser.genome.getChromosome(clickedAlignment.mate.chr)) {
|
|
49705
|
-
this.highlightedAlignmentReadNamed = clickedAlignment.readName;
|
|
49706
|
-
|
|
49718
|
+
this.highlightedAlignmentReadNamed = clickedAlignment.readName; //this.browser.presentMultiLocusPanel(clickedAlignment, referenceFrame)
|
|
49719
|
+
|
|
49720
|
+
const bpWidth = referenceFrame.end - referenceFrame.start;
|
|
49721
|
+
const frameStart = clickedAlignment.mate.position - bpWidth / 2;
|
|
49722
|
+
const frameEnd = clickedAlignment.mate.position + bpWidth / 2;
|
|
49723
|
+
this.browser.addMultiLocusPanel(clickedAlignment.mate.chr, frameStart, frameEnd, referenceFrame);
|
|
49707
49724
|
} else {
|
|
49708
49725
|
Alert.presentAlert(`Reference does not contain chromosome: ${clickedAlignment.mate.chr}`);
|
|
49709
49726
|
}
|
|
@@ -49751,20 +49768,7 @@
|
|
|
49751
49768
|
list.push({
|
|
49752
49769
|
label: 'Add discordant pairs to circular view',
|
|
49753
49770
|
click: () => {
|
|
49754
|
-
|
|
49755
|
-
const {
|
|
49756
|
-
referenceFrame
|
|
49757
|
-
} = viewport;
|
|
49758
|
-
const inView = viewport.getCachedFeatures().allAlignments().filter(a => {
|
|
49759
|
-
return a.end >= referenceFrame.start && a.start <= referenceFrame.end && a.mate && a.mate.chr && (a.mate.chr !== a.chr || Math.max(a.fragmentLength) > maxFragmentLength);
|
|
49760
|
-
});
|
|
49761
|
-
this.browser.circularViewVisible = true;
|
|
49762
|
-
const chords = makePairedAlignmentChords(inView);
|
|
49763
|
-
const color = IGVColor.addAlpha(this.parent.color || 'rgb(0,0,255)', 0.02);
|
|
49764
|
-
this.browser.circularView.addChords(chords, {
|
|
49765
|
-
track: this.parent.name,
|
|
49766
|
-
color: color
|
|
49767
|
-
});
|
|
49771
|
+
this.parent.addPairedChordsForViewport(viewport);
|
|
49768
49772
|
}
|
|
49769
49773
|
});
|
|
49770
49774
|
}
|
|
@@ -49773,23 +49777,7 @@
|
|
|
49773
49777
|
list.push({
|
|
49774
49778
|
label: 'Add split reads to circular view',
|
|
49775
49779
|
click: () => {
|
|
49776
|
-
|
|
49777
|
-
|
|
49778
|
-
for (let a of viewport.getCachedFeatures().allAlignments()) {
|
|
49779
|
-
const referenceFrame = viewport.referenceFrame;
|
|
49780
|
-
const sa = a.hasTag('SA');
|
|
49781
|
-
|
|
49782
|
-
if (a.end >= referenceFrame.start && a.start <= referenceFrame.end && sa) {
|
|
49783
|
-
inView.push(a);
|
|
49784
|
-
}
|
|
49785
|
-
}
|
|
49786
|
-
|
|
49787
|
-
const chords = makeSupplementalAlignmentChords(inView);
|
|
49788
|
-
const color = IGVColor.addAlpha(this.color || 'rgb(0,0,255)', 0.1);
|
|
49789
|
-
this.browser.circularView.addChords(chords, {
|
|
49790
|
-
track: this.name,
|
|
49791
|
-
color: color
|
|
49792
|
-
});
|
|
49780
|
+
this.parent.addSplitChordsForViewport(viewport);
|
|
49793
49781
|
}
|
|
49794
49782
|
});
|
|
49795
49783
|
}
|
|
@@ -49805,7 +49793,7 @@
|
|
|
49805
49793
|
const y = clickState.y;
|
|
49806
49794
|
const genomicLocation = clickState.genomicLocation;
|
|
49807
49795
|
const showSoftClips = this.parent.showSoftClips;
|
|
49808
|
-
let features = viewport.
|
|
49796
|
+
let features = viewport.cachedFeatures;
|
|
49809
49797
|
if (!features || features.length === 0) return;
|
|
49810
49798
|
let packedAlignmentRows = features.packedAlignmentRows;
|
|
49811
49799
|
let downsampledIntervals = features.downsampledIntervals;
|
|
@@ -49891,13 +49879,16 @@
|
|
|
49891
49879
|
break;
|
|
49892
49880
|
}
|
|
49893
49881
|
|
|
49882
|
+
case "tlen":
|
|
49894
49883
|
case "fragmentLength":
|
|
49895
|
-
if (alignment.mate && alignment.isMateMapped()
|
|
49896
|
-
|
|
49897
|
-
|
|
49898
|
-
|
|
49899
|
-
|
|
49900
|
-
|
|
49884
|
+
if (alignment.mate && alignment.isMateMapped()) {
|
|
49885
|
+
if (alignment.mate.chr !== alignment.chr) {
|
|
49886
|
+
color = getChrColor(alignment.mate.chr);
|
|
49887
|
+
} else if (this.parent.minTemplateLength && Math.abs(alignment.fragmentLength) < this.parent.minTemplateLength) {
|
|
49888
|
+
color = this.smallTLENColor;
|
|
49889
|
+
} else if (this.parent.maxTemplateLength && Math.abs(alignment.fragmentLength) > this.parent.maxTemplateLength) {
|
|
49890
|
+
color = this.largeTLENColor;
|
|
49891
|
+
}
|
|
49901
49892
|
}
|
|
49902
49893
|
|
|
49903
49894
|
break;
|
|
@@ -49939,10 +49930,7 @@
|
|
|
49939
49930
|
alignmentContainer.packedAlignmentRows.sort(function (rowA, rowB) {
|
|
49940
49931
|
const i = rowA.score > rowB.score ? 1 : rowA.score < rowB.score ? -1 : 0;
|
|
49941
49932
|
return true === direction ? i : -i;
|
|
49942
|
-
});
|
|
49943
|
-
// for(let r of alignmentContainer.packedAlignmentRows) {
|
|
49944
|
-
// console.log(r.score);
|
|
49945
|
-
// }
|
|
49933
|
+
});
|
|
49946
49934
|
}
|
|
49947
49935
|
|
|
49948
49936
|
function shadedBaseColor(qual, baseColor) {
|
|
@@ -50097,7 +50085,7 @@
|
|
|
50097
50085
|
});
|
|
50098
50086
|
this.$viewport.append(this.$rulerLabel);
|
|
50099
50087
|
this.$rulerLabel.click(async () => {
|
|
50100
|
-
await this.browser.
|
|
50088
|
+
await this.browser.gotoMultilocusPanel(this.referenceFrame); // const removals = this.browser.referenceFrameList.filter(r => this.referenceFrame !== r)
|
|
50101
50089
|
// for (let referenceFrame of removals) {
|
|
50102
50090
|
// await this.browser.removeMultiLocusPanel(referenceFrame)
|
|
50103
50091
|
// }
|
|
@@ -50412,7 +50400,7 @@
|
|
|
50412
50400
|
referenceFrame.start = ss;
|
|
50413
50401
|
referenceFrame.end = ee;
|
|
50414
50402
|
referenceFrame.bpPerPixel = (ee - ss) / width;
|
|
50415
|
-
this.browser.updateViews(
|
|
50403
|
+
this.browser.updateViews(true);
|
|
50416
50404
|
}
|
|
50417
50405
|
|
|
50418
50406
|
this.boundClickHandler = clickHandler.bind(this);
|
|
@@ -51289,7 +51277,9 @@
|
|
|
51289
51277
|
|
|
51290
51278
|
repaintViews() {
|
|
51291
51279
|
for (let viewport of this.viewports) {
|
|
51292
|
-
viewport.
|
|
51280
|
+
if (viewport.isVisible()) {
|
|
51281
|
+
viewport.repaint();
|
|
51282
|
+
}
|
|
51293
51283
|
}
|
|
51294
51284
|
|
|
51295
51285
|
if (typeof this.track.paintAxis === 'function') {
|
|
@@ -51313,6 +51303,9 @@
|
|
|
51313
51303
|
}
|
|
51314
51304
|
/**
|
|
51315
51305
|
* Update viewports to reflect current genomic state, possibly loading additional data.
|
|
51306
|
+
*
|
|
51307
|
+
* @param force - if true, force a repaint even if no new data is loaded
|
|
51308
|
+
* @returns {Promise<void>}
|
|
51316
51309
|
*/
|
|
51317
51310
|
|
|
51318
51311
|
|
|
@@ -51328,7 +51321,7 @@
|
|
|
51328
51321
|
} // rpv: viewports whose image (canvas) does not fully cover current genomic range
|
|
51329
51322
|
|
|
51330
51323
|
|
|
51331
|
-
const reloadableViewports = this.viewportsToReload(
|
|
51324
|
+
const reloadableViewports = force ? visibleViewports : this.viewportsToReload(); // Trigger viewport to load features needed to cover current genomic range
|
|
51332
51325
|
// NOTE: these must be loaded synchronously, do not user Promise.all, not all file readers are thread safe
|
|
51333
51326
|
|
|
51334
51327
|
for (let viewport of reloadableViewports) {
|
|
@@ -51336,7 +51329,7 @@
|
|
|
51336
51329
|
}
|
|
51337
51330
|
|
|
51338
51331
|
if (this.disposed) return; // Track was removed during load
|
|
51339
|
-
//
|
|
51332
|
+
// Special case for variant tracks in multilocus view. The # of rows to allocate to the variant (site)
|
|
51340
51333
|
// section depends on data from all the views. We only need to adjust this however if any data was loaded
|
|
51341
51334
|
// (i.e. reloadableViewports.length > 0)
|
|
51342
51335
|
|
|
@@ -51344,8 +51337,8 @@
|
|
|
51344
51337
|
let maxRow = 0;
|
|
51345
51338
|
|
|
51346
51339
|
for (let viewport of this.viewports) {
|
|
51347
|
-
if (viewport.
|
|
51348
|
-
maxRow = Math.max(maxRow, viewport.
|
|
51340
|
+
if (viewport.featureCache && viewport.featureCache.features) {
|
|
51341
|
+
maxRow = Math.max(maxRow, viewport.featureCache.features.reduce((a, f) => Math.max(a, f.row || 0), 0));
|
|
51349
51342
|
}
|
|
51350
51343
|
}
|
|
51351
51344
|
|
|
@@ -51368,14 +51361,14 @@
|
|
|
51368
51361
|
const start = referenceFrame.start;
|
|
51369
51362
|
const end = start + referenceFrame.toBP($$1(visibleViewport.contentDiv).width());
|
|
51370
51363
|
|
|
51371
|
-
if (visibleViewport.
|
|
51372
|
-
if (typeof visibleViewport.
|
|
51373
|
-
const max = visibleViewport.
|
|
51364
|
+
if (visibleViewport.featureCache && visibleViewport.featureCache.features) {
|
|
51365
|
+
if (typeof visibleViewport.featureCache.features.getMax === 'function') {
|
|
51366
|
+
const max = visibleViewport.featureCache.features.getMax(start, end);
|
|
51374
51367
|
allFeatures.push({
|
|
51375
51368
|
value: max
|
|
51376
51369
|
});
|
|
51377
51370
|
} else {
|
|
51378
|
-
allFeatures = allFeatures.concat(FeatureUtils.findOverlapping(visibleViewport.
|
|
51371
|
+
allFeatures = allFeatures.concat(FeatureUtils.findOverlapping(visibleViewport.featureCache.features, start, end));
|
|
51379
51372
|
}
|
|
51380
51373
|
}
|
|
51381
51374
|
}
|
|
@@ -51385,16 +51378,22 @@
|
|
|
51385
51378
|
} else {
|
|
51386
51379
|
this.track.dataRange = doAutoscale(allFeatures);
|
|
51387
51380
|
}
|
|
51388
|
-
} // Must repaint all viewports if autoscaling
|
|
51381
|
+
} // Must repaint all viewports if autoscaling. Always repaint ruler.
|
|
51389
51382
|
|
|
51390
51383
|
|
|
51391
|
-
if (
|
|
51392
|
-
for (let
|
|
51393
|
-
|
|
51384
|
+
if (this.track.autoscale || this.track.autoscaleGroup || this.track.type === 'ruler' || force) {
|
|
51385
|
+
for (let vp of visibleViewports) {
|
|
51386
|
+
vp.repaint();
|
|
51394
51387
|
}
|
|
51395
51388
|
} else {
|
|
51396
|
-
|
|
51397
|
-
|
|
51389
|
+
const reloadedViewports = new Set(reloadableViewports);
|
|
51390
|
+
|
|
51391
|
+
for (let vp of visibleViewports) {
|
|
51392
|
+
const invalid = vp.canvas && vp.canvas._data && vp.canvas._data.invalidate;
|
|
51393
|
+
|
|
51394
|
+
if (invalid || reloadedViewports.has(vp)) {
|
|
51395
|
+
vp.repaint();
|
|
51396
|
+
}
|
|
51398
51397
|
}
|
|
51399
51398
|
}
|
|
51400
51399
|
|
|
@@ -51422,13 +51421,13 @@
|
|
|
51422
51421
|
*/
|
|
51423
51422
|
|
|
51424
51423
|
|
|
51425
|
-
async getInViewFeatures(
|
|
51424
|
+
async getInViewFeatures() {
|
|
51426
51425
|
if (!(this.browser && this.browser.referenceFrameList)) {
|
|
51427
51426
|
return [];
|
|
51428
51427
|
} // List of viewports that need reloading
|
|
51429
51428
|
|
|
51430
51429
|
|
|
51431
|
-
const rpV = this.viewportsToReload(
|
|
51430
|
+
const rpV = this.viewportsToReload();
|
|
51432
51431
|
const promises = rpV.map(function (vp) {
|
|
51433
51432
|
return vp.loadFeatures();
|
|
51434
51433
|
});
|
|
@@ -51436,18 +51435,18 @@
|
|
|
51436
51435
|
let allFeatures = [];
|
|
51437
51436
|
|
|
51438
51437
|
for (let vp of this.viewports) {
|
|
51439
|
-
if (vp.
|
|
51438
|
+
if (vp.featureCache && vp.featureCache.features) {
|
|
51440
51439
|
const referenceFrame = vp.referenceFrame;
|
|
51441
51440
|
const start = referenceFrame.start;
|
|
51442
51441
|
const end = start + referenceFrame.toBP($$1(vp.contentDiv).width());
|
|
51443
51442
|
|
|
51444
|
-
if (typeof vp.
|
|
51445
|
-
const max = vp.
|
|
51443
|
+
if (typeof vp.featureCache.features.getMax === 'function') {
|
|
51444
|
+
const max = vp.featureCache.features.getMax(start, end);
|
|
51446
51445
|
allFeatures.push({
|
|
51447
51446
|
value: max
|
|
51448
51447
|
});
|
|
51449
51448
|
} else {
|
|
51450
|
-
allFeatures = allFeatures.concat(FeatureUtils.findOverlapping(vp.
|
|
51449
|
+
allFeatures = allFeatures.concat(FeatureUtils.findOverlapping(vp.featureCache.features, start, end));
|
|
51451
51450
|
}
|
|
51452
51451
|
}
|
|
51453
51452
|
}
|
|
@@ -51504,7 +51503,7 @@
|
|
|
51504
51503
|
const start = referenceFrame.start;
|
|
51505
51504
|
const end = start + referenceFrame.toBP($$1(viewport.contentDiv).width());
|
|
51506
51505
|
const bpPerPixel = referenceFrame.bpPerPixel;
|
|
51507
|
-
return
|
|
51506
|
+
return !viewport.featureCache || !viewport.featureCache.containsRange(chr, start, end, bpPerPixel);
|
|
51508
51507
|
}
|
|
51509
51508
|
});
|
|
51510
51509
|
return viewports;
|
|
@@ -56314,7 +56313,7 @@
|
|
|
56314
56313
|
this.genome = genome;
|
|
56315
56314
|
this.sourceType = config.sourceType === undefined ? "file" : config.sourceType;
|
|
56316
56315
|
this.maxWGCount = config.maxWGCount || DEFAULT_MAX_WG_COUNT;
|
|
56317
|
-
const queryableFormats = new Set(["bigwig", "bw", "bigbed", "bb", "tdf"]);
|
|
56316
|
+
const queryableFormats = new Set(["bigwig", "bw", "bigbed", "bb", "biginteract", "tdf"]);
|
|
56318
56317
|
|
|
56319
56318
|
if (config.features && Array.isArray(config.features)) {
|
|
56320
56319
|
// Explicit array of features
|
|
@@ -56326,7 +56325,7 @@
|
|
|
56326
56325
|
}
|
|
56327
56326
|
|
|
56328
56327
|
this.queryable = false;
|
|
56329
|
-
this.featureCache = new FeatureCache(features, genome);
|
|
56328
|
+
this.featureCache = new FeatureCache$1(features, genome);
|
|
56330
56329
|
} else if (config.reader) {
|
|
56331
56330
|
// Explicit reader implementation
|
|
56332
56331
|
this.reader = config.reader;
|
|
@@ -56497,13 +56496,13 @@
|
|
|
56497
56496
|
} // Note - replacing previous cache with new one. genomicInterval is optional (might be undefined => includes all features)
|
|
56498
56497
|
|
|
56499
56498
|
|
|
56500
|
-
this.featureCache = new FeatureCache(features, this.genome, genomicInterval); // If track is marked "searchable"< cache features by name -- use this with caution, memory intensive
|
|
56499
|
+
this.featureCache = new FeatureCache$1(features, this.genome, genomicInterval); // If track is marked "searchable"< cache features by name -- use this with caution, memory intensive
|
|
56501
56500
|
|
|
56502
56501
|
if (this.config.searchable || this.config.searchableFields) {
|
|
56503
56502
|
this.addFeaturesToDB(features);
|
|
56504
56503
|
}
|
|
56505
56504
|
} else {
|
|
56506
|
-
this.featureCache = new FeatureCache([], genomicInterval); // Empty cache
|
|
56505
|
+
this.featureCache = new FeatureCache$1([], genomicInterval); // Empty cache
|
|
56507
56506
|
}
|
|
56508
56507
|
}
|
|
56509
56508
|
|
|
@@ -56727,8 +56726,8 @@
|
|
|
56727
56726
|
|
|
56728
56727
|
//table chromatinInteract
|
|
56729
56728
|
|
|
56730
|
-
function getDecoder(definedFieldCount, fieldCount, autoSql) {
|
|
56731
|
-
if (autoSql && 'chromatinInteract' === autoSql.table) {
|
|
56729
|
+
function getDecoder(definedFieldCount, fieldCount, autoSql, format) {
|
|
56730
|
+
if (autoSql && 'chromatinInteract' === autoSql.table || "biginteract" === format) {
|
|
56732
56731
|
return decodeInteract;
|
|
56733
56732
|
} else {
|
|
56734
56733
|
const standardFieldCount = definedFieldCount - 3;
|
|
@@ -56863,6 +56862,7 @@
|
|
|
56863
56862
|
class BWReader {
|
|
56864
56863
|
constructor(config, genome) {
|
|
56865
56864
|
this.path = config.url;
|
|
56865
|
+
this.format = config.format || "bigwig";
|
|
56866
56866
|
this.genome = genome;
|
|
56867
56867
|
this.rpTreeCache = {};
|
|
56868
56868
|
this.config = config;
|
|
@@ -57441,7 +57441,7 @@
|
|
|
57441
57441
|
function getBedDataDecoder() {
|
|
57442
57442
|
const minSize = 3 * 4 + 1; // Minimum # of bytes required for a bed record
|
|
57443
57443
|
|
|
57444
|
-
const decoder = getDecoder(this.header.definedFieldCount, this.header.fieldCount, this.autoSql);
|
|
57444
|
+
const decoder = getDecoder(this.header.definedFieldCount, this.header.fieldCount, this.autoSql, this.format);
|
|
57445
57445
|
return function (data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict) {
|
|
57446
57446
|
const binaryParser = new BinaryParser(data);
|
|
57447
57447
|
|
|
@@ -58361,7 +58361,7 @@
|
|
|
58361
58361
|
function FeatureSource(config, genome) {
|
|
58362
58362
|
const format = config.format ? config.format.toLowerCase() : undefined;
|
|
58363
58363
|
|
|
58364
|
-
if ('bigwig' === format || 'bigbed' === format || 'bb' === format) {
|
|
58364
|
+
if ('bigwig' === format || 'bigbed' === format || 'bb' === format || "biginteract" === format) {
|
|
58365
58365
|
return new BWSource(config, genome);
|
|
58366
58366
|
} else if ("tdf" === format) {
|
|
58367
58367
|
return new TDFSource(config, genome);
|
|
@@ -59273,14 +59273,12 @@
|
|
|
59273
59273
|
this.featureType = 'numeric';
|
|
59274
59274
|
this.paintAxis = paintAxis;
|
|
59275
59275
|
const format = config.format ? config.format.toLowerCase() : config.format;
|
|
59276
|
+
this.flipAxis = config.flipAxis ? config.flipAxis : false;
|
|
59277
|
+
this.logScale = config.logScale ? config.logScale : false;
|
|
59276
59278
|
|
|
59277
59279
|
if ("bigwig" === format) {
|
|
59278
|
-
this.flipAxis = config.flipAxis ? config.flipAxis : false;
|
|
59279
|
-
this.logScale = config.logScale ? config.logScale : false;
|
|
59280
59280
|
this.featureSource = new BWSource(config, this.browser.genome);
|
|
59281
59281
|
} else if ("tdf" === format) {
|
|
59282
|
-
this.flipAxis = config.flipAxis ? config.flipAxis : false;
|
|
59283
|
-
this.logScale = config.logScale ? config.logScale : false;
|
|
59284
59282
|
this.featureSource = new TDFSource(config, this.browser.genome);
|
|
59285
59283
|
} else {
|
|
59286
59284
|
this.featureSource = FeatureSource(config, this.browser.genome);
|
|
@@ -60057,7 +60055,7 @@
|
|
|
60057
60055
|
|
|
60058
60056
|
const sortHandler = sort => {
|
|
60059
60057
|
const viewport = clickState.viewport;
|
|
60060
|
-
const features = viewport.
|
|
60058
|
+
const features = viewport.cachedFeatures;
|
|
60061
60059
|
this.sortSamples(sort.chr, sort.start, sort.end, sort.direction, features);
|
|
60062
60060
|
};
|
|
60063
60061
|
|
|
@@ -60163,10 +60161,16 @@
|
|
|
60163
60161
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
60164
60162
|
* THE SOFTWARE.
|
|
60165
60163
|
*/
|
|
60164
|
+
/**
|
|
60165
|
+
* Represents 2 or more wig tracks overlaid on a common viewport.
|
|
60166
|
+
*/
|
|
60166
60167
|
|
|
60167
60168
|
class MergedTrack extends TrackBase {
|
|
60168
60169
|
constructor(config, browser) {
|
|
60169
60170
|
super(config, browser);
|
|
60171
|
+
this.type = "merged";
|
|
60172
|
+
this.featureType = 'numeric';
|
|
60173
|
+
this.paintAxis = paintAxis;
|
|
60170
60174
|
}
|
|
60171
60175
|
|
|
60172
60176
|
init(config) {
|
|
@@ -60177,21 +60181,6 @@
|
|
|
60177
60181
|
super.init(config);
|
|
60178
60182
|
}
|
|
60179
60183
|
|
|
60180
|
-
get height() {
|
|
60181
|
-
return this._height;
|
|
60182
|
-
}
|
|
60183
|
-
|
|
60184
|
-
set height(h) {
|
|
60185
|
-
this._height = h;
|
|
60186
|
-
|
|
60187
|
-
if (this.tracks) {
|
|
60188
|
-
for (let t of this.tracks) {
|
|
60189
|
-
t.height = h;
|
|
60190
|
-
t.config.height = h;
|
|
60191
|
-
}
|
|
60192
|
-
}
|
|
60193
|
-
}
|
|
60194
|
-
|
|
60195
60184
|
async postInit() {
|
|
60196
60185
|
this.tracks = [];
|
|
60197
60186
|
const p = [];
|
|
@@ -60213,45 +60202,83 @@
|
|
|
60213
60202
|
}
|
|
60214
60203
|
}
|
|
60215
60204
|
|
|
60216
|
-
this.
|
|
60205
|
+
this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false;
|
|
60206
|
+
this.logScale = this.config.logScale ? this.config.logScale : false;
|
|
60207
|
+
this.autoscale = this.config.autoscale || this.config.max === undefined;
|
|
60208
|
+
|
|
60209
|
+
if (!this.autoscale) {
|
|
60210
|
+
this.dataRange = {
|
|
60211
|
+
min: this.config.min || 0,
|
|
60212
|
+
max: this.config.max
|
|
60213
|
+
};
|
|
60214
|
+
}
|
|
60215
|
+
|
|
60216
|
+
for (let t of this.tracks) {
|
|
60217
|
+
t.autoscale = false;
|
|
60218
|
+
t.dataRange = this.dataRange;
|
|
60219
|
+
}
|
|
60220
|
+
|
|
60221
|
+
this.height = this.config.height || 50;
|
|
60217
60222
|
return Promise.all(p);
|
|
60218
60223
|
}
|
|
60219
60224
|
|
|
60225
|
+
get height() {
|
|
60226
|
+
return this._height;
|
|
60227
|
+
}
|
|
60228
|
+
|
|
60229
|
+
set height(h) {
|
|
60230
|
+
this._height = h;
|
|
60231
|
+
|
|
60232
|
+
if (this.tracks) {
|
|
60233
|
+
for (let t of this.tracks) {
|
|
60234
|
+
t.height = h;
|
|
60235
|
+
t.config.height = h;
|
|
60236
|
+
}
|
|
60237
|
+
}
|
|
60238
|
+
}
|
|
60239
|
+
|
|
60240
|
+
menuItemList() {
|
|
60241
|
+
let items = [];
|
|
60242
|
+
|
|
60243
|
+
if (this.flipAxis !== undefined) {
|
|
60244
|
+
items.push({
|
|
60245
|
+
label: "Flip y-axis",
|
|
60246
|
+
click: () => {
|
|
60247
|
+
this.flipAxis = !this.flipAxis;
|
|
60248
|
+
this.trackView.repaintViews();
|
|
60249
|
+
}
|
|
60250
|
+
});
|
|
60251
|
+
}
|
|
60252
|
+
|
|
60253
|
+
items = items.concat(MenuUtils.numericDataMenuItems(this.trackView));
|
|
60254
|
+
return items;
|
|
60255
|
+
}
|
|
60256
|
+
|
|
60220
60257
|
async getFeatures(chr, bpStart, bpEnd, bpPerPixel) {
|
|
60221
60258
|
const promises = this.tracks.map(t => t.getFeatures(chr, bpStart, bpEnd, bpPerPixel));
|
|
60222
60259
|
return Promise.all(promises);
|
|
60223
60260
|
}
|
|
60224
60261
|
|
|
60225
60262
|
draw(options) {
|
|
60226
|
-
|
|
60227
|
-
mergedFeatures = options.features; // Array of feature arrays, 1 for each track
|
|
60263
|
+
const mergedFeatures = options.features; // Array of feature arrays, 1 for each track
|
|
60228
60264
|
|
|
60229
|
-
|
|
60265
|
+
if (this.autoscale) {
|
|
60266
|
+
this.dataRange = autoscale(options.referenceFrame.chr, mergedFeatures);
|
|
60267
|
+
}
|
|
60230
60268
|
|
|
60231
|
-
for (i = 0, len = this.tracks.length; i < len; i++) {
|
|
60232
|
-
trackOptions = Object.assign({}, options);
|
|
60269
|
+
for (let i = 0, len = this.tracks.length; i < len; i++) {
|
|
60270
|
+
const trackOptions = Object.assign({}, options);
|
|
60233
60271
|
trackOptions.features = mergedFeatures[i];
|
|
60234
|
-
this.tracks[i].dataRange = dataRange;
|
|
60272
|
+
this.tracks[i].dataRange = this.dataRange;
|
|
60273
|
+
this.tracks[i].flipAxis = this.flipAxis;
|
|
60274
|
+
this.tracks[i].logScale = this.logScale;
|
|
60275
|
+
this.tracks[i].graphType = this.graphType;
|
|
60235
60276
|
this.tracks[i].draw(trackOptions);
|
|
60236
60277
|
}
|
|
60237
60278
|
}
|
|
60238
60279
|
|
|
60239
|
-
paintAxis(ctx, pixelWidth, pixelHeight) {
|
|
60240
|
-
var i, len, autoscale, track;
|
|
60241
|
-
autoscale = true; // Hardcoded for now
|
|
60242
|
-
|
|
60243
|
-
for (i = 0, len = this.tracks.length; i < len; i++) {
|
|
60244
|
-
track = this.tracks[i];
|
|
60245
|
-
|
|
60246
|
-
if (typeof track.paintAxis === 'function') {
|
|
60247
|
-
track.paintAxis(ctx, pixelWidth, pixelHeight);
|
|
60248
|
-
if (autoscale) break;
|
|
60249
|
-
}
|
|
60250
|
-
}
|
|
60251
|
-
}
|
|
60252
|
-
|
|
60253
60280
|
popupData(clickState, features) {
|
|
60254
|
-
const featuresArray = features || clickState.viewport.
|
|
60281
|
+
const featuresArray = features || clickState.viewport.cachedFeatures;
|
|
60255
60282
|
|
|
60256
60283
|
if (featuresArray && featuresArray.length === this.tracks.length) {
|
|
60257
60284
|
// Array of feature arrays, 1 for each track
|
|
@@ -60269,39 +60296,23 @@
|
|
|
60269
60296
|
}
|
|
60270
60297
|
|
|
60271
60298
|
supportsWholeGenome() {
|
|
60272
|
-
|
|
60273
|
-
return b;
|
|
60299
|
+
return this.tracks.every(track => track.supportsWholeGenome());
|
|
60274
60300
|
}
|
|
60275
60301
|
|
|
60276
60302
|
}
|
|
60277
60303
|
|
|
60278
60304
|
function autoscale(chr, featureArrays) {
|
|
60279
|
-
|
|
60280
|
-
|
|
60281
|
-
// if (chr === 'all') {
|
|
60282
|
-
// allValues = [];
|
|
60283
|
-
// featureArrays.forEach(function (features) {
|
|
60284
|
-
// features.forEach(function (f) {
|
|
60285
|
-
// if (!Number.isNaN(f.value)) {
|
|
60286
|
-
// allValues.push(f.value);
|
|
60287
|
-
// }
|
|
60288
|
-
// });
|
|
60289
|
-
// });
|
|
60290
|
-
//
|
|
60291
|
-
// min = Math.min(0, IGVMath.percentile(allValues, .1));
|
|
60292
|
-
// max = IGVMath.percentile(allValues, 99.9);
|
|
60293
|
-
//
|
|
60294
|
-
// }
|
|
60295
|
-
// else {
|
|
60305
|
+
let min = 0;
|
|
60306
|
+
let max = -Number.MAX_VALUE;
|
|
60296
60307
|
|
|
60297
|
-
|
|
60298
|
-
|
|
60308
|
+
for (let features of featureArrays) {
|
|
60309
|
+
for (let f of features) {
|
|
60299
60310
|
if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) {
|
|
60300
60311
|
min = Math.min(min, f.value);
|
|
60301
60312
|
max = Math.max(max, f.value);
|
|
60302
60313
|
}
|
|
60303
|
-
}
|
|
60304
|
-
}
|
|
60314
|
+
}
|
|
60315
|
+
}
|
|
60305
60316
|
|
|
60306
60317
|
return {
|
|
60307
60318
|
min: min,
|
|
@@ -60885,20 +60896,21 @@
|
|
|
60885
60896
|
const cachedFeatures = "all" === refFrame.chr ? this.featureSource.getAllFeatures() : this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end); // inView features are simply features that have been drawn, i.e. have a drawState
|
|
60886
60897
|
|
|
60887
60898
|
const inView = cachedFeatures.filter(f => f.drawState);
|
|
60888
|
-
if (inView.length === 0)
|
|
60899
|
+
if (inView.length === 0) return;
|
|
60889
60900
|
this.browser.circularViewVisible = true;
|
|
60890
|
-
const chords = makeBedPEChords(inView);
|
|
60891
|
-
|
|
60892
|
-
|
|
60893
|
-
|
|
60894
|
-
|
|
60895
|
-
const
|
|
60896
|
-
|
|
60897
|
-
|
|
60898
|
-
|
|
60899
|
-
|
|
60900
|
-
|
|
60901
|
-
})
|
|
60901
|
+
const chords = makeBedPEChords(inView);
|
|
60902
|
+
sendChords(chords, this, refFrame, 0.5); //
|
|
60903
|
+
//
|
|
60904
|
+
// // for filtered set, distinguishing the chromosomes is more critical than tracks
|
|
60905
|
+
// const chordSetColor = IGVColor.addAlpha("all" === refFrame.chr ? this.color : getChrColor(refFrame.chr), 0.5)
|
|
60906
|
+
// const trackColor = IGVColor.addAlpha(this.color, 0.5)
|
|
60907
|
+
//
|
|
60908
|
+
// // name the chord set to include locus and filtering information
|
|
60909
|
+
// const encodedName = this.name.replaceAll(' ', '%20')
|
|
60910
|
+
// const chordSetName = "all" === refFrame.chr ?
|
|
60911
|
+
// encodedName :
|
|
60912
|
+
// `${encodedName} (${refFrame.chr}:${refFrame.start}-${refFrame.end} ; range:${this.dataRange.min}-${this.dataRange.max})`
|
|
60913
|
+
// this.browser.circularView.addChords(chords, {track: chordSetName, color: chordSetColor, trackColor: trackColor})
|
|
60902
60914
|
}
|
|
60903
60915
|
|
|
60904
60916
|
doAutoscale(features) {
|
|
@@ -60985,7 +60997,7 @@
|
|
|
60985
60997
|
clickedFeatures(clickState, features) {
|
|
60986
60998
|
// We use the cached features rather than method to avoid async load. If the
|
|
60987
60999
|
// feature is not already loaded this won't work, but the user wouldn't be mousing over it either.
|
|
60988
|
-
const featureList = features || clickState.viewport.
|
|
61000
|
+
const featureList = features || clickState.viewport.cachedFeatures;
|
|
60989
61001
|
const candidates = [];
|
|
60990
61002
|
|
|
60991
61003
|
if (featureList) {
|
|
@@ -61571,7 +61583,7 @@
|
|
|
61571
61583
|
variantColor = "gray";
|
|
61572
61584
|
}
|
|
61573
61585
|
} else if (this._color) {
|
|
61574
|
-
variantColor =
|
|
61586
|
+
variantColor = this.color;
|
|
61575
61587
|
} else if ("NONVARIANT" === v.type) {
|
|
61576
61588
|
variantColor = this.nonRefColor;
|
|
61577
61589
|
} else if ("MIXED" === v.type) {
|
|
@@ -61583,6 +61595,10 @@
|
|
|
61583
61595
|
return variantColor;
|
|
61584
61596
|
}
|
|
61585
61597
|
|
|
61598
|
+
get color() {
|
|
61599
|
+
return this._color ? typeof this._color === "function" ? this._color(v) : this._color : this.defaultColor;
|
|
61600
|
+
}
|
|
61601
|
+
|
|
61586
61602
|
clickedFeatures(clickState, features) {
|
|
61587
61603
|
let featureList = super.clickedFeatures(clickState, features);
|
|
61588
61604
|
const vGap = this.displayMode === 'EXPANDED' ? this.expandedVGap : this.squishedVGap;
|
|
@@ -61848,24 +61864,10 @@
|
|
|
61848
61864
|
menuItems.push({
|
|
61849
61865
|
label: 'Add SVs to circular view',
|
|
61850
61866
|
click: () => {
|
|
61851
|
-
const inView = [];
|
|
61852
61867
|
|
|
61853
61868
|
for (let viewport of this.trackView.viewports) {
|
|
61854
|
-
|
|
61855
|
-
|
|
61856
|
-
for (let f of viewport.getCachedFeatures()) {
|
|
61857
|
-
if (f.end >= refFrame.start && f.start <= refFrame.end) {
|
|
61858
|
-
inView.push(f);
|
|
61859
|
-
}
|
|
61860
|
-
}
|
|
61869
|
+
this.sendChordsForViewport(viewport);
|
|
61861
61870
|
}
|
|
61862
|
-
|
|
61863
|
-
const chords = makeVCFChords(inView);
|
|
61864
|
-
const color = IGVColor.addAlpha(this._color || this.defaultColor, 0.5);
|
|
61865
|
-
this.browser.circularView.addChords(chords, {
|
|
61866
|
-
track: this.name,
|
|
61867
|
-
color: color
|
|
61868
|
-
});
|
|
61869
61871
|
}
|
|
61870
61872
|
});
|
|
61871
61873
|
}
|
|
@@ -61881,20 +61883,20 @@
|
|
|
61881
61883
|
list.push({
|
|
61882
61884
|
label: 'Add SVs to Circular View',
|
|
61883
61885
|
click: () => {
|
|
61884
|
-
|
|
61885
|
-
const inView = "all" === refFrame.chr ? this.featureSource.getAllFeatures() : this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end);
|
|
61886
|
-
const chords = makeVCFChords(inView);
|
|
61887
|
-
const color = IGVColor.addAlpha(this._color || this.defaultColor, 0.5);
|
|
61888
|
-
this.browser.circularView.addChords(chords, {
|
|
61889
|
-
track: this.name,
|
|
61890
|
-
color: color
|
|
61891
|
-
});
|
|
61886
|
+
this.sendChordsForViewport(viewport);
|
|
61892
61887
|
}
|
|
61893
61888
|
});
|
|
61894
61889
|
list.push('<hr/>');
|
|
61895
61890
|
return list;
|
|
61896
61891
|
}
|
|
61897
61892
|
}
|
|
61893
|
+
|
|
61894
|
+
sendChordsForViewport(viewport) {
|
|
61895
|
+
const refFrame = viewport.referenceFrame;
|
|
61896
|
+
const inView = "all" === refFrame.chr ? this.featureSource.getAllFeatures() : this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end);
|
|
61897
|
+
const chords = makeVCFChords(inView);
|
|
61898
|
+
sendChords(chords, this, refFrame, 0.5);
|
|
61899
|
+
}
|
|
61898
61900
|
/**
|
|
61899
61901
|
* Create a "color by" checkbox menu item, optionally initially checked
|
|
61900
61902
|
* @param menuItem
|
|
@@ -62197,7 +62199,7 @@
|
|
|
62197
62199
|
|
|
62198
62200
|
|
|
62199
62201
|
popupData(clickState) {
|
|
62200
|
-
let features = clickState.viewport.
|
|
62202
|
+
let features = clickState.viewport.cachedFeatures;
|
|
62201
62203
|
if (!features || features.length === 0) return [];
|
|
62202
62204
|
const tolerance = 3;
|
|
62203
62205
|
const tissue = this.name;
|
|
@@ -62543,7 +62545,7 @@
|
|
|
62543
62545
|
popupData(clickState) {
|
|
62544
62546
|
let data = [];
|
|
62545
62547
|
const track = clickState.viewport.trackView.track;
|
|
62546
|
-
const features = clickState.viewport.
|
|
62548
|
+
const features = clickState.viewport.cachedFeatures;
|
|
62547
62549
|
|
|
62548
62550
|
if (features) {
|
|
62549
62551
|
let count = 0;
|
|
@@ -63232,7 +63234,7 @@
|
|
|
63232
63234
|
if (!this.featureCache) {
|
|
63233
63235
|
const options = buildOptions(this.config);
|
|
63234
63236
|
const data = await igvxhr.loadString(this.config.url, options);
|
|
63235
|
-
this.featureCache = new FeatureCache(parseBP(data), genome);
|
|
63237
|
+
this.featureCache = new FeatureCache$1(parseBP(data), genome);
|
|
63236
63238
|
return this.featureCache.queryFeatures(chr, start, end);
|
|
63237
63239
|
} else {
|
|
63238
63240
|
return this.featureCache.queryFeatures(chr, start, end);
|
|
@@ -64475,6 +64477,15 @@
|
|
|
64475
64477
|
this.id = guid$2();
|
|
64476
64478
|
}
|
|
64477
64479
|
|
|
64480
|
+
extend(locus) {
|
|
64481
|
+
const newStart = Math.min(locus.start, this.start);
|
|
64482
|
+
const newEnd = Math.max(locus.end, this.end);
|
|
64483
|
+
const ratio = (newEnd - newStart) / (this.end - this.start);
|
|
64484
|
+
this.start = newStart;
|
|
64485
|
+
this.end = newEnd;
|
|
64486
|
+
this.bpPerPixel *= ratio;
|
|
64487
|
+
}
|
|
64488
|
+
|
|
64478
64489
|
calculateEnd(pixels) {
|
|
64479
64490
|
return this.start + this.bpPerPixel * pixels;
|
|
64480
64491
|
}
|
|
@@ -64559,7 +64570,7 @@
|
|
|
64559
64570
|
const viewChanged = start !== this.start || bpPerPixel !== this.bpPerPixel;
|
|
64560
64571
|
|
|
64561
64572
|
if (viewChanged) {
|
|
64562
|
-
await browser.updateViews(
|
|
64573
|
+
await browser.updateViews(true);
|
|
64563
64574
|
}
|
|
64564
64575
|
}
|
|
64565
64576
|
|
|
@@ -66524,7 +66535,12 @@
|
|
|
66524
66535
|
}
|
|
66525
66536
|
}
|
|
66526
66537
|
|
|
66527
|
-
await this.loadTrackList(trackConfigurations);
|
|
66538
|
+
await this.loadTrackList(trackConfigurations); // The ruler track is not explicitly loaded, but needs updated nonetheless.
|
|
66539
|
+
|
|
66540
|
+
for (let rtv of this.trackViews.filter(tv => tv.track.type === 'ruler')) {
|
|
66541
|
+
rtv.updateViews();
|
|
66542
|
+
}
|
|
66543
|
+
|
|
66528
66544
|
this.updateUIWithReferenceFrameList();
|
|
66529
66545
|
}
|
|
66530
66546
|
|
|
@@ -66689,26 +66705,22 @@
|
|
|
66689
66705
|
}
|
|
66690
66706
|
|
|
66691
66707
|
async loadTrackList(configList) {
|
|
66692
|
-
|
|
66693
|
-
const promises = [];
|
|
66694
|
-
|
|
66695
|
-
for (let config of configList) {
|
|
66696
|
-
promises.push(this.loadTrack(config, false));
|
|
66697
|
-
}
|
|
66708
|
+
const promises = [];
|
|
66698
66709
|
|
|
66699
|
-
|
|
66700
|
-
|
|
66701
|
-
|
|
66702
|
-
});
|
|
66710
|
+
for (let config of configList) {
|
|
66711
|
+
promises.push(this.loadTrack(config));
|
|
66712
|
+
}
|
|
66703
66713
|
|
|
66704
|
-
|
|
66705
|
-
|
|
66706
|
-
|
|
66714
|
+
const loadedTracks = await Promise.all(promises);
|
|
66715
|
+
const groupAutoscaleViews = this.trackViews.filter(function (trackView) {
|
|
66716
|
+
return trackView.track.autoscaleGroup;
|
|
66717
|
+
});
|
|
66707
66718
|
|
|
66708
|
-
|
|
66709
|
-
|
|
66710
|
-
await this.resize();
|
|
66719
|
+
if (groupAutoscaleViews.length > 0) {
|
|
66720
|
+
this.updateViews();
|
|
66711
66721
|
}
|
|
66722
|
+
|
|
66723
|
+
return loadedTracks;
|
|
66712
66724
|
}
|
|
66713
66725
|
|
|
66714
66726
|
async loadROI(config) {
|
|
@@ -66722,7 +66734,9 @@
|
|
|
66722
66734
|
}
|
|
66723
66735
|
} else {
|
|
66724
66736
|
this.roi.push(new ROI(config, this.genome));
|
|
66725
|
-
}
|
|
66737
|
+
} // Force reload all views (force = true) to insure ROI features are loaded. Wasteful but this function is
|
|
66738
|
+
// rarely called.
|
|
66739
|
+
|
|
66726
66740
|
|
|
66727
66741
|
await this.updateViews(true);
|
|
66728
66742
|
}
|
|
@@ -66736,7 +66750,7 @@
|
|
|
66736
66750
|
}
|
|
66737
66751
|
|
|
66738
66752
|
for (let tv of this.trackViews) {
|
|
66739
|
-
tv.
|
|
66753
|
+
tv.repaintViews();
|
|
66740
66754
|
}
|
|
66741
66755
|
}
|
|
66742
66756
|
|
|
@@ -66744,7 +66758,7 @@
|
|
|
66744
66758
|
this.roi = [];
|
|
66745
66759
|
|
|
66746
66760
|
for (let tv of this.trackViews) {
|
|
66747
|
-
tv.
|
|
66761
|
+
tv.repaintViews();
|
|
66748
66762
|
}
|
|
66749
66763
|
}
|
|
66750
66764
|
|
|
@@ -66760,25 +66774,13 @@
|
|
|
66760
66774
|
/**
|
|
66761
66775
|
* Return a promise to load a track.
|
|
66762
66776
|
*
|
|
66763
|
-
* Each track is associated with the following DOM elements
|
|
66764
|
-
*
|
|
66765
|
-
* leftHandGutter - div on the left for track controls and legend
|
|
66766
|
-
* contentDiv - a div element wrapping all the track content. Height can be > viewportDiv height
|
|
66767
|
-
* viewportDiv - a div element through which the track is viewed. This might have a vertical scrollbar
|
|
66768
|
-
* canvas - canvas element upon which the track is drawn. Child of contentDiv
|
|
66769
|
-
*
|
|
66770
|
-
* The width of all elements should be equal. Height of the viewportDiv is controlled by the user, but never
|
|
66771
|
-
* greater than the contentDiv height. Height of contentDiv and canvas are equal, and governed by the data
|
|
66772
|
-
* loaded.
|
|
66773
|
-
*
|
|
66774
|
-
*
|
|
66775
66777
|
* @param config
|
|
66776
66778
|
* @param doResize - undefined by default
|
|
66777
66779
|
* @returns {*}
|
|
66778
66780
|
*/
|
|
66779
66781
|
|
|
66780
66782
|
|
|
66781
|
-
async loadTrack(config
|
|
66783
|
+
async loadTrack(config) {
|
|
66782
66784
|
// config might be json
|
|
66783
66785
|
if (isString$3(config)) {
|
|
66784
66786
|
config = JSON.parse(config);
|
|
@@ -66843,11 +66845,6 @@
|
|
|
66843
66845
|
|
|
66844
66846
|
msg += ": " + config.url;
|
|
66845
66847
|
Alert.presentAlert(new Error(msg), undefined);
|
|
66846
|
-
} finally {
|
|
66847
|
-
// TODO: If loadTrack() is called individually - not via loadTrackList() - call this.resize()
|
|
66848
|
-
if (false === doResize) ; else {
|
|
66849
|
-
await this.resize();
|
|
66850
|
-
}
|
|
66851
66848
|
}
|
|
66852
66849
|
}
|
|
66853
66850
|
/**
|
|
@@ -67080,40 +67077,7 @@
|
|
|
67080
67077
|
this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV);
|
|
67081
67078
|
}
|
|
67082
67079
|
|
|
67083
|
-
await
|
|
67084
|
-
}
|
|
67085
|
-
|
|
67086
|
-
async resize() {
|
|
67087
|
-
const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);
|
|
67088
|
-
|
|
67089
|
-
for (let referenceFrame of this.referenceFrameList) {
|
|
67090
|
-
const index = this.referenceFrameList.indexOf(referenceFrame);
|
|
67091
|
-
const {
|
|
67092
|
-
chr,
|
|
67093
|
-
genome
|
|
67094
|
-
} = referenceFrame;
|
|
67095
|
-
const {
|
|
67096
|
-
bpLength
|
|
67097
|
-
} = genome.getChromosome(referenceFrame.chr);
|
|
67098
|
-
const viewportWidthBP = referenceFrame.toBP(viewportWidth); // viewportWidthBP > bpLength occurs when locus is full chromosome and user widens browser
|
|
67099
|
-
|
|
67100
|
-
if (GenomeUtils.isWholeGenomeView(chr) || viewportWidthBP > bpLength) {
|
|
67101
|
-
// console.log(`${ Date.now() } Recalc referenceFrame(${ index }) bpp. viewport ${ StringUtils.numberFormatter(viewportWidthBP) } > ${ StringUtils.numberFormatter(bpLength) }.`)
|
|
67102
|
-
referenceFrame.bpPerPixel = bpLength / viewportWidth;
|
|
67103
|
-
} else {
|
|
67104
|
-
// console.log(`${ Date.now() } Recalc referenceFrame(${ index }) end.`)
|
|
67105
|
-
referenceFrame.end = referenceFrame.start + referenceFrame.toBP(viewportWidth);
|
|
67106
|
-
}
|
|
67107
|
-
|
|
67108
|
-
for (let {
|
|
67109
|
-
viewports
|
|
67110
|
-
} of this.trackViews) {
|
|
67111
|
-
viewports[index].setWidth(viewportWidth);
|
|
67112
|
-
}
|
|
67113
|
-
}
|
|
67114
|
-
|
|
67115
|
-
await this.updateViews(true);
|
|
67116
|
-
this.updateUIWithReferenceFrameList();
|
|
67080
|
+
await resize.call(this);
|
|
67117
67081
|
}
|
|
67118
67082
|
|
|
67119
67083
|
async updateViews(force) {
|
|
@@ -67189,6 +67153,12 @@
|
|
|
67189
67153
|
}
|
|
67190
67154
|
}
|
|
67191
67155
|
|
|
67156
|
+
repaintViews() {
|
|
67157
|
+
for (let trackView of this.trackViews) {
|
|
67158
|
+
trackView.repaintViews();
|
|
67159
|
+
}
|
|
67160
|
+
}
|
|
67161
|
+
|
|
67192
67162
|
updateLocusSearchWidget() {
|
|
67193
67163
|
const referenceFrameList = this.referenceFrameList; // Update end position of reference frames based on pixel widths. This is hacky, but its been done here
|
|
67194
67164
|
// for a long time, although indirectly.
|
|
@@ -67280,7 +67250,54 @@
|
|
|
67280
67250
|
}
|
|
67281
67251
|
|
|
67282
67252
|
this.centerLineList = this.createCenterLineList(this.columnContainer);
|
|
67283
|
-
await
|
|
67253
|
+
await resize.call(this);
|
|
67254
|
+
}
|
|
67255
|
+
/**
|
|
67256
|
+
* Add a new multi-locus panel for the specified region
|
|
67257
|
+
* @param chr
|
|
67258
|
+
* @param start
|
|
67259
|
+
* @param end
|
|
67260
|
+
* @param referenceFrameLeft - optional, if supplied new panel should be placed to the immediate right
|
|
67261
|
+
*/
|
|
67262
|
+
|
|
67263
|
+
|
|
67264
|
+
async addMultiLocusPanel(chr, start, end, referenceFrameLeft) {
|
|
67265
|
+
// account for reduced viewport width as a result of adding right mate pair panel
|
|
67266
|
+
const viewportWidth = this.calculateViewportWidth(1 + this.referenceFrameList.length);
|
|
67267
|
+
const scaleFactor = this.calculateViewportWidth(this.referenceFrameList.length) / this.calculateViewportWidth(1 + this.referenceFrameList.length);
|
|
67268
|
+
|
|
67269
|
+
for (let refFrame of this.referenceFrameList) {
|
|
67270
|
+
refFrame.bpPerPixel *= scaleFactor;
|
|
67271
|
+
}
|
|
67272
|
+
|
|
67273
|
+
const bpp = (end - start) / viewportWidth;
|
|
67274
|
+
const newReferenceFrame = new ReferenceFrame(this.genome, chr, start, end, bpp);
|
|
67275
|
+
const indexLeft = referenceFrameLeft ? this.referenceFrameList.indexOf(referenceFrameLeft) : this.referenceFrameList.length - 1;
|
|
67276
|
+
const indexRight = 1 + indexLeft; // TODO -- this is really ugly
|
|
67277
|
+
|
|
67278
|
+
const {
|
|
67279
|
+
$viewport
|
|
67280
|
+
} = this.trackViews[0].viewports[indexLeft];
|
|
67281
|
+
const viewportColumn = viewportColumnManager.insertAfter($viewport.get(0).parentElement);
|
|
67282
|
+
|
|
67283
|
+
if (indexRight === this.referenceFrameList.length) {
|
|
67284
|
+
this.referenceFrameList.push(newReferenceFrame);
|
|
67285
|
+
|
|
67286
|
+
for (let trackView of this.trackViews) {
|
|
67287
|
+
const viewport = createViewport(trackView, viewportColumn, newReferenceFrame);
|
|
67288
|
+
trackView.viewports.push(viewport);
|
|
67289
|
+
}
|
|
67290
|
+
} else {
|
|
67291
|
+
this.referenceFrameList.splice(indexRight, 0, newReferenceFrame);
|
|
67292
|
+
|
|
67293
|
+
for (let trackView of this.trackViews) {
|
|
67294
|
+
const viewport = createViewport(trackView, viewportColumn, newReferenceFrame);
|
|
67295
|
+
trackView.viewports.splice(indexRight, 0, viewport);
|
|
67296
|
+
}
|
|
67297
|
+
}
|
|
67298
|
+
|
|
67299
|
+
this.centerLineList = this.createCenterLineList(this.columnContainer);
|
|
67300
|
+
resize.call(this);
|
|
67284
67301
|
}
|
|
67285
67302
|
|
|
67286
67303
|
async removeMultiLocusPanel(referenceFrame) {
|
|
@@ -67309,8 +67326,15 @@
|
|
|
67309
67326
|
const scaleFactor = this.calculateViewportWidth(1 + this.referenceFrameList.length) / this.calculateViewportWidth(this.referenceFrameList.length);
|
|
67310
67327
|
await this.rescaleForMultiLocus(scaleFactor);
|
|
67311
67328
|
}
|
|
67329
|
+
/**
|
|
67330
|
+
* Goto the locus represented by the selected referenceFrame, discarding all other panels
|
|
67331
|
+
*
|
|
67332
|
+
* @param referenceFrame
|
|
67333
|
+
* @returns {Promise<void>}
|
|
67334
|
+
*/
|
|
67312
67335
|
|
|
67313
|
-
|
|
67336
|
+
|
|
67337
|
+
async gotoMultilocusPanel(referenceFrame) {
|
|
67314
67338
|
const referenceFrameIndex = this.referenceFrameList.indexOf(referenceFrame); // Remove columns for unselected panels
|
|
67315
67339
|
|
|
67316
67340
|
this.columnContainer.querySelectorAll('.igv-column').forEach((column, c) => {
|
|
@@ -67358,7 +67382,7 @@
|
|
|
67358
67382
|
|
|
67359
67383
|
this.centerLineList = this.createCenterLineList(this.columnContainer);
|
|
67360
67384
|
this.updateUIWithReferenceFrameList();
|
|
67361
|
-
await this.updateViews(
|
|
67385
|
+
await this.updateViews();
|
|
67362
67386
|
}
|
|
67363
67387
|
/**
|
|
67364
67388
|
* @deprecated This is a deprecated method with no known usages. To be removed in a future release.
|
|
@@ -67612,18 +67636,9 @@
|
|
|
67612
67636
|
return surl;
|
|
67613
67637
|
}
|
|
67614
67638
|
|
|
67615
|
-
|
|
67616
|
-
const loci = [];
|
|
67639
|
+
currentReferenceFrames() {
|
|
67617
67640
|
const anyTrackView = this.trackViews[0];
|
|
67618
|
-
|
|
67619
|
-
for (let {
|
|
67620
|
-
referenceFrame
|
|
67621
|
-
} of anyTrackView.viewports) {
|
|
67622
|
-
const locusString = referenceFrame.getLocusString();
|
|
67623
|
-
loci.push(locusString);
|
|
67624
|
-
}
|
|
67625
|
-
|
|
67626
|
-
return loci;
|
|
67641
|
+
return anyTrackView.viewports.map(vp => vp.referenceFrame);
|
|
67627
67642
|
}
|
|
67628
67643
|
/**
|
|
67629
67644
|
* Record a mouse click on a specific viewport. This might be the start of a drag operation. Dragging
|
|
@@ -67736,12 +67751,9 @@
|
|
|
67736
67751
|
}
|
|
67737
67752
|
|
|
67738
67753
|
addWindowResizeHandler() {
|
|
67739
|
-
this.
|
|
67754
|
+
// Create a copy of the prototype "resize" function bound to this instance. Neccessary to support removing.
|
|
67755
|
+
this.boundWindowResizeHandler = resize.bind(this);
|
|
67740
67756
|
window.addEventListener('resize', this.boundWindowResizeHandler);
|
|
67741
|
-
|
|
67742
|
-
function windowResizeHandler() {
|
|
67743
|
-
this.resize();
|
|
67744
|
-
}
|
|
67745
67757
|
}
|
|
67746
67758
|
|
|
67747
67759
|
removeWindowResizeHandler() {
|
|
@@ -67835,6 +67847,47 @@
|
|
|
67835
67847
|
}
|
|
67836
67848
|
|
|
67837
67849
|
}
|
|
67850
|
+
/**
|
|
67851
|
+
* Function called win window is resized, or visibility changed (e.g. "show" from a tab). This is a function rather
|
|
67852
|
+
* than class method because it needs to be copied and bound to specific instances of browser to support listener
|
|
67853
|
+
* removal
|
|
67854
|
+
*
|
|
67855
|
+
* @returns {Promise<void>}
|
|
67856
|
+
*/
|
|
67857
|
+
|
|
67858
|
+
|
|
67859
|
+
async function resize() {
|
|
67860
|
+
const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);
|
|
67861
|
+
|
|
67862
|
+
for (let referenceFrame of this.referenceFrameList) {
|
|
67863
|
+
const index = this.referenceFrameList.indexOf(referenceFrame);
|
|
67864
|
+
const {
|
|
67865
|
+
chr,
|
|
67866
|
+
genome
|
|
67867
|
+
} = referenceFrame;
|
|
67868
|
+
const {
|
|
67869
|
+
bpLength
|
|
67870
|
+
} = genome.getChromosome(referenceFrame.chr);
|
|
67871
|
+
const viewportWidthBP = referenceFrame.toBP(viewportWidth); // viewportWidthBP > bpLength occurs when locus is full chromosome and user widens browser
|
|
67872
|
+
|
|
67873
|
+
if (GenomeUtils.isWholeGenomeView(chr) || viewportWidthBP > bpLength) {
|
|
67874
|
+
// console.log(`${ Date.now() } Recalc referenceFrame(${ index }) bpp. viewport ${ StringUtils.numberFormatter(viewportWidthBP) } > ${ StringUtils.numberFormatter(bpLength) }.`)
|
|
67875
|
+
referenceFrame.bpPerPixel = bpLength / viewportWidth;
|
|
67876
|
+
} else {
|
|
67877
|
+
// console.log(`${ Date.now() } Recalc referenceFrame(${ index }) end.`)
|
|
67878
|
+
referenceFrame.end = referenceFrame.start + referenceFrame.toBP(viewportWidth);
|
|
67879
|
+
}
|
|
67880
|
+
|
|
67881
|
+
for (let {
|
|
67882
|
+
viewports
|
|
67883
|
+
} of this.trackViews) {
|
|
67884
|
+
viewports[index].setWidth(viewportWidth);
|
|
67885
|
+
}
|
|
67886
|
+
}
|
|
67887
|
+
|
|
67888
|
+
this.updateUIWithReferenceFrameList();
|
|
67889
|
+
await this.updateViews(true);
|
|
67890
|
+
}
|
|
67838
67891
|
|
|
67839
67892
|
function handleMouseMove(e) {
|
|
67840
67893
|
e.preventDefault();
|