KarrLab/datanator_frontend

View on GitHub
src/scenes/BiochemicalEntityDetails/Gene/RnaHalfLifeDataTable.js

Summary

Maintainability
F
1 wk
Test Coverage
F
48%
import React, { Component } from "react";
import PropTypes from "prop-types";
import {
  upperCaseFirstLetter,
  isOrthoDbId,
  isUniProtId,
  castToArray,
} from "~/utils/utils";
import DataTable from "../DataTable/DataTable";
import { HtmlColumnHeader } from "../HtmlColumnHeader";
import Tooltip from "@material-ui/core/Tooltip";
import { TAXONOMIC_PROXIMITY_TOOLTIP } from "../ColumnsToolPanel/TooltipDescriptions";

class RnaHalfLifeDataTable extends Component {
  static propTypes = {
    "set-scene-metadata": PropTypes.func.isRequired,
  };

  getUrl(query, organism) {
    let endpoint;
    const args = [];

    if (isOrthoDbId(query)) {
      // ortholog groups of mRNA
      endpoint = "rna/halflife/get_info_by_ko/";
      args.push("ko_number=" + query);
    } else if (isUniProtId(query)) {
      // individual genes
      endpoint = "rna/halflife/get_info_by_uniprot/";
      args.push("uniprot_id=" + query);
    } else {
      // ortholog groups of non-coding RNA
      endpoint = "rna/halflife/get_info_by_uniprot/";
      args.push("uniprot_id=" + query);
    }

    args.push("_from=0");
    args.push("size=1000");

    if (organism) {
      args.push("taxon_distance=true");
      args.push("species=" + organism);
    }

    return endpoint + "?" + args.join("&");
  }

  static formatData(query, organism, rawData) {
    const formattedData = [];
    for (const rawDatum of rawData) {
      if ("halflives" in rawDatum && rawDatum.halflives) {
        const measurements = rawDatum.halflives;
        for (const measurement of measurements) {
          if ("halflife" in measurement) {
            let formattedDatum = {
              halfLife: parseFloat(measurement.halflife),
              units: measurement.unit,
              proteinName:
                "protein_names" in rawDatum && rawDatum.protein_names
                  ? rawDatum.protein_names[0]
                  : null,
              uniprotId: "uniprot_id" in rawDatum ? rawDatum.uniprot_id : null,
              organism: measurement.species,
              cellLine: null,
              growthMedium:
                "growth_medium" in measurement
                  ? measurement.growth_medium
                  : null,
              source: {
                id: "DOI: " + castToArray(measurement.reference)[0].doi,
                url:
                  "https://dx.doi.org/" +
                  castToArray(measurement.reference)[0].doi,
              },
            };

            if (organism != null) {
              formattedDatum[
                "taxonomicProximity"
              ] = DataTable.calcTaxonomicDistance(
                measurement.taxon_distance,
                organism,
                measurement.species
              );
            }

            formattedData.push(formattedDatum);
          } else if ("values" in measurement) {
            const cellLineValues = {};

            for (const value of measurement.values) {
              let cellLine;
              for (const key in value) {
                if (
                  key !== "biological_replicates" &&
                  key !== "technical_replicates" &&
                  key !== "note" &&
                  key !== "unit"
                ) {
                  cellLine = key;
                }
              }

              let units = value.unit;
              let halfLife = value[cellLine];
              if (halfLife == null) {
                continue;
              }

              if (units === "hr") {
                units = "s";
                halfLife *= 60;
              }

              if ("biological_replicates" in value) {
                if (cellLine in cellLineValues) {
                  if ("values" in cellLineValues[cellLine]) {
                    cellLineValues[cellLine].values.push(halfLife);
                  }
                } else {
                  cellLineValues[cellLine] = {
                    values: [halfLife],
                    units: units,
                  };
                }
              } else {
                cellLineValues[cellLine] = { value: halfLife, units: units };
              }
            }

            for (const cellLine in cellLineValues) {
              const cellLineValue = cellLineValues[cellLine];

              let formattedDatum = {
                units: cellLineValue.units,
                proteinName:
                  "protein_names" in rawDatum && rawDatum.protein_names
                    ? rawDatum.protein_names[0]
                    : null,
                uniprotId:
                  "uniprot_id" in rawDatum ? rawDatum.uniprot_id : null,
                organism: measurement.species,
                cellLine: cellLine.toUpperCase(),
                growthMedium:
                  "growth_medium" in measurement
                    ? measurement.growth_medium
                    : null,
                source: {
                  id: "DOI: " + castToArray(measurement.reference)[0].doi,
                  url:
                    "https://dx.doi.org/" +
                    castToArray(measurement.reference)[0].doi,
                },
              };

              if ("value" in cellLineValue) {
                formattedDatum.halfLife = cellLineValue.value;
              } else {
                formattedDatum.halfLife =
                  cellLineValue.values.reduce((a, b) => a + b, 0) /
                  cellLineValue.values.length;
              }

              if (organism != null) {
                formattedDatum[
                  "taxonomicProximity"
                ] = DataTable.calcTaxonomicDistance(
                  measurement.taxon_distance,
                  organism,
                  measurement.species
                );
              }

              formattedData.push(formattedDatum);
            }
          }
        }
      }
    }

    return formattedData;
  }

