<commit_before>// @flow

import React from 'react';
import { compose, withState, lifecycle } from 'recompose';
import LocationSubscriber from '@ncigdc/components/LocationSubscriber';

import { parseFilterParam } from '@ncigdc/utils/uri';
import { fetchApi } from '@ncigdc/utils/ajax';
import { getDefaultCurve } from '@ncigdc/utils/survivalplot';
import { makeFilter, setFilter, replaceFilters } from '@ncigdc/utils/filters';

import { Row, Column } from '@ncigdc/uikit/Flex';

import FrequentMutationsChart from '@ncigdc/containers/FrequentMutationsChart';
import FrequentMutationsTable from '@ncigdc/containers/FrequentMutationsTable';

import MostAffectedCasesContainer from '@ncigdc/components/MostAffectedCasesContainer';
import OncoGridWrapper from '@ncigdc/components/Oncogrid/OncogridWrapper';
import FrequentlyMutatedGenesContainer from '@ncigdc/components/FrequentlyMutatedGenesContainer';
import SpinnerParticle from '@ncigdc/uikit/Loaders/Particle';
import SurvivalPlotWrapper from '@ncigdc/components/SurvivalPlotWrapper';

const styles = {
  heading: {
    flexGrow: 1,
    fontSize: '2rem',
    marginBottom: 7,
    marginTop: 7,
  },
  card: {
    backgroundColor: 'white',
  },
};

const initialState = {
  loading: true,
  numCasesAggByProject: {},
  mutatedGenesProject: {},
  defaultSurvivalRawData: {},
};

const enhance = compose(
  withState('selectedSurvivalData', 'setSelectedSurvivalData', {}),
  withState('state', 'setState', initialState),
  lifecycle({
    async componentDidMount(): Promise<*> {
      const { projectId } = this.props;
      const data1 = await fetchApi(
        'analysis/mutated_cases_count_by_project?size=0',
        { headers: { 'Content-Type': 'application/json' } }
      );

      const numCasesAggByProject = data1.aggregations.projects.buckets.reduce((acc, b) => ({
        ...acc,
        [b.key]: b.case_summary.case_with_ssm.doc_count,
      }), {});

      const defaultSurvivalData = await getDefaultCurve({
        totalCases: numCasesAggByProject[projectId],
        currentFilters: { op: '=', content: { field: 'cases.project.project_id', value: projectId } },
        slug: projectId,
      });

      this.props.setState(s => ({
        ...s,
        loading: false,
        numCasesAggByProject,
        defaultSurvivalData,
      }));
    },
  })
);

const ProjectVisualizations = enhance(({
  state: {
    defaultSurvivalData,
    numCasesAggByProject,
    loading,
  },
  setSelectedSurvivalData,
  selectedSurvivalData,
  projectId,
  viewer,
}) => {
  if (loading) return <Column style={{ alignItems: 'center', padding: '20px' }}><SpinnerParticle /></Column>;

  const survivalData = {
    legend: selectedSurvivalData.legend || defaultSurvivalData.legend,
    rawData: selectedSurvivalData.rawData || defaultSurvivalData.rawData,
  };

  const totalNumCases = Object.keys(numCasesAggByProject).reduce((sum, b) => sum + numCasesAggByProject[b], 0);

  const fmFilters = makeFilter([{ field: 'cases.project.project_id', value: projectId }], false);

  return (
    <div>
      <Column style={styles.card}>
        <h1 style={{ ...styles.heading, padding: '1rem' }} id="mutated-genes">
          <i className="fa fa-bar-chart-o" style={{ paddingRight: '10px' }} />
          Most Frequently Mutated Genes
        </h1>
        <LocationSubscriber>{(ctx: {| pathname: string, query: TRawQuery |}) => {
          const { filters } = ctx.query || {};
          const currentFilters = parseFilterParam(filters, { op: 'and', content: [] });
          const componentFilters = replaceFilters(setFilter({
            field: 'cases.project.project_id',
            value: projectId,
          }), currentFilters);
          return (
            <FrequentlyMutatedGenesContainer
              numCasesAggByProject={numCasesAggByProject}
              survivalData={survivalData}
              setSelectedSurvivalData={setSelectedSurvivalData}
              selectedSurvivalData={selectedSurvivalData}
              totalNumCases={totalNumCases}
              projectId={projectId}
              currentFilters={componentFilters}
            />
          );
        }}</LocationSubscriber>

      </Column>

      <Column style={{ ...styles.card, marginTop: '2rem', position: 'static' }}>
        <h1 style={{ ...styles.heading, padding: '1rem' }} id="oncogrid">
          <i className="fa fa-th" style={{ paddingRight: '10px' }} />
          OncoGrid
        </h1>
        <LocationSubscriber>{(ctx: {| pathname: string, query: TRawQuery |}) => {
          const { filters } = ctx.query || {};
          const currentFilters = parseFilterParam(filters, { op: 'and', content: [] });
          const componentFilters = replaceFilters(setFilter({ field: 'cases.project.project_id', value: projectId }), currentFilters);
          return (
            <OncoGridWrapper
              projectId={projectId}
              currentFilters={componentFilters}
            />
          );
        }}</LocationSubscriber>


      </Column>

      <Column style={{ ...styles.card, marginTop: '2rem' }}>
        <h1 style={{ ...styles.heading, padding: '1rem' }} id="frequent-mutations">
          <i className="fa fa-bar-chart-o" style={{ paddingRight: '10px' }} />
          Most Frequent Mutations
        </h1>
        <Column>
          <Row>
            <Column flex="1">
              <FrequentMutationsChart
                projectId={projectId}
                numCasesAggByProject={numCasesAggByProject}
                defaultFilters={fmFilters}
                cohort={viewer.frequentMutationsChartFragment}
                showSurvivalPlot
              />
            </Column>
            <Column flex="1">
              <SurvivalPlotWrapper
                {...survivalData}
                onReset={() => setSelectedSurvivalData({})}
                height={240}
                survivalPlotloading={loading}
              />
            </Column>
          </Row>
          <FrequentMutationsTable
            projectId={projectId}
            numCasesAggByProject={numCasesAggByProject}
            defaultFilters={fmFilters}
            cohort={viewer.frequentMutationsTableFragment}
            selectedSurvivalData={selectedSurvivalData}
            setSelectedSurvivalData={setSelectedSurvivalData}
            showSurvivalPlot
          />
        </Column>
      </Column>
      <Column style={{ ...styles.card, marginTop: '2rem' }}>
        <h1 style={{ ...styles.heading, padding: '1rem' }} id="most-affected-cases">
          <i className="fa fa-bar-chart-o" style={{ paddingRight: '10px' }} />
          Most Affected Cases
        </h1>
        <MostAffectedCasesContainer projectId={projectId} />
      </Column>
    </div>
  );
});

