diff --git a/src/pages/patientView/mutation/PatientViewMutationTable.tsx b/src/pages/patientView/mutation/PatientViewMutationTable.tsx index 9b046c65805..6c352a765a9 100644 --- a/src/pages/patientView/mutation/PatientViewMutationTable.tsx +++ b/src/pages/patientView/mutation/PatientViewMutationTable.tsx @@ -46,6 +46,7 @@ export default class PatientViewMutationTable extends MutationTable extends React. } }; + this._columns[MutationTableColumnType.HGVSG] = { + name: "HGVSg", + render: (d:Mutation[]) => HgvsgColumnFormatter.renderFunction(d, this.props.genomeNexusCache), + download: (d:Mutation[]) => HgvsgColumnFormatter.download(d, this.props.genomeNexusCache as GenomeNexusCache), + sortBy: (d:Mutation[]) => HgvsgColumnFormatter.getSortValue(d, this.props.genomeNexusCache as GenomeNexusCache), + visible: true, + align: "left" + }; + this._columns[MutationTableColumnType.CANCER_TYPE] = { name: "Cancer Type", render: (d:Mutation[]) => CancerTypeColumnFormatter.render(d, this.props.uniqueSampleKeyToTumorType), diff --git a/src/shared/components/mutationTable/column/GenomeNexusLogo.png b/src/shared/components/mutationTable/column/GenomeNexusLogo.png new file mode 100644 index 00000000000..7c9cab016da Binary files /dev/null and b/src/shared/components/mutationTable/column/GenomeNexusLogo.png differ diff --git a/src/shared/components/mutationTable/column/HgvsgColumnFormatter.tsx b/src/shared/components/mutationTable/column/HgvsgColumnFormatter.tsx new file mode 100644 index 00000000000..3d797122a76 --- /dev/null +++ b/src/shared/components/mutationTable/column/HgvsgColumnFormatter.tsx @@ -0,0 +1,107 @@ +import * as React from 'react'; +import {Circle} from "better-react-spinkit"; +import 'rc-tooltip/assets/bootstrap_white.css'; +import {Mutation} from "shared/api/generated/CBioPortalAPI"; +import { + TableCellStatusIndicator, + TableCellStatus, + VariantAnnotation +} from "cbioportal-frontend-commons"; +import GenomeNexusCache, { GenomeNexusCacheDataType } from "shared/cache/GenomeNexusCache"; + +import hgvsgStyles from "./hgvsg.module.scss"; + + +export default class HgvsgColumnFormatter { + + public static renderFunction(data:Mutation[], + genomeNexusCache:GenomeNexusCache|undefined) { + const genomeNexusCacheData = HgvsgColumnFormatter.getGenomeNexusDataFromCache(data, genomeNexusCache); + + return {HgvsgColumnFormatter.getHgvsgDataViz(genomeNexusCacheData)}; + } + + private static getGenomeNexusDataFromCache(data:Mutation[], cache:GenomeNexusCache|undefined):GenomeNexusCacheDataType | null { + if (data.length === 0 || !cache) { + return null; + } + return cache.get(data[0]); + } + + private static getHgvsgDataViz(genomeNexusCacheData:GenomeNexusCacheDataType|null) { + let status:TableCellStatus | null = null; + if (genomeNexusCacheData === null) { + status = TableCellStatus.LOADING; + } else if (genomeNexusCacheData.status === "error") { + status = TableCellStatus.ERROR; + } else if (genomeNexusCacheData.data === null) { + status = TableCellStatus.NA; + } else { + let hgvsgData = HgvsgColumnFormatter.getData(genomeNexusCacheData.data); + if (hgvsgData == null) { + return null; + } + else { + return ( + + {hgvsgData} + Genome Nexus + + ); + } + } + + if (status !== null) { + // show loading circle + if (status === TableCellStatus.LOADING) { + return ; + } + else { + return ; + } + } + } + + public static getData(genomeNexusData: VariantAnnotation | null): string | null + { + if (!genomeNexusData) + { + return null; + } + return genomeNexusData.hgvsg; + } + + public static download(data:Mutation[], genomeNexusCache:GenomeNexusCache): string + { + const genomeNexusData = HgvsgColumnFormatter.getGenomeNexusDataFromCache(data, genomeNexusCache); + const hgvsgData = genomeNexusData && HgvsgColumnFormatter.getData(genomeNexusData.data); + + if (!hgvsgData) { + return ""; + } + else { + return hgvsgData; + } + } + + public static getSortValue(data:Mutation[], genomeNexusCache:GenomeNexusCache): string|null { + const genomeNexusCacheData = HgvsgColumnFormatter.getGenomeNexusDataFromCache(data, genomeNexusCache); + if (genomeNexusCacheData) { + let hgvsgData = HgvsgColumnFormatter.getData(genomeNexusCacheData.data); + if (hgvsgData == null) { + return null + } + else { + return hgvsgData; + } + } + else { + return null; + } + } +} \ No newline at end of file diff --git a/src/shared/components/mutationTable/column/hgvsg.module.scss b/src/shared/components/mutationTable/column/hgvsg.module.scss new file mode 100644 index 00000000000..9e5a4dfab94 --- /dev/null +++ b/src/shared/components/mutationTable/column/hgvsg.module.scss @@ -0,0 +1,22 @@ +.hgvsg-data a, +.hgvsg-data a:hover, +.hgvsg-data a:focus, +.hgvsg-data a:active, +.hgvsg-data a:visited { + color: black; +} + +.hgvsg-data { + white-space: nowrap; + max-width: 300px; + overflow: hidden; + text-overflow: ellipsis; + display:block; +} + +.hgvsg-data:hover { + text-overflow: clip; + word-break: break-all; + overflow: visible; + white-space: normal; +} \ No newline at end of file diff --git a/src/shared/lib/MutationUtils.ts b/src/shared/lib/MutationUtils.ts index d1219e8af36..5812d9dd54a 100644 --- a/src/shared/lib/MutationUtils.ts +++ b/src/shared/lib/MutationUtils.ts @@ -232,7 +232,18 @@ export function extractGenomicLocation(mutation: Mutation) // TODO remove when done refactoring mutation mapper export function genomicLocationString(genomicLocation: GenomicLocation) { - return `${genomicLocation.chromosome},${genomicLocation.start},${genomicLocation.end},${genomicLocation.referenceAllele},${genomicLocation.variantAllele}`; + // mapping chromosome X with 23 + let chromosome = ""; + if (genomicLocation.chromosome === "X") { + chromosome = "23"; + } + else if (genomicLocation.chromosome === "Y") { + chromosome = "24"; + } + else { + chromosome = genomicLocation.chromosome; + } + return `${chromosome},${genomicLocation.start},${genomicLocation.end},${genomicLocation.referenceAllele},${genomicLocation.variantAllele}`; } // TODO remove when done refactoring mutation mapper