Skip to content

Commit

Permalink
Fix rendering association frequencies; use proper field for sorting t…
Browse files Browse the repository at this point in the history
…hem (#911)

### Related issues

- Closes #910

### Summary

* Fixes rendering of frequency values in Disease-Phenotype association
tables
* Makes API calls to sort by computed frequency rather than just
`frequency_qualifier`

### Checks

- [x] All tests have passed (or issues created for failing tests)

---------

Co-authored-by: Patrick Golden <[email protected]>
  • Loading branch information
ptgolden and Patrick Golden authored Nov 27, 2024
1 parent af5ab7b commit 84dab5f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 12 deletions.
38 changes: 32 additions & 6 deletions frontend/src/api/associations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,35 @@ export const getAssociations = async (
sort: Sort = null,
) => {
/** make query params */
let sortBy = sort?.key;

/**
* Sorting by frequency_qualifier is a special case. Those terms are entities
* like HP:0040280 ("Always present"), and are only one out of three ways to
* represent the frequency of a phenotypic association. The other two are a
* ratio and a percentage. To sort all three values at the same time, we have
* a derived column in the index that unifies all of these representation
* called `frequency_computed_sortable_float`.
*
* This replacement could be done on /any/ frequency key (has_percentage,
* has_count, has_total), but for now, we only use frequency qualifier in the
* table.
*
* This could end up being a bug if someone /actually/, /really/ wanted to
* only sort by the frequency qualifier, and have the other two classes show
* up as null.
*/
if (sortBy === "frequency_qualifier") {
sortBy = "frequency_computed_sortable_float";
}

const params = {
offset,
limit,
query: search || "",
traverse_orthologs: !!traverseOrthologs,
direct: direct,
sort: sort
? `${sort.key} ${sort.direction === "up" ? "asc" : "desc"}`
: null,
sort: sort ? `${sortBy} ${sort.direction === "up" ? "asc" : "desc"}` : null,
};

/** make query */
Expand All @@ -45,14 +65,20 @@ export const downloadAssociations = async (
sort: Sort = null,
) => {
/** make query params */

let sortBy = sort?.key;

/** See comment in getAssociations() */
if (sortBy === "frequency_qualifier") {
sortBy = "frequency_computed_sortable_float";
}

const params = {
limit: maxDownload,
query: search || "",
traverse_orthologs: !!traverseOrthologs,
direct: direct,
sort: sort
? `${sort.key} ${sort.direction === "up" ? "asc" : "desc"}`
: null,
sort: sort ? `${sortBy} ${sort.direction === "up" ? "asc" : "desc"}` : null,
download: true,
format: "tsv",
};
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/pages/node/AssociationsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

<template #frequency="{ row }">
<AppPercentage
v-if="frequencyPercentage(row) !== undefined"
v-if="frequencyPercentage(row) != undefined"
type="bar"
:percent="frequencyPercentage(row) || 0"
:tooltip="frequencyTooltip(row)"
Expand Down Expand Up @@ -358,14 +358,14 @@ async function download() {
/** get phenotype frequency percentage 0-1 */
const frequencyPercentage = (row: DirectionalAssociation) => {
/** frequency from % out of 100 */
if (row.has_percentage !== undefined) return row.has_percentage / 100;
if (row.has_percentage != undefined) return row.has_percentage / 100;

/** frequency from ratio */
if (row.has_count !== undefined && row.has_total !== undefined) {
if (row.has_count != undefined && row.has_total != undefined) {
return row.has_count / row.has_total;
}
/** enumerated frequencies */
if (row.frequency_qualifier !== undefined)
if (row.frequency_qualifier != undefined)
switch (row.frequency_qualifier) {
case "HP:0040280":
return 1;
Expand All @@ -385,12 +385,12 @@ const frequencyPercentage = (row: DirectionalAssociation) => {
/** get frequency tooltip */
const frequencyTooltip = (row: DirectionalAssociation) => {
// display fraction if possible
if (row.has_count !== undefined && row.has_total !== undefined) {
if (row.has_count != undefined && row.has_total != undefined) {
return `${row.has_count} of ${row.has_total} cases`;
}

// if percentage is present but fraction isn't, that's what was originally in the data
if (row.has_percentage !== undefined && row.has_total !== undefined) {
if (row.has_percentage != undefined && row.has_total != undefined) {
return `${row.has_percentage.toFixed(0)}%`;
}
// if no percentage or fraction, display the qualifier label
Expand Down

0 comments on commit 84dab5f

Please sign in to comment.