export default ProjectVisualizations;<commit_msg>:bug: PRTL-831 proj pg - seperate states for the 2 survival plots (#1361)<commit_after>// @flow

import React from 'react';
import { compose, withState, lifecycle } from 'recompose';
import LocationSubscriber from '@ncigdc/components/LocationSubscriber';

import { parseFilterParam } from '@ncigdc/utils/uri';
import { fetchApi } from '@ncigdc/utils/ajax';
import { getDefaultCurve } from '@ncigdc/utils/survivalplot';
import { makeFilter, setFilter, replaceFilters } from '@ncigdc/utils/filters';

import { Row, Column } from '@ncigdc/uikit/Flex';

import FrequentMutationsChart from '@ncigdc/containers/FrequentMutationsChart';
import FrequentMutationsTable from '@ncigdc/containers/FrequentMutationsTable';

import MostAffectedCasesContainer from '@ncigdc/components/MostAffectedCasesContainer';
import OncoGridWrapper from '@ncigdc/components/Oncogrid/OncogridWrapper';
import FrequentlyMutatedGenesContainer from '@ncigdc/components/FrequentlyMutatedGenesContainer';
import SpinnerParticle from '@ncigdc/uikit/Loaders/Particle';
import SurvivalPlotWrapper from '@ncigdc/components/SurvivalPlotWrapper';

const styles = {
  heading: {
    flexGrow: 1,
    fontSize: '2rem',
    marginBottom: 7,
    marginTop: 7,
  },
  card: {
    backgroundColor: 'white',
  },
};

const initialState = {
  loading: true,
  numCasesAggByProject: {},
  mutatedGenesProject: {},
  defaultSurvivalRawData: {},
};

const enhance = compose(
  withState('selectedMutatedGenesSurvivalData', 'setSelectedMutatedGenesSurvivalData', {}),
  withState('selectedFrequentMutationsSurvivalData', 'setSelectedFrequentMutationsSurvivalData', {}),
  withState('state', 'setState', initialState),
  lifecycle({
    async componentDidMount(): Promise<*> {
      const { projectId } = this.props;
      const data1 = await fetchApi(
        'analysis/mutated_cases_count_by_project?size=0',
        { headers: { 'Content-Type': 'application/json' } }
      );

      const numCasesAggByProject = data1.aggregations.projects.buckets.reduce((acc, b) => ({
        ...acc,
        [b.key]: b.case_summary.case_with_ssm.doc_count,
      }), {});

      const defaultSurvivalData = await getDefaultCurve({
        totalCases: numCasesAggByProject[projectId],
        currentFilters: { op: '=', content: { field: 'cases.project.project_id', value: projectId } },
        slug: projectId,
      });

      this.props.setState(s => ({
        ...s,
        loading: false,
        numCasesAggByProject,
        defaultSurvivalData,
      }));
    },
  })
);

const ProjectVisualizations = enhance(({
  state: {
    defaultSurvivalData,
    numCasesAggByProject,
    loading,
  },
  selectedMutatedGenesSurvivalData,
  setSelectedMutatedGenesSurvivalData,
  selectedFrequentMutationsSurvivalData,
  setSelectedFrequentMutationsSurvivalData,
  projectId,
  viewer,
}) => {
  if (loading) return <Column style={{ alignItems: 'center', padding: '20px' }}><SpinnerParticle /></Column>;

  const mutatedGenesSurvivalData = {
    legend: selectedMutatedGenesSurvivalData.legend || defaultSurvivalData.legend,
    rawData: selectedMutatedGenesSurvivalData.rawData || defaultSurvivalData.rawData,
  };

  const frequentMutationsSurvivalData = {
    legend: selectedFrequentMutationsSurvivalData.legend || defaultSurvivalData.legend,
    rawData: selectedFrequentMutationsSurvivalData.rawData || defaultSurvivalData.rawData,
  };
  const totalNumCases = Object.keys(numCasesAggByProject).reduce((sum, b) => sum + numCasesAggByProject[b], 0);

  const fmFilters = makeFilter([{ field: 'cases.project.project_id', value: projectId }], false);

  return (
    <div>
      <Column style={styles.card}>
        <h1 style={{ ...styles.heading, padding: '1rem' }} id="mutated-genes">
          <i className="fa fa-bar-chart-o" style={{ paddingRight: '10px' }} />
          Most Frequently Mutated Genes
        </h1>
        <LocationSubscriber>{(ctx: {| pathname: string, query: TRawQuery |}) => {
          const { filters } = ctx.query || {};
          const currentFilters = parseFilterParam(filters, { op: 'and', content: [] });
          const componentFilters = replaceFilters(setFilter({
            field: 'cases.project.project_id',
            value: projectId,
          }), currentFilters);
          return (
            <FrequentlyMutatedGenesContainer
              numCasesAggByProject={numCasesAggByProject}
              survivalData={mutatedGenesSurvivalData}
              setSelectedSurvivalData={setSelectedMutatedGenesSurvivalData}
              selectedSurvivalData={selectedMutatedGenesSurvivalData}
              totalNumCases={totalNumCases}
              projectId={projectId}
              currentFilters={componentFilters}
            />
          );
        }}</LocationSubscriber>

      </Column>

      <Column style={{ ...styles.card, marginTop: '2rem', position: 'static' }}>
        <h1 style={{ ...styles.heading, padding: '1rem' }} id="oncogrid">
          <i className="fa fa-th" style={{ paddingRight: '10px' }} />
          OncoGrid
        </h1>
        <LocationSubscriber>{(ctx: {| pathname: string, query: TRawQuery |}) => {
          const { filters } = ctx.query || {};
          const currentFilters = parseFilterParam(filters, { op: 'and', content: [] });
          const componentFilters = replaceFilters(setFilter({ field: 'cases.project.project_id', value: projectId }), currentFilters);
          return (
            <OncoGridWrapper
              projectId={projectId}
              currentFilters={componentFilters}
            />
          );
        }}</LocationSubscriber>


      </Column>

      <Column style={{ ...styles.card, marginTop: '2rem' }}>
        <h1 style={{ ...styles.heading, padding: '1rem' }} id="frequent-mutations">
          <i className="fa fa-bar-chart-o" style={{ paddingRight: '10px' }} />
          Most Frequent Mutations
        </h1>
        <Column>
          <Row>
            <Column flex="1">
              <FrequentMutationsChart
                projectId={projectId}
                numCasesAggByProject={numCasesAggByProject}
                defaultFilters={fmFilters}
                cohort={viewer.frequentMutationsChartFragment}
                showSurvivalPlot
              />
            </Column>
            <Column flex="1">
              <SurvivalPlotWrapper
                {...frequentMutationsSurvivalData}
                onReset={() => setSelectedFrequentMutationsSurvivalData({})}
                height={240}
                survivalPlotloading={loading}
              />
            </Column>
          </Row>
          <FrequentMutationsTable
            projectId={projectId}
            numCasesAggByProject={numCasesAggByProject}
            defaultFilters={fmFilters}
            cohort={viewer.frequentMutationsTableFragment}
            selectedSurvivalData={selectedFrequentMutationsSurvivalData}
            setSelectedSurvivalData={setSelectedFrequentMutationsSurvivalData}
            showSurvivalPlot
          />
        </Column>
      </Column>
      <Column style={{ ...styles.card, marginTop: '2rem' }}>
        <h1 style={{ ...styles.heading, padding: '1rem' }} id="most-affected-cases">
          <i className="fa fa-bar-chart-o" style={{ paddingRight: '10px' }} />
          Most Affected Cases
        </h1>
        <MostAffectedCasesContainer projectId={projectId} />
      </Column>
    </div>
  );
});

export default ProjectVisualizations;
{'fraction_non_alphanumeric': 0.12647162495593936, 'fraction_numerical': 0.005921748325696158, 'mean_word_length': 2.8083221476510065, 'pattern_counts': {'":': 0, '<': 91, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4554887', 'n_tokens_mistral': 4263, 'n_tokens_neox': 4075, 'n_words': 756}