<commit_before>// @flow
/* global API */

import React from 'react';
import _ from 'lodash';
import { compose, withState, lifecycle } from 'recompose';
import { insertRule } from 'glamor';
import { connect } from 'react-redux';
import JSURL from 'jsurl';

import sapien from '@oncojs/sapien';

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

import withRouter from '@ncigdc/utils/withRouter';
import { makeFilter } from '@ncigdc/utils/filters';

import styled from '@ncigdc/theme/styled';

import ExploringLinks from './ExploringLinks';
import PortalSummary from './PortalSummary';
import GDCAppsRow from './GDCAppsRow';

type TTransformChartData = ({ hits: Array<Object> }) => Array<Object>;
const transformChartData: TTransformChartData = ({ hits }) => {
  if (!hits) return [];

  // reduce the array keyed on projectID
  const primarySites = hits.reduce((primarySiteData, project) => {
    const primarySite = project.primary_site;

    if (primarySite) {
      if (!_.isArray(primarySiteData[primarySite])) {
        primarySiteData[primarySite] = [];
      }

      primarySiteData[primarySite].push(project);
    }

    return primarySiteData;
  }, {});

  const primarySiteIDs = _.keys(primarySites);

  if (!primarySiteIDs.length) return [];

  const firstPassProjectData = primarySiteIDs.map(pID => {
    const primarySiteData = primarySites[pID];
    let caseCount = 0;
    let fileCount = 0;

    for (let i = 0; i < primarySiteData.length; i++) {
      caseCount += +(_.get(primarySiteData[i], 'summary.case_count', 0));
      fileCount += +(_.get(primarySiteData[i], 'summary.file_count', 0));
    }

    /* _key and _count are required data properties for the marked bar chart */
    return { _key: pID, values: primarySiteData, _count: caseCount, fileCount };
  })
    .filter(d => d._count > 0)
    .sort((a, b) => b._count - a._count);

  return firstPassProjectData.map(primarySite => {
    const dataStack : any = {};

    let primarySiteTotal = 0;

    _.assign(dataStack, primarySite);

    const sortedProjects = primarySite.values.sort((a, b) => a.summary.case_count - b.summary.case_count);

    dataStack.stacks = sortedProjects.map(project => {
      // Make sure previous site y1 > y0
      if (primarySiteTotal > 0) {
        primarySiteTotal++;
      }

      const newPrimarySiteTotal = primarySiteTotal + project.summary.case_count;

      const stack = {
        _key: primarySite._key,
        primarySite: primarySite._key,
        y0: primarySiteTotal,
        y1: newPrimarySiteTotal,
        projectID: project.project_id,
        caseCount: project.summary.case_count,
        fileCount: project.summary.file_count,
      };

      primarySiteTotal = newPrimarySiteTotal;

      return stack;
    });

    dataStack._maxY = primarySiteTotal;

    return dataStack;
  });
};

const center = {
  alignItems: 'center',
  justifyContent: 'center',
};

const Title = styled.div({
  color: 'white',
  fontSize: '3rem',
});

const SubTitle = styled.div({
  color: 'white',
});

const GradientContainer = styled(Row, {
  backgroundColor: '#000',
  backgroundImage:
    'radial-gradient(ellipse at center, rgba(147,206,222,1) 0%, rgba(117,189,209,1) 48%, rgba(73,129,189,1) 100%)',
});

const containerStyle = {
  flex: 1,
  padding: '3rem',
  height: '50rem',
  position: 'relative',
};

const InsideContainer = styled.div(containerStyle);
const CenteredColumnContainer = styled(Column, {
  ...containerStyle,
  ...center,
});

const initialState = {
  humanBodyLoading: true,
};

