diff --git a/configs/vue.config.A2FKP.js b/configs/vue.config.A2FKP.js deleted file mode 100644 index e4a726ad6..000000000 --- a/configs/vue.config.A2FKP.js +++ /dev/null @@ -1,317 +0,0 @@ -/* We define all the pages first in an object that can be modified BEFORE being - * exported so we can add/remove pages based on build type. - */ - -let pages = { - index: { - entry: "src/views/A2fIndex/main.js", - template: "public/index.html", - filename: "index.html", - title: "Home", - chunks: ["chunk-vendors", "chunk-common", "index"], - }, - debug: { - entry: "src/views/Debug/main.js", - template: "public/index.html", - filename: "debug.html", - title: "Debug Page", - chunks: ["chunk-vendors", "chunk-common", "debug"], - }, - phenotype: { - entry: "src/views/Phenotype/main.js", - template: "public/index.html", - filename: "phenotype.html", - title: "Phenotype", - chunks: ["chunk-vendors", "chunk-common", "phenotype"], - }, - region: { - entry: "src/views/Region/main.js", - template: "public/index.html", - filename: "region.html", - title: "Region Info", - chunks: ["chunk-vendors", "chunk-common", "region"], - }, - variant: { - entry: "src/views/Variant/main.js", - template: "public/index.html", - filename: "variant.html", - title: "Variant Info", - chunks: ["chunk-vendors", "chunk-common", "variant"], - }, - gene: { - entry: "src/views/Gene/main.js", - template: "public/index.html", - filename: "gene.html", - title: "Gene Info", - chunks: ["chunk-vendors", "chunk-common", "gene"], - }, - datasets: { - entry: "src/views/Datasets/main.js", - template: "public/index.html", - filename: "datasets.html", - title: "Datasets", - chunks: ["chunk-vendors", "chunk-common", "datasets"], - }, - dinspector: { - entry: "src/views/DatasetInspector/main.js", - template: "public/index.html", - filename: "dinspector.html", - title: "Dataset Inspector", - chunks: ["chunk-vendors", "chunk-common", "dinspector"], - }, - downloads: { - entry: "src/views/Downloads/main.js", - template: "public/index.html", - filename: "downloads.html", - title: "Downloads", - chunks: ["chunk-vendors", "chunk-common", "downloads"], - }, - policies: { - entry: "src/views/Policies/main.js", - template: "public/index.html", - filename: "policies.html", - title: "Policies", - chunks: ["chunk-vendors", "chunk-common", "policies"], - }, - about: { - entry: "src/views/About/main.js", - template: "public/index.html", - filename: "about.html", - title: "About", - chunks: ["chunk-vendors", "chunk-common", "about"], - }, - collaborate: { - entry: "src/views/Collaborate/main.js", - template: "public/index.html", - filename: "collaborate.html", - title: "Collaborate", - chunks: ["chunk-vendors", "chunk-common", "collaborate"], - }, - resources: { - entry: "src/views/Resources/main.js", - template: "public/index.html", - filename: "resources.html", - title: "Resources", - chunks: ["chunk-vendors", "chunk-common", "resources"], - }, - publications: { - entry: "src/views/Publications/main.js", - template: "public/index.html", - filename: "publications.html", - title: "Publications", - chunks: ["chunk-vendors", "chunk-common", "publications"], - }, - news: { - entry: "src/views/News/main.js", - template: "public/index.html", - filename: "news.html", - title: "News", - chunks: ["chunk-vendors", "chunk-common", "news"], - }, - contacts: { - entry: "src/views/Contacts/main.js", - template: "public/index.html", - filename: "contacts.html", - title: "Contacts", - chunks: ["chunk-vendors", "chunk-common", "contacts"], - }, - kplab: { - entry: "src/views/KPLab/main.js", - template: "public/index.html", - filename: "kplab.html", - title: "KP Lab", - chunks: ["chunk-vendors", "chunk-common", "kplab"], - }, - apis: { - entry: "src/views/Apis/main.js", - template: "public/index.html", - filename: "apis.html", - title: "APIs", - chunks: ["chunk-vendors", "chunk-common", "apis"], - }, - epigeneticdatasets: { - entry: "src/views/EpigeneticDatasets/main.js", - template: "public/index.html", - filename: "epigeneticdatasets.html", - title: "Epigenetic Datasets", - chunks: ["chunk-vendors", "chunk-common", "epigeneticdatasets"], - }, - epigenomicdatasets: { - entry: "src/views/EpigenomicDatasets/main.js", - template: "public/index.html", - filename: "epigenomicdatasets.html", - title: "Epigenomic Datasets", - chunks: ["chunk-vendors", "chunk-common", "epigenomicdatasets"], - }, - ampt2dpartnership: { - entry: "src/views/AmpT2dPartnership/main.js", - template: "public/index.html", - filename: "ampt2dpartnership.html", - title: "AMP T2D Partnership", - chunks: ["chunk-vendors", "chunk-common", "ampt2dpartnership"], - }, - effectorgenes: { - entry: "src/views/EffectorGenes/main.js", - template: "public/index.html", - filename: "effectorgenes.html", - title: "Predicted Effector Genes Research Methods", - chunks: ["chunk-vendors", "chunk-common", "effectorgenes"], - }, - eglmethod: { - entry: "src/views/EglMethod/main.js", - template: "public/index.html", - filename: "method.html", - title: "Research Method", - chunks: ["chunk-vendors", "chunk-common", "eglmethod"], - }, - hugecalculator: { - entry: "src/views/HuGeCalculator/main.js", - template: "public/index.html", - filename: "hugecalculator.html", - title: "HuGe Calculator", - chunks: ["chunk-vendors", "chunk-common", "hugecalculator"], - }, - - genefinder: { - entry: "src/views/GeneFinder/main.js", - template: "public/index.html", - filename: "genefinder.html", - title: "Gene Finder", - chunks: ["chunk-vendors", "chunk-common", "genefinder"], - }, - signalsifter: { - entry: "src/views/SignalSifter/main.js", - template: "public/index.html", - filename: "signalsifter.html", - title: "Signal Sifter", - chunks: ["chunk-vendors", "chunk-common", "signalsifter"], - }, - complicationsviewer: { - entry: "src/views/ComplicationsViewer/main.js", - template: "public/index.html", - filename: "complicationsviewer.html", - title: "Complications Viewer", - chunks: ["chunk-vendors", "chunk-common", "complicationsviewer"], - }, - - page404: { - entry: "src/views/404/main.js", - template: "public/index.html", - filename: "404.html", - title: "Page Not Found", - chunks: ["chunk-vendors", "chunk-common", "page404"], - }, - gait: { - entry: "src/views/GAIT/main.js", - template: "public/index.html", - filename: "gait.html", - title: "Genetic Association Interactive Tool", - chunks: ["chunk-vendors", "chunk-common", "gait"], - }, - gait2: { - entry: "src/views/GAIT2/main.js", - template: "public/index.html", - filename: "ncgait.html", - title: "Non-Coding Genetic Association Interactive Tool", - chunks: ["chunk-vendors", "chunk-common", "gait2"], - }, - project: { - entry: "src/views/Project/main.js", - template: "public/index.html", - filename: "project.html", - title: "Project", - chunks: ["chunk-vendors", "chunk-common", "project"], - }, - variantsearch: { - entry: "src/views/VariantSearch/main.js", - template: "public/index.html", - filename: "variantsearch.html", - title: "Variant Search", - chunks: ["chunk-vendors", "chunk-common", "variantsearch"], - }, - research: { - entry: "src/views/Papers/Research/main.js", - template: "public/index.html", - filename: "research.html", - title: "Research", - chunks: ["chunk-vendors", "chunk-common", "research"], - }, - egggenerator: { - entry: "src/views/EggGenerator/main.js", - template: "public/index.html", - filename: "egggenerator.html", - title: "Exome Gene-Level Group-file Generator", - chunks: ["chunk-vendors", "chunk-common", "egggenerator"], - }, - help: { - entry: "src/views/Help/main.js", - template: "public/index.html", - filename: "help.html", - title: "Help", - chunks: ["chunk-vendors", "chunk-common", "help"], - }, -}; - -// remove the debug page in production -if (process.env.NODE_ENV === "production") { - delete pages.debug; -} - -module.exports = { - devServer: { - writeToDisk: true, // https://webpack.js.org/configuration/dev-server/#devserverwritetodisk- - }, - configureWebpack: (config) => { - let bioindex_dev = process.env.BIOINDEX_DEV; - let bioindex_host = "https://bioindex.hugeamp.org"; // production by default - //set private bioindex host if variable is defined, otherwise use default - let bioindex_host_private = - process.env.BIOINDEX_HOST_PRIVATE || "https://bioindex.hugeamp.org"; - - if (!!bioindex_dev) { - bioindex_host = - bioindex_dev == "localhost" - ? "http://localhost:5000" - : "https://bioindex-dev.hugeamp.org"; - } - - // output which vue config file and bioindex is being used - console.log( - `VUE_CONFIG_PATH=${process.env.VUE_CLI_SERVICE_CONFIG_PATH}; BIOINDEX_DEV=${process.env.BIOINDEX_DEV}; using ${bioindex_host} and ${bioindex_host_private}` - ); - - // add the transform rule for bioindex - config.module.rules.push({ - test: /bioIndexUtils\.js$/, - loader: "string-replace-loader", - options: { - search: "SERVER_IP_ADDRESS", - replace: bioindex_host, - flags: "g", - }, - }); - - // add the transform rule for bioindex - // Helen 2021-06-17 - config.module.rules.push({ - test: /bioIndexUtils\.js$/, - loader: "string-replace-loader", - options: { - search: "SERVER_IP_PRIVATE", - replace: bioindex_host_private, - flags: "g", - }, - }); - - // create inline maps for dev builds - if (process.env.NODE_ENV !== "production") { - //config.devtool = "inline-source-map"; - - //https://stackoverflow.com/questions/48047150/chrome-extension-compiled-by-webpack-throws-unsafe-eval-error - config.devtool = "cheap-module-source-map"; - } - }, - outputDir: "portals/A2FKP/dist", - productionSourceMap: false, - pages, -}; diff --git a/configs/vue.config.mouseportal.js b/configs/vue.config.mouseportal.js new file mode 100644 index 000000000..98fe7af28 --- /dev/null +++ b/configs/vue.config.mouseportal.js @@ -0,0 +1,91 @@ +/* We define all the pages first in an object that can be modified BEFORE being + * exported so we can add/remove pages based on build type. + */ + +let pages = { + index: { + entry: "src/portals/MousePortal/views/Index/main.js", + template: "src/portals/MousePortal/index.html", + filename: "index.html", + title: "MousePortal", + chunks: ["chunk-vendors", "chunk-common", "index"], + }, + page404: { + entry: "src/views/404/main.js", + template: "src/portals/MousePortal/index.html", + filename: "404.html", + title: "Page Not Found", + chunks: ["chunk-vendors", "chunk-common", "page404"], + }, + gene: { + entry: "src/portals/MousePortal/views/Gene/main.js", + template: "src/portals/MousePortal/index.html", + filename: "gene.html", + title: "Mouse Gene", + chunks: ["chunk-vendors", "chunk-common", "gene"], + }, + tissue: { + entry: "src/portals/MousePortal/views/Tissue/main.js", + template: "src/portals/MousePortal/index.html", + filename: "tissue.html", + title: "Mouse Tissue", + chunks: ["chunk-vendors", "chunk-common", "tissue"], + } +}; + +module.exports = { + devServer: { + writeToDisk: true, // https://webpack.js.org/configuration/dev-server/#devserverwritetodisk- + }, + configureWebpack: (config) => { + let bioindex_dev = process.env.BIOINDEX_DEV; + let bioindex_host = "https://bioindex.hugeamp.org"; // production by default + //set private bioindex host if variable is defined, otherwise use default + let bioindex_host_private = + process.env.BIOINDEX_HOST_PRIVATE || "https://bioindex.hugeamp.org"; + + if (!!bioindex_dev) { + bioindex_host = + bioindex_dev == "localhost" + ? "http://localhost:5000" + : "https://bioindex-dev.hugeamp.org"; + } + + // output which vue config file and bioindex is being used + console.log( + `VUE_CONFIG_PATH=${process.env.VUE_CLI_SERVICE_CONFIG_PATH}; BIOINDEX_DEV=${process.env.BIOINDEX_DEV}; using ${bioindex_host} and ${bioindex_host_private}` + ); + + // add the transform rule for bioindex + config.module.rules.push({ + test: /bioIndexUtils\.js$/, + loader: "string-replace-loader", + options: { + search: "SERVER_IP_ADDRESS", + replace: bioindex_host, + flags: "g", + }, + }); + + config.module.rules.push({ + test: /bioIndexUtils\.js$/, + loader: "string-replace-loader", + options: { + search: "SERVER_IP_PRIVATE", + replace: bioindex_host_private, + flags: "g", + }, + }); + + // create inline maps for dev builds + if (process.env.NODE_ENV !== "production") { + //config.devtool = "inline-source-map"; + + //https://stackoverflow.com/questions/48047150/chrome-extension-compiled-by-webpack-throws-unsafe-eval-error + config.devtool = "cheap-module-source-map"; + } + }, + outputDir: "portals/MousePortal", + productionSourceMap: false, + pages, +}; diff --git a/src/portals/MousePortal/assets/layout.css b/src/portals/MousePortal/assets/layout.css new file mode 100644 index 000000000..ea72e5cc5 --- /dev/null +++ b/src/portals/MousePortal/assets/layout.css @@ -0,0 +1,57 @@ +/* LAYOUT STYLES */ +.no-events{ + pointer-events: none; +} +.f-col{ + display: flex; + flex-direction: column; +} +.f-row{ + display: flex; + flex-direction: row; +} +.f-col.align-v-center{ + justify-content: center; +} +.f-row.align-v-center{ + align-items: center; +} +.f-col.align-h-center{ + align-items: center; +} +.f-row.align-h-center{ + justify-content: center; +} +.f-col.align-v-bottom{ + justify-content: flex-end; +} +.f-row.align-v-bottom{ + align-items: flex-end; +} +.f-col.align-h-bottom{ + align-items: flex-end; +} +.f-row.align-h-bottom{ + justify-content: flex-end; +} +.f-col.spread-out, +.f-row.spread-out{ + justify-content: space-between; +} +.fill-height{ + height: stretch; + height: 100%; +} +.fill-width{ + width: stretch; + width: 100%; +} +.hug-height{ + height: fit-content; +} +.hug-width{ + width: fit-content +} +.grow-children>*{ + flex-grow: 1; +} \ No newline at end of file diff --git a/src/portals/MousePortal/assets/mdkp_copy.css b/src/portals/MousePortal/assets/mdkp_copy.css new file mode 100644 index 000000000..c6573acac --- /dev/null +++ b/src/portals/MousePortal/assets/mdkp_copy.css @@ -0,0 +1,2489 @@ +@import url("https://fonts.googleapis.com/css?family=Roboto+Condensed:100,200,300,400italic,400,700,700italic|Open+Sans:400,600, 700,700italic,600italic,600,400italic|Oswald:400,300,700"); + +body.kp-default { + background-color: #eee; + font-family: "Roboto", Arial, sans-serif; +} + +a { + /*color: #0097d6 !important;*/ + color: #007bff !important; +} + +a:hover { + /*text-decoration: none !important;*/ +} + +/*huge calculator*/ +#posteriorpriorplot .center-posterior-prior-plot { + display: flex; + justify-content: center; + align-items: center; + height: 200px; + border: 3px solid green; +} + +/* front page */ +.front-top-banner-agingkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/agingkp_front_bg.png), + linear-gradient(#75bee9, #20c4f4); + background-position: 120% 100px, top left; +} + +.front-top-banner-kidneykp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/kidneykp_front_bg.png), + linear-gradient(#96cbca, #619faf); + background-position: 120% 100px, top left; +} + +.front-top-banner-autoimmunekp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/autoimmunekp_front_bg.png), + linear-gradient(#71cddd, #009bc8); + background-position: 120% 100px, top left; +} + +.front-top-banner-ocularkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/ocular_front_bg.png), + linear-gradient(#008fd0, #005e9e); + background-position: 120% 100px, top left; +} + +.front-top-banner-reproductivekp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/reproductive_front_bg.png), + linear-gradient(#8f7fbb, #5e53a3); + background-position: 120% 100px, top left; +} + +.front-top-banner-mdkp { + /*background-image: url(//kp4cd.org/sites/default/files/vueportal/mdkp_front_bg.png), + linear-gradient(#0097d6, #8ed8f8);*/ + background-image: linear-gradient(#0077b6, #5ec8e8); + background-position: 120% 0px, top left; +} + +.front-top-banner-cvdkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/cvdkp_front_bg.png), + linear-gradient(#f58752, #fdbc63); + background-position: 120% 100px, top left; +} + +.front-top-banner-sleepkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/sleepkp_front_bg.png), + linear-gradient(#74b9e2, #477cbf); + background-position: 120% 100px, top left; +} + +.front-top-banner-t2dkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/t2dkp_front_bg.png), + linear-gradient(#55aaee, #3c80bd); + background-position: 120% 100px, top left; +} + +.front-top-banner-skinkp { + background-image: linear-gradient(#286FB7, #61C2EE); + background-position: 120% 0px, top left; +} + +.front-top-banner-cdkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/cdkp_front_bg.png), + linear-gradient(#73d253, #38942d); + background-position: 120% 100px, top left; +} + +.front-top-banner-v2fkp, +.front-top-banner-a2fkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/a2fkp_front_bg.png), + linear-gradient(#f7835c, #bd516f); + background-position: 100% 300px, top left; +} + +.front-top-banner-t1dkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/t1dkp_front_bg.png), + linear-gradient(#5481c1, #aec5e7); + background-position: 120% 100px, top left; +} + +.front-top-banner-mskkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/mskkp_front_bg.png), + linear-gradient(#bcafd6, #918bc3); + background-position: 120% 100px, top left; +} + +.front-top-banner-lungkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/lungkp_front_bg.png), + linear-gradient(#7accc8, #08b89d); + background-position: 120% 100px, top left; +} + +.front-top-banner-alskp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/alskp_front_bg.png), + linear-gradient(#5eb9e9, #4967b0); + background-position: 120% 100px, top left; +} + +.front-top-banner-nephkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/nephkp_front_bg.png), + linear-gradient(#39bbed, #59be86); + background-position: 120% 100px, top left; +} + +.front-top-banner-ndkpkp { + background-image: url(//kp4cd.org/sites/default/files/vueportal/ndkpkp_front_bg.png), + linear-gradient(#5698d2, #70a4d8); + background-position: 120% 100px, top left; +} + +.front-top-banner-nagekp { + background-image: linear-gradient(#751dc7, #9928c5); + background-position: 120% 0px, top left; +} + +.front-top-banner { + font-size: 16px; + background-repeat: no-repeat; + padding: 30px 0 20px 0; +} + +.front-logo-wrapper { + margin-left: auto; + margin-right: auto; + width: 900px; +} + +.front-logo-img { + width: 470px; + padding-right: 30px; + border-right: solid 1px #fff; + margin-right: 30px; + padding: 20px 20px 20px 0; + float: left; +} + +.front-top-banner-mdkp .front-logo-img { + width: 490px; + margin-left: -20px; + border-right: solid 1px #5ec8e8; + padding: 0 20px 20px 0; +} + +.front-top-banner-cvdkp .front-logo-img { + width: 430px; +} + +.front-top-banner-cdkp .front-logo-img { + width: 430px; +} + +.front-top-banner-sleepkp .front-logo-img { + width: 430px; +} + +.front-top-banner-t2dkp .front-logo-img { + width: 430px; +} + +.front-top-banner-skinkp .front-logo-img { + width: 430px; +} + +.front-top-banner-v2fkp .front-logo-img, +.front-top-banner-a2fkp .front-logo-img { + width: 430px; +} + +.front-top-banner-t1dkp .front-logo-img { + width: 430px; +} + +.front-top-banner-mskkp .front-logo-img { + width: 470px; +} + +.front-top-banner-alskp .front-logo-img { + width: 430px; +} + +.front-top-banner-nephkp .front-logo-img { + width: 430px; +} + +.front-top-banner-ndkpkp .front-logo-img { + width: 470px; +} + +.front-top-banner-nagekp .front-logo-img { + width: 470px; +} + +.front-banner-btn { + border-radius: 30px !important; + width: 250px; + background: none; + border: solid 1px #fff !important; + color: #fff !important; +} + +.front-logo-tagline { + color: #fff; + width: 400px; + font-size: 24px; + display: block; + float: left; +} + +.front-logo-tagline-agingkp { + transform: translate(0%, 70%); +} + +.front-logo-tagline-kidneykp { + transform: translate(0%, 75%); +} + +.front-logo-tagline-autoimmunekp { + transform: translate(0%, 25%); +} + +.front-logo-tagline-ocularkp { + transform: translate(0%, 35%); +} + +.front-logo-tagline-reproductivekp { + transform: translate(0%, 35%); +} + +.front-logo-tagline-mdkp { + transform: translate(0%, 65%); +} + +.front-logo-tagline-t2dkp { + transform: translate(0%, 20%); +} + +.front-logo-tagline-skinkp { + transform: translate(0%, 80%); +} + +.front-logo-tagline-cvdkp { + transform: translate(0%, 29%); +} + +.front-logo-tagline-cdkp { + transform: translate(0%, 35%); +} + +.front-logo-tagline-sleepkp { + transform: translate(0%, 35%); +} + +.front-logo-tagline-v2fkp, +.front-logo-tagline-a2fkp { + transform: translate(0%, 85%); +} + +.front-logo-tagline-t1dkp { + transform: translate(0%, 20%); +} + +.front-logo-tagline-mskkp { + transform: translate(0%, 25%); +} + +.front-logo-tagline-lungkp { + transform: translate(0%, 85%); +} + +.front-logo-tagline-alskp { + transform: translate(0%, 20%); +} + +.front-logo-tagline-nephkp { + transform: translate(0%, 20%); +} + +.front-logo-tagline-ndkpkp { + transform: translate(0%, 25%); +} + +.front-logo-tagline-nagekp { + transform: translate(0%, 8%); +} + +.front-banner-ui-tabs { + width: 800px; + margin-left: auto; + margin-right: auto; + text-align: center; + margin-top: 70px; + border-bottom: solid 1px rgba(255, 255, 255, 1); + font-size: 45px; + padding-bottom: 15px; + color: #fff; +} + +.amp-banner-2021 { + height: 70px; + background-position-x: right; + background-position-y: top; + background-image: url(//kp4cd.org/sites/default/files/vueportal/amp_banner_bg.jpg); + border-bottom: solid 1px #acd; +} + +.amp-header { + height: 70px; + background-image: url(//kp4cd.org/sites/default/files/vueportal/amp_banner_middle.png); + background-size: 100% 70px; +} + +.amp-banner-right { + width: 100%; + height: 70px; + background-image: url(//kp4cd.org/sites/default/files/vueportal/amp_banner_right.png); + background-repeat: no-repeat; + background-position: right; +} + +.amp-banner-left { + height: 70px; + background-image: url(//kp4cd.org/sites/default/files/vueportal/amp_banner_left.png); + background-repeat: no-repeat; + background-position: left top; + padding: 15px 0 0 20px; +} + +.amp-banner-left a { + color: #fff !important; + font-size: 30px; + font-weight: 200; + letter-spacing: 0.01em; + text-decoration: none; +} + +.portals-2-mdkp-logo { + width: 500px; +} + +.agingkp-logo { + height: 50px; +} + +.kidneykp-logo { + height: 50px; +} + +.autoimmunekp-logo { + height: 50px; +} + +.ocularkp-logo { + height: 50px; +} + +.reproductivekp-logo { + height: 50px; +} + +.mdkp-logo { + height: 50px; +} + +.t2dkp-logo { + height: 50px; +} + +.skinkp-logo { + height: 50px; +} + +.cvdkp-logo { + height: 50px; +} + +.cdkp-logo { + height: 50px; +} + +.sleepkp-logo { + height: 50px; +} + +.v2fkp-logo, +.a2fkp-logo { + height: 50px; +} + +.t1dkp-logo { + height: 50px; +} + +.mskkp-logo { + height: 50px; +} + +.lungkp-logo { + height: 50px; +} + +.alskp-logo { + height: 50px; +} + +.nephkp-logo { + height: 50px; +} + +.ndkpkp-logo { + height: 50px; +} + +.nagekp-logo { + height: 50px; +} + +.registered-mark { + display: none; +} + +.mdkp-footer .registered-mark { + display: contents; +} + +.agingkp-header, +.agingkp-footer { + background-color: #75bee9; + height: 50px; +} + +.kidneykp-header, +.kidneykp-footer { + background-color: #96cbca; + height: 50px; +} + +.autoimmunekp-header, +.autoimmunekp-footer { + background-color: #71cddd; + height: 50px; +} + +.ocularkp-header, +.ocularkp-footer { + background-color: #008fd0; + height: 50px; +} + +.reproductivekp-header, +.reproductivekp-footer { + background-color: #8f7fbb; + height: 50px; +} + +.mdkp-header, +.mdkp-footer { + background-color: #0077b6; + height: 50px; +} + +.cvdkp-header, +.cvdkp-footer { + background-color: #f58752; + height: 50px; +} + +.sleepkp-header, +.sleepkp-footer { + background-color: #74b9e2; + height: 50px; +} + +.cdkp-header, +.cdkp-footer { + background-color: #73d253; + height: 50px; +} + +.t2dkp-header, +.t2dkp-footer { + background-color: #55aaee; + height: 50px; +} + +.skinkp-header, +.skinkp-footer { + background-color: #286fb7; + height: 50px; +} + +.v2fkp-header, +.v2fkp-footer, +.a2fkp-header, +.a2fkp-footer { + background-color: #f7835c; + height: 50px; +} + +.t1dkp-header, +.t1dkp-footer { + background-color: #5481c1; + height: 50px; +} + +.mskkp-header, +.mskkp-footer { + background-color: #bcafd6; + height: 50px; +} + +.lungkp-header, +.lungkp-footer { + background-color: #7accc8; + height: 50px; +} + +.alskp-header, +.alskp-footer { + background-color: #5eb9e9; + height: 50px; +} + +.nephkp-header, +.nephkp-footer { + background-color: #39bbed; + height: 50px; +} + +.ndkpkp-header, +.ndkpkp-footer { + background-color: #5698d2; + height: 50px; +} + +.nagekp-header, +.nagekp-footer { + background-color: #751dc7; + height: 50px; +} + +.kp-menu-wrapper { + text-align: right; +} + +.a2fkp-header>.a2fkp-logo-wrapper { + flex: 0 0 100%; + max-width: 100%; +} + +.a2fkp-header>.kp-menu-wrapper { + position: absolute; + right: 15px; +} + +.portal-menu-wrapper, +.login-menu-wrapper { + display: inline-block; +} + +.portal-menu-wrapper ul, +.login-menu-wrapper ul, +.portal-menu-wrapper, +.login-menu-wrapper { + list-style: none; + margin: 0; + padding: 0; +} + +.portal-menu-wrapper>ul>li, +.login-menu-wrapper>ul>li { + display: inline-block; + position: relative; + padding-top: 15px; +} + +.login-menu-wrapper>ul>li>a { + border-left: solid 1px #fff; +} + +.portal-menu-wrapper>ul>li>a, +.login-menu-wrapper>ul>li>a { + padding-left: 10px; + padding-right: 10px; + padding-top: 5px; + padding-bottom: 5px; + color: #fff !important; + font-size: 16px; + font-weight: 300; +} + +.portal-menu-wrapper .item+.item:before { + content: "" !important; +} + +.portal-menu-wrapper>ul>li>ul { + display: none; + position: absolute; + z-index: 100000; + padding: 0; + margin: 0; +} + +.portal-menu-wrapper>ul>li:hover>ul { + display: block; +} + +.portal-menu-wrapper>ul>li>ul>li { + width: 100%; + padding: 0 !important; + font-size: 0.8em; + background-color: rgba(100, 100, 100, 0.85); + text-align: left; + list-style: none; +} + +.portal-menu-wrapper>ul>li>ul>li:hover { + background-color: rgba(90, 90, 90, 1); +} + +.portal-menu-wrapper>ul>li>ul>li>a { + display: block; + width: 100%; + padding: 5px 15px 5px 15px; + border-bottom: solid 1px #666; + list-style: none; + white-space: nowrap; + color: #ffffff !important; + font-size: 16px; + font-weight: 300; +} + +.agingkp-footer, +.kidneykp-footer, +.autoimmunekp-footer, +.ocularkp-footer, +.reproductivekp-footer, +.mdkp-footer, +.cvdkp-footer, +.sleepkp-footer, +.t2dkp-footer, +.skinkp-footer, +.cdkp-footer, +.v2fkp-footer, +.a2fkp-footer, +.t1dkp-footer, +.mskkp-footer, +.lungkp-footer, +.alskp-footer, +.nephkp-footer, +.ndkpkp-footer, +.nagekp-footer { + text-align: center; + padding-top: 15px; + color: #fff; + font-weight: 300; + font-size: 14px; +} + +.agingkp-body, +.kidneykp-body, +.autoimmunekp-body, +.ocularkp-body, +.reproductivekp-body, +.mdkp-body, +.cvdkp-body, +.sleekp-body, +.t2dkp-body, +.skinkp-body, +.cdkp-body, +.v2fkp-body, +.a2fkp-body, +.t1dkp-body, +.mskkp-body, +.lungkp-body, +.alskp-body, +.nephkp-body, +.ndkpkp-body, +.nagekp-body { + background-color: #eee; + min-height: 400px; + padding-top: 10px; + padding-bottom: 10px; +} + +.agingkp-card, +.kidneykp-card, +.autoimmunekp-card, +.ocularkp-card, +.reproductivekp-card, +.mdkp-card, +.cvdkp-card, +.sleepkp-card, +.t2dkp-card, +.skinkp-card, +.cdkp-card, +.v2fkp-card, +.a2fkp-card, +.t1dkp-card, +.mskkp-card, +.lungkp-card, +.alskp-card, +.nephkp-card, +.ndkpkp-card, +.nagekp-card { + margin-top: 10px; + margin-bottom: 10px; + min-width: 1024px !important; +} + +.card.gem-wrapper { + box-shadow: inset 0 0 5px #00000050; + border: solid 1px #9cf; +} + +.portal-front-tabs { + margin-top: 50px; +} + +.portal-front-tabs .nav-tabs .nav-link, +.portal-front-tabs .nav-tabs .nav-link.active, +.portal-front-tabs .nav-tabs .nav-item.show .nav-link { + color: rgba(255, 255, 255, 0.75) !important; + font-size: 25px; + background: none; + border-color: rgba(255, 255, 255, 0.5); + border-radius: 0; + border-top: none; + margin-right: -1px; +} + +.portal-front-tabs .nav-tabs .nav-link.active { + color: rgba(255, 255, 255, 1) !important; + background-image: linear-gradient(rgba(255, 255, 255, 0), + rgba(255, 255, 255, 0), + rgba(255, 255, 255, 0), + rgba(255, 255, 255, 0.5)); +} + +.portal-front-tabs .tab-content { + padding-top: 20px; + padding-bottom: 20px; +} + +.portal-front-tabs .tab-content .v-select { + width: 50%; + margin: auto; +} + +.portal-front-tabs .tab-content .vs__clear { + width: 20px; +} + +.portal-front-tabs .tab-content .vs__open-indicator { + height: 10px; +} + +.portal-front-tabs .tab-content .vs__dropdown-toggle { + background-color: rgba(255, 255, 255, 0.75); + border-color: #fff; + height: 50px; +} + +.portal-front-tabs .tab-content .disease-group-select { + width: 50%; + margin: auto; +} + +.portal-front-tabs .tab-content .disease-group-select select { + height: 50px; + width: 100%; + font-size: 16px; + background-color: rgba(255, 255, 255, 0.75); + border-color: #fff; +} + +/* front page datasets info graphs */ + +.front-datasets-graph, +.front-phenotypes-graph { + width: 50%; + padding: 0px 10px 20px 10px; + display: inline-block; + position: relative; +} + +.front-datasets-graph .each-item, +.front-phenotypes-graph .each-item { + font-size: 16px; + position: relative; + width: 100%; + height: 30px; + margin-bottom: 3px; +} + +.front-datasets-graph .percent-bg, +.front-phenotypes-graph .percent-bg { + position: absolute; + left: 0; + top: 0; + background-color: #ccc; + border-radius: 30px; + width: 0%; + transition: width 2s; + height: 30px; +} + +.front-datasets-graph .percent-bg { + background-color: rgba(0, 185, 242, 0.5); +} + +.front-phenotypes-graph .percent-bg { + background-color: rgba(128, 194, 66, 0.5); +} + +.front-datasets-graph .info-label, +.front-phenotypes-graph .info-label { + position: absolute; + left: 10px; + top: 5px; + font-size: 14px; +} + +.header-disease-group-select-wrapper { + display: inline-block; + border-left: solid 1px #ddd; + margin-left: 10px; + padding-left: 10px; + padding-top: 5px; + padding-bottom: 5px; +} + +.header-disease-group-select-wrapper select { + color: #fff; + background: none; + border: none; +} + +.gene-page-header .card-body { + padding: 0px 15px !important; +} + +.gene-page-header-title { + font-size: 12px; + padding: 2px 0 2px 5px; + border-bottom: solid 1px #eee; + border-left: solid 1px #eee; +} + +a.edit-btn { + position: absolute; + top: 0; + right: 0; + background-color: #ddd; + color: #fff; + font-size: 12px; + padding: 2px 5px; + z-index: 15; +} + +a.edit-btn:hover { + cursor: pointer; +} + +.gene-page-header-search-holder { + position: absolute; + top: 0; + left: 0; + /*height: 65px;*/ + width: 100%; + background-color: #fff; + font-size: 16px; + z-index: 10; +} + +.shorten-when-full { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.gene-page-header-body { + /*height: 65px;*/ + font-size: 25px; + padding: 12px 0 12px 5px; + border-left: solid 1px #eee; +} + +.gene-page-header-search-holder {} + +div.filtering-tools { + border: solid 1px #ddd; + border-radius: 5px; + background-color: #efefef; + text-align: center; + margin-bottom: 40px; + padding-top: 8px; +} + +div.filtering-tools table td, +div.filtering-tools table th { + padding-right: 10px; + padding-left: 10px; + border-right: solid 1px #fff; +} + +.table-filter label { + display: block; + max-width: 100%; + margin-bottom: 20px; + font-weight: 700; +} + +.phenotype-btn { + position: relative; +} + +.phenotype-btn.mr-1 { + margin-right: 10px !important; +} + +.phenotype-btn>span.remove { + font-family: "Roboto"; + font-size: 1.2em; + position: absolute; + background-color: #ccc; + color: #000; + font-size: 12px; + font-weight: 800; + width: 18px; + height: 18px; + border-radius: 10px; + padding: 2px; + padding-top: 1px; + top: -5px; + right: -5px; + text-align: center; +} + +.phenotype-btn:hover>span.remove { + background-color: #000; + color: #fff; +} + +#phenotypeSearchHolder input.form-control, +#datasetSearchHolder input.form-control { + border-radius: 0; + border: solid 1px #ddd; + height: 65px; + width: 100%; + font-size: 20px; + background-image: url("/images/searchicon.png"); + background-position: 10px 20px; + background-repeat: no-repeat; + padding-left: 40px; +} + +.search-header { + margin-top: -10px; + border-top-left-radius: 0 !important; + border-top-right-radius: 0 !important; + background-color: #bbbbbb !important; + font-size: 14px !important; + padding: 1px !important; + color: #333333; + font-weight: 300 !important; + border: none !important; + position: relative; + z-index: 10; +} + +.search-header.fixed-header { + position: fixed; + top: 8px; + width: calc(100% - 30px); + background-color: #bbbbbb; + left: 15px; +} + +.search-header .row { + padding: 0 1.25rem; +} + +.search-header div[class^="col-md-"] { + padding: 0; +} + +.search-header .input-wrapper input[type="text"] { + border: none; + border-radius: 0; + border-right: solid 1px #ddd; + display: inline-block; +} + +.reset-page-parameters { + position: relative; + display: block; + width: 250px; + margin-left: auto; + margin-right: auto; + margin-bottom: -25px; + padding: 5px 15px; + background-color: #bbbbbb; + border-bottom-left-radius: 5px !important; + border-bottom-right-radius: 5px !important; + font-weight: 400; +} + +.reset-page-parameters:hover { + cursor: pointer; +} + +#regionSearchHolder .region-search { + height: 100%; +} + +.region-search>.input-wrapper { + display: inline-block !important; +} + +.region-search-examples { + text-align: center; + color: #fff; + margin-top: 10px; +} + +.region-search-examples a { + color: #fff !important; +} + +#regionSearchHolder .input-wrapper { + display: inline-block; + min-height: 100%; + position: relative; + padding: 0; + margin: 0; +} + +#regionSearchHolder .input-wrapper span.gene-search-or { + position: absolute; + display: block; + background-color: #ccc; + width: 30px; + height: 30px; + color: #fff; + border-radius: 20px; + padding-top: 3px; + margin: auto; + position: absolute; + text-align: center; + top: 25%; +} + +#regionSearchHolder .input-default, +#variantSearchHolder .input-default, +#regionSearchHolder .input-group, +#variantSearchHolder .input-group, +#regionSearchHolder input.form-control, +#variantSearchHolder input.form-control { + height: 100%; + width: 100%; + border: 0; + position: absolute; + top: 0; + left: 0; + border-left: solid 1px #ddd; + border-radius: 0; + font-size: 20px; +} + +#regionSearchHolder .vbt-autcomplete-list, +#variantSearchHolder .vbt-autcomplete-list { + top: 95% !important; + height: auto !important; +} + +#variantSearchHolder div { + height: 100%; + display: inline-block; + vertical-align: top; +} + +#variantSearchHolder div.search-example, +div.search-example { + font-size: 14px; + padding-top: 8px; +} + +#regionSearchHolder #regionSearchGo, +#variantSearchHolder #variantSearchGo { + position: absolute; + padding: 0; + top: 13px; + right: calc(50% - 20px); + height: 40px; + width: 40px; + border-radius: 30px; + background-color: #0097d6; + border: solid 1px #0097d6; + text-align: center; +} + +.front-gene-search-wrapper, +.front-dataset-search-wrapper, +.front-phenotype-search-wrapper { + width: 50%; + margin: auto; +} + +.front-gene-search-wrapper .input-wrapper { + display: inline-block; + padding: 0; +} + +.front-gene-search-wrapper .input-wrapper .input-default, +.front-phenotype-search-wrapper input { + height: 50px; + background-color: rgba(255, 255, 255, 0.75); + border-color: #fff; + width: 100%; +} + +.front-gene-search-wrapper #regionSearchGo { + padding: 0; + height: 50px; + width: 50px; + border-radius: 30px; + background-color: rgba(255, 255, 255, 0.75); + border: solid 1px rgba(255, 255, 255, 1); + text-align: center; + color: #666; + margin-left: 10px; +} + +.gene-with-signal { + display: inline-block; + margin: 0px 10px 10px 0; + padding: 2px 20px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + font-size: 13px; + color: #007bff; +} + +.gene-with-signal>a { + text-decoration: none; +} + +.gene-with-signal.protein_coding { + cursor: pointer; + background-color: #a0d7ff; + border: solid 1px #30b7f6; +} + +.gene-with-signal.antisense { + cursor: pointer; + background-color: #b7eab7; + border: solid 1px #72ce49; +} + +.gene-with-signal.none { + background-color: #eee; + border: solid 1px #ccc; +} + +.phenotype-with-signal.high { + background-color: #a0d7ff; + border: solid 1px #30b7f6; +} + +.phenotype-with-signal.moderate { + /*background-color: #d0efff; + border: solid 1px #30b7f6;*/ + background-color: #ffffb3; + border: solid 1px #ffcc44; +} + +.phenotype-with-signal.none { + background-color: #eee; + border: solid 1px #ccc; +} + +.phenotype-with-signal.none.hidden { + display: none; +} + +.variant-table-row.high { + background-color: #d0efff; +} + +.variant-table-cell.high { + background-color: #d0efff; +} + +.c3 .c3-axis-x path, +.c3 .c3-axis-x line { + fill: none; + stroke: #000; + stroke-width: 0.5px; +} + +.c3 .c3-axis-x .c3-axis-x-label, +.c3 .c3-axis-y .c3-axis-y-label { + font-size: 12px; +} + +.c3 .c3-axis-y path, +.c3 .c3-axis-y line { + fill: none; + stroke: #000; + stroke-width: 0.5px; +} + +.static-content-section { + padding-top: 50px; +} + +.under-datasets-section-wrapper { + margin-top: 40px; + padding-top: 20px; + padding-bottom: 20px; +} + +.under-datasets-section-wrapper h4.header { + font-weight: 400; + font-size: 35px; + font-family: "Oswald"; + margin: 2px 0 0 10px; + padding: 0px 5px 2px 5px; + border: solid 1px #ddd; + border-right: none; + border-left: none; +} + +.under-datasets-section-wrapper ul { + list-style: none; + padding: 0; + margin-top: 20px; +} + +.under-datasets-section-wrapper ul li { + display: block; + clear: both; + font-family: Oswald; + font-size: 30px; + line-height: 25px; + margin-bottom: 30px; +} + +.under-datasets-section-wrapper ul li img { + display: block; + float: left; + margin-right: 15px; + width: 80px; + height: 80px; + margin-top: -15px; +} + +.under-datasets-section-wrapper ul li a { + font-size: 20px; + font-family: "Roboto", Arial, sans-serif; + font-weight: 500; +} + +#news-feed { + position: relative; + height: 140px; + margin-bottom: 30px; +} + +#news-feed ul.news-items { + list-style: none; + padding: 0; + margin: 0; +} + +#news-feed ul.news-items li { + padding: 0; + margin: 0; + display: none; +} + +#news-feed ul.news-items li:first-child { + display: block; +} + +#news-feed ul.news-items li span p { + display: contents; +} + +#news-feed .news-items-ui { + position: absolute; + top: 10px; + right: 0; +} + +#news-feed .news-items-ui a { + display: inline-block; + width: 16px; + height: 16px; + border-radius: 8px; + background-color: #aaa; + color: #fff !important; + font-size: 10px; + margin-left: 7px; + font-size: 12px; + text-align: center; +} + +#news-feed .news-items-ui a.on-view { + background-color: #0097d6; +} + +path.slice { + stroke-width: 2px; +} + +polyline { + opacity: 0.3; + stroke: black; + stroke-width: 2px; + fill: none; +} + +.slice-value { + font-family: "Oswald"; + font-size: 30px; +} + +.slice-label { + font-size: 12px; +} + +.p-bellow-section-header { + font-size: 16px; + margin-bottom: 20px; +} + +.popped-out { + position: fixed; + z-index: 100; + top: 2%; + width: 96%; + left: 2%; + height: 96% !important; + max-height: 96% !important; +} + +.pop-out-icon { + display: block; + background-image: url(pop_out.svg); + width: 20px; + height: 20px; + background-position: center; + background-repeat: no-repeat; + float: right; + margin-top: -10px; + margin-right: -10px; +} + +.pop-out-icon:hover { + background-image: url(pop_out_over.svg); +} + +.hidden, +.row.hidden { + display: none; +} + +.front-page-body { + background-color: #fff !important; +} + +.pagination.b-pagination { + border: solid 1px #dddddd; + border-radius: 25px; + padding: 3px 10px; + font-size: 15px; + /* width: fit-content;*/ + margin: auto; + width: intrinsic; + /* Safari/WebKit uses a non-standard name */ + width: -moz-max-content; + /* Firefox/Gecko */ + width: -webkit-max-content; + /* Chrome */ +} + +.pagination.b-pagination .page-item { + display: inline-block; +} + +.pagination.b-pagination .page-link { + border: solid 1px #fff !important; + border-radius: 20px; + min-width: 31px; + height: 31px; +} + +.pagination.b-pagination .page-item:last-child .page-link, +.pagination.b-pagination .page-item:first-child .page-link { + border-radius: 20px; +} + +.alternative-names span::after { + content: ", "; +} + +.alternative-names span:last-child::after { + content: ""; +} + +.dataset-page-header .card-body h2 { + margin: 0 !important; +} + +/* Filtering UI */ +div.filtering-ui-wrapper { + border: solid 1px #ddd; + border-radius: 5px; + background-color: #efefef; + text-align: center; + margin-bottom: 10px; + padding: 3px 0; + position: relative; +} + +div.filtering-ui-wrapper.add-content { + background-color: #ddefff; + border: 1px solid #bbdfff; +} + +div.filtering-ui-wrapper .filter-by-label { + font-size: 14px; + font-weight: 600; +} + +div.filtering-ui-wrapper .list-group { + text-align: left; +} + +div.selected-filters-ui-wrapper { + margin-bottom: 30px; + text-align: center; + font-size: 14px; + font-weight: 400; + min-height: 1px; +} + +div.selected-filters-ui-wrapper .badge-pill { + font-size: 12px; + font-weight: 400; + margin: 0 3px; +} + +div.filtering-ui-content { + width: auto !important; + display: block; +} + +div.filtering-ui-content .divider.col { + width: 1px !important; + height: 61px; + padding: 0 1px 0 0; + background-color: #aaa; + margin-bottom: -17px; + margin-left: 8px; + margin-right: 8px; +} + +div.filtering-ui-content .divider.col .or-text { + display: block; + position: absolute; + left: -8px; + top: 35%; + font-size: 10px; + background-color: #aaa; + color: #fff; + padding: 2px 2px 1px 2px; + border-radius: 14px; +} + +#pageSearchParameters .divider.col { + width: 1px !important; + height: 61px; + padding: 0 1px 0 0; + background-color: #fff; + margin-bottom: -17px; + margin-left: 8px; + margin-right: 8px; +} + +#pageSearchParameters .divider.col .or-text { + display: block; + position: absolute; + left: -6px; + top: 35%; + font-size: 10px; + background-color: #666; + color: #fff; + padding: 2px 2px 1px 2px; + border-radius: 14px; + width: 18px; + font-weight: 500; + height: 18px; +} + +#pageSearchParameters .btn.go { + border: 1px solid #ced4da; + border-radius: 0.25em; + height: 30px; + margin-top: -2px !important; +} + +div.filtering-ui-content div.col { + display: inline-block !important; + width: auto !important; + font-size: 14px; + padding: 5px 7px; +} + +div.filtering-ui-content div.col.hidden-search { + display: none !important; +} + +div.filtering-ui-content div.col .label { + font-weight: 600; +} + +span div.label { + font-size: 14px; + font-weight: 600; +} + +div.filtering-ui-content div.col .form-control, +div.filtering-ui-content div.col select, +div.filtering-ui-content div.col input { + height: 30px; + width: 175px; + font-size: 14px; +} + +div.filtering-ui-content div.col input.or-half-gt, +div.filtering-ui-content div.col input.or-half-lt { + width: 70px; +} + +div.filtering-ui-content div.col.filter-col-md .form-control, +div.filtering-ui-content div.col.filter-col-md select, +div.filtering-ui-content div.col.filter-col-md input { + width: 220px; + display: inline-block; +} + +div.filtering-ui-content div.col.filter-col-lg .form-control, +div.filtering-ui-content div.col.filter-col-lg select, +div.filtering-ui-content div.col.filter-col-lg input { + width: 300px !important; + display: inline-block; +} + +div.filtering-ui-content div.filter-col-sm .form-control, +div.filtering-ui-content div.col.filter-col-sm select, +div.filtering-ui-content div.col.filter-col-sm input { + width: 110px !important; + display: inline-block; +} + +.help-content.filter-wrapper-help { + display: block !important; + position: absolute; + top: 2px; + left: 5px; +} + +.help-content.filter-wrapper-help .help-content-caller.hover { + padding: 0.075em 0.525em 0.075em 0.525em !important; +} + +.btn.btn-sm.btn-2-vptz { + height: 30px; + font-size: 12px; + margin-top: -1px; + background-color: #a0d7ff; + border: solid 1px #30b7f6; + color: #0087c6 !important; +} + +.btn.btn-sm.btn-2-vptz:hover { + background-color: #30b7f6; + border: solid 1px #30b7f6; + color: #fff !important; +} + +/* IGV */ +.igv-zooms-wrapper { + position: relative; + z-index: 1000000; + float: right; + margin-right: 50px; + margin-bottom: 8px; + font-size: 14px; +} + +.igv-zoom { + width: 28px; + height: 28px; + background-color: #30b7f6; + border: solid 1px #0087d6; + border-radius: 15px; + color: #fff; +} + +/* style for new features page */ +.news-content-wrapper, +.resource-content-wrapper { + background-color: #eee; + padding: 15px; + border: solid 1px #ccc; + border-radius: 0.25em; +} + +.new-feature-item-wrapper, +.resource-item-wrapper { + margin: 15px 0; + padding-bottom: 10px; + border-bottom: solid 1px #ddd; +} + +.new-feature-item-wrapper h3, +.resource-item-wrapper h3 { + font-size: 22px; +} + +.resources-iframe-wrapper { + width: 560px; + height: 315px; + margin: 0 auto; +} + +.egl-research-method-wrapper { + display: block; + border-bottom: solid 1px #ccc; + padding-bottom: 35px; + padding: 35px 35px 0 35px !important; +} + +.egl-research-trait-bubbles { + list-style: none; +} + +.egl-research-trait-bubbles li { + display: inline-block; + margin-right: 5px; + margin-bottom: 7px; +} + +.egl-research-trait-bubbles-multi li { + font-size: 20px; + margin-bottom: 10px; +} + +.egl-research-trait-bubbles li a, +.egl-research-trait-bubbles-multi li a { + display: block; + background-color: #0097d6; + color: #fff !important; + padding: 5px 10px; + height: 34px; + border-radius: 5px; + display: inline-block; + font-size: 16px; +} + +.egl-research-trait-bubbles li a:hover, +.egl-research-trait-bubbles-multi li a:hover { + background-color: #0097d675; +} + +.egl-research-trait-bubbles li a::after, +.egl-research-trait-bubbles-multi li a::after { + content: ""; +} + +.egl-research-trait-bubbles li a:hover::after, +.egl-research-trait-bubbles-multi li a:hover::after { + content: " GO >"; + font-size: 0.75em; +} + +.egl-table-ss { + width: 350px; + border: solid 1px #ccc; + float: right; +} + +.viewing-region { + float: left; + margin-right: 20px; +} + +.expand-region-select { + background-color: #66bbff !important; + border: solid 1px #3399ff !important; + color: #fff; + font-size: 20px; + border-radius: 5px; + padding: 5px; + float: left; +} + +.expand-region-select:hover { + background-color: #66bbff75 !important; +} + +.temporary-card { + background-color: #66bbff30 !important; + border: solid 1px #3399ff30 !important; + padding-bottom: 0.25em !important; +} + +a.to-previous-page { + color: #fff !important; + font-size: 14px; + background-color: #00aaff75; + border: solid 1px #00aaff95; + padding: 1px 10px; +} + +a.to-previous-page:hover { + background-color: #00aaff95; +} + +.dev-flag { + position: fixed; + top: 0; + right: 0; + z-index: 20000; + width: 50px; + height: 50px; +} + +.img .alert, +.no-access .alert { + border-style: dashed; + border-width: 1px; + text-align: center; +} + +.img .alert-warning, +.no-access .alert-warning { + border-color: darkorange; +} + +.img .alert-danger, +.no-access .alert-danger { + border-color: darkred; +} + +/* pheWAS dataset association table */ +#phewas-datasets { + border-right: none; + margin-top: 1rem; +} + +#phewas-datasets div { + border-left: none; + border-right: none; +} + +#phewas-datasets .top-level-value-item:first-child { + text-align: left; +} + +#phewas-datasets .top-level-header, +#phewas-datasets .top-level-value { + font-size: 1rem; +} + +#phewas-datasets .top-level-value:hover { + background-color: #efefef; +} + +#phewas-datasets .list { + margin-bottom: 1rem; +} + +#phewas-datasets .feature-content-wrapper { + border-left: 4px solid #6c757d78; +} + +#phewas-datasets .feature-header-item { + background-color: #d2d2d2; +} + +.phenotype-gene-association { + position: relative; +} + +.phenotype-gene-association>.options-4-actions { + display: none; + position: absolute; + background-color: #000000; + color: #fff; + font-weight: 400; + padding: 10px; + border-radius: 5px; + left: -12px; + top: 10px; + z-index: 20; + white-space: nowrap; + line-height: 1.5em; +} + +.phenotype-gene-association>.options-4-actions { + left: 80%; + top: -30%; +} + +.phenotype-gene-association:hover>.options-4-actions { + display: block; +} + +.phenotype-gene-association:hover>.options-4-actions a { + color: #ffffff !important; +} + +.phenotype-gene-association:hover>.options-4-actions a:hover { + color: #aaaaff !important; +} + +/* for vue-bootstrap-typeahead */ +[type="search"] { + background: #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px; +} + +[class*="filter-pill-"] { + margin-right: 2px; + margin-left: 2px; +} + +/* !important is required to override the default pill styling from Bootstrap */ +.filter-pill-pValue { + background-color: #dc3545 !important; +} + +.filter-pill-fold { + background-color: #dc3545 !important; +} + +.filter-pill-beta { + background-color: #007bff !important; +} + +.filter-pill-nearest { + background-color: #28a745 !important; +} + +.filter-pill-phenotype { + background-color: #28a745 !important; +} + +.filter-pill-condition { + background-color: #28a745 !important; +} + +.filter-pill-secondaryPhenotype { + background-color: #007bff !important; +} + +.filter-pill-primaryphenotype { + background-color: #28a745 !important; +} + +.filter-pill-secondaryphenotype { + background-color: #007bff !important; +} + +.filter-pill-nearest { + background-color: #28a745 !important; +} + +.filter-pill-gene { + background-color: #28a745 !important; +} + +.filter-pill-geneHuge { + background-color: #52a866 !important; +} + +.filter-pill-phenotypeHuge { + background-color: #b2c060 !important; +} + +.filter-pill-consequence { + background-color: #28a745 !important; +} + +.filter-pill-annotation { + background-color: hsl(211deg 100% 50% / 80%) !important; +} + +.filter-pill-source { + background-color: #28a745 !important; +} + +.filter-pill-moleculeType { + background-color: #28a745 !important; +} + +.filter-pill-tech { + background-color: #28a745 !important; +} + +.filter-pill-method { + background-color: #28a745 !important; +} + +.filter-pill-tissue { + background-color: rgb(231 31 175 / 74%) !important; +} + +.filter-pill-ancestry { + background-color: #28a745 !important; +} + +.filter-pill-collection { + margin: 10px 0 10px 0; +} + +.filter-pill-collection.center { + display: flex; + justify-content: center; + align-items: center; +} + +/* HuGe Calculator specific */ +#huge .filter-pill-gene { + background-color: #ff8c00 !important; +} + +#huge .filter-pill-phenotype { + background-color: #9de21c !important; +} + +/* GAIT specific */ +#gait .accordion .card.mb-1 { + overflow: unset; +} + +#gait .accordion .btn-block { + text-align: left; + position: relative; +} + +#gait .accordion .btn-block.btn-outline-primary { + border-color: transparent; +} + +#gait .accordion .criteria { + position: absolute; + right: 0.75rem; + top: unset; +} + +#gait .criteria { + display: inline; + overflow: visible; +} + +#gait .accordion .alert, +#variant-search .alert { + text-align: center; +} + +#gait .reference>span { + color: white; +} + +#gait .function { + text-align: center; + margin: 20px auto; +} + +#gait .filter-tests.card { + border-style: dashed; +} + +#gait .filter-tests>.card-header { + background-color: #cce5ff; + color: #004085; +} + +#gait .filter-pill-dataset { + background-color: #8a2be2 !important; +} + +#gait .filter-pill-gene, +#gait .filter-pill-geneORregion { + background-color: #ff8c00 !important; +} + +#gait .filter-pill-test { + background-color: #dc3545 !important; +} + +#gait .filter-pill-transcript { + background-color: #3e78ff !important; +} + +#gait .form-group { + margin-bottom: auto; +} + +#gait .alert-info, +#variant-search .alert-info, +#dataset_inspector .alert-info { + padding: 0.1rem 1.25rem; +} + +#gait .b-table-details { + background-color: unset; +} + +#gait .b-table-details td { + padding: 0; +} + +#gait .variants { + margin-top: 2rem; +} + +button.btn.btn-mini { + padding: 0.1rem 0.25rem; + font-size: 0.75rem; + line-height: 1.25rem; +} + +#gait .forest-plot-simple { + position: relative; + padding-top: 20px; + padding-bottom: 10px; + overflow-x: hidden; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + line-height: 2rem; + border-left: 4px solid #ddd; + color: #aaa; + margin-left: 15px; +} + +#gait .forest-plot-html-row { + margin-top: 10px auto; +} + +#gait .forest-plot-html-row:hover { + background-color: unset; +} + +#gait .beta-box { + background-color: #55aaee; +} + +#gait .plot { + overflow: hidden; +} + +.fade-enter-active, +.fade-leave-active { + transition: opacity 1s; +} + +.fade-enter, +.fade-leave-to + +/* .fade-leave-active below version 2.1.8 */ + { + opacity: 0; +} + +/* for volcano plot. Move it to it's own CSS when there's too much */ +#volcanoPlot { + display: block; + margin-left: auto; + margin-right: auto; +} + +.volcano-plot-label { + text-align: center; + font-size: 16px; + font-weight: bold; +} + +.volcano-plot-legend { + text-align: center; + font-size: 14px; +} + +span.volcano-score-0, +span.volcano-score-1, +span.volcano-score-2 { + width: 12px; + height: 12px; + display: inline-block; + background-color: #00000050; + border-radius: 6px; + vertical-align: middle; + margin-left: 10px; +} + +span.volcano-score-1 { + background-color: #09910980; +} + +span.volcano-score-2 { + background-color: #ff003780; +} + +#clicked_dot_value, +#ld_clicked_dot_value, +#clicked_cell_value { + position: absolute; + background-color: #fff; + border: solid 1px #aaa; + box-shadow: 0 0 5px #00000075; + font-size: 12px; + padding: 0px 10px 5px 10px; + max-width: 300px; + border-radius: 5px; + z-index: 10; + width: auto; +} + +.gene-on-clicked-dot { + /* + background-color: #ddd; + border: solid 1px #aaa; + padding: 2px 6px; + border-radius: 3px; + */ + + display: inline-block; + margin-right: 10px; + margin-top: 3px; +} + +.top-associations-section-phenotype-filter { + margin-bottom: 35px; + display: block; +} + +.top-associations-section-phenotype-filter>div { + background-color: #ddefff; + border: solid 1px #bbdfff; + border-radius: 5px; + height: 58px; +} + +.top-associations-section-phenotype-filter div.filtering-ui-wrapper { + border: none !important; + background: none !important; + width: 50% !important; + display: inline-block; + text-align: left; + padding-left: 30px; + padding-bottom: 20px; + padding-top: 10px; +} + +.top-associations-section-phenotype-filter span.filter-pill-collection { + border: none !important; + background: none !important; + width: 50% !important; + display: inline-block; + text-align: right; + padding-right: 10px; +} + +.top-associations-section-phenotype-filter div.filter-col-md>div { + display: inline-block; + margin-right: 10px; +} + +.kp-lab-icon { + width: 75px; + float: left; + margin-right: 10px; +} + +.svg-wrapper, +.tab-content-wrapper, +.plot-tab-content-wrapper { + visibility: visible; + height: auto; +} + +.svg-wrapper.hidden-svg, +.tab-content-wrapper.hidden-content, +.plot-tab-content-wrapper.hidden-content, +.tab-content-wrapper.hidden-content .plot-tab-content-wrapper { + visibility: hidden; + height: 25px; +} + +.hidden-svg .plot-tab-content-wrapper { + visibility: hidden; + height: 1; +} + +.kp-tabs-wrapper { + margin-bottom: -1px; + padding-left: 20px; +} + +.kp-tabs { + z-index: 1; + margin: 0 !important; + padding: 0 !important; + white-space: nowrap; + margin-left: 40px; +} + +.kp-tabs li { + display: inline-block; + background-color: #eee; + border: solid 1px #ddd; + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} + +.kp-tabs li.active { + border-bottom: solid 1px #fff; + background-color: #fff; +} + +.kp-tabs li>a { + display: block; + padding: 10px 15px 5px 15px; + cursor: pointer; +} + +.kp-tabs-contents { + /*margin: auto;*/ + background-color: #fff; + padding: 1.25em; + border-radius: 5px; + border: solid 1px #ddd; +} + +.kp-tabs-contents.not-active { + background: none; + padding: 1.25em; + border: none; +} + +.kp-tab-content { + visibility: hidden; + height: 0px !important; + margin: 0 !important; +} + +.kp-tab-content .svg-wrapper { + visibility: hidden; + height: 0px !important; + margin: 0 !important; +} + +.kp-tab-content.active { + visibility: visible; + height: auto !important; +} + +.kp-tab-content.active .svg-wrapper { + visibility: visible !important; + height: auto !important; +} + +.kp-tab-content.active .svg-wrapper.hidden-svg { + visibility: hidden !important; + height: 25px !important; +} + +span[class^="spacer-"], +span[class^=" spacer-"] { + display: inline-block; +} + +span.spacer-1 { + width: 1em; +} + +span.spacer-2 { + width: 2em; +} + +span.spacer-3 { + width: 3em; +} + +span.spacer-4 { + width: 4em; +} + +span.spacer-5 { + width: 5em; +} + +.reference-area { + border-left: solid 1px #ddd; + height: 100%; + padding-top: 15px; + padding-bottom: 15px; +} + +/* for tool tip UI. */ + +.tip-wrapper { + vertical-align: -13px; + margin-left: 5px; + position: relative; +} + +.tip-wrapper>.tip-content { + display: none; + position: absolute; + width: auto; + z-index: 10; + top: 0; + left: 18px; + min-width: 300px; + background-color: #000000; + color: #ffffff; + padding: 5px 10px; + border-radius: 3px; + font-size: 13px; +} + +.tip-wrapper:hover>.tip-content { + display: block; +} + +.tip-bigger { + font-size: 1.25em; +} + +.warning { + color: #ff0000; +} + +.all_biosamples { + font-weight: bold; +} + +.download-images-setting { + position: absolute; + top: -10px; + right: 5px; +} + +.download-images-setting .options-gear { + color: #333333; + padding: 3px 10px; + border-radius: 15px; + font-size: 12px; + margin-right: 10px; + border: solid 1px #dddddd; +} + +.download-images-setting .options-gear>svg { + font-size: 12px !important; +} + +.download-images-setting:hover .options-gear { + color: #000000; +} + +.download-images-setting ul.options { + display: none; + position: absolute; + background-color: #ffffff; + padding: 15px; + border: solid 1px #dddddd; + border-radius: 5px; + z-index: 10; + list-style: none; + right: 0; + box-shadow: 0px 5px 5px 5px rgb(0 0 0 / 20%) +} + +.download-images-setting ul.options li { + white-space: nowrap; +} + +.download-images-setting ul.options li label { + padding-left: 5px; +} + +.download-images-setting:hover ul.options { + display: block; +} + +.greater-less-filter select { + /* This can't be done at component level due to scope concerns.*/ + display: inline; + width: inherit; + margin-right: -5px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + height: 30px; +} + +.greater-less-filter input { + height: 30px; + margin-left: -5px; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} + +.greater-less-filter .label { + margin-left: -30px !important; +} + +/* single search on gene, region, phenotype, variant pages */ + +.search-header-content .byor-single-search { + width: 400px !important; +} + +.search-header-content .byor-single-search-wrapper .reset-search { + top: 24px !important; +} + +/* BYOR stuff */ + +/* Associations table color coding - can't do scoped because it is within table template*/ +.assoc-table-bottom-line td.meta { + width: 10px; +} + +.assoc-table-bottom-line td.bottom-line-only { + background-color: #6dcff6; +} + +.assoc-table-bottom-line td.bottom-line-min-p { + background-color: #8781bd; +} + +.assoc-table-bottom-line td.all-meta-types { + background-color: #b6aaa7; +} + +.alert-pop-up { + position: fixed; + z-index: 200; + width: 400px; + top: 50%; + left: calc(50% - 200px); + background-color: #ffefef; + padding: 15px 30px; + border: solid 1px #ff8888; + border-radius: 5px; + font-size: 1.15em; + box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px; +} \ No newline at end of file diff --git a/src/portals/MousePortal/assets/mouseportal.css b/src/portals/MousePortal/assets/mouseportal.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/portals/MousePortal/assets/placeholder_mouselogo.png b/src/portals/MousePortal/assets/placeholder_mouselogo.png new file mode 100644 index 000000000..a793119a5 Binary files /dev/null and b/src/portals/MousePortal/assets/placeholder_mouselogo.png differ diff --git a/src/portals/MousePortal/assets/pop_out.svg b/src/portals/MousePortal/assets/pop_out.svg new file mode 100644 index 000000000..839a12856 --- /dev/null +++ b/src/portals/MousePortal/assets/pop_out.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/portals/MousePortal/assets/pop_out_over.svg b/src/portals/MousePortal/assets/pop_out_over.svg new file mode 100644 index 000000000..2a6dc93a8 --- /dev/null +++ b/src/portals/MousePortal/assets/pop_out_over.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/portals/MousePortal/components/MouseSingleSearch.vue b/src/portals/MousePortal/components/MouseSingleSearch.vue new file mode 100644 index 000000000..156be8383 --- /dev/null +++ b/src/portals/MousePortal/components/MouseSingleSearch.vue @@ -0,0 +1,442 @@ + + + + + diff --git a/src/portals/MousePortal/components/mouse-footer.vue b/src/portals/MousePortal/components/mouse-footer.vue new file mode 100644 index 000000000..9d4c25f80 --- /dev/null +++ b/src/portals/MousePortal/components/mouse-footer.vue @@ -0,0 +1,27 @@ + + + \ No newline at end of file diff --git a/src/portals/MousePortal/components/mouse-header.vue b/src/portals/MousePortal/components/mouse-header.vue new file mode 100644 index 000000000..274148fc9 --- /dev/null +++ b/src/portals/MousePortal/components/mouse-header.vue @@ -0,0 +1,44 @@ + + + \ No newline at end of file diff --git a/src/portals/MousePortal/index.html b/src/portals/MousePortal/index.html new file mode 100644 index 000000000..2e0f4a582 --- /dev/null +++ b/src/portals/MousePortal/index.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + <%= htmlWebpackPlugin.options.title %> | PanKBase + + + + + +
+ + + + diff --git a/src/portals/MousePortal/mixins/mouseMixin.js b/src/portals/MousePortal/mixins/mouseMixin.js new file mode 100644 index 000000000..253f6ad26 --- /dev/null +++ b/src/portals/MousePortal/mixins/mouseMixin.js @@ -0,0 +1,17 @@ +import Vue from "vue"; +import { BootstrapVue, BootstrapVueIcons } from "bootstrap-vue"; +import "bootstrap/dist/css/bootstrap.css"; +import "bootstrap-vue/dist/bootstrap-vue.css"; +import MouseHeader from "@/portals/MousePortal/components/mouse-header.vue"; +import MouseFooter from "@/portals/MousePortal/components/mouse-footer.vue"; + +Vue.use(BootstrapVue); +Vue.use(BootstrapVueIcons); +Vue.config.productionTip = false; + +export const mouseMixin = { + components: { + MouseHeader, + MouseFooter, + }, +}; diff --git a/src/portals/MousePortal/views/Gene/Template.vue b/src/portals/MousePortal/views/Gene/Template.vue new file mode 100644 index 000000000..72f5cf67e --- /dev/null +++ b/src/portals/MousePortal/views/Gene/Template.vue @@ -0,0 +1,499 @@ + + + diff --git a/src/portals/MousePortal/views/Gene/main.js b/src/portals/MousePortal/views/Gene/main.js new file mode 100644 index 000000000..63b463e0b --- /dev/null +++ b/src/portals/MousePortal/views/Gene/main.js @@ -0,0 +1,346 @@ +import Vue from "vue"; +import Template from "./Template.vue"; +import store from "./store.js"; + +import CriterionFunctionGroup from "../../../../components/criterion/group/CriterionFunctionGroup.vue"; +import FilterPValue from "../../../../components/criterion/FilterPValue.vue"; +import FilterEnumeration from "../../../../components/criterion/FilterEnumeration.vue"; +import FilterGreaterThan from "../../../../components/criterion/FilterGreaterThan.vue"; +import FilterLessThan from "../../../../components/criterion/FilterLessThan.vue"; +import SearchHeaderWrapper from "../../../../components/SearchHeaderWrapper.vue"; +import TissueSelectPicker from "../../../../components/TissueSelectPicker.vue"; +import Scatterplot from "../../../../components/Scatterplot.vue"; +import MouseSummaryTable from "../../../../components/MouseSummaryTable.vue"; +import MouseTissueSelect from "../../../../components/MouseTissueSelect.vue"; +import MouseGeneSelect from "../../../../components/MouseGeneSelect.vue"; +import MouseDiffExpTable from "../../../../components/MouseDiffExpTable.vue"; +import MouseWhiskerPlot from "../../../../components/MouseWhiskerPlot.vue"; +import ResearchPheWAS from "../../../../components/researchPortal/ResearchPheWAS.vue"; +import HugeScoresTable from "../../../../components/HugeScoresTable.vue"; +import UnauthorizedMessage from "../../../../components/UnauthorizedMessage"; +import GeneAssociationsTable from "../../../../components/GeneAssociationsTable"; +import GeneAssociationsMasks from "../../../../components/GeneAssociationsMasks"; +import MouseSingleSearch from "../../components/MouseSingleSearch.vue"; + +import uiUtils from "../../../../utils/uiUtils"; +import plotUtils from "../../../../utils/plotUtils"; +import sortUtils from "../../../../utils/sortUtils"; +import alertUtils from "../../../../utils/alertUtils"; +import Formatters from "../../../../utils/formatters"; +import dataConvert from "../../../../utils/dataConvert"; +import keyParams from "../../../../utils/keyParams"; +import regionUtils from "../../../../utils/regionUtils"; + +import "../../assets/layout.css"; +import "../../assets/mouseportal.css"; +import "../../assets/mdkp_copy.css"; +import { pageMixin } from "../../../../mixins/pageMixin"; +new Vue({ + store, + components: { + CriterionFunctionGroup, + FilterPValue, + FilterEnumeration, + FilterGreaterThan, + FilterLessThan, + SearchHeaderWrapper, + TissueSelectPicker, + Scatterplot, + MouseSummaryTable, + MouseTissueSelect, + MouseGeneSelect, + MouseDiffExpTable, + MouseWhiskerPlot, + ResearchPheWAS, + HugeScoresTable, + UnauthorizedMessage, + GeneAssociationsMasks, + GeneAssociationsTable, + MouseSingleSearch, + }, + mixins: [pageMixin], + data() { + return { + currentPage: 1, + perPage: 10, + phenotypeFilterList: [], + activeTab: "hugeScorePheWASPlot", + plotColors: [ + "#007bff", + "#048845", + "#8490C8", + "#BF61A5", + "#EE3124", + "#FCD700", + "#5555FF", + "#7aaa1c", + "#9F78AC", + "#F88084", + "#F5A4C7", + "#CEE6C1", + "#cccc00", + "#6FC7B6", + "#D5A768", + "#d4d4d4", + ], + phewasPlotMargin: { + leftMargin: 150, + rightMargin: 40, + topMargin: 20, + bottomMargin: 100, + bump: 11, + }, + hugeScoreRenderConfig: { + type: "phewas plot", + "render by": "phenotype", + "group by": "group", + "phenotype map": "kp phenotype map", + "y axis field": "renderScore", + "convert y -log10": "false", + "y axis label": "Log(HuGE score)", + "x axis label": "", + "beta field": "null", + "hover content": ["bf_common", "bf_rare", "huge"], + thresholds: [Math.log(3), Math.log(30)], + "label in black": "greater than", + height: "600", + "plot margin": { + left: 150, + right: 150, + top: 250, + bottom: 300, + }, + }, + commonVariantRenderConfig: { + type: "phewas plot", + "render by": "phenotype", + "group by": "phenotype group", + "phenotype map": "kp phenotype map", + "y axis field": "pValue", + "convert y -log10": "true", + "y axis label": "-Log10(p-value)", + "x axis label": "beta", + "beta field": "null", + "hover content": ["pValue"], + thresholds: ["2.5e-6"], + height: "600", + "plot margin": { + left: 150, + right: 150, + top: 250, + bottom: 300, + }, + }, + mouseGeneOnly: false, + }; + }, + computed: { + utilsBox() { + let utils = { + Formatters: Formatters, + uiUtils: uiUtils, + alertUtils: alertUtils, + keyParams: keyParams, + dataConvert: dataConvert, + sortUtils: sortUtils, + plotUtils: plotUtils, + regionUtils: regionUtils, + }; + return utils; + }, + rareVariantRenderConfig() { + let config = structuredClone(this.commonVariantRenderConfig); + config["beta field"] = "beta"; + config["hover content"].push("beta"); + config["thresholds"].push(0.05); + return config; + }, + phenotypeMap() { + return this.$store.state.bioPortal.phenotypeMap; + }, + diseaseSystem() { + return this.$store.getters["bioPortal/diseaseSystem"]; + }, + homologRegion() { + return this.$store.getters.region; + }, + docDetails() { + let r = this.homologRegion; + return { + tissue: this.tissue + ? this.tissue.toUpperCase().replaceAll("_", " ") + : "", + gene: this.$store.state.gene, + region: !!r + ? `${r.chromosome}:${Formatters.intFormatter( + r.start + )}-${Formatters.intFormatter(r.end)}` + : null, + }; + }, + diffExpData() { + let data = structuredClone(this.$store.state.diffExp.data); + for (let i = 0; i < data.length; i++) { + data[i].founder_sex = `${data[i].founder}_${data[i].sex}`; + } + return data; + }, + geneassociations() { + let data = this.$store.state.geneassociations.data; + + if (!!this.diseaseInSession && this.diseaseInSession != "") { + data = sessionUtils.getInSession( + data, + this.phenotypesInSession, + "phenotype" + ); + } + + let assocMap = {}; + + for (let i in data) { + const assoc = data[i]; + + // skip associations not part of the disease group + if (!this.phenotypeMap[assoc.phenotype]) { + continue; + } + + const curAssoc = assocMap[assoc.phenotype]; + if (!curAssoc || assoc.pValue < curAssoc.pValue) { + assocMap[assoc.phenotype] = assoc; + } + } + + // convert to an array, sorted by p-value + let x = Object.values(assocMap).sort((a, b) => a.pValue - b.pValue); + return x; + }, + transcriptOr52k() { + let endpoint = !this.$store.state.selectedTranscript + ? this.$store.state.associations52k + : this.$store.state.transcriptAssoc; + this.$store.state.restricted = endpoint.restricted; + + if (!!this.diseaseInSession && this.diseaseInSession != "") { + endpoint.data = sessionUtils.getInSession( + endpoint.data, + this.phenotypesInSession, + "phenotype" + ); + } + + let assocMap = {}; + + for (let i in endpoint.data) { + const assoc = endpoint.data[i]; + + // skip associations not part of the disease group + if (!this.phenotypeMap[assoc.phenotype]) { + continue; + } + + const curAssoc = assocMap[assoc.phenotype]; + if (!curAssoc || assoc.pValue < curAssoc.pValue) { + assocMap[assoc.phenotype] = assoc; + } + } + + endpoint.data.sort( + (a, b) => + this.pValueFormatter(a.pValue) - + this.pValueFormatter(b.pValue) + ); + + return endpoint.data; + }, + filteredAssociations() { + return ( + this.geneassociations.filter((row) => { + return this.phenotypeMap[row.phenotype]; + }) || [] + ); + }, + hugeScores() { + let data = sortUtils.sortArrOfObjects( + this.$store.state.hugeScores.data, + "huge", + "number", + "desc" + ); + + if (!!this.diseaseInSession && this.diseaseInSession != "") { + data = sessionUtils.getInSession( + data, + this.phenotypesInSession, + "phenotype" + ); + } + + let hugeMap = {}; + + for (let i in data) { + const score = data[i]; + let phenotypeEntity = + this.$store.state.bioPortal.phenotypeMap[score.phenotype]; + score["group"] = phenotypeEntity + ? phenotypeEntity.group + : "No group info"; + score["renderScore"] = Math.log(data[i].huge); + + // skip associations not part of the disease group + if (!this.phenotypeMap[score.phenotype]) { + continue; + } + + hugeMap[score.phenotype] = score; + } + + // convert to an array, sorted by p-value + let x = Object.values(hugeMap); + return x; + }, + mouseOnly(){ + return this.mouseGeneOnly; + } + + }, + created() { + // get the disease group and set of phenotypes available + this.$store.dispatch("bioPortal/getDiseaseGroups"); + this.$store.dispatch("bioPortal/getPhenotypes"); + this.$store.dispatch("bioPortal/getDatasets"); + this.$store.dispatch("bioPortal/getDiseaseSystems"); + + this.$store.dispatch("queryDiffExp"); + }, + methods: { + tissueFormatter: Formatters.tissueFormatter, + ancestryFormatter: Formatters.ancestryFormatter, + pValueFormatter: Formatters.pValueFormatter, + searchDiffExp() { + this.$store.dispatch("queryDiffExp"); + }, + filterPhenotype(newFilters) { + this.phenotypeFilterList = newFilters; + }, + renderPhewas(REF) { + this.activeTab = REF; + let refComponent = this.$children[0].$refs[REF]; + setTimeout(function () { + refComponent.renderPheWas(); + }, 500); + }, + }, + watch: { + "$store.state.homologGene"(newGene){ + console.log(JSON.stringify(newGene)); + this.mouseGeneOnly = false; + if (newGene.data.length === 0){ + console.log("data missing"); + this.mouseGeneOnly = true; + } + } + }, + render: (h) => h(Template), +}).$mount("#app"); diff --git a/src/views/MouseDiffExp/store.js b/src/portals/MousePortal/views/Gene/store.js similarity index 100% rename from src/views/MouseDiffExp/store.js rename to src/portals/MousePortal/views/Gene/store.js diff --git a/src/portals/MousePortal/views/Index/Template.vue b/src/portals/MousePortal/views/Index/Template.vue new file mode 100644 index 000000000..3c789cfbf --- /dev/null +++ b/src/portals/MousePortal/views/Index/Template.vue @@ -0,0 +1,212 @@ + + diff --git a/src/portals/MousePortal/views/Index/main.js b/src/portals/MousePortal/views/Index/main.js new file mode 100644 index 000000000..8dfa94d22 --- /dev/null +++ b/src/portals/MousePortal/views/Index/main.js @@ -0,0 +1,105 @@ +import Vue from "vue"; +import Template from "./Template.vue"; +import store from "./store.js"; + +import CriterionFunctionGroup from "../../../../components/criterion/group/CriterionFunctionGroup.vue"; +import FilterPValue from "../../../../components/criterion/FilterPValue.vue"; +import FilterEnumeration from "../../../../components/criterion/FilterEnumeration.vue"; +import FilterGreaterThan from "../../../../components/criterion/FilterGreaterThan.vue"; +import FilterLessThan from "../../../../components/criterion/FilterLessThan.vue"; +import SearchHeaderWrapper from "../../../../components/SearchHeaderWrapper.vue"; +import TissueSelectPicker from "../../../../components/TissueSelectPicker.vue"; +import Scatterplot from "../../../../components/Scatterplot.vue"; +import MouseSummaryTable from "../../../../components/MouseSummaryTable.vue"; +import MouseTissueSelect from "../../../../components/MouseTissueSelect.vue"; +import MouseGeneSelect from "../../../../components/MouseGeneSelect.vue"; +import MouseDiffExpTable from "../../../../components/MouseDiffExpTable.vue"; +import MouseWhiskerPlot from "../../../../components/MouseWhiskerPlot.vue"; +import ResearchPheWAS from "../../../../components/researchPortal/ResearchPheWAS.vue"; +import HugeScoresTable from "../../../../components/HugeScoresTable.vue"; +import UnauthorizedMessage from "../../../../components/UnauthorizedMessage"; +import GeneAssociationsTable from "../../../../components/GeneAssociationsTable"; +import GeneAssociationsMasks from "../../../../components/GeneAssociationsMasks"; + +import uiUtils from "../../../../utils/uiUtils.js"; +import plotUtils from "../../../../utils/plotUtils.js"; +import sortUtils from "../../../../utils/sortUtils.js"; +import alertUtils from "../../../../utils/alertUtils.js"; +import Formatters from "../../../../utils/formatters.js"; +import dataConvert from "../../../../utils/dataConvert.js"; +import keyParams from "../../../../utils/keyParams.js"; +import regionUtils from "../../../../utils/regionUtils.js"; + +import "../../assets/layout.css"; +import "../../assets/mouseportal.css"; +import "../../assets/mdkp_copy.css"; +import MouseSingleSearch from "../../components/MouseSingleSearch.vue"; +import { pageMixin } from "../../../../mixins/pageMixin.js"; + +new Vue({ + store, + components: { + MouseGeneSelect, + MouseTissueSelect, + MouseSingleSearch + }, + mixins: [pageMixin], + data() { + return { + searchConfig: { + "search instruction": "Search by gene or tissue", + "search parameters": [ + { parameter: "gene", values: []}, + { parameter: "tissue", values: []}] + } + }; + }, + methods: { + goToGene(gene){ + location.href = `/gene.html?gene=${gene}`; + }, + goToTissue(tissue){ + location.href = `/tissue.html?tissue=${tissue}`; + } + }, + computed: { + utilsBox() { + let utils = { + Formatters: Formatters, + uiUtils: uiUtils, + alertUtils: alertUtils, + keyParams: keyParams, + dataConvert: dataConvert, + sortUtils: sortUtils, + plotUtils: plotUtils, + regionUtils: regionUtils, + }; + return utils; + }, + diseaseGroup() { + return this.$store.getters["bioPortal/diseaseGroup"]; + }, + frontContents() { + let contents = this.$store.state.kp4cd.frontContents; + if (contents.length === 0) { + return {}; + } + return contents[0]; + }, + }, + watch: { + diseaseGroup(group) { + this.$store.dispatch("kp4cd/getFrontContents", group.name); + }, + }, + async created() { + this.$store.dispatch("bioPortal/getDiseaseSystems"); + this.$store.dispatch("bioPortal/getDiseaseGroups"); + this.$store.dispatch("bioPortal/getPhenotypes"); + this.$store.dispatch("bioPortal/getDatasets"); + }, + + render(createElement, context) { + return createElement(Template); + }, +}).$mount("#app"); diff --git a/src/portals/MousePortal/views/Index/store.js b/src/portals/MousePortal/views/Index/store.js new file mode 100644 index 000000000..97af9f86d --- /dev/null +++ b/src/portals/MousePortal/views/Index/store.js @@ -0,0 +1,40 @@ +import Vue from "vue"; +import Vuex from "vuex"; +import bioPortal from "../../../../modules/bioPortal"; +import bioIndex from "../../../../modules/bioIndex"; +import kp4cd from "../../../../modules/kp4cd"; +import keyParams from "../../../../utils/keyParams"; +import bioIndexUtils from "../../../../utils/bioIndexUtils"; +import { BIO_INDEX_HOST } from "../../../../utils/bioIndexUtils"; + +Vue.use(Vuex); + +export default new Vuex.Store({ + modules: { + bioPortal, + kp4cd, + }, + state: { + tissueKeys: [], + tissueToQuery: "", + }, + + mutations: {}, + + getters: { + }, + + actions: { + async getTissueKeys(context) { + let tissues = await fetch(`${BIO_INDEX_HOST}/api/bio/keys/diff-exp/2?columns=tissue`) + .then(resp => resp.json()) + .then(json => { + if (json.count == 0) { + return null; + } + return json.keys.map(key => key[0]) + }); + context.state.tissueKeys = tissues; + }, + }, +}); diff --git a/src/portals/MousePortal/views/Tissue/Template.vue b/src/portals/MousePortal/views/Tissue/Template.vue new file mode 100644 index 000000000..14c0e6c3f --- /dev/null +++ b/src/portals/MousePortal/views/Tissue/Template.vue @@ -0,0 +1,153 @@ + + + diff --git a/src/portals/MousePortal/views/Tissue/main.js b/src/portals/MousePortal/views/Tissue/main.js new file mode 100644 index 000000000..202b0b2e7 --- /dev/null +++ b/src/portals/MousePortal/views/Tissue/main.js @@ -0,0 +1,345 @@ +import Vue from "vue"; +import Template from "./Template.vue"; +import store from "./store.js"; + +import CriterionFunctionGroup from "../../../../components/criterion/group/CriterionFunctionGroup.vue"; +import FilterPValue from "../../../../components/criterion/FilterPValue.vue"; +import FilterEnumeration from "../../../../components/criterion/FilterEnumeration.vue"; +import FilterGreaterThan from "../../../../components/criterion/FilterGreaterThan.vue"; +import FilterLessThan from "../../../../components/criterion/FilterLessThan.vue"; +import SearchHeaderWrapper from "../../../../components/SearchHeaderWrapper.vue"; +import TissueSelectPicker from "../../../../components/TissueSelectPicker.vue"; +import Scatterplot from "../../../../components/Scatterplot.vue"; +import MouseSummaryTable from "../../../../components/MouseSummaryTable.vue"; +import MouseTissueSelect from "../../../../components/MouseTissueSelect.vue"; +import MouseGeneSelect from "../../../../components/MouseGeneSelect.vue"; +import MouseDiffExpTable from "../../../../components/MouseDiffExpTable.vue"; +import MouseWhiskerPlot from "../../../../components/MouseWhiskerPlot.vue"; +import ResearchPheWAS from "../../../../components/researchPortal/ResearchPheWAS.vue"; +import HugeScoresTable from "../../../../components/HugeScoresTable.vue"; +import UnauthorizedMessage from "../../../../components/UnauthorizedMessage"; +import GeneAssociationsTable from "../../../../components/GeneAssociationsTable"; +import GeneAssociationsMasks from "../../../../components/GeneAssociationsMasks"; +import MouseSingleSearch from "../../components/MouseSingleSearch.vue"; + +import uiUtils from "../../../../utils/uiUtils.js"; +import plotUtils from "../../../../utils/plotUtils.js"; +import sortUtils from "../../../../utils/sortUtils.js"; +import alertUtils from "../../../../utils/alertUtils.js"; +import Formatters from "../../../../utils/formatters.js"; +import dataConvert from "../../../../utils/dataConvert.js"; +import keyParams from "../../../../utils/keyParams.js"; +import regionUtils from "../../../../utils/regionUtils.js"; + +import "../../assets/layout.css"; +import "../../assets/mouseportal.css"; +import "../../assets/mdkp_copy.css"; +import { pageMixin } from "../../../../mixins/pageMixin.js"; +new Vue({ + store, + components: { + CriterionFunctionGroup, + FilterPValue, + FilterEnumeration, + FilterGreaterThan, + FilterLessThan, + SearchHeaderWrapper, + TissueSelectPicker, + Scatterplot, + MouseSummaryTable, + MouseTissueSelect, + MouseGeneSelect, + MouseDiffExpTable, + MouseWhiskerPlot, + ResearchPheWAS, + HugeScoresTable, + UnauthorizedMessage, + GeneAssociationsMasks, + GeneAssociationsTable, + MouseSingleSearch + }, + mixins: [pageMixin], + data() { + return { + currentPage: 1, + perPage: 10, + phenotypeFilterList: [], + activeTab: "hugeScorePheWASPlot", + plotColors: [ + "#007bff", + "#048845", + "#8490C8", + "#BF61A5", + "#EE3124", + "#FCD700", + "#5555FF", + "#7aaa1c", + "#9F78AC", + "#F88084", + "#F5A4C7", + "#CEE6C1", + "#cccc00", + "#6FC7B6", + "#D5A768", + "#d4d4d4", + ], + phewasPlotMargin: { + leftMargin: 150, + rightMargin: 40, + topMargin: 20, + bottomMargin: 100, + bump: 11, + }, + hugeScoreRenderConfig: { + type: "phewas plot", + "render by": "phenotype", + "group by": "group", + "phenotype map": "kp phenotype map", + "y axis field": "renderScore", + "convert y -log10": "false", + "y axis label": "Log(HuGE score)", + "x axis label": "", + "beta field": "null", + "hover content": ["bf_common", "bf_rare", "huge"], + thresholds: [Math.log(3), Math.log(30)], + "label in black": "greater than", + height: "600", + "plot margin": { + left: 150, + right: 150, + top: 250, + bottom: 300, + }, + }, + commonVariantRenderConfig: { + type: "phewas plot", + "render by": "phenotype", + "group by": "phenotype group", + "phenotype map": "kp phenotype map", + "y axis field": "pValue", + "convert y -log10": "true", + "y axis label": "-Log10(p-value)", + "x axis label": "beta", + "beta field": "null", + "hover content": ["pValue"], + thresholds: ["2.5e-6"], + height: "600", + "plot margin": { + left: 150, + right: 150, + top: 250, + bottom: 300, + }, + }, + mouseGeneOnly: false, + }; + }, + computed: { + utilsBox() { + let utils = { + Formatters: Formatters, + uiUtils: uiUtils, + alertUtils: alertUtils, + keyParams: keyParams, + dataConvert: dataConvert, + sortUtils: sortUtils, + plotUtils: plotUtils, + regionUtils: regionUtils, + }; + return utils; + }, + rareVariantRenderConfig() { + let config = structuredClone(this.commonVariantRenderConfig); + config["beta field"] = "beta"; + config["hover content"].push("beta"); + config["thresholds"].push(0.05); + return config; + }, + phenotypeMap() { + return this.$store.state.bioPortal.phenotypeMap; + }, + diseaseSystem() { + return this.$store.getters["bioPortal/diseaseSystem"]; + }, + homologRegion() { + return this.$store.getters.region; + }, + docDetails() { + let r = this.homologRegion; + return { + tissue: this.tissue + ? this.tissue.toUpperCase().replaceAll("_", " ") + : "", + gene: this.$store.state.gene, + region: !!r + ? `${r.chromosome}:${Formatters.intFormatter( + r.start + )}-${Formatters.intFormatter(r.end)}` + : null, + }; + }, + diffExpData() { + let data = structuredClone(this.$store.state.diffExp.data); + for (let i = 0; i < data.length; i++) { + data[i].founder_sex = `${data[i].founder}_${data[i].sex}`; + } + return data; + }, + geneassociations() { + let data = this.$store.state.geneassociations.data; + + if (!!this.diseaseInSession && this.diseaseInSession != "") { + data = sessionUtils.getInSession( + data, + this.phenotypesInSession, + "phenotype" + ); + } + + let assocMap = {}; + + for (let i in data) { + const assoc = data[i]; + + // skip associations not part of the disease group + if (!this.phenotypeMap[assoc.phenotype]) { + continue; + } + + const curAssoc = assocMap[assoc.phenotype]; + if (!curAssoc || assoc.pValue < curAssoc.pValue) { + assocMap[assoc.phenotype] = assoc; + } + } + + // convert to an array, sorted by p-value + let x = Object.values(assocMap).sort((a, b) => a.pValue - b.pValue); + return x; + }, + transcriptOr52k() { + let endpoint = !this.$store.state.selectedTranscript + ? this.$store.state.associations52k + : this.$store.state.transcriptAssoc; + this.$store.state.restricted = endpoint.restricted; + + if (!!this.diseaseInSession && this.diseaseInSession != "") { + endpoint.data = sessionUtils.getInSession( + endpoint.data, + this.phenotypesInSession, + "phenotype" + ); + } + + let assocMap = {}; + + for (let i in endpoint.data) { + const assoc = endpoint.data[i]; + + // skip associations not part of the disease group + if (!this.phenotypeMap[assoc.phenotype]) { + continue; + } + + const curAssoc = assocMap[assoc.phenotype]; + if (!curAssoc || assoc.pValue < curAssoc.pValue) { + assocMap[assoc.phenotype] = assoc; + } + } + + endpoint.data.sort( + (a, b) => + this.pValueFormatter(a.pValue) - + this.pValueFormatter(b.pValue) + ); + + return endpoint.data; + }, + filteredAssociations() { + return ( + this.geneassociations.filter((row) => { + return this.phenotypeMap[row.phenotype]; + }) || [] + ); + }, + hugeScores() { + let data = sortUtils.sortArrOfObjects( + this.$store.state.hugeScores.data, + "huge", + "number", + "desc" + ); + + if (!!this.diseaseInSession && this.diseaseInSession != "") { + data = sessionUtils.getInSession( + data, + this.phenotypesInSession, + "phenotype" + ); + } + + let hugeMap = {}; + + for (let i in data) { + const score = data[i]; + let phenotypeEntity = + this.$store.state.bioPortal.phenotypeMap[score.phenotype]; + score["group"] = phenotypeEntity + ? phenotypeEntity.group + : "No group info"; + score["renderScore"] = Math.log(data[i].huge); + + // skip associations not part of the disease group + if (!this.phenotypeMap[score.phenotype]) { + continue; + } + + hugeMap[score.phenotype] = score; + } + + // convert to an array, sorted by p-value + let x = Object.values(hugeMap); + return x; + }, + mouseOnly(){ + return this.mouseGeneOnly; + } + + }, + created() { + // get the disease group and set of phenotypes available + this.$store.dispatch("bioPortal/getDiseaseGroups"); + this.$store.dispatch("bioPortal/getPhenotypes"); + this.$store.dispatch("bioPortal/getDatasets"); + this.$store.dispatch("bioPortal/getDiseaseSystems"); + this.$store.dispatch("queryDiffExp"); + }, + methods: { + tissueFormatter: Formatters.tissueFormatter, + ancestryFormatter: Formatters.ancestryFormatter, + pValueFormatter: Formatters.pValueFormatter, + searchDiffExp() { + this.$store.dispatch("queryDiffExp"); + }, + filterPhenotype(newFilters) { + this.phenotypeFilterList = newFilters; + }, + renderPhewas(REF) { + this.activeTab = REF; + let refComponent = this.$children[0].$refs[REF]; + setTimeout(function () { + refComponent.renderPheWas(); + }, 500); + }, + }, + watch: { + "$store.state.homologGene"(newGene){ + console.log(JSON.stringify(newGene)); + this.mouseGeneOnly = false; + if (newGene.data.length === 0){ + console.log("data missing"); + this.mouseGeneOnly = true; + } + } + }, + render: (h) => h(Template), +}).$mount("#app"); diff --git a/src/portals/MousePortal/views/Tissue/store.js b/src/portals/MousePortal/views/Tissue/store.js new file mode 100644 index 000000000..4d4ffdb7d --- /dev/null +++ b/src/portals/MousePortal/views/Tissue/store.js @@ -0,0 +1,120 @@ +import Vue from "vue"; +import Vuex from "vuex"; + +import bioPortal from "@/modules/bioPortal"; +import bioIndex from "@/modules/bioIndex"; +import kp4cd from "@/modules/kp4cd"; +import keyParams from "@/utils/keyParams"; +import { BIO_INDEX_HOST } from "@/utils/bioIndexUtils"; + +Vue.use(Vuex); + +export default new Vuex.Store({ + modules: { + bioPortal, + kp4cd, + diffExp: bioIndex("diff-exp"), + tissueSummary: bioIndex("diff-exp-summary-tissue"), + geneSummary: bioIndex("diff-exp-summary-gene"), + hugeScores: bioIndex("huge"), + geneassociations: bioIndex("gene-associations"), + varassociations: bioIndex("associations"), + associations52k: bioIndex("gene-associations-52k"), + geneToTranscript: bioIndex("gene-to-transcript"), + transcriptAssoc: bioIndex("transcript-associations"), + homologGene: bioIndex("gene"), + }, + state: { + tissue: keyParams.tissue || "", + gene: keyParams.gene || "", + tissueKeys: [], + tissueToQuery: "", + geneToQuery: "", + selectedAncestry: "", + loadingGene: false, + loadingExpression: false, + }, + + mutations: { + setTissueName(state, tissueName) { + state.tissue = tissueName || state.tissue; + keyParams.set({ tissue: state.tissue }); + }, + setGeneName(state, geneName) { + state.gene = geneName || state.gene; + keyParams.set({ gene: state.gene }); + }, + setCommonVariantsLength(state, NUM) { + state.commonVariantsLength = NUM; + }, + setLoadingGene(state, loading=true){ + state.loadingGene = loading; + }, + setLoadingExpression(state, loading=true){ + state.loadingExpression = loading; + } + }, + getters: { + region(state) { + let data = state.homologGene.data; + + if (data.length > 0) { + let gene = data[0]; + + return { + chromosome: gene.chromosome, + start: gene.start, + end: gene.end, + }; + } + }, + }, + actions: { + commonVariantsLength(context, NUM) { + context.commit("setCommonVariantsLength", NUM); + }, + async getTissueKeys(context) { + let tissues = await fetch(`${BIO_INDEX_HOST}/api/bio/keys/diff-exp/2?columns=tissue`) + .then(resp => resp.json()) + .then(json => { + if (json.count == 0) { + return null; + } + return json.keys.map(key => key[0]) + }); + context.state.tissueKeys = tissues; + }, + async selectGeneName(context, geneName){ + context.state.geneToQuery = geneName; + }, + async queryDiffExp(context) { + context.commit("setLoadingExpression"); + + let gene = context.state.geneToQuery || context.state.gene; + context.commit("setLoadingGene"); + context.commit("setGeneName", gene); + await context.dispatch("homologGene/query", {q: gene}); + context.commit("setLoadingGene", false); + + let tissue = context.state.tissueToQuery || context.state.tissue; + context.commit("setTissueName", tissue); + + if (!!tissue){ + context.dispatch("tissueSummary/query", {q: tissue}); + } + if (!!gene){ + let query = { q: gene}; + context.dispatch("geneSummary/query", query); + context.dispatch("hugeScores/query", query); + context.dispatch("associations52k/query", query); + context.dispatch("geneassociations/query", query); + context.dispatch("geneToTranscript/query", query); + } + if (!!gene && !!tissue) { + await context.dispatch("diffExp/query", { q: + `${gene},${tissue}` }); + context.commit("setLoadingExpression", false); + } + }, + }, +}); diff --git a/src/views/Mouse/Gene/Template.vue b/src/views/Mouse/Gene/Template.vue new file mode 100644 index 000000000..f04ec4383 --- /dev/null +++ b/src/views/Mouse/Gene/Template.vue @@ -0,0 +1,945 @@ + + + diff --git a/src/views/Mouse/Gene/main.js b/src/views/Mouse/Gene/main.js new file mode 100644 index 000000000..03e692c09 --- /dev/null +++ b/src/views/Mouse/Gene/main.js @@ -0,0 +1,731 @@ +import Vue from "vue"; +import Template from "./Template.vue"; +import store from "./store.js"; +import _ from "lodash"; + +import UniprotReferencesTable from "@/components/UniprotReferencesTable.vue"; +import GeneAssociationsTable from "@/components/GeneAssociationsTable"; +import GeneAssociationsMasks from "@/components/GeneAssociationsMasks"; +import UnauthorizedMessage from "@/components/UnauthorizedMessage"; +import Documentation from "@/components/Documentation.vue"; +import TooltipDocumentation from "@/components/TooltipDocumentation.vue"; +import Autocomplete from "@/components/Autocomplete.vue"; +import GeneSelectPicker from "@/components/GeneSelectPicker.vue"; +import AncestrySelectPicker from "@/components/AncestrySelectPicker"; +import TranscriptSelectPicker from "@/components/TranscriptSelectPicker"; +import VariantSearch from "@/components/VariantSearch.vue"; +import LocusZoom from "@/components/lz/LocusZoom"; +import LocusZoomPhewasPanel from "@/components/lz/panels/LocusZoomPhewasPanel"; +import ResearchPheWAS from "@/components/researchPortal/ResearchPheWAS.vue"; +import HugeScoresTable from "@/components/HugeScoresTable.vue"; +import ResearchExpressionDisplay from "@/components/researchPortal/ResearchExpressionDisplay.vue"; +import ResearchDataTable from "@/components/researchPortal/ResearchDataTable.vue"; +import EffectorGenesSectionOnGene from "@/components/EffectorGenesSectionOnGene.vue"; +import MouseSummaryTable from "@/components/MouseSummaryTable.vue"; +import ColocusTable from "@/components/ColocusTable.vue"; +import CriterionFunctionGroup from "@/components/criterion/group/CriterionFunctionGroup.vue"; +import FilterPValue from "@/components/criterion/FilterPValue.vue"; +import FilterEnumeration from "@/components/criterion/FilterEnumeration.vue"; +import FilterGreaterThan from "@/components/criterion/FilterGreaterThan.vue"; +import ColorBarPlot from "@/components/ColorBarPlot.vue"; +import SearchHeaderWrapper from "@/components/SearchHeaderWrapper.vue"; +import ResearchSingleSearch from "@/components/researchPortal/ResearchSingleSearch.vue"; +import GenePageCombinedEvidenceTable from "@/components/GenePageCombinedEvidenceTable.vue"; + +import NCATSPredicateTable from "@/components/NCATS/old/PredicateTable.vue"; +import ResultsDashboard from "@/components/NCATS/ResultsDashboard.vue"; + +import sessionUtils from "@/utils/sessionUtils"; +import HugeCalScoreSection from "@/components/HugeCalScoreSection.vue"; + +import Counter from "@/utils/idCounter"; +import regionUtils from "@/utils/regionUtils"; + +import uiUtils from "@/utils/uiUtils"; +import plotUtils from "@/utils/plotUtils"; +import sortUtils from "@/utils/sortUtils"; +import alertUtils from "@/utils/alertUtils"; +import Formatters from "@/utils/formatters"; +import dataConvert from "@/utils/dataConvert"; +import keyParams from "@/utils/keyParams"; +import { pageMixin } from "@/mixins/pageMixin.js"; + +Vue.config.productionTip = false; + +new Vue({ + store, + modules: {}, + components: { + UniprotReferencesTable, + GeneAssociationsTable, + GeneAssociationsMasks, + Documentation, + TooltipDocumentation, + Autocomplete, + GeneSelectPicker, + AncestrySelectPicker, + TranscriptSelectPicker, + UnauthorizedMessage, + CriterionFunctionGroup, + FilterPValue, + FilterEnumeration, + FilterGreaterThan, + LocusZoom, + LocusZoomPhewasPanel, + ResearchPheWAS, + ResearchExpressionDisplay, + ResearchDataTable, + SearchHeaderWrapper, + ResultsDashboard, + NCATSPredicateTable, + VariantSearch, + ColorBarPlot, + GenePageCombinedEvidenceTable, + HugeCalScoreSection, + HugeScoresTable, + EffectorGenesSectionOnGene, + ResearchSingleSearch, + MouseSummaryTable, + ColocusTable, + }, + mixins: [pageMixin], + + data() { + return { + counter: 0, + genePageSearchCriterion: [], + phenotypeFilterList: [], + activeTab: "hugeScorePheWASPlot", + externalResources: { + ensembl: { + title: "Ensembl", + link: "https://useast.ensembl.org/Homo_sapiens/Gene/Summary?db=core;g=", + }, + hgnc: { + title: "HUGO Gene Nomenclature Committee", + link: "https://www.genenames.org/data/gene-symbol-report/#!/hgnc_id/", + }, + mgd: { + title: "Mouse Genome Database", + link: "http://www.informatics.jax.org/marker/", + }, + rgd: { + title: "Rat Genome Database", + link: "https://rgd.mcw.edu/rgdweb/report/gene/main.html?id=", + }, + ucsc: { + title: "USSC Genome Browser", + link: "http://genome.ucsc.edu/cgi-bin/hgGene?db=hg19&hgg_gene=", + }, + uniprot: { + title: "Universal Protein Resource", + link: "https://www.uniprot.org/uniprot/", + }, + }, + noTranscriptDataPortal: ["sleep", "lung", "ndkp", "autoimmune"], + plotColors: [ + "#007bff", + "#048845", + "#8490C8", + "#BF61A5", + "#EE3124", + "#FCD700", + "#5555FF", + "#7aaa1c", + "#9F78AC", + "#F88084", + "#F5A4C7", + "#CEE6C1", + "#cccc00", + "#6FC7B6", + "#D5A768", + "#d4d4d4", + ], + phewasPlotMargin: { + leftMargin: 150, + rightMargin: 40, + topMargin: 20, + bottomMargin: 100, + bump: 11, + }, + hugeScoreRenderConfig: { + type: "phewas plot", + "render by": "phenotype", + "group by": "group", + "phenotype map": "kp phenotype map", + "y axis field": "renderScore", + "convert y -log10": "false", + "y axis label": "Log(HuGE score)", + "x axis label": "", + "beta field": "null", + "hover content": ["bf_common", "bf_rare", "huge"], + thresholds: [Math.log(3), Math.log(30)], + "label in black": "greater than", + height: "600", + "plot margin": { + left: 150, + right: 150, + top: 250, + bottom: 300, + }, + }, + commonVariantRenderConfig: { + type: "phewas plot", + "render by": "phenotype", + "group by": "phenotype group", + "phenotype map": "kp phenotype map", + "y axis field": "pValue", + "convert y -log10": "true", + "y axis label": "-Log10(p-value)", + "x axis label": "beta", + "beta field": "null", + "hover content": ["pValue"], + thresholds: ["2.5e-6"], + height: "600", + "plot margin": { + left: 150, + right: 150, + top: 250, + bottom: 300, + }, + }, + rareVariantRenderConfig: { + type: "phewas plot", + "group by": "phenotype group", + "render by": "phenotype", + "phenotype map": "kp phenotype map", + "y axis field": "pValue", + "convert y -log10": "true", + "y axis label": "-Log10(p-value)", + "x axis label": "beta", + "beta field": "beta", + "hover content": ["pValue", "beta"], + thresholds: ["2.5e-6", "0.05"], + height: "600", + "plot margin": { + left: 150, + right: 150, + top: 250, + bottom: 300, + }, + }, + }; + }, + + computed: { + utilsBox() { + let utils = { + Formatters: Formatters, + uiUtils: uiUtils, + alertUtils: alertUtils, + keyParams: keyParams, + dataConvert: dataConvert, + sortUtils: sortUtils, + plotUtils: plotUtils, + regionUtils: regionUtils, + }; + return utils; + }, + /// for disease systems + diseaseInSession() { + if (this.$store.state.diseaseInSession == null) { + return ""; + } else { + return this.$store.state.diseaseInSession; + } + }, + phenotypesInSession() { + if (this.$store.state.phenotypesInSession == null) { + return this.$store.state.bioPortal.phenotypes; + } else { + return this.$store.state.phenotypesInSession; + } + }, + rawPhenotypes() { + return this.$store.state.bioPortal.phenotypes; + }, + /// + phenotypeOptions() { + return this.phenotypesInSession + .filter((x) => x.name != this.$store.state.phenotype) + .map((phenotype) => phenotype.name); + }, + + transcriptOr52k() { + let endpoint = !this.$store.state.selectedTranscript + ? this.$store.state.associations52k + : this.$store.state.transcriptAssoc; + this.$store.state.restricted = endpoint.restricted; + + if (!!this.diseaseInSession && this.diseaseInSession != "") { + endpoint.data = sessionUtils.getInSession( + endpoint.data, + this.phenotypesInSession, + "phenotype" + ); + } + + let assocMap = {}; + + for (let i in endpoint.data) { + const assoc = endpoint.data[i]; + + // skip associations not part of the disease group + if (!this.phenotypeMap[assoc.phenotype]) { + continue; + } + + const curAssoc = assocMap[assoc.phenotype]; + if (!curAssoc || assoc.pValue < curAssoc.pValue) { + assocMap[assoc.phenotype] = assoc; + } + } + + endpoint.data.sort( + (a, b) => + this.pValueFormatter(a.pValue) - + this.pValueFormatter(b.pValue) + ); + + return endpoint.data; + }, + + geneassociations() { + let data = this.$store.state.geneassociations.data; + + if (!!this.diseaseInSession && this.diseaseInSession != "") { + data = sessionUtils.getInSession( + data, + this.phenotypesInSession, + "phenotype" + ); + } + + let assocMap = {}; + + for (let i in data) { + const assoc = data[i]; + + // skip associations not part of the disease group + if (!this.phenotypeMap[assoc.phenotype]) { + continue; + } + + const curAssoc = assocMap[assoc.phenotype]; + if (!curAssoc || assoc.pValue < curAssoc.pValue) { + assocMap[assoc.phenotype] = assoc; + } + } + + // convert to an array, sorted by p-value + let x = Object.values(assocMap).sort((a, b) => a.pValue - b.pValue); + return x; + }, + //filter associations that only exist in the phenotypeMap + filteredAssociations() { + return ( + this.geneassociations.filter((row) => { + return this.phenotypeMap[row.phenotype]; + }) || [] + ); + }, + hugeScores() { + let data = sortUtils.sortArrOfObjects( + this.$store.state.hugeScores.data, + "huge", + "number", + "desc" + ); + + if (!!this.diseaseInSession && this.diseaseInSession != "") { + data = sessionUtils.getInSession( + data, + this.phenotypesInSession, + "phenotype" + ); + } + + let hugeMap = {}; + + for (let i in data) { + const score = data[i]; + let phenotypeEntity = + this.$store.state.bioPortal.phenotypeMap[score.phenotype]; + score["group"] = phenotypeEntity + ? phenotypeEntity.group + : "No group info"; + score["renderScore"] = Math.log(data[i].huge); + + // skip associations not part of the disease group + if (!this.phenotypeMap[score.phenotype]) { + continue; + } + + hugeMap[score.phenotype] = score; + } + + // convert to an array, sorted by p-value + let x = Object.values(hugeMap); + return x; + }, + + associations52k() { + let data = this.$store.state.associations52k.data; + + if (!!this.diseaseInSession && this.diseaseInSession != "") { + data = sessionUtils.getInSession( + data, + this.phenotypesInSession, + "phenotype" + ); + } + + let assocMap = {}; + + for (let i in data) { + const assoc = data[i]; + + // skip associations not part of the disease group + if (!this.phenotypeMap[assoc.phenotype]) { + continue; + } + + const curAssoc = assocMap[assoc.phenotype]; + if (!curAssoc || assoc.pValue < curAssoc.pValue) { + assocMap[assoc.phenotype] = assoc; + } + } + + // convert to an array, sorted by p-value + let x = Object.values(assocMap).sort((a, b) => a.pValue - b.pValue); + return x; + }, + geneExpression() { + let data = this.$store.state.geneExpression.data; + return data; + }, + + /*smallestpValuePhenotype() { + // let data = this.$store.state.varassociations.data; + // let x = data.sort( + // (a, b) => a.pValue - b.pValue + // ); + + return "T2D"; + },*/ + selectedPhenotypes() { + let phenotypeMap = this.$store.state.bioPortal.phenotypeMap; + if (Object.keys(phenotypeMap).length === 0) { + return []; + } + + return this.genePageSearchCriterion + .filter((criterion) => criterion.field === "phenotype") + .map((criterion) => phenotypeMap[criterion.threshold]); + }, + + selectedPhenotype() { + if (this.selectedPhenotypes.length > 0) { + return this.selectedPhenotypes[0].name; + } else return "T2D"; + }, + + queries() { + return [ + this.biolinkQueryGraph("NCBIGENE:1017", { + subject: "biolink:Gene", + predicate: "biolink:enables", + object: "biolink:MolecularActivity", + }), + ]; + }, + + region() { + return this.$store.getters.region; + }, + + symbolName() { + return this.$store.getters.canonicalSymbol; + }, + geneSymbol() { + return this.$store.getters.geneSymbol; + }, + + aliasNames() { + return this.$store.state.genes.data.filter( + (g) => g.source === "alias" + ); + }, + + alternateNames() { + let geneData = this.$store.state.gene.data; + return this.$store.state.genes.data + .filter((g) => g.start == geneData[0].start) + .filter((g) => g.end == geneData[0].end) + .filter((g) => g.source !== "symbol") + .sort((a, b) => { + if (a.source < b.source) return -1; + if (a.source > b.source) return 1; + return 0; + }); + }, + + dbReference() { + return this.$store.getters["uniprot/dbReference"] || []; + }, + + accession() { + return this.$store.getters["uniprot/accession"] || []; + }, + + geneFunction() { + return this.$store.getters["uniprot/geneFunction"] || ""; + }, + + geneNames() { + return this.$store.getters["uniprot/geneNames"] || []; + }, + + gene() { + let data = this.$store.state.gene.data; + if (data.length > 0) { + return data[0]; + } + return {}; + }, + + regionText() { + let r = this.region; + + if (r) { + return `${r.chromosome}:${Formatters.intFormatter( + r.start + )}-${Formatters.intFormatter(r.end)}`; + } else { + return ""; + } + }, + + regionTextExpanded() { + let r = this.region; + + if (r) { + return `${r.chromosome}:${Formatters.intFormatter( + r.start - 50000 + )}-${Formatters.intFormatter(r.end + 50000)}`; + } else { + return ""; + } + }, + + associationPhenotypes() { + return this.$store.state.geneassociations.data.map( + (a) => a.phenotype + ); + }, + + docDetails() { + let symbol = this.geneSymbol; + let r = this.region; + + if (!!symbol && !!r) { + return { + gene: symbol, + region: `${r.chromosome}:${Formatters.intFormatter( + r.start + )}-${Formatters.intFormatter(r.end)}`, + }; + } + return {}; + }, + + phenotypeMap() { + return this.$store.state.bioPortal.phenotypeMap; + }, + }, + + watch: { + geneassociations(newData, oldData) { + let topPhenotype = "LDL"; + if (newData.length > 0) { + topPhenotype = newData[0].phenotype; + if (this.genePageSearchCriterion[0] != topPhenotype) { + this.genePageSearchCriterion = []; + } + this.pushCriterionPhenotype(topPhenotype); + + this.$store.dispatch("getVarAssociationsData", topPhenotype); + } + }, + geneExpressionTable() { + console.log(this.geneExpressionTable); + }, + + selectedPhenotypes(phenotypes, oldPhenotypes) { + const removedPhenotypes = _.difference( + oldPhenotypes.map((p) => p.name), + phenotypes.map((p) => p.name) + ); + this.$store.dispatch("get52KAssociationData"); + if (removedPhenotypes.length > 0) { + this.$store.dispatch( + "getVarAssociationsData", + phenotypes[0].name + ); + } + }, + + diseaseGroup(group) { + this.$store.dispatch("kp4cd/getFrontContents", group.name); + }, + + // the region for the gene was found + region(region) { + if (region) { + //uiUtils.hideElement("pageSearchHeaderContent"); + this.$store.dispatch("queryGeneRegion", region); + } + }, + + // the canonical symbol was found + symbolName(symbol) { + this.$store.dispatch("queryUniprot", symbol); + this.$store.dispatch("queryAssociations"); + this.$store.dispatch("getHugeScoresData"); + this.$store.dispatch("getMouseData"); + }, + "$store.state.selectedAncestry"(newAncestry) { + let geneQuery = !newAncestry + ? { q: this.$store.state.geneName } + : { q: `${this.$store.state.geneName},${newAncestry}` }; + this.$store.dispatch("geneassociations/query", geneQuery); + }, + "$store.state.selectedTranscript"(newTranscript) { + if (newTranscript) { + this.$store.dispatch("transcriptAssoc/query", { + q: newTranscript, + }); + } + }, + "$store.state.geneName"(NAME) { + this.$store.dispatch("getHugeScoresData"); + }, + }, + + created() { + /// disease systems + this.$store.dispatch("bioPortal/getDiseaseSystems"); + //// + this.$store.dispatch("queryGeneName", this.$store.state.geneName); + // this.$store.dispatch("queryAliasName", this.$store.state.aliasName) + //this.$store.dispatch("queryAssociations"); + // get the disease group and set of phenotypes available + this.$store.dispatch("bioPortal/getDiseaseGroups"); + this.$store.dispatch("bioPortal/getPhenotypes"); + this.$store.dispatch("bioPortal/getDatasets"); + this.pushCriterionPhenotype("T2D"); + this.checkGeneName(this.$store.state.geneName); + }, + + methods: { + ...uiUtils, + ...sessionUtils, + ancestryFormatter: Formatters.ancestryFormatter, + pValueFormatter: Formatters.pValueFormatter, + + async checkGeneName(KEY) { + let gene = await regionUtils.geneSymbol(KEY); + + if (!!gene && gene != KEY) { + document.getElementById("invalidGeneMessage").innerHTML = + "Your search term is an alias name for gene symbol " + + gene + + ". Please enter a new search term above, or go to the " + + gene + + " Gene page"; + + document + .getElementById("invalidGeneRedirect") + .setAttribute("href", "/gene.html?gene=" + gene); + uiUtils.showElement("invalidGeneWarning"); + //uiUtils.showElement("pageSearchHeaderContent"); + } + }, + + hideGeneWarning() { + uiUtils.hideElement("invalidGeneWarning"); + }, + + pushCriterionPhenotype(phenotypeName) { + this.genePageSearchCriterion.push({ + field: "phenotype", + threshold: phenotypeName, + }); + }, + biolinkQueryGraph(subjectCurie, { subject, predicate, object }) { + const uuid = Counter.getUniqueId; + const sid = uuid("s"); + const oid = uuid("o"); + const eid = uuid("e"); + return { + query_graph: { + nodes: { + [sid]: { + id: subjectCurie, + category: subject, + }, + [oid]: { + category: object, + }, + }, + edges: { + [eid]: { + subject: sid, + object: oid, + predicate: predicate, + }, + }, + }, + }; + }, + + // go to region page + exploreRegion(expanded = 0) { + let r = this.region; + + if (r) { + window.location.href = `./region.html?chr=${ + r.chromosome + }&start=${r.start - expanded}&end=${r.end + expanded}`; + } + }, + + topPhenotype(topAssocData) { + return topAssocData[0]; + }, + renderPhewas(REF) { + this.activeTab = REF; + let refComponent = this.$children[0].$refs[REF]; + setTimeout(function () { + refComponent.renderPheWas(); + }, 500); + }, + filterPhenotype(newFilters) { + this.phenotypeFilterList = newFilters; + }, + clearCriterion(criterion) { + if (criterion === "transcript") { + this.$store.state.selectedTranscript = ""; + return; + } + if (criterion === "ancestry") { + this.$store.state.selectedAncestry = ""; + return; + } + }, + }, + + render(createElement, context) { + return createElement(Template); + }, +}).$mount("#app"); diff --git a/src/views/Mouse/Gene/store.js b/src/views/Mouse/Gene/store.js new file mode 100644 index 000000000..a72a3120c --- /dev/null +++ b/src/views/Mouse/Gene/store.js @@ -0,0 +1,197 @@ +import Vue from "vue"; +import Vuex from "vuex"; + +import bioPortal from "@/modules/bioPortal"; +import bioIndex from "@/modules/bioIndex"; +import kp4cd from "@/modules/kp4cd"; +import keyParams from "@/utils/keyParams"; +import uniprot from "@/modules/uniprot"; +import regionUtils from "@/utils/regionUtils"; + +Vue.use(Vuex); + +export default new Vuex.Store({ + modules: { + bioPortal, + kp4cd, + gene: bioIndex("gene"), + genes: bioIndex("genes"), + geneassociations: bioIndex("gene-associations"), + varassociations: bioIndex("associations"), + ancestryAssoc: bioIndex("ancestry-associations"), + associations52k: bioIndex("gene-associations-52k"), + geneToTranscript: bioIndex("gene-to-transcript"), + transcriptAssoc: bioIndex("transcript-associations"), + hugeScores: bioIndex("huge"), + geneExpression: bioIndex("gene-expression"), + mouseSummary: bioIndex("diff-exp-summary-gene"), + uniprot, + }, + state: { + geneName: keyParams.gene, + geneToQuery: "", + aliasName: null, + prior: 0.3696, + phenotypesInSession: null, + diseaseInSession: null, + phenotypeCorrelation: null, + selectedAncestry: "", + selectedTranscript: "", + commonVariantsLength: 0, + }, + + mutations: { + setGeneName(state, geneName) { + state.geneName = geneName || state.geneName; + keyParams.set({ gene: state.geneName }); + }, + setGene(state, { name, chromosome, start, end }) { + state.geneName = name; + state.geneRegion = `${chromosome}:${start}-${end}`; + }, + setAliasName(state, aliasName) { + state.aliasName = aliasName || state.aliasName; + }, + setPhenotypesInSession(state, PHENOTYPES) { + state.phenotypesInSession = PHENOTYPES; + }, + setDiseaseInSession(state, DISEASE) { + state.diseaseInSession = DISEASE; + }, + setPhenotypeCorrelation(state, Correlation) { + state.phenotypeCorrelation = Correlation; + }, + setCommonVariantsLength(state, NUM) { + state.commonVariantsLength = NUM; + }, + }, + + getters: { + region(state) { + let data = state.gene.data; + + if (data.length > 0) { + let gene = data[0]; + + return { + chromosome: gene.chromosome, + start: gene.start, + end: gene.end, + }; + } + }, + + // canonicalSymbol(state) { + // let data = state.genes.data; + // let geneData = state.gene.data; + + // for (let i in data) { + // if (data[i].source === "symbol") { + // return data[i].name; + // } + // } + // }, + canonicalSymbol(state) { + let data = state.gene.data; + if (data.length > 0) { + return data[0].symbol; + } + return null; + }, + + geneSymbol(state) { + let data = state.genes.data; + let geneData = state.gene.data; + + for (let i in data) { + if ( + data[i].chromosome == geneData[0].chromosome && + data[i].start == geneData[0].start && + data[i].end == geneData[0].end + ) { + if (data[i].source === "symbol") { + return data[i].name; + } + } + } + }, + }, + + actions: { + // For custom phenotypes + phenotypesInSession(context, PHENOTYPES) { + context.commit("setPhenotypesInSession", PHENOTYPES); + }, + diseaseInSession(context, DISEASE) { + context.commit("setDiseaseInSession", DISEASE); + }, + commonVariantsLength(context, NUM) { + context.commit("setCommonVariantsLength", NUM); + }, + + async queryGeneName(context, symbol) { + let name = context.state.geneToQuery || context.state.geneName; + context.commit("setGeneName", name); + + if (!!name) { + context.dispatch("gene/query", { q: name }); + context.dispatch("geneToTranscript/query", { q: name }); + } + }, + /// + + async queryGeneRegion(context, region) { + //To match with HuGE cal +- 300000 to the region + let { chromosome, start, end } = region || context.getters.region; + let q = `${chromosome}:${start - 300000}-${end + 300000}`; + + context.dispatch("genes/query", { q }); + }, + + async queryUniprot(context, symbol) { + let name = symbol || context.getters.canonicalSymbol; + + if (!!symbol) { + context.dispatch("uniprot/getUniprotGeneInfo", name); + } + }, + + async queryAssociations(context) { + let query = { q: context.state.geneName }; + context.dispatch("associations52k/query", query); + context.dispatch("geneassociations/query", query); + context.dispatch("geneExpression/query", query); + }, + async getVarAssociationsData(context, phenotype) { + let gene = context.state.geneName; + let locus = await regionUtils.parseRegion(gene, true, 50000); + + if (locus) { + context.state.newChr = locus.chr; + context.state.newStart = locus.start; + context.state.newEnd = locus.end; + } + + const phenoRegionQuery = `${phenotype},${locus.chr}:${ + locus.start - 50000 + }-${locus.end + 50000}`; + + context.dispatch("varassociations/query", { q: phenoRegionQuery }); + }, + async get52KAssociationData(context) { + let name = context.state.geneName; + context.dispatch("associations52k/query", { q: name }); + }, + async getHugeScoresData(context) { + let name = context.state.geneName; + context.dispatch("hugeScores/query", { q: name }); + }, + async getMouseData(context) { + let name = context.state.geneName; + context.dispatch("mouseSummary/query", { q: name }); + }, + phenotypeCorrelation(context, DATA) { + context.commit("setPhenotypeCorrelation", DATA); + }, + }, +}); diff --git a/src/views/Mouse/Index/Template.vue b/src/views/Mouse/Index/Template.vue new file mode 100644 index 000000000..1660fb3f7 --- /dev/null +++ b/src/views/Mouse/Index/Template.vue @@ -0,0 +1,220 @@ + + diff --git a/src/views/Mouse/Index/main.js b/src/views/Mouse/Index/main.js new file mode 100644 index 000000000..af612e798 --- /dev/null +++ b/src/views/Mouse/Index/main.js @@ -0,0 +1,419 @@ +import Vue from "vue"; +import Template from "./Template.vue"; +import store from "./store.js"; + +import PhenotypeSelectPicker from "@/components/PhenotypeSelectPicker.vue"; +import DatasetSelectPicker from "@/components/DatasetSelectPicker.vue"; +import NewsFeedSection from "@/components/frontPage/NewsFeedSection.vue"; +import DiseaseGroupSelect from "@/components/DiseaseGroupSelect.vue"; +import DiseaseSystems from "@/components/DiseaseSystems.vue"; +import Autocomplete from "@/components/Autocomplete.vue"; +import ResearchSingleSearch from "@/components/researchPortal/ResearchSingleSearch.vue"; +import ResearchPageDescription from "@/components/researchPortal/ResearchPageDescription.vue"; + +import uiUtils from "@/utils/uiUtils"; +import plotUtils from "@/utils/plotUtils"; +import sortUtils from "@/utils/sortUtils"; +import alertUtils from "@/utils/alertUtils"; +import pigeanUtils from "@/utils/pigeanUtils.js"; +import Formatters from "@/utils/formatters"; +import dataConvert from "@/utils/dataConvert"; +import keyParams from "@/utils/keyParams"; +import regionUtils from "@/utils/regionUtils"; +import { BIO_INDEX_HOST } from "@/utils/bioIndexUtils"; +import { pageMixin } from "@/mixins/pageMixin.js"; + +new Vue({ + store, + components: { + PhenotypeSelectPicker, + DatasetSelectPicker, + NewsFeedSection, + DiseaseGroupSelect, + Autocomplete, + ResearchSingleSearch, + ResearchPageDescription, + DiseaseSystems, + }, + mixins: [pageMixin], + + data: { + selected: "", + searches: [ + { id: "gene", name: "gene" }, + { id: "variantOrRegion", name: "variantOrRegion" }, + ], + stats: [], + statsKeys: [ + { icon: "phenotypes", label: "Phenotypes" }, + { icon: "genetic_datasets", label: "Genetic datasets" }, + { icon: "genomic_datasets", label: "Genomic datasets" }, + { icon: "bioinfomatics_methods", label: "Bioinformatic methods" }, + { icon: "curated_datasets", label: "Curated datasets" }, + ], + oldStats: keyParams.oldstats, + config: { + "search instruction": "Search gene, geneset or phenotype", + "search examples": [ + { + parameter: "gene", + value: "PLAU", + }, + { + parameter: "gene", + value: "MLX", + }, + ], + "search parameters": [ + { + parameter: "gene", + "data point": { + type: "api", + url: `${BIO_INDEX_HOST}/api/bio/keys/pigean-gene/3?columns=gene`, + "data type": "json", + "data wrapper": ["keys"], + }, + "target page": { + label: "Search Gene", + url: "/pigean/gene.html?", + }, + }, + { + parameter: "geneset", + "data point": { + type: "api", + url: `${BIO_INDEX_HOST}/api/bio/keys/pigean-gene-set/3?columns=gene_set`, + "data type": "json", + "data wrapper": ["keys"], + }, + "target page": { + label: "Search Geneset", + url: "/pigean/geneset.html?", + }, + }, + // { + // parameter: "phenotype", + // "data point": { + // type: "api", + // url: "https://bioindex-dev.hugeamp.org/api/bio/keys/pigean-gene-set-phenotype/1", + // "data type": "json", + // "data wrapper": ["keys"], + // }, + // "target page": { + // label: "Search Phenotype", + // url: "/pigean/phenotype.html?", + // }, + // }, + { + parameter: "phenotype", + values: "kp phenotypes", + "target page": { + label: "Search Phenotype", + url: "/pigean/phenotype.html?", + }, + }, + ], + }, + }, + + computed: { + utilsBox() { + let utils = { + Formatters: Formatters, + uiUtils: uiUtils, + alertUtils: alertUtils, + keyParams: keyParams, + dataConvert: dataConvert, + sortUtils: sortUtils, + plotUtils: plotUtils, + regionUtils: regionUtils, + }; + return utils; + }, + diseaseGroups() { + return this.$store.state.bioPortal.diseaseGroups; + }, + phenotypes() { + return this.$store.state.bioPortal.phenotypes; + }, + diseaseInSession() { + if (this.$store.state.diseaseInSession == null) { + return ""; + } else { + return this.$store.state.diseaseInSession; + } + }, + phenotypesInSession() { + if (this.$store.state.phenotypesInSession == null) { + return this.$store.state.bioPortal.phenotypes; + } else { + return this.$store.state.phenotypesInSession; + } + }, + matchingGenes() { + return this.$store.state.matchingGenes; + }, + geneOrRegionOrVariant() { + return this.$store.state.geneOrRegionOrVariant; + }, + + datasetsInfo() { + let datasets = this.$store.state.kp4cd.datasetsInfo; + + if (datasets.length === 0) { + return {}; + } + return datasets[0]; + }, + kPortals() { + let portals = this.$store.state.kp4cd.portals; + + if (portals.length === 0) { + return null; + } + return portals; + }, + phenotypesByName() { + if (!this.phenotypes) { + return null; + } + + let content = {}; + + this.phenotypes.map((p) => { + content[p.name] = p; + }); + + return content; + }, + datasetsDescription() { + let datasets = this.$store.state.bioPortal.datasets; + let diseases = this.$store.state.bioPortal.diseaseSystems; + + //first get datasets by phenotype groups + if ( + datasets.length > 0 && + !!this.phenotypesByName && + diseases.length > 0 + ) { + let pGroups = {}; + + this.$store.state.bioPortal.phenotypes.map((p) => { + if (!pGroups[p.group]) { + pGroups[p.group] = { phenotypes: [], datasets: [] }; + } + pGroups[p.group].phenotypes.push(p.name); + }); + + datasets.map((d) => { + d.phenotypes.map((dp) => { + for (const [key, data] of Object.entries(pGroups)) { + if (data.phenotypes.includes(dp)) { + data.datasets.push(d.name); + } + } + }); + }); + + let diseaseSystems = [ + ...new Set(diseases.map((d) => d.system)), + ].sort(); + + let dGroups = {}; + + diseaseSystems.map((ds) => { + dGroups[ds] = { phenotypes: [], datasets: [] }; + }); + + diseases.map((d) => { + if (!dGroups[d.system].phenotypes.includes(d.group)) { + dGroups[d.system].phenotypes.push(d.group); + } + }); + + //then get dataset numbers by disease systems X phenotype groups + + Object.keys(dGroups).map((dg) => { + dGroups[dg].phenotypes.map((p) => { + if (pGroups[p]) { + let tempDatasetsArr = [].concat( + dGroups[dg].datasets, + pGroups[p].datasets + ); + dGroups[dg].datasets = [ + ...new Set(tempDatasetsArr), + ]; + } + }); + }); + + let filteredDGroups = {}; + + Object.keys(dGroups).map((dg) => { + if (dGroups[dg].datasets.length > 0) { + filteredDGroups[dg] = dGroups[dg]; + } + }); + + //then create diagram content by disease groups + + let dataContent = ""; + + let dGroupKeys = Object.keys(filteredDGroups).sort(); + let dcountLength = dGroupKeys.length - 1; + + let kIndex = 0; + + dGroupKeys.map((k) => { + dataContent += + '"' + + k.replaceAll(" system", "").replaceAll(" & ", " / ") + + '":' + + filteredDGroups[k].datasets.length; + dataContent += kIndex < dcountLength ? "," : ""; + + kIndex++; + }); + + let content = + '
{"type":"bar","data": { ' + + dataContent + + ' },"width": 400,"height": 150,"color": "multi","x label angle":65,"label space":100}
'; + + return content; + } else { + return null; + } + }, + phenotypesDescription() { + let phenotypes = this.$store.state.bioPortal.phenotypes; + + if (phenotypes.length > 0) { + ///create phenotypes plot content + + let groupLabel = [ + ...new Set(phenotypes.map((p) => p.group)), + ].sort(); + let group = phenotypes.map((g) => g.group); + let groupCount = {}; + + groupLabel.map((l) => { + let tempCount = group.filter((t) => t == l); + groupCount[l] = tempCount.length; + }); + + let groupContent = ""; + let gCountLength = Object.keys(groupCount).length - 1; + + let gIndex = 0; + Object.keys(groupCount).map((g) => { + groupContent += '"' + g + '":' + groupCount[g]; + + groupContent += gIndex < gCountLength ? "," : ""; + gIndex++; + }); + + let content = + '
{"type":"bar","data": { ' + + groupContent + + ' },"width": 400,"height": 150,"color": "multi","x label angle":65,"label space":175}
'; + + return content; + } else { + return null; + } + }, + + pageDescription() { + if ( + this.phenotypesDescription != null && + this.datasetsDescription != null + ) { + let datasets = this.$store.state.bioPortal.datasets; + let phenotypes = this.$store.state.bioPortal.phenotypes; + + let content = "
Datasets by organ system
"; + content += + "Total: " + datasets.length + " datasets"; + content += this.datasetsDescription; + content += "
Phenotypes by group
"; + content += + "Total: " + phenotypes.length + " phenotypes"; + content += this.phenotypesDescription; + + return content; + } else { + return null; + } + }, + pageStats() { + if (this.diseaseGroup) { + return this.stats.find( + (s) => s["Portal ID"] == this.diseaseGroup.name + ); + } else { + return {}; + } + }, + }, + + watch: { + geneOrRegionOrVariant() { + this.$store.commit("setInvalidGeneOrRegionOrVariant", false); + }, + + diseaseGroup(group) { + this.$store.dispatch("kp4cd/getNewsFeed", group.name); + this.$store.dispatch("kp4cd/getFrontContents", group.name); + // this.$store.dispatch("kp4cd/getDatasetsInfo", group.name); + this.$store.dispatch("kp4cd/getPortals"); + }, + }, + + async created() { + this.$store.dispatch("bioPortal/getDiseaseSystems"); + this.$store.dispatch("bioPortal/getDiseaseGroups"); + this.$store.dispatch("bioPortal/getPhenotypes"); + this.$store.dispatch("bioPortal/getDatasets"); + this.getStats(); + await this.$store.dispatch("getPigeanPhenotypes"); + this.formatAllPhenotypes(); + }, + + methods: { + ...uiUtils, + showHideElement(ID) { + uiUtils.showHideElement(ID); + }, + async getStats() { + let dataPoint = + "https://hugeampkpncms.org/rest/directcsv?id=Portal_stats_501"; + + let contJson = await fetch(dataPoint).then((resp) => resp.json()); + + if (contJson.error == null) { + let data = dataConvert.csv2Json( + contJson[0]["field_data_points"] + ); + this.stats = data; + } + }, + capitalize(str) { + return str.replace(/\b\w/g, function (char) { + return char.toUpperCase(); + }); + }, + formatAllPhenotypes(){ + let newPhenotypes = this.$store.state.pigeanAllPhenotypes.data; + let output = []; + for (let i = 0; i < newPhenotypes.length; i++){ + output.push(pigeanUtils.toOldStyle(newPhenotypes[i])); + } + this.$store.dispatch("phenotypesInSession", output); + } + }, + + render(createElement, context) { + return createElement(Template); + }, +}).$mount("#app"); diff --git a/src/views/Mouse/Index/store.js b/src/views/Mouse/Index/store.js new file mode 100644 index 000000000..4ecd45c0e --- /dev/null +++ b/src/views/Mouse/Index/store.js @@ -0,0 +1,101 @@ +import Vue from "vue"; +import Vuex from "vuex"; + +import bioPortal from "@/modules/bioPortal"; +import bioIndex from "@/modules/bioIndex"; +import kp4cd from "@/modules/kp4cd"; +import regionUtils from "@/utils/regionUtils"; +import variantUtils from "@/utils/variantUtils"; +import { postAlertError } from "@/components/Alert.vue"; +import { match } from "@/utils/bioIndexUtils"; + +Vue.use(Vuex); + +export default new Vuex.Store({ + + modules: { + bioPortal, + kp4cd, + pigeanAllPhenotypes: bioIndex("pigean-phenotypes"), + }, + state: { + geneOrRegionOrVariant: null, + invalidGeneOrRegionOrVariant: false, + userInput: null, + matchingGenes: null, + phenotypesInSession: null, + diseaseInSession: null, + phenotypeCorrelation: null, + }, + mutations: { + setInvalidGeneOrRegionOrVariant(state, flag) { + state.invalidGeneOrRegionOrVariant = flag; + }, + setExample(state, example) { + state.geneOrRegionOrVariant = example; + }, + setMatchingGenes(state, genes) { + state.matchingGenes = genes; + }, + setPhenotypesInSession(state, PHENOTYPES) { + state.phenotypesInSession = PHENOTYPES; + }, + setDiseaseInSession(state, DISEASE) { + state.diseaseInSession = DISEASE; + }, + setPhenotypeCorrelation(state, Correlation) { + state.phenotypeCorrelation = Correlation; + } + }, + + actions: { + phenotypesInSession(context, PHENOTYPES) { + context.commit("setPhenotypesInSession", PHENOTYPES); + }, + diseaseInSession(context, DISEASE) { + context.commit("setDiseaseInSession", DISEASE); + }, + + phenotypeCorrelation(context, DATA) { + context.commit("setPhenotypeCorrelation", DATA); + }, + + async exploreRegionOrVariant(context, input) { + let locus = await regionUtils.parseRegion(input, true, 50000); + let varID = await variantUtils.parseVariant(input); + + if (locus) { + window.location.href = `./region.html?chr=${locus.chr}&start=${locus.start}&end=${locus.end}`; + } + else if (varID) { + window.location.href = `./variant.html?variant=${varID}`; + } else { + postAlertError("Invalid gene, variant, or region"); + } + }, + + async lookupGenes(context, input) { + let matches = await match('gene', input, { limit: 10 }) + context.commit('setMatchingGenes', matches); + }, + + //select gene on autocomplete. + async onGeneChange(context, gene) { + let locus = await regionUtils.parseRegion(gene, true, 50000); + + if (locus) { + window.location.href = `./region.html?chr=${locus.chr}&start=${locus.start}&end=${locus.end}`; + } + }, + + //select gene on autocomplete. + async onDatasetChange(context, dataset) { + window.location.href = "./dinspector.html?dataset=" + dataset.name; + }, + async getPigeanPhenotypes(context) { + await context.dispatch("pigeanAllPhenotypes/query", {q:1}); + }, + + }, + +}); diff --git a/src/views/MouseDiffExp/Template.vue b/src/views/Mouse/MouseDiffExp/Template.vue similarity index 100% rename from src/views/MouseDiffExp/Template.vue rename to src/views/Mouse/MouseDiffExp/Template.vue diff --git a/src/views/MouseDiffExp/main.js b/src/views/Mouse/MouseDiffExp/main.js similarity index 100% rename from src/views/MouseDiffExp/main.js rename to src/views/Mouse/MouseDiffExp/main.js diff --git a/src/views/Mouse/MouseDiffExp/store.js b/src/views/Mouse/MouseDiffExp/store.js new file mode 100644 index 000000000..4d4ffdb7d --- /dev/null +++ b/src/views/Mouse/MouseDiffExp/store.js @@ -0,0 +1,120 @@ +import Vue from "vue"; +import Vuex from "vuex"; + +import bioPortal from "@/modules/bioPortal"; +import bioIndex from "@/modules/bioIndex"; +import kp4cd from "@/modules/kp4cd"; +import keyParams from "@/utils/keyParams"; +import { BIO_INDEX_HOST } from "@/utils/bioIndexUtils"; + +Vue.use(Vuex); + +export default new Vuex.Store({ + modules: { + bioPortal, + kp4cd, + diffExp: bioIndex("diff-exp"), + tissueSummary: bioIndex("diff-exp-summary-tissue"), + geneSummary: bioIndex("diff-exp-summary-gene"), + hugeScores: bioIndex("huge"), + geneassociations: bioIndex("gene-associations"), + varassociations: bioIndex("associations"), + associations52k: bioIndex("gene-associations-52k"), + geneToTranscript: bioIndex("gene-to-transcript"), + transcriptAssoc: bioIndex("transcript-associations"), + homologGene: bioIndex("gene"), + }, + state: { + tissue: keyParams.tissue || "", + gene: keyParams.gene || "", + tissueKeys: [], + tissueToQuery: "", + geneToQuery: "", + selectedAncestry: "", + loadingGene: false, + loadingExpression: false, + }, + + mutations: { + setTissueName(state, tissueName) { + state.tissue = tissueName || state.tissue; + keyParams.set({ tissue: state.tissue }); + }, + setGeneName(state, geneName) { + state.gene = geneName || state.gene; + keyParams.set({ gene: state.gene }); + }, + setCommonVariantsLength(state, NUM) { + state.commonVariantsLength = NUM; + }, + setLoadingGene(state, loading=true){ + state.loadingGene = loading; + }, + setLoadingExpression(state, loading=true){ + state.loadingExpression = loading; + } + }, + getters: { + region(state) { + let data = state.homologGene.data; + + if (data.length > 0) { + let gene = data[0]; + + return { + chromosome: gene.chromosome, + start: gene.start, + end: gene.end, + }; + } + }, + }, + actions: { + commonVariantsLength(context, NUM) { + context.commit("setCommonVariantsLength", NUM); + }, + async getTissueKeys(context) { + let tissues = await fetch(`${BIO_INDEX_HOST}/api/bio/keys/diff-exp/2?columns=tissue`) + .then(resp => resp.json()) + .then(json => { + if (json.count == 0) { + return null; + } + return json.keys.map(key => key[0]) + }); + context.state.tissueKeys = tissues; + }, + async selectGeneName(context, geneName){ + context.state.geneToQuery = geneName; + }, + async queryDiffExp(context) { + context.commit("setLoadingExpression"); + + let gene = context.state.geneToQuery || context.state.gene; + context.commit("setLoadingGene"); + context.commit("setGeneName", gene); + await context.dispatch("homologGene/query", {q: gene}); + context.commit("setLoadingGene", false); + + let tissue = context.state.tissueToQuery || context.state.tissue; + context.commit("setTissueName", tissue); + + if (!!tissue){ + context.dispatch("tissueSummary/query", {q: tissue}); + } + if (!!gene){ + let query = { q: gene}; + context.dispatch("geneSummary/query", query); + context.dispatch("hugeScores/query", query); + context.dispatch("associations52k/query", query); + context.dispatch("geneassociations/query", query); + context.dispatch("geneToTranscript/query", query); + } + if (!!gene && !!tissue) { + await context.dispatch("diffExp/query", { q: + `${gene},${tissue}` }); + context.commit("setLoadingExpression", false); + } + }, + }, +}); diff --git a/src/views/Mouse/Tissue/Template.vue b/src/views/Mouse/Tissue/Template.vue new file mode 100644 index 000000000..6acc0de34 --- /dev/null +++ b/src/views/Mouse/Tissue/Template.vue @@ -0,0 +1,350 @@ + + + diff --git a/src/views/Mouse/Tissue/main.js b/src/views/Mouse/Tissue/main.js new file mode 100644 index 000000000..5f3f855ee --- /dev/null +++ b/src/views/Mouse/Tissue/main.js @@ -0,0 +1,183 @@ +import Vue from "vue"; +import Template from "./Template.vue"; +import store from "./store.js"; +import TissueHeritabilityTable from "@/components/TissueHeritabilityTable.vue"; +import TissueExpressionTable from "@/components/TissueExpressionTable.vue"; +import CriterionFunctionGroup from "@/components/criterion/group/CriterionFunctionGroup.vue"; +import FilterPValue from "@/components/criterion/FilterPValue.vue"; +import FilterEnumeration from "@/components/criterion/FilterEnumeration.vue"; +import FilterGreaterThan from "@/components/criterion/FilterGreaterThan.vue"; +import FilterLessThan from "@/components/criterion/FilterLessThan.vue"; +import SearchHeaderWrapper from "@/components/SearchHeaderWrapper.vue"; +import TissueSelectPicker from "@/components/TissueSelectPicker.vue"; +import Scatterplot from "@/components/Scatterplot.vue"; +import MouseSummaryTable from "@/components/MouseSummaryTable.vue"; +import C2ctTable from "@/components/C2ctTable.vue"; +import PhenotypeSelectPicker from "@/components/PhenotypeSelectPicker.vue"; +import AncestrySelectPicker from "@/components/AncestrySelectPicker.vue"; + +import uiUtils from "@/utils/uiUtils"; +import plotUtils from "@/utils/plotUtils"; +import sortUtils from "@/utils/sortUtils"; +import alertUtils from "@/utils/alertUtils"; +import Formatters from "@/utils/formatters"; +import dataConvert from "@/utils/dataConvert"; +import keyParams from "@/utils/keyParams"; +import regionUtils from "@/utils/regionUtils"; + +import ResearchSingleSearch from "@/components/researchPortal/ResearchSingleSearch.vue"; +import { pageMixin } from "@/mixins/pageMixin"; +new Vue({ + store, + components: { + TissueHeritabilityTable, + TissueExpressionTable, + CriterionFunctionGroup, + FilterPValue, + FilterEnumeration, + FilterGreaterThan, + FilterLessThan, + SearchHeaderWrapper, + TissueSelectPicker, + ResearchSingleSearch, + Scatterplot, + MouseSummaryTable, + C2ctTable, + PhenotypeSelectPicker, + AncestrySelectPicker, + }, + mixins: [pageMixin], + data() { + return { + tissue: keyParams.tissue || "", + selectTissue: "", + logScale: false, + cs2ctAncestry: "", + plotConfig: { + xField: "H", + xAxisLabel: "Entropy (genericity)", + yField: "meanTpm", + yAxisLabel: "TPM (mean)", + dotKey: "gene", + hoverBoxPosition: "both", + plotHeight: 300, + hoverFields: [ + { + key: "gene", + label: "Gene", + }, + { + key: "H", + label: "Genericity", + formatter: Formatters.pValueFormatter, + }, + { + key: "Q", + label: "Combined score", + formatter: Formatters.tpmFormatter, + }, + { + key: "meanTpm", + label: "TPM (mean)", + formatter: Formatters.tpmFormatter, + }, + { + key: "nSamples", + label: "Samples", + }, + ], + }, + annotation: "", + }; + }, + computed: { + utilsBox() { + let utils = { + Formatters: Formatters, + uiUtils: uiUtils, + alertUtils: alertUtils, + keyParams: keyParams, + dataConvert: dataConvert, + sortUtils: sortUtils, + plotUtils: plotUtils, + regionUtils: regionUtils, + }; + return utils; + }, + rawPhenotypes() { + return this.$store.state.bioPortal.phenotypes; + }, + phenotypesInSession() { + if (this.$store.state.phenotypesInSession == null) { + return this.$store.state.bioPortal.phenotypes; + } else { + return this.$store.state.phenotypesInSession; + } + }, + diseaseSystem() { + return this.$store.getters["bioPortal/diseaseSystem"]; + }, + tissueData() { + return this.$store.getters["tissueData"]; + }, + docDetails() { + return { + tissue: this.tissue + ? this.tissue.toUpperCase().replaceAll("_", " ") + : "", + }; + }, + cs2ctData() { + let data = this.$store.state.cs2ct.data; + data.forEach((d) => { + // Makes biosamples show up alphabetically in the dropdown menu. + d.originalBiosample = d.biosample; + d.biosample = Formatters.tissueFormatter(d.biosample); + }); + return data.filter(d => d.source !== 'bottom-line_analysis_rare'); + }, + }, + created() { + // get the disease group and set of phenotypes available + this.$store.dispatch("bioPortal/getDiseaseGroups"); + this.$store.dispatch("bioPortal/getPhenotypes"); + this.$store.dispatch("bioPortal/getDatasets"); + this.$store.dispatch("bioPortal/getDiseaseSystems"); + if (this.tissue) { + this.$store.dispatch("getTissue"); + } + this.$store.dispatch("getAnnotations"); + this.$store.dispatch("getAncestries"); + }, + methods: { + tissueFormatter: Formatters.tissueFormatter, + ancestryFormatter: Formatters.ancestryFormatter, + phenotypeFormatter: Formatters.phenotypeFormatter, + newTissue(tissue) { + this.selectTissue = tissue; + }, + updateTissueData() { + this.tissue = this.selectTissue; + this.$store.commit("setTissueName", this.tissue); + this.$store.dispatch("getTissue"); + }, + getTopPhenotype(phenotype) { + if (this.$store.state.selectedPhenotype === null){ + this.$store.dispatch("onPhenotypeChange", phenotype); + } + }, + onAnnotationSelected(){ + this.$store.commit("setSelectedAnnotation", this.annotation); + this.$store.dispatch("getCs2ct"); + } + }, + watch: { + "$store.state.annotationOptions"(data) { + this.annotation = data[0]; + }, + "$store.state.selectedAncestry"(){ + this.$store.dispatch("getCs2ct"); + }, + }, + render: (h) => h(Template), +}).$mount("#app"); diff --git a/src/views/Mouse/Tissue/store.js b/src/views/Mouse/Tissue/store.js new file mode 100644 index 000000000..451d1c39e --- /dev/null +++ b/src/views/Mouse/Tissue/store.js @@ -0,0 +1,123 @@ +import Vue from "vue"; +import Vuex from "vuex"; + +import bioPortal from "@/modules/bioPortal"; +import bioIndex from "@/modules/bioIndex"; +import kp4cd from "@/modules/kp4cd"; +import keyParams from "@/utils/keyParams"; +import { BIO_INDEX_HOST } from "@/utils/bioIndexUtils"; +import { query } from "@/utils/bioIndexUtils"; + +Vue.use(Vuex); + +export default new Vuex.Store({ + modules: { + bioPortal, + kp4cd, + tissue: bioIndex("gene-expression-tissue"), + geneExpression: bioIndex("gene-expression"), + geneLinks: bioIndex("gene-links"), + mouseSummary: bioIndex("diff-exp-summary-tissue"), + cs2ct: bioIndex("c2ct-tissue"), + }, + state: { + tissueName: keyParams.tissue || "", + selectedTissue: "", + geneExpressionTissue: [], + selectedAncestry: "", + selectedPhenotype: null, + annotationOptions: [], + selectedAnnotation: "", + }, + + mutations: { + setTissueName(state, tissueName) { + state.tissueName = tissueName || state.tissueName; + keyParams.set({ tissue: state.tissueName }); + }, + setTopPhenotype(state, phenotype) { + state.topPhenotype = phenotype || state.topPhenotype; + if (!state.selectedPhenotype){ + console.log("no phenotype here"); + state.selectedPhenotype = phenotype; + } + }, + setSelectedAnnotation(state, annotation){ + state.selectedAnnotation = annotation || state.selectedAnnotation; + } + }, + actions: { + getTissue(context) { + context.state.tissueName = context.state.selectedTissue || context.state.tissueName; + context.dispatch("tissue/query", { + q: context.state.tissueName.replaceAll(" ", "_"), limit: 1000 + }); + let name = context.state.tissueName; + // TODO FIX BIOINDICES + if (name === 'adipose_tissue'){ + name = 'adipose'; + } + context.dispatch("mouseSummary/query", {q: name}); + }, + async getEvidence(context, { q }) { + //Do we neeed this? + let evidence = await context.dispatch("geneExpression/query", { + q, + }); + return evidence; + }, + onTissueChange(context, tissue){ + tissue = tissue.replaceAll(" ", "_"); + context.state.selectedTissue = tissue; + keyParams.set({ tissue: tissue }); + }, + getCs2ct(context){ + let queryString = `${context.state.selectedAnnotation},${context.state.tissueName}`; + if (!!context.state.selectedAncestry){ + queryString = `${context.state.selectedAncestry},${queryString}`; + } + queryString = `${context.state.selectedPhenotype.name},${queryString}`; + console.log(queryString); + context.dispatch("cs2ct/query", { q : queryString }); + }, + onPhenotypeChange(context, phenotype){ + context.state.selectedPhenotype = phenotype; + // Credible set is based on top phenotype or user selected phenotype, + // whichever is changed most recently. + context.dispatch("getCs2ct"); + }, + async getAnnotations(context) { + let annotations = await fetch(`${BIO_INDEX_HOST}/api/bio/keys/c2ct-tissue/3?columns=annotation`) + .then(resp => resp.json()) + .then(json => { + if (json.count == 0) { + return null; + } + return json.keys.map(key => key[0]) + }); + console.log(annotations); + context.state.annotationOptions = annotations; + context.state.selectedAnnotation = annotations[0]; + }, + async getAncestries(context) { + let ancestries = await fetch(`${BIO_INDEX_HOST}/api/bio/keys/c2ct-tissue/4?columns=ancestry`) + .then(resp => resp.json()) + .then(json => { + if (json.count == 0) { + return null; + } + return json.keys.map(key => key[0]) + }); + context.state.ancestryOptions = ancestries; + }, + }, + getters: { + tissueData(state) { + if (state.tissue.data) { + //return all data where meanTpm > 1 + return state.tissue.data.filter((d) => d.meanTpm >= 1); + } + return []; + }, + }, +}); diff --git a/vue.config.js b/vue.config.js index 410bf18c9..9087b2d8c 100644 --- a/vue.config.js +++ b/vue.config.js @@ -298,10 +298,31 @@ let pages = { title: "Gene Set Factorization Server", chunks: ["chunk-vendors", "chunk-common", "factorization"], }, + mouse_index: { + entry: "src/views/Mouse/Index/main.js", + template: "public/index.html", + filename: "mouse/index.html", + title: "Mouse Knowledge Portal", + chunks: ["chunk-vendors", "chunk-common", "mouse_index"], + }, + mouse_gene: { + entry: "src/views/Mouse/Gene/main.js", + template: "public/index.html", + filename: "mouse/gene.html", + title: "Mouse Gene", + chunks: ["chunk-vendors", "chunk-common", "mouse_gene"], + }, + mouse_tissue: { + entry: "src/views/Mouse/Tissue/main.js", + template: "public/index.html", + filename: "mouse/tissue.html", + title: "Mouse Tissue", + chunks: ["chunk-vendors", "chunk-common", "mouse_tissue"], + }, mouse_diff_exp: { - entry: "src/views/MouseDiffExp/main.js", + entry: "src/views/Mouse/MouseDiffExp/main.js", template: "public/index.html", - filename: "mouse_diff_exp.html", + filename: "mouse/diff_exp.html", title: "Mouse Differential Expression", chunks: ["chunk-vendors", "chunk-common", "mouse_diff_exp"], },