Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add additional fields to list view table #126

Merged
merged 6 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion web/gui-v2/src/components/AddRemoveColumnDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const styles = {
columnDialogContents: css`
font-family: GTZirkonLight;
padding: 0 0.5rem 0.5rem;
width: 320px;
width: 400px;
`,
columnDialogTitle: css`
font-family: GTZirkonRegular;
Expand Down
15 changes: 11 additions & 4 deletions web/gui-v2/src/components/CellStat.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import { commas } from '../util';
const styles = {
cell: css`
display: grid;
grid-template-columns: 60% 40%;
gap: 0.5rem;
/*
* 3.2em was chosen because it was a touch above the size needed to safely
* display a 4-digit company ranking. If we ever get above 10,000 companies
* and things start looking funky, just increase this accordingly.
*/
grid-template-columns: 1fr 3.2em;
justify-content: center;

& > div {
Expand All @@ -15,17 +21,18 @@ const styles = {

.rank {
color: #a0a0a0;
margin-left: 0.5rem;
}
`,
};

const CellStat = ({data, colKey}) => {
return (
<div css={styles.cell}>
<div className="val">{commas(data.total)}</div>
<div className="val">
{ data?.total === null ? 'n/a' : commas(data.total) }
</div>
<div className="rank">
{ data?.total === 0 ? '---' : <>#{data.rank}</> }
{ (data?.total === 0 || data?.total === null) ? '---' : <>#{data.rank}</> }
</div>
</div>
);
Expand Down
5 changes: 3 additions & 2 deletions web/gui-v2/src/components/HeaderSlider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ const HeaderSlider = ({
);

// Debounce handler for propagating internal changes to the outside
const externalHandler = (newVal) => onChange(newVal);
const handleExternalChange = useMemo(() => {
return debounce(onChange, 300);
}, [onChange]);
return debounce(externalHandler, 300);
}, []);

// Trigger external state change
useEffect(
Expand Down
39 changes: 12 additions & 27 deletions web/gui-v2/src/components/ListViewTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const styles = {
const DATAKEYS_WITH_SUBKEYS = [
"articles",
"patents",
"other_metrics",
];

const DEFAULT_COLUMNS = columnDefinitions
Expand All @@ -125,13 +126,14 @@ const SLIDER_COLUMNS = columnDefinitions
.filter(colDef => colDef.type === "slider")
.map(colDef => colDef.key);

const ALL_COLUMNS = [
...DROPDOWN_COLUMNS,
...SLIDER_COLUMNS,
];

const DEFAULT_FILTER_VALUES = {
name: [],
country: [],
continent: [],
stage: [],
ai_pubs: [0, 100],
ai_patents: [0, 100],
...DROPDOWN_COLUMNS.reduce((obj, e) => { obj[e] = []; return obj; }, {}),
...SLIDER_COLUMNS.reduce((obj, e) => { obj[e] = [0, 100]; return obj; }, {}),
};
const initialVal = (key) => {
return DEFAULT_FILTER_VALUES[key]?.join(',') ?? '';
Expand All @@ -149,7 +151,6 @@ const AGGREGATE_SUM_COLUMNS = [
'ai_patents',
];


// Determine whether a given row matches the filters and/or selected group
const filterRow = (row, filters, selectedGroupMembers) => {
const filterKeys = Object.keys(filters);
Expand Down Expand Up @@ -194,10 +195,6 @@ const filterRow = (row, filters, selectedGroupMembers) => {
if ( rowVal < min || ( max < 100 && max < rowVal) ) {
return false;
}
} else if ( colDef.type === "stock" ) {
// TODO: Figure out how we're filtering the `market_list` column
// -- Actually - are we even wanting this column, or did I just make
// it as a placeholder?
} else {
console.error(`Invalid column type for key '${colDef.key}': column.type should be either "dropdown" or "slider" but is instead "${colDef.type}"`);
}
Expand Down Expand Up @@ -236,17 +233,10 @@ const ListViewTable = ({
// Store filters via the URL parameters, making the values (and setters)
// accessible via an object.
const filters = useMultiState(
{
name: useQueryParamString('name', initialVal('name')),
country: useQueryParamString('country', initialVal('country')),
continent: useQueryParamString('continent', initialVal('continent')),
stage: useQueryParamString('stage', initialVal('stage')),
// ...
ai_pubs: useQueryParamString('ai_pubs', initialVal('ai_pubs')),
ai_patents: useQueryParamString('ai_patents', initialVal('ai_patents')),
// ...
// market_list: useQueryParamString('market_list', ''),
},
ALL_COLUMNS.reduce((obj, e) => {
obj[e] = useQueryParamString(e, initialVal(e));
return obj;
}, {}),
(key, val) => {
if ( DROPDOWN_COLUMNS.includes(key) ) {
let result = val.split(',').filter(e => e !== "");
Expand Down Expand Up @@ -422,11 +412,6 @@ const ListViewTable = ({
/>
);
break;
case 'stock':
display_name = (
colDef.title
);
break;
default:
display_name = colDef.title;
}
Expand Down
199 changes: 175 additions & 24 deletions web/gui-v2/src/static_data/table_columns.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const styles = {
}
`,
sliderColumn: css`
min-width: 100px;
width: 120px;

.MuiButtonBase-root {
Expand All @@ -20,6 +21,39 @@ const styles = {
`,
};

/**
* Helper function to define the `extract` and `format` functions of slider
* fields in a consistent way across all columns.
*
* @param {string} dataKey
* @param {string} dataSubkey
* @returns {{
* css: SerializedStyles,
* dataKey: string,
* dataSubkey: string,
* extract: (val: any, row: object) => any,
* format: (val: any, row: object) => ReactNode,
* initialCol: boolean,
* sortable: boolean,
* type: 'dropdown'|'slider',
* }}
*/
const generateSliderColDef = (dataKey, dataSubkey) => {
return {
css: styles.sliderColumn,
dataKey,
dataSubkey,
extract: (_val, row) => {
const res = row[dataKey][dataSubkey].total;
return res === null ? 0 : res;
},
format: (_val, row) => <CellStat data={row[dataKey][dataSubkey]} />,
initialCol: false,
sortable: true,
type: 'slider',
}
};

export default [
{
title: "Company",
Expand All @@ -33,38 +67,155 @@ export default [
{ title: "Country", key: "country", initialCol: true, type: 'dropdown' },
{ title: "Region", key: "continent", initialCol: true, type: 'dropdown' },
{ title: "Stage", key: "stage", initialCol: true, type: 'dropdown' },

{
brianlove marked this conversation as resolved.
Show resolved Hide resolved
title: "All publications",
key: "all_pubs",
...generateSliderColDef("articles", "all_publications"),
},
{
title: "Citation counts",
key: "citations",
...generateSliderColDef("articles", "citation_counts"),
},
{
title: "AI publications",
key: "ai_pubs",
dataKey: "articles",
dataSubkey: "ai_publications",
css: styles.sliderColumn,
...generateSliderColDef("articles", "ai_publications"),
initialCol: true,
extract: (_val, row) => row.articles.ai_publications.total,
format: (_val, row) => <CellStat data={row.articles.ai_publications} />,
sortable: true,
type: 'slider',
},
{
title: "AI publications in top conferences",
key: "ai_pubs_top_conf",
...generateSliderColDef("articles", "ai_pubs_top_conf"),
},
{
title: "AI patents",
key: "ai_patents",
dataKey: "patents",
dataSubkey: "ai_patents",
css: styles.sliderColumn,
...generateSliderColDef("patents", "ai_patents"),
initialCol: true,
extract: (_val, row) => row.patents.ai_patents.total,
format: (_val, row) => <CellStat data={row.patents.ai_patents} />,
sortable: true,
type: 'slider',
},
// { title: "AI publication intensity", key: "ai_pubs_int", initialCol: false, type: 'slider' },
// { title: "NLP publications", key: "nlp_pubs", initialCol: true },
// { title: "NLP patents", key: "nlp_patents", initialCol: true },
// { title: "CV publications", key: "cv_pubs", initialCol: false },
// { title: "CV patents", key: "cv_patents", initialCol: false },
// { title: "Robotics publications", key: "ro_pubs", initialCol: false },
// { title: "Robotics patents", key: "ro_patents", initialCol: false },
// { title: "tt1 jobs (??)", key: "tt1_jobs", initialCol: false },
// { title: "AI jobs", key: "ai_jobs", initialCol: false },
// { title: "Stock ticker", key: "market_list", type: "stock" },
{
title: "CV publications",
key: "cv_pubs",
...generateSliderColDef("articles", "cv_pubs"),
},
{
title: "NLP publications",
key: "nlp_pubs",
...generateSliderColDef("articles", "nlp_pubs"),
},
{
title: "Robotics publications",
key: "ro_pubs",
...generateSliderColDef("articles", "robotics_pubs"),
},

{
title: "Agricultural patents",
key: "agri_patents",
...generateSliderColDef("patents", "Agricultural"),
},
{
title: "Banking and finance patents",
key: "finance_patents",
...generateSliderColDef("patents", "Banking_and_Finance"),
},
{
title: "Business patents",
key: "business_patents",
...generateSliderColDef("patents", "Business"),
},
{
title: "Computing in government patents",
key: "comp_in_gov_patents",
...generateSliderColDef("patents", "Computing_in_Government"),
},
{
title: "Document management and publishing patents",
key: "doc_mgt_patents",
...generateSliderColDef("patents", "Document_Mgt_and_Publishing"),
},
{
title: "Education patents",
key: "edu_patents",
...generateSliderColDef("patents", "Education"),
},
{
title: "Energy patents",
key: "energy_mgt_patents",
...generateSliderColDef("patents", "Energy_Management"),
},
{
title: "Entertainment patents",
key: "entertain_patents",
...generateSliderColDef("patents", "Entertainment"),
},
{
title: "Industrial and manufacturing patents",
key: "industry_patents",
...generateSliderColDef("patents", "Industrial_and_Manufacturing"),
},
{
title: "Life sciences patents",
key: "life_patents",
...generateSliderColDef("patents", "Life_Sciences"),
},
{
title: "Military patents",
key: "mil_patents",
...generateSliderColDef("patents", "Military"),
},
{
title: "Nanotechnology patents",
key: "nano_patents",
...generateSliderColDef("patents", "Nanotechnology"),
},
{
title: "Networks patents",
key: "network_patents",
...generateSliderColDef("patents", "Networks__eg_social_IOT_etc"),
},
{
title: "Personal devices and computing patents",
key: "personal_comp_patents",
...generateSliderColDef("patents", "Personal_Devices_and_Computing"),
},
{
title: "Physical sciences and engineering patents",
key: "phys_sci_patents",
...generateSliderColDef("patents", "Physical_Sciences_and_Engineering"),
},
{
title: "Security patents",
key: "security_patents",
...generateSliderColDef("patents", "Security__eg_cybersecurity"),
},
{
title: "Semiconductor patents",
key: "semiconductor_patents",
...generateSliderColDef("patents", "Semiconductors"),
},
{
title: "Telecommunications patents",
key: "telecom_patents",
...generateSliderColDef("patents", "Telecommunications"),
},
{
title: "Transportation patents",
key: "transport_patents",
...generateSliderColDef("patents", "Transportation"),
},

{
title: "AI jobs",
key: "ai_jobs",
...generateSliderColDef("other_metrics", "ai_jobs"),
initialCol: true,
},
{
title: "Tech Tier 1 jobs",
key: "tt1_jobs",
...generateSliderColDef("other_metrics", "tt1_jobs"),
},
];