  static getSideBarDef() {
    return {
      toolPanels: [
        {
          id: "columns",
          labelDefault: "Columns",
          labelKey: "columns",
          iconKey: "columns",
          toolPanel: "columnsToolPanel",
        },
        {
          id: "filters",
          labelDefault: "Filters",
          labelKey: "filters",
          iconKey: "filter",
          toolPanel: "filtersToolPanel",
        },
        {
          id: "stats",
          labelDefault: "Stats",
          labelKey: "chart",
          iconKey: "chart",
          toolPanel: "statsToolPanel",
          toolPanelParams: {
            col: ["halfLife"],
          },
        },
      ],
      position: "left",
      defaultToolPanel: "filters",
      hiddenByDefault: false,
    };
  }

  static getColDefs(query, organism, formattedData, taxonomicRanks) {
    const colDefs = [
      {
        headerName: "Half-life",
        headerComponentFramework: HtmlColumnHeader,
        headerComponentParams: {
          name: <span>Half-life</span>,
        },
        field: "halfLife",
        cellRenderer: "numericCellRenderer",
        type: "numericColumn",
        filter: "numberFilter",
        checkboxSelection: true,
        headerCheckboxSelection: true,
        headerCheckboxSelectionFilteredOnly: true,
        comparator: DataTable.numericComparator,
      },
      {
        headerName: "Units",
        field: "units",
        filter: "textFilter",
      },
      {
        headerName: "Protein",
        field: "proteinName",
        filter: "textFilter",
      },
      {
        headerName: "UniProt id",
        field: "uniprotId",
        cellRenderer: function (params) {
          return (
            '<a href="https://www.uniprot.org/uniprot/' +
            params.value +
            '" target="_blank" rel="noopener noreferrer">' +
            params.value +
            "</a>"
          );
        },
      },
      {
        headerName: "Organism",
        field: "organism",
        filter: "textFilter",
        cellRenderer: function (params) {
          const organism = params.value;
          if (organism) {
            return (
              '<a href="https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?name=' +
              organism +
              '" target="_blank" rel="noopener noreferrer">' +
              organism +
              "</a>"
            );
          } else {
            return null;
          }
        },
      },
      {
        headerName: "Taxonomic similarity",
        headerComponentFramework: HtmlColumnHeader,
        headerComponentParams: {
          name: (
            <Tooltip title={TAXONOMIC_PROXIMITY_TOOLTIP} arrow>
              <span>Taxonomic similarity</span>
            </Tooltip>
          ),
        },
        field: "taxonomicProximity",
        hide: true,
        filter: "taxonomyFilter",
        valueFormatter: (params) => {
          if (params.value != null) {
            const value = taxonomicRanks[params.value];
            return upperCaseFirstLetter(value);
          } else {
            return null;
          }
        },
        comparator: DataTable.numericComparator,
        processCellCallback: (value) => {
          if (value) {
            return taxonomicRanks[value];
          } else {
            return null;
          }
        },
      },
      {
        headerName: "Cell line",
        field: "cellLine",
        filter: "textFilter",
        cellRenderer: function (params) {
          const cellLine = params.value;
          if (cellLine) {
            return (
              '<a href="https://www.coriell.org/0/Sections/Search/Sample_Detail.aspx?Ref=' +
              cellLine +
              '" target="_blank" rel="noopener noreferrer">' +
              cellLine +
              "</a>"
            );
          } else {
            return null;
          }
        },
      },
      {
        headerName: "Media",
        field: "growthMedium",
        filter: "textFilter",
        hide: false,
      },
      {
        headerName: "Source",
        field: "source",
        cellRenderer: function (params) {
          const source = params.value;
          return (
            '<a href="' +
            source.url +
            '" target="_blank" rel="noopener noreferrer">' +
            source.id +
            "</a>"
          );
        },
        filterValueGetter: (params) => {
          const source = params.data.source;
          return source.id;
        },
        filter: "textFilter",
        processCellCallback: (value) => {
          if (value) {
            return value.id;
          } else {
            return null;
          }
        },
      },
    ];

    if (!organism) {
      colDefs.splice(-4, 1);
    }
    return colDefs;
  }

  static getColSortOrder() {
    return [
      { colId: "taxonomicProximity", sort: "asc" },
      { colId: "organism", sort: "asc" },
      // { colId: "cellLine", sort: "asc" },
      { colId: "halfLife", sort: "asc" },
    ];
  }

  render() {
    return (
      <DataTable
        id="rna-half-life"
        title="RNA half-life"
        entity-type="ortholog group"
        data-type="RNA half-life"
        get-data-url={this.getUrl}
        format-data={RnaHalfLifeDataTable.formatData}
        get-side-bar-def={RnaHalfLifeDataTable.getSideBarDef}
        get-col-defs={RnaHalfLifeDataTable.getColDefs}
        get-col-sort-order={RnaHalfLifeDataTable.getColSortOrder}
        dom-layout="normal"
        set-scene-metadata={this.props["set-scene-metadata"]}
      />
    );
  }
}
export { RnaHalfLifeDataTable };