Skip to content

Commit

Permalink
Merge pull request #151 from georgetown-cset/gui-updates-following-da…
Browse files Browse the repository at this point in the history
…ta-updates

Update GUI to accomodate data updates
  • Loading branch information
jmelot authored Oct 20, 2023
2 parents b673653 + 89919de commit 397e40e
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 71 deletions.
6 changes: 3 additions & 3 deletions web/gui-v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"gatsby"
],
"scripts": {
"develop": "gatsby develop -p 8550",
"start": "gatsby develop -p 8550",
"build": "gatsby build",
"develop": "NODE_OPTIONS=--max-old-space-size=6144 gatsby develop -p 8550",
"start": "NODE_OPTIONS=--max-old-space-size=6144 gatsby develop -p 8550",
"build": "NODE_OPTIONS=--max-old-space-size=6144 gatsby build",
"serve": "gatsby serve",
"clean": "gatsby clean",
"test": "jest",
Expand Down
1 change: 1 addition & 0 deletions web/gui-v2/src/components/DetailView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import DetailViewPublications from './DetailViewPublications';
import DetailViewPatents from './DetailViewPatents';
import DetailViewWorkforce from './DetailViewWorkforce';
import tableOfContentsData from '../static_data/detail-toc.json';
import overallData from '../static_data/overall_data.json';
import { useWindowSize } from '../util';
import { plausibleEvent } from '../util/analytics';

Expand Down
14 changes: 13 additions & 1 deletion web/gui-v2/src/components/DetailViewIntro.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ const styles = {
padding: 0.5rem;
}
`,
linkWrapper: css`
list-style: none;
padding: 0;
li + li {
margin-top: 0;
}
`,
buttonWrapper: css`
display: flex;
margin-top: 1rem !important;
Expand All @@ -69,7 +77,11 @@ const DetailViewIntro = ({
if ( data.market_filt && data.market_filt.length > 0 ) {
metadata.push({
title: "Stock tickers",
value: data.market_filt.map((e) => <ExternalLink href={e.url} key={e.text}>{e.text}</ExternalLink>),
value: (
<ul css={styles.linkWrapper}>
{data.market_filt.map((e) => <li key={e.text}><ExternalLink href={e.url}>{e.text}</ExternalLink></li>)}
</ul>
),
});
}

Expand Down
4 changes: 2 additions & 2 deletions web/gui-v2/src/components/DetailViewMoreMetadataDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ const MoreMetadataDialog = ({
{data.linkedin.map(e => <ExternalLink href={e} key={e}>{e}</ExternalLink>)}
</div>
},
{ title: 'In S&P 500?', value: data.in_sandp_500 ? 'Yes' : 'No' },
{ title: 'In Fortune Global 500?', value: data.in_fortune_global_500 ? 'Yes' : 'No' },
{ title: 'In S&P 500?', value: data.groups.sp500 ? 'Yes' : 'No' },
{ title: 'In Fortune Global 500?', value: data.groups.global500 ? 'Yes' : 'No' },
{ title: 'Stage', value: data.stage },
{ title: 'Full market links', value: 'TODO - data are currently in an `__html` object' },
];
Expand Down
94 changes: 53 additions & 41 deletions web/gui-v2/src/components/DetailViewPatents.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React, { useState } from 'react';
import { css } from '@emotion/react';

import { Dropdown } from '@eto/eto-ui-components';
import { Autocomplete, Dropdown } from '@eto/eto-ui-components';

import HeaderWithLink from './HeaderWithLink';
import StatGrid from './StatGrid';
import TableSection from './TableSection';
import TextAndBigStat from './TextAndBigStat';
import TrendsChart from './TrendsChart';
import overall from '../static_data/overall_data.json';
import { patentMap } from '../static_data/table_columns';
import { commas } from '../util';
import { assemblePlotlyParams } from '../util/plotly-helpers';
Expand All @@ -22,10 +23,13 @@ const styles = {
}
`,
trendsDropdown: css`
.MuiInputBase-input.MuiSelect-select {
align-items: center;
display: flex;
justify-content: center;
.MuiAutocomplete-root .MuiInput-root.MuiInputBase-sizeSmall .MuiInput-input {
padding: 4px;
text-align: center;
}
ul > li {
text-align: left;
}
`,
};
Expand All @@ -41,17 +45,20 @@ const chartLayoutChanges = {
},
};

const startIx = overall.years.findIndex(e => e === overall.startPatentYear);
const endIx = overall.years.findIndex(e => e === overall.endPatentYear);

const DetailViewPatents = ({
data,
}) => {
const [aiSubfield, setAiSubfield] = useState("ai_patents");

const numYears = data.years.length;
const startIx = numYears - 7;
const endIx = numYears - 2;
const yearSpanNdash = <>{overall.years[startIx]}&ndash;{overall.years[endIx]}</>;
// const yearSpanAnd = <>{overall.years[startIx]} and {overall.years[endIx]}</>;

const yearSpanNdash = <>{data.years[startIx]}&ndash;{data.years[endIx]}</>;
// const yearSpanAnd = <>{data.years[startIx]} and {data.years[endIx]}</>;
const aiPatentStart = data.patents.ai_patents.counts[startIx];
const aiPatentEnd = data.patents.ai_patents.counts[endIx];
const aiPatentGrowth = Math.round((aiPatentEnd - aiPatentStart) / aiPatentStart * 1000) / 10

const statGridEntries = [
{
Expand All @@ -61,7 +68,7 @@ const DetailViewPatents = ({
},
{
key: "ai-patent-growth",
stat: <>NUM%</>,
stat: <>{aiPatentGrowth}%</>,
text: <>growth in {data.name}'s AI patenting ({yearSpanNdash})</>,
},
{
Expand All @@ -79,41 +86,46 @@ const DetailViewPatents = ({
const patentTableColumns = [
{ display_name: "Subfield", key: "subfield" },
{ display_name: "Patents granted", key: "patents" },
{ display_name: <>Growth ({data.years[startIx]}&ndash;{data.years[endIx]})</>, key: "growth" },
{ display_name: <>Growth ({overall.startPatentYear}&ndash;{overall.endPatentYear})</>, key: "growth" },
];

const patentSubkeys = Object.keys(data.patents);

// NOTE: for the time being, I'm hardcoding these to get data to display. The
// final implementation will require discussion and coordination.
const patentApplicationAreas = patentSubkeys.slice(0, 5).map((key) => {
const startVal = data.patents[key].counts[startIx];
const endVal = data.patents[key].counts[endIx];
const growth = `${Math.round((endVal - startVal) / startVal * 1000) / 10}%`;
return {
subfield: data.patents[key].name,
patents: data.patents[key].total,
growth,
};
});

const patentIndustryAreas = patentSubkeys.slice(5, 10).map((key) => {
const startVal = data.patents[key].counts[startIx];
const endVal = data.patents[key].counts[endIx];
const growth = `${Math.round((endVal - startVal) / startVal * 1000) / 10}%`;
return {
subfield: data.patents[key].name,
patents: data.patents[key].total,
growth,
};
});

// Temporarily using just a generic slice of patents
const aiSubfieldOptions = patentSubkeys.slice(0, 10).map(k => ({ text: patentMap[k], val: k }));
const patentApplicationAreas = patentSubkeys
.filter(key => data.patents[key].table === "application")
.map((key) => {
const startVal = data.patents[key].counts[startIx];
const endVal = data.patents[key].counts[endIx];
const growth = `${Math.round((endVal - startVal) / startVal * 1000) / 10}%`;
return {
subfield: patentMap[key],
patents: data.patents[key].total,
growth,
};
})
.sort((a, b) => b.patents - a.patents);

const patentIndustryAreas = patentSubkeys
.filter(key => data.patents[key].table === "industry")
.map((key) => {
const startVal = data.patents[key].counts[startIx];
const endVal = data.patents[key].counts[endIx];
const growth = `${Math.round((endVal - startVal) / startVal * 1000) / 10}%`;
return {
subfield: patentMap[key],
patents: data.patents[key].total,
growth,
};
})
.sort((a, b) => b.patents - a.patents);

const aiSubfieldOptions = patentSubkeys
.map(k => ({ text: patentMap[k].replace(/ patents/i, ''), val: k }))
.sort((a, b) => a.text.localeCompare(b.text, 'en', { sensitivity: 'base' }));

const aiSubfieldChartData = assemblePlotlyParams(
"Trends in research....",
data.years,
overall.years,
[
[
aiSubfieldOptions.find(e => e.val === aiSubfield)?.text,
Expand All @@ -128,7 +140,7 @@ const DetailViewPatents = ({
<HeaderWithLink title="Patents" />

<TextAndBigStat
smallText={<>Between {data.years[0]} and {data.years[data.years.length-1]}, {data.name} obtained</>}
smallText={<>Between {overall.years[0]} and {overall.years[overall.years.length-1]}, {data.name} obtained</>}
bigText={<>{commas(data.patents.ai_patents.total)} AI patents</>}
/>

Expand Down Expand Up @@ -157,7 +169,7 @@ const DetailViewPatents = ({
title={
<>
Trends in {data.name}'s patenting in
<Dropdown
<Autocomplete
css={styles.trendsDropdown}
inputLabel="patent subfield"
options={aiSubfieldOptions}
Expand Down
20 changes: 10 additions & 10 deletions web/gui-v2/src/components/DetailViewPublications.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import StatGrid from './StatGrid';
import TableSection from './TableSection';
import TextAndBigStat from './TextAndBigStat';
import TrendsChart from './TrendsChart';
import overall from '../static_data/overall_data.json';
import { articleMap } from '../static_data/table_columns';
import { commas } from '../util';
import { assemblePlotlyParams } from '../util/plotly-helpers';
Expand Down Expand Up @@ -44,21 +45,20 @@ const chartLayoutChanges = {
},
};

const startIx = overall.years.findIndex(e => e === overall.startArticleYear);
const endIx = overall.years.findIndex(e => e === overall.endArticleYear);

const DetailViewPublications = ({
data,
}) => {
const [aiSubfield, setAiSubfield] = useState("ai_publications");

const yearSpanNdash = <>{data.years[0]}&ndash;{data.years[data.years.length-1]}</>;
const yearSpanAnd = <>{data.years[0]} and {data.years[data.years.length-1]}</>;
const yearSpanNdash = <>{overall.years[0]}&ndash;{overall.years[overall.years.length-1]}</>;
const yearSpanAnd = <>{overall.years[0]} and {overall.years[overall.years.length-1]}</>;

const averageCitations = Math.round(10 * data.articles.citation_counts.total / data.articles.all_publications.total) / 10;
const aiResearchPercent = Math.round(1000 * data.articles.ai_publications.total / data.articles.all_publications.total) / 10;

const numYears = data.years.length;
const startIx = numYears - 7;
const endIx = numYears - 2;

const statGridEntries = [
{
key: "ai-papers",
Expand Down Expand Up @@ -96,10 +96,10 @@ const DetailViewPublications = ({
{ display_name: "Subfield", key: "subfield" },
{ display_name: "Articles", key: "articles" },
{ display_name: "Citations per article", key: "citations" },
{ display_name: <>Growth ({data.years[startIx]}&ndash;{data.years[endIx]})</>, key: "growth" },
{ display_name: <>Growth ({overall.startArticleYear}&ndash;{overall.endArticleYear})</>, key: "growth" },
];
const topAiResearchTopics = Object.entries(data.articles)
.filter(([key, _val]) => ['cv_pubs', 'nlp_pubs', 'robotics_pubs'].includes(key))
.filter(([_key, val]) => val.isTopResearch)
.map(([key, val]) => {
const startVal = val.counts[startIx];
const endVal = val.counts[endIx];
Expand All @@ -121,7 +121,7 @@ const DetailViewPublications = ({

const aiSubfieldChartData = assemblePlotlyParams(
"Trends in research....",
data.years,
overall.years,
[
[
aiSubfieldOptions.find(e => e.val === aiSubfield)?.text,
Expand All @@ -133,7 +133,7 @@ const DetailViewPublications = ({

const topConfs = assemblePlotlyParams(
<>{data.name}'s top AI conference publications</>,
data.years,
overall.years,
[
["AI top conference publications", data.articles.ai_pubs_top_conf.counts],
],
Expand Down
6 changes: 4 additions & 2 deletions web/gui-v2/src/components/DetailViewWorkforce.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import React from 'react';
import HeaderWithLink from './HeaderWithLink';
import StatBox from './StatBox';
import StatWrapper from './StatWrapper';
import overall from '../static_data/overall_data.json';
import { otherMetricMap } from '../static_data/table_columns';

const DetailViewWorkforce = ({
data,
}) => {
const yearSpanText = <>{data.years[0]} to {data.years[data.years.length-1]}</>;
const yearSpanText = <>{overall.years[0]} to {overall.years[overall.years.length-1]}</>;

const otherMetricsWorkforceKeys = ['ai_jobs', 'tt1_jobs'];

Expand All @@ -27,7 +29,7 @@ const DetailViewWorkforce = ({
</>
}
key={key}
label={data.other_metrics[key].name}
label={otherMetricMap[key]}
value={data.other_metrics[key].total}
/>
))}
Expand Down
4 changes: 2 additions & 2 deletions web/gui-v2/src/components/ListView.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ describe("ListView", () => {
for ( const column of INITIAL_COLUMNS.filter(e => e !== REMOVED_COLUMN) ) {
expect(screen.getByRole('columnheader', { name: new RegExp(column, 'i') }));
}
}, 40000);
}, 60000);
});

describe('groups', () => {
Expand Down Expand Up @@ -106,6 +106,6 @@ describe("ListView", () => {
expect(getByRole(table, 'row', { name: /Google/ })).toBeVisible();
expect(getByRole(table, 'row', { name: /Apple/ })).toBeVisible();
expect(getByRole(table, 'row', { name: /3M/ })).toBeVisible();
}, 30000);
}, 60000);
});
});
30 changes: 26 additions & 4 deletions web/gui-v2/src/components/StatBox.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
import React from 'react';
import { css } from '@emotion/react';

import { breakpoints } from '@eto/eto-ui-components';

import { commas } from '../util';

const styles = {
outerWrapper: css`
column-gap: 2rem;
--statbox-border: 2px;
--statbox-padding: 1rem;
--statbox-width: 240px;
column-gap: 1rem;
display: grid;
grid-template-columns: 240px 1fr;
grid-template-columns: 1fr;
row-gap: 0.5rem;
${breakpoints.phone_large} {
grid-template-columns: var(--statbox-width) 1fr;
}
${breakpoints.tablet_small} {
column-gap: 2rem;
}
`,
statbox: css`
align-items: center;
background-color: var(--bright-blue-lighter);
border: 2px solid var(--bright-blue);
border: var(--statbox-border) solid var(--bright-blue);
color: var(--bright-blue);
display: flex;
flex-direction: column;
padding: 1rem 1rem;
margin: 0 auto;
width: calc(var(--statbox-width) - 2*var(--statbox-padding) - 2*var(--statbox-border));
padding: var(--statbox-padding);
`,
label: css`
font-size: 1.25rem;
Expand All @@ -27,6 +44,11 @@ const styles = {
description: css`
align-items: center;
display: flex;
text-align: center;
${breakpoints.phone_large} {
text-align: start;
}
`,
};

Expand Down
Loading

0 comments on commit 397e40e

Please sign in to comment.