const Home = compose(
  withState('state', 'setState', initialState),
  connect(state => ({ config: state.versionInfo })),
  withRouter,
  lifecycle({
    async componentDidMount(): Promise<*> {
      const { setState, dispatch, push } = this.props; // eslint-disable-line

      setState(state => ({ ...state, humanBodyLoading: !this.props.humanBodyData.length }));

      const data = transformChartData({ hits: this.props.humanBodyData })
        .sort((a, b) => a._key > b._key ? 1 : -1);

      if (this.props.humanBodyData.length) {
        setTimeout(() => {
          const root = document.getElementById('human-body-root');
          sapien.default({
            clickHandler: d => {
              const key = d._key.replace(/-/g, ' ');

              if (data.find(x => x._key === key)) {
                const query = {
                  filters: JSURL.stringify(makeFilter([
                    {
                      field: 'projects.primary_site',
                      value: [key],
                    }],
                    false
                  )),
                };
                push({ pathname: '/projects', query });
              }
              dispatch(setTooltip(null));
            },
            mouseOverHandler: d => {
              dispatch(setTooltip(
                <span>
                  <div style={{ fontSize: '16px', color: '#bb0e3d' }}>{d._key}</div>
                  <div style={{ fontSize: '12px', color: 'rgb(20, 20, 20)' }}>
                    {d._count} cases ({d.fileCount} files)
                  </div><commit_msg>💄 hide sapien highlights with no related data<commit_after>// @flow
/* global API */

import React from 'react';
import _ from 'lodash';
import { compose, withState, lifecycle } from 'recompose';
import { insertRule } from 'glamor';
import { connect } from 'react-redux';
import JSURL from 'jsurl';

import sapien from '@oncojs/sapien';

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

import withRouter from '@ncigdc/utils/withRouter';
import { makeFilter } from '@ncigdc/utils/filters';

import styled from '@ncigdc/theme/styled';

import ExploringLinks from './ExploringLinks';
import PortalSummary from './PortalSummary';
import GDCAppsRow from './GDCAppsRow';

type TTransformChartData = ({ hits: Array<Object> }) => Array<Object>;
const transformChartData: TTransformChartData = ({ hits }) => {
  if (!hits) return [];

  // reduce the array keyed on projectID
  const primarySites = hits.reduce((primarySiteData, project) => {
    const primarySite = project.primary_site;

    if (primarySite) {
      if (!_.isArray(primarySiteData[primarySite])) {
        primarySiteData[primarySite] = [];
      }

      primarySiteData[primarySite].push(project);
    }

    return primarySiteData;
  }, {});

  const primarySiteIDs = _.keys(primarySites);

  if (!primarySiteIDs.length) return [];

  const firstPassProjectData = primarySiteIDs.map(pID => {
    const primarySiteData = primarySites[pID];
    let caseCount = 0;
    let fileCount = 0;

    for (let i = 0; i < primarySiteData.length; i++) {
      caseCount += +(_.get(primarySiteData[i], 'summary.case_count', 0));
      fileCount += +(_.get(primarySiteData[i], 'summary.file_count', 0));
    }

    /* _key and _count are required data properties for the marked bar chart */
    return { _key: pID, values: primarySiteData, _count: caseCount, fileCount };
  })
    .filter(d => d._count > 0)
    .sort((a, b) => b._count - a._count);

  return firstPassProjectData.map(primarySite => {
    const dataStack : any = {};

    let primarySiteTotal = 0;

    _.assign(dataStack, primarySite);

    const sortedProjects = primarySite.values.sort((a, b) => a.summary.case_count - b.summary.case_count);

    dataStack.stacks = sortedProjects.map(project => {
      // Make sure previous site y1 > y0
      if (primarySiteTotal > 0) {
        primarySiteTotal++;
      }

      const newPrimarySiteTotal = primarySiteTotal + project.summary.case_count;

      const stack = {
        _key: primarySite._key,
        primarySite: primarySite._key,
        y0: primarySiteTotal,
        y1: newPrimarySiteTotal,
        projectID: project.project_id,
        caseCount: project.summary.case_count,
        fileCount: project.summary.file_count,
      };

      primarySiteTotal = newPrimarySiteTotal;

      return stack;
    });

    dataStack._maxY = primarySiteTotal;

    return dataStack;
  });
};

const center = {
  alignItems: 'center',
  justifyContent: 'center',
};

const Title = styled.div({
  color: 'white',
  fontSize: '3rem',
});

const SubTitle = styled.div({
  color: 'white',
});

const GradientContainer = styled(Row, {
  backgroundColor: '#000',
  backgroundImage:
    'radial-gradient(ellipse at center, rgba(147,206,222,1) 0%, rgba(117,189,209,1) 48%, rgba(73,129,189,1) 100%)',
});

const containerStyle = {
  flex: 1,
  padding: '3rem',
  height: '50rem',
  position: 'relative',
};

const InsideContainer = styled.div(containerStyle);
const CenteredColumnContainer = styled(Column, {
  ...containerStyle,
  ...center,
});

const initialState = {
  humanBodyLoading: true,
};

const Home = compose(
  withState('state', 'setState', initialState),
  connect(state => ({ config: state.versionInfo })),
  withRouter,
  lifecycle({
    async componentDidMount(): Promise<*> {
      const { setState, dispatch, push } = this.props; // eslint-disable-line

      setState(state => ({ ...state, humanBodyLoading: !this.props.humanBodyData.length }));

      const data = transformChartData({ hits: this.props.humanBodyData })
        .sort((a, b) => a._key > b._key ? 1 : -1);

      if (this.props.humanBodyData.length) {
        setTimeout(() => {
          const highlights = document.querySelectorAll('#human-body-highlights > svg');
          for (const h of highlights) {
            if (!data.some(d => d._key === h.id.replace(/-/g, ' '))) {
              h.style.display = 'none';
            }
          }
        }, 100);
        setTimeout(() => {
          const root = document.getElementById('human-body-root');
          sapien.default({
            clickHandler: d => {
              const key = d._key.replace(/-/g, ' ');
              if (data.find(x => x._key === key)) {
                const query = {
                  filters: JSURL.stringify(makeFilter([
                    {
                      field: 'projects.primary_site',
                      value: [key],
                    }],
                    false
                  )),
                };
                push({ pathname: '/projects', query });
              }
              dispatch(setTooltip(null));
            },
            mouseOverHandler: d => {
              dispatch(setTooltip(
                <span>
                  <div style={{ fontSize: '16px', color: '#bb0e3d' }}>{d._key}</div>
                  <div style={{ fontSize: '12px', color: 'rgb(20, 20, 20)' }}>
                    {d._count} cases ({d.fileCount} files)
                  </div>
{'fraction_non_alphanumeric': 0.14218455743879474, 'fraction_numerical': 0.01327683615819209, 'mean_word_length': 2.605227427019688, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 62, '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': '3426476', 'n_tokens_mistral': 3331, 'n_tokens_neox': 3160, 'n_words': 741}