{"version":3,"sources":["serviceWorker.ts","theme.tsx","app/query.ts","app/hooks.ts","app/terms/TermChip.tsx","app/terms/TermsInput.tsx","api.ts","app/terms/TermsPreset.tsx","app/Highlight.tsx","app/terms/TermsList.tsx","app/queryClient.ts","app/chart/Chart.tsx","app/wizard/wizard.ts","app/terms/TermsFilter.tsx","app/images/grant-explorer.svg","app/images/filter-divisions.svg","app/nav/DrawerToggle.tsx","app/nav/NavigationBar.tsx","app/images/nih-logo.svg","app/images/nsf-logo.svg","app/images/dod-logo.svg","app/divisions/DivisionToolbar.tsx","app/divisions/checkFSM.ts","app/divisions/DivisionRow.tsx","app/divisions/Entry.tsx","app/divisions/DirectoryTableHead.tsx","app/divisions/useDirectory.tsx","app/divisions/DirectoryTree.tsx","app/nav/Drawer.tsx","app/images/moore-foundation-logo.svg","app/images/datalab-logo.svg","app/nav/Footer.tsx","app/sort.ts","app/chart/ChartTooltip.tsx","app/chart/ChartLegend.tsx","app/chart/D3Timeline.ts","app/chart/D3Tooltip.ts","app/chart/D3utils.ts","app/chart/D3Chart.ts","app/grants/grantsDownload.ts","app/nav/Actions.tsx","app/grants/AbstractDialog.tsx","app/grants/GrantRow.tsx","app/grants/useInfiniteLoadGrants.ts","app/grants/GrantsTable.tsx","app/grants/FilterChip.tsx","app/grants/GrantsDialog.tsx","app/wizard/WizardTooltip.tsx","app/wizard/About.tsx","App.tsx","index.tsx"],"names":["Boolean","window","location","hostname","match","interleave","v","i","a","Math","trunc","length","colorScales","count","d3","Object","values","deepPurple","slice","map","amount","green","theme","blue","red","amber","pink","color","createTheme","drawerWidth","palette","primary","main","counts","amounts","ThemeProvider","_ref","children","_jsx","MuiThemeProvider","_jsxs","EmotionThemeProvider","CssBaseline","OrgParam","withDefault","StringParam","ArrayParam","DelimitedArrayParam","DivisionsArrayParam","undefined","DefaultStringParam","DefaultNumberParam","NumberParam","DefaultBooleanParam","BooleanParam","SortParam","SortDirectionParam","MatchParam","paramConfigMap","grantParamConfig","useSearchQuery","useQueryParams","useGrantsDialogQuery","useTermsQuery","useQueryParam","useGrantIdQuery","useQuery","_objectSpread","useDivisionsQuery","useBeta","useTutorial","useAbout","useMeasure","_ref$current","ref","useRef","padding","useEffect","current","_ref$current$parentEl","bbox","getBoundingClientRect","parent","parentElement","width","getWindowDimensions","innerWidth","innerHeight","useWindowDimensions","_useState3","useState","_useState4","_slicedToArray","windowDimensions","setWindowDimensions","handleResize","addEventListener","removeEventListener","StyledChip","styled","Chip","concat","spacing","grey","secondary","dark","alpha","common","white","ChipContent","_ref2","breakpoints","down","text","black","animateIn","e","style","transform","animate","opacity","TermChip","props","Flipped","onAppear","flipId","term","variant","selected","label","format","replace","CircularProgress","size","onClick","_props$onClick","call","onDelete","memo","InputContainer","Box","ChipInput","InputBase","transitions","create","up","Dropdown","Paper","_ref3","topics","TermsInput","forwardRef","suggestions","onAddChip","onDeleteLastChip","onClearInput","inputProps","_objectWithoutProperties","_excluded","inputRef","_useState","_useState2","focused","setFocused","anchorEl","setAnchorEl","_useQuery","terms","handleFocus","_e$currentTarget$pare","_e$currentTarget$pare2","_e$currentTarget$pare3","_e$currentTarget$pare4","currentTarget","handleKeyDown","console","log","key","value","handleClickAway","_inputRef$current2","blur","ClickAwayListener","onClickAway","_inputRef$current","focus","flipProps","componentsProps","root","placeholder","onFocus","onKeyDown","Popper","open","placement","transition","_ref4","TransitionProps","Fade","timeout","useGetTopics","options","_queryOptions$queryKe2","queryOptions","query","axiosOptions","axios","queryKey","get","getTopics","useLoadDirectory","org","_queryOptions$queryKe3","getLoadDirectoryQueryKey","loadDirectory","enabled","useSearch","params","_queryOptions$queryKe4","_toConsumableArray","getSearchQueryKey","search","useYears","_queryOptions$queryKe5","_ref5","getYearsQueryKey","years","useLoadTypeahead","prefix","_queryOptions$queryKe6","_ref6","getLoadTypeaheadQueryKey","loadTypeahead","useLoadRelated","_queryOptions$queryKe7","_ref7","getLoadRelatedQueryKey","loadRelated","useLoadTermCounts","_queryOptions$queryKe8","_ref8","getLoadTermCountsQueryKey","loadTermCounts","loadGrants","useLoadAbstract","id","_queryOptions$queryKe11","_ref11","getLoadAbstractQueryKey","loadAbstract","StyledList","List","TermsPreset","_useGetTopics","data","isFetching","refetch","_useTermsQuery","setTerms","ListSubheader","Science","flexGrow","Button","endIcon","Shuffle","LinearProgress","topic","ListItem","topicIdx","Highlight","parse","part","idx","fontWeight","highlight","StyledListItem","disabled","el","anime","targets","delay","easing","duration","animateOut","onComplete","complete","exitThenFlipAndEnter","hideEnteringElements","animateEnteringElements","animateExitingElements","animateFlippedElements","then","TermsList","_props$terms","Flipper","flipKey","JSON","stringify","handleEnterUpdateDelete","subheader","header","t","onExit","dense","ListItemText","input","beta","className","forms","join","ListItemIcon","AddCircle","Axios","defaults","paramsSerializer","vis","queryClient","QueryClient","stepOrder","steps","hello","anchorOrigin","vertical","horizontal","transformOrigin","title","filterTerms","description","clearTerms","filterOrganizations","filterDivisions","chartToggles","anyAllSetting","filterYears","overflowMenu","refs","useWizardRef","step","_useQueryParam","stepIdx","indexOf","active","SearchContainer","shape","borderRadius","ChipContainer","SearchIcon","TermsFilter","setInput","_useBeta","debouncedInput","_useState5","_useState6","debouncedValue","setDebouncedValue","timer","setTimeout","clearTimeout","useDebounce","filterTermsRef","clearTermsRef","_useQueryParam2","sort","setSort","find","keepPreviousData","select","_useLoadTypeahead","selected_terms","_ref6$data","filter","d","includes","typeahead","typeaheadKey","_useLoadRelated","_ref7$data","related","relatedKey","handleClickChip","chip","preventDefault","replaceAll","handleAddChip","chipString","chips","split","c","handleDeleteChip","inverseFlipId","display","flexDirection","Search","Tooltip","IconButton","t1","t2","_counts$t","_counts$t2","localeCompare","Sort","SortByAlpha","onChange","target","removeQueries","HighlightOff","ClearAll","ResponsiveButton","DrawerToggle","drawerOpen","setDrawerOpen","BarChart","Icon","src","StyledToolbar","Toolbar","Logo","AboutButton","TitleBar","Title","Typography","SearchAppBar","titleBarRef","_useAbout","setAboutOpen","href","AppBar","position","grantExplorer","alt","noWrap","Link","startIcon","Info","htmlColor","StyledSelect","Select","Actions","_templateObject","_taggedTemplateLiteral","orgs","abbr","nsf","nih","dod","DivisionToolbar","_useWizardRef","organizationsRef","organizationsActive","divisionsRef","setOpen","alignItems","onChangeOrg","onOpen","onClose","o","MenuItem","Input","onChangeFilter","startAdornment","InputAdornment","FilterList","getNextCheckboxState","checked","Row","tooltip","checkable","nohover","scrollOffset","action","hover","Column","column","NumberColumn","light","backgroundColor","rgb2hsl","hex","_map$slice$map","exec","parseInt","_map$slice$map2","r","g","b","max","min","DivisionRow","_props$onCheck","onCheck","dataKey","onMouseOver","_props$onMouseOver","onMouseOut","_props$onMouseOut","Checkbox","indeterminate","name","cells","fill","cell","toString","DirectoryRoot","TreeItem","treeItemClasses","content","typography","fontWeightMedium","fontWeightRegular","group","iconContainer","DirectoryEntry","nodeId","desc","other","disableInteractive","expandIcon","KeyboardArrowRight","collapseIcon","KeyboardArrowDown","field","ExpandButton","Container","columns","Component","numeric","DirectoryTableHead","onExpandAll","allExpanded","UnfoldLess","UnfoldMore","onSelectAll","enterDelay","TableSortLabel","orderBy","direction","onRequestSort","useDirectory","_useLoadDirectory","divisionMap","fromEntries","flatMap","_ref2$departments","departments","_excluded2","divisionTree","dir","_dir$departments$map","_dir$departments","_useLoadDirectory$dat","_useLoadDirectory$dat2","rest","ScrollableDiv","DirectoryTree","_query$sort","_useMeasure","_useMeasure2","_useSearchQuery","_useSearchQuery2","setQuery","_useDivisionsQuery","_useDivisionsQuery2","divisions","setDivisions","selectedDivisions","Set","divisionFilter","setDivisionFilter","expanded","setExpanded","orderDivisions","_useSearch","forEach","divisionAggs","_useDirectory","isLoading","handleCheck","_key$split","_key$split2","div2","stopPropagation","handleSelectGroup","_divisionTree$key","getDirectoryCheckState","has","every","div","allChecked","keys","isFiltered","isDirFiltered","_divisionTree$key2","isExpanded","overflow","height","numSelected","roots","TreeView","defaultCollapseIcon","ArrowDropDown","defaultExpandIcon","ArrowRight","defaultEndIcon","multiSelect","onNodeToggle","_div$divisions","_div$divisions$filter","DivisionDrawer","wideScreen","useMediaQuery","Drawer","container","document","body","anchor","ModalProps","keepMounted","StyledFooter","Footer","rel","mooreLogo","dataLabLogo","isAgg","ChartTooltip","_divisionAggs$filter","_year$toString","widthRef","year","_data$bars$find$divis","_data$bars$find","array","stabilizedThis","index","sign","order","stableSort","bars","legendFilter","totals","rows","elevation","_divisionMap$key","StyledMenu","Menu","Label","units","icon","InsertDriveFile","AttachMoney","radio","ChartLegend","_useQuery2","togglesRef","chartTogglesActive","_useWizardRef2","anyAllRef","anyAllActive","handleChangeAgg","handleChangeBool","intersection","handleToggle","_Fragment","Settings","RadioGroup","u","FormControlLabel","control","Radio","fontSize","D3Timeline","_createClass","_this","_classCallCheck","animationDur","chart","chartWidth","chartHeight","x","y","nice","xAxis","yAxis","tickFormat","brush","gb","yearRange","agg","getXAxis","_d3$extent","domain","_d3$extent2","tickValues","getYAxis","Infinity","setYearRange","start","end","updateBrush","raise","measure","attr","left","top","rangeRound","extent","redraw","updateAxes","xInverse","paddingOuter","eachBand","round","update","apply","selectAll","enter","append","bandwidth","exit","remove","classed","getBrushBounds","endOffset","this","svg","on","_props$onBrushEnded","sourceEvent","selection","onBrushEnded","move","tooltipDebounce","fn","debounce","containerEl","bottom","right","timelineLayout","timeline","stack","divs","invDivs","offsets","domainUpdated","prev","yLabel","gridLines","onTooltipEnter","onTooltipLeave","onBarClick","yearGap","boundaryYearGap","ceil","getGridLines","tickSize","scale","ticks","divDomain","_this$prev","_this$prev2","getStackOrderOffsets","getStack","flat","stacks","each","getYTransition","getXTransition","_this$prev3","_this$x","_this$onTooltipEnter","rect","node","bar","_tooltip$select$node","scrollIntoView","behavior","block","inline","tipBbox","chartRightEdge","tipSide","tipLeft","rectCenter","tipTop","transitionTooltip","_this$onTooltipLeave","_this$onBarClick","copy","_d$aggs$key$agg","_d$aggs$key","aggs","sub","sup","s","layout","_this$x2","first","last","from","to","prevGroup","highlightGroup","dimensions","timelineRef","defs","html","clientWidth","clientHeight","ChartContainer","Chart","visRef","_useGrantsDialogQuery","setDialogQuery","chartData","yearData","per_year","tooltipProps","setTooltipProps","handleTooltipEnter","handleBarClick","handleSetYearRange","grantDialogOpen","grantDialogYear","grantDialogDivision","useGrantsDownload","_dialog$grantDialogYe","_dialog$grantDialogYe2","dialog","stringifyUrl","url","baseURL","grantDirection","grantSort","StyledAction","SpeedDialAction","_useBeta2","setBeta","_useTutorial","setTutorial","grantsUrl","overflowMenuRef","actions","Download","handleClick","GitHub","Help","SpeedDial","ariaLabel","sx","classList","contains","tooltipTitle","Subtitle","Abstract","AbstractDialog","_grant$abstract","date","_useTermsQuery2","_useGrantIdQuery","_useGrantIdQuery2","grantId","setGrantId","_useLoadAbstract","grant","dismissDialog","Dialog","DialogTitle","external_url","LaunchIcon","cat1_raw","recipient_org","investigators","DialogContent","Collapse","in","abstract","nodeName","toLowerCase","innerText","dangerouslySetInnerHTML","__html","DialogActions","cols","timeFormat","timeParse","GrantListItem","EndOfListItem","GrantColumn","GrantRow","getQueryData","page","pages","floor","useMemo","useGrant","ProgressBar","GrantsTable","_useWindowDimensions","_useInfiniteLoadGrant","_data$pages$reduce","_data$pages","hasMountedRef","loaderRef","loadMoreGrants","_asyncToGenerator","_regeneratorRuntime","mark","_callee","_ref$pageParam","pageParam","_yield$loadGrants","wrap","_context","next","sent","abrupt","stop","_x","arguments","_useInfiniteQuery","useInfiniteQuery","getNextPageParam","lastPage","isError","clearGrants","_loaderRef$current","resetloadMoreItemsCache","setQueryData","pageParams","fetchNextPage","reduce","noMore","useInfiniteLoadGrants","hasNextPage","isFetchingNextPage","isFetchedAfterMount","handleLoadGrants","InfiniteLoader","isItemLoaded","itemCount","loadMoreItems","onItemsRendered","FixedSizeList","itemSize","shadows","FilterChip","onClear","avatar","TopAlignedDialog","GrantListHeader","h6","GrantsDialog","_useGrantsDialogQuery2","handleClose","getFilterLabel","_dialog$grantDialogDi","_dialog$grantDialogDi2","toUpperCase","fullWidth","maxWidth","component","StyledActions","Overlay","Spotlight","WizardTooltip","_useWizard","_useTutorial2","setStepIdx","navigateForward","useCallback","navigateBack","cancelWizard","localStorage","setItem","tutorialNav","tutorialViewed","getItem","prevStepIdx","useWizard","Close","NavigateBefore","NavigateNext","About","_useAbout2","aboutOpen","cursor","ResponsiveContainer","App","_useMeasureChart","topRef","bottomRef","_useWindowDimensions2","windowWidth","windowHeight","prevTerms","setPrevTerms","dims","useMeasureChart","_useMeasureChart2","navbarRef","footerRef","NavigationBar","ReactDOM","render","Router","QueryParamProvider","ReactRouterRoute","Route","QueryClientProvider","client","getElementById","navigator","serviceWorker","ready","registration","unregister"],"mappings":"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","file":"static/js/main.36a548cc.chunk.js","sourcesContent":["// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.1/8 is considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\ntype Config = {\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\n};\n\nexport function register(config?: Config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(\n (process as { env: { [key: string]: string } }).env.PUBLIC_URL,\n window.location.href\n );\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl: string, config?: Config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl)\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import * as d3 from 'd3';\nimport { ThemeProvider as EmotionThemeProvider } from '@emotion/react';\nimport {\n createTheme,\n Theme as MuiTheme,\n ThemeProvider as MuiThemeProvider,\n} from '@material-ui/core/styles';\nimport { CssBaseline } from '@material-ui/core';\nimport {\n deepPurple,\n green,\n blue,\n red,\n amber,\n pink,\n} from '@material-ui/core/colors';\n\nexport const interleave = (v: T, i: number, a: T[]) => (\n a[Math.trunc(i / 2) + (i % 2 ? a.length / 2 : 0)]\n);\n\nexport const colorScales = {\n count: d3.scaleOrdinal(Object.values(deepPurple).slice(0, -4).map(interleave)),\n amount: d3.scaleOrdinal(Object.values(green).slice(0, -4).map(interleave)),\n};\n\nexport const hierColorScale = d3.scaleOrdinal(\n [deepPurple, green, blue, red, amber, pink].map(color =>\n d3.scaleOrdinal(Object.values(color).slice(0, -4).map(interleave))\n )\n);\n\ndeclare module '@material-ui/core/styles/createPalette' {\n export interface PaletteOptions {\n amounts: PaletteColorOptions,\n counts: PaletteColorOptions,\n }\n}\n \ndeclare module '@material-ui/core/styles/createTheme' {\n export interface ThemeOptions {\n drawerWidth: string\n }\n \n export interface Theme {\n drawerWidth: string\n }\n}\n\nconst theme = createTheme({\n drawerWidth: '35em',\n palette: {\n primary: {\n main: '#6772e5'\n },\n counts: {\n main: deepPurple[500],\n },\n amounts: {\n main: green[500],\n }, \n },\n});\n\nconst ThemeProvider = ({ children }: { children: JSX.Element }) => {\n return (\n \n \n \n {children}\n \n \n );\n};\n\n// Re-declare the emotion theme to have the properties of the MaterialUiTheme\ndeclare module '@emotion/react' {\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\n export interface Theme extends MuiTheme {}\n}\n\nexport default ThemeProvider;","import { BooleanParam, DelimitedArrayParam, NumberParam, QueryParamConfig, StringParam, useQueryParam, useQueryParams, withDefault } from 'use-query-params';\nimport { SortableKeys } from 'app/sort';\n\nexport type Organization = 'nsf' | 'nih';\n\nexport const OrgParam = withDefault(\n StringParam,\n 'nsf',\n) as QueryParamConfig;\n\nexport const ArrayParam = withDefault(\n DelimitedArrayParam,\n [],\n) as QueryParamConfig;\n\nexport const DivisionsArrayParam = withDefault(\n DelimitedArrayParam,\n undefined,\n) as QueryParamConfig;\n\nexport const DefaultStringParam = withDefault(\n StringParam,\n undefined\n) as QueryParamConfig;\n\nexport const DefaultNumberParam = withDefault(\n NumberParam,\n undefined\n) as QueryParamConfig;\n\nexport const DefaultBooleanParam = withDefault(\n BooleanParam,\n undefined\n) as QueryParamConfig;\n\nconst SortParam = withDefault(\n StringParam,\n 'amount',\n) as QueryParamConfig;\n\nconst SortDirectionParam = withDefault(\n StringParam,\n 'desc',\n) as QueryParamConfig<'asc' | 'desc'>;\n\nconst MatchParam = withDefault(\n ArrayParam,\n ['title', 'abstract']\n) as QueryParamConfig>;\n\nexport const paramConfigMap = {\n 'org': OrgParam,\n 'terms': ArrayParam,\n 'start': DefaultNumberParam,\n 'end': DefaultNumberParam,\n 'intersection': DefaultBooleanParam,\n 'match': MatchParam,\n 'sort': SortParam,\n 'direction': SortDirectionParam,\n};\n\nconst grantParamConfig = {\n 'grantDialogOpen': BooleanParam,\n 'grantDialogYear': NumberParam,\n 'grantDialogDivision': StringParam,\n 'grantSort': DefaultStringParam,\n 'grantDirection': SortDirectionParam,\n};\n\nexport const useSearchQuery = () => (\n useQueryParams(paramConfigMap)\n);\n\nexport const useGrantsDialogQuery = () => (\n useQueryParams(grantParamConfig)\n);\n\nexport const useTermsQuery = () => (\n useQueryParam('terms', ArrayParam)\n);\n\nexport const useGrantIdQuery = () => (\n useQueryParam('grantId', DefaultStringParam)\n);\n\nexport const useQuery = () => (\n useQueryParams({\n ...paramConfigMap,\n 'divisions': ArrayParam,\n })\n);\n\nexport const useSortQuery = () => (\n useQueryParams({\n 'sort': SortParam,\n 'direction': SortDirectionParam,\n })\n);\n\nexport const useDivisionsQuery = () => {\n return useQueryParam('divisions', DivisionsArrayParam);\n // const [ divisions, setDivisions ] = useQueryParam('divisions', DelimitedArrayParam);\n // const { divisionMap } = useDirectory();\n // if (divisions && divisions.every(d => d)) {\n // return [ new Set(divisions as string[]), setDivisions ];\n // } else {\n // return [ new Set(Object.keys(divisionMap)), setDivisions ];\n // }\n};\n\n\nexport const useBeta = () => useQueryParam('beta', DefaultBooleanParam);\n\nexport const useTutorial = () => useQueryParam('tutorial', DefaultNumberParam);\n\nexport const useAbout = () => useQueryParam('about', DefaultBooleanParam);\n\nexport type QueryParams = ReturnType[0];\n","import { useState, useEffect, useRef, RefObject, useMemo } from 'react';\nimport { useQuery } from './query';\n\nexport const useMeasure = (): [ RefObject, number ] => {\n \n const ref = useRef(null);\n const padding = useRef(0);\n\n useEffect(() => {\n if (ref.current) {\n const bbox = ref.current.getBoundingClientRect();\n const parent = ref.current.parentElement?.getBoundingClientRect();\n if (parent && bbox.width) {\n padding.current = parent.width - bbox.width;\n }\n }\n }, [ref.current?.getBoundingClientRect().width]);\n \n return [ ref, padding.current ];\n};\n\ntype Dims = {\n width: number\n height: number\n}\n\nexport const useMeasureChart = (): [ RefObject, RefObject, Dims ] => {\n \n const topRef = useRef(null);\n const bottomRef = useRef(null);\n const [ windowWidth, windowHeight ] = useWindowDimensions();\n // resize when terms change since they change height of toolbar\n const [{ terms }] = useQuery();\n const [ prevTerms, setPrevTerms ] = useState(terms);\n\n useEffect(() => {\n setPrevTerms(terms);\n }, [terms]);\n\n const dims = useMemo(() => {\n if (topRef.current && bottomRef.current) {\n const top = topRef.current.getBoundingClientRect();\n const bottom = bottomRef.current.getBoundingClientRect();\n if (top.height && bottom.height) {\n return {\n width: top.width,\n height: windowHeight - top.height - bottom.height,\n };\n }\n }\n return { width: 0, height: 0 };\n }, [topRef.current, bottomRef.current, windowWidth, windowHeight, JSON.stringify(prevTerms)]);\n \n return [ topRef, bottomRef, dims ];\n};\n\ntype ResultBox = { v: T }\n\nexport const useConstant = (fn: () => T): T => {\n const ref = useRef>();\n\n if (!ref.current) {\n ref.current = { v: fn() };\n }\n\n return ref.current.v;\n};\n\nconst getWindowDimensions = () => {\n return [ window.innerWidth, window.innerHeight ];\n};\n\nexport const useWindowDimensions = () => {\n const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());\n\n useEffect(() => {\n const handleResize = () => {\n setWindowDimensions(getWindowDimensions());\n };\n \n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n\n return windowDimensions;\n};\n\nexport const useDebounce = (value: T, delay?: number): T => {\n\n const [debouncedValue, setDebouncedValue] = useState(value);\n\n useEffect(() => {\n const timer = setTimeout(() => setDebouncedValue(value), delay || 500);\n return () => {\n clearTimeout(timer);\n };\n }, [value, delay]);\n\n return debouncedValue;\n};\n","import { memo, MouseEvent } from 'react';\nimport { Flipped } from 'react-flip-toolkit';\nimport { animate } from 'motion';\nimport { Chip, CircularProgress } from '@material-ui/core';\nimport { alpha, styled } from '@material-ui/core/styles';\nimport { format } from 'd3';\n\nconst StyledChip = styled(Chip)(({ theme }) => `\n margin-right: ${theme.spacing(1)};\n margin-bottom: ${theme.spacing(1)};\n &.MuiChip-root {\n background-color: ${theme.palette.grey[300]};\n &:hover {\n background-color: ${theme.palette.grey[400]};\n }\n }\n &.MuiChip-colorSecondary {\n background-color: ${theme.palette.secondary.main};\n &:hover {\n background-color: ${theme.palette.secondary.dark};\n }\n & > span > span > span {\n background-color: ${alpha(theme.palette.common.white, 0.7)};\n }\n }\n`);\n\nconst ChipContent = styled('span')(({ theme }) => `\n display: flex;\n flex-direction: row;\n align-items: center;\n // count\n & > span {\n ${theme.breakpoints.down('sm')} {\n display: none;\n }\n height: ${theme.spacing(3)};\n min-width: ${theme.spacing(3)};\n color: ${theme.palette.text.primary};\n background-color: ${alpha(theme.palette.common.black, 0.26)};\n margin-left: -${theme.spacing(0.9)};\n margin-right: ${theme.spacing(1)};\n padding: ${theme.spacing(0.25, 0.5)};\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: ${theme.spacing(1.5)};\n }\n`);\n\nconst animateIn = (e: HTMLElement, i: number) => {\n e.style.transform = 'translate(50%)';\n return animate(e, {\n // delay: i * 15,\n opacity: 100,\n transform: 'translate(0%)',\n });\n};\n\nconst animateOut = (e: HTMLElement) => (\n animate(e, {\n opacity: 0,\n // transform: 'scale(0%)'\n })\n);\n\nexport type TermChipProps = {\n term: string\n count?: number\n onClick?: (e: MouseEvent, key: string) => void\n onDelete?: () => void\n selected?: boolean\n};\n\nconst TermChip = (props: TermChipProps) => (\n \n \n \n {props.count !== undefined\n ? format('.2s')(props.count).replace('.0', '')\n : \n }\n \n {props.term}\n \n }\n onClick={(e) => props.onClick?.(e, props.term)}\n onDelete={props.onDelete}\n />\n \n);\n \nexport default memo(TermChip);","import { MouseEvent, FocusEvent, forwardRef, KeyboardEvent, useRef, useState } from 'react';\nimport { Box, ClickAwayListener, Fade, InputBase, InputBaseProps, Paper, Popper, styled } from '@material-ui/core';\nimport { Flipped } from 'react-flip-toolkit';\nimport { useQuery } from 'app/query';\n\nconst InputContainer = styled(Box)(({ theme }) => `\n flex-grow: 1;\n cursor: text;\n`);\n\nconst ChipInput = styled(InputBase)(({ theme }) => `\n padding: 0;\n color: 'inherit';\n & .MuiInputBase-input {\n color: ${theme.palette.common.white};\n // transition: ${theme.transitions.create('width')};\n width: 100%;\n padding-left: ${theme.spacing(1)};\n padding-bottom: ${theme.spacing(1.5)};\n ${theme.breakpoints.up('sm')} {\n width: 10ch;\n // &:focus {\n // width: 20ch;\n // }\n }\n }\n`);\n\nconst Dropdown = styled(Paper)<{ topics: boolean }>(({ theme, topics }) => `\n right: 0;\n width: 100%;\n margin-top: ${theme.spacing(.5)};\n max-height: calc(100vh - 256px);\n overflow-x: hidden;\n overflow-y: auto;\n z-index: 3;\n ${theme.breakpoints.up('sm')} {\n width: ${topics ? '50em' : '25em'};\n }\n`);\n\ntype TermsInputProps = {\n value: string\n suggestions: React.ReactElement | null\n onAddChip: (chips: string) => void\n onDeleteLastChip: () => void\n onClearInput: () => void\n};\n\nconst TermsInput = forwardRef((props: InputBaseProps & TermsInputProps, ref) => {\n\n const {\n suggestions,\n onAddChip,\n onDeleteLastChip,\n onClearInput,\n ...inputProps\n } = props;\n\n const inputRef = useRef(null);\n const [ focused, setFocused ] = useState(false);\n const [ anchorEl, setAnchorEl ] = useState(null);\n const [{ terms }] = useQuery();\n \n const handleClickFocus = (e: MouseEvent) => {\n inputRef.current?.focus();\n setFocused(true);\n };\n\n const handleFocus = (e: FocusEvent) => {\n setFocused(true);\n if (e.currentTarget) {\n setAnchorEl(e.currentTarget\n .parentElement\n ?.parentElement\n ?.parentElement\n ?.parentElement\n ?.parentElement as HTMLElement);\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n console.log(e.key);\n switch(e.key) {\n case 'Enter':\n onAddChip(props.value);\n break;\n case 'Backspace':\n if (props.value.length === 0) {\n onDeleteLastChip();\n } else if (props.value.length === 1) {\n onClearInput();\n }\n break;\n case 'Escape':\n handleClickAway();\n break;\n case 'ArrowDown':\n console.log('down');\n break;\n case 'ArrowUp':\n console.log('down');\n break;\n }\n };\n\n const handleClickAway = () => {\n setFocused(false);\n inputRef.current?.blur();\n };\n\n return (\n \n \n \n {flipProps => (\n \n )}\n \n \n {({ TransitionProps }) => (\n \n \n {suggestions}\n \n \n )}\n \n \n \n );\n});\n\nexport default TermsInput;","/**\n * Generated by orval v6.5.3 🍺\n * Do not edit manually.\n * FastAPI\n * OpenAPI spec version: 0.1.0\n */\nimport axios,{\n AxiosRequestConfig,\n AxiosResponse,\n AxiosError\n} from 'axios'\nimport {\n useQuery,\n UseQueryOptions,\n QueryFunction,\n UseQueryResult,\n QueryKey\n} from 'react-query'\nexport type LoadAbstractParams = { terms?: string[]; beta?: boolean };\n\nexport type DownloadGrantsParams = { org: string; start?: number; end?: number; divisions?: string[]; match?: string[]; terms?: string[]; sort?: string; order?: string; intersection?: boolean };\n\nexport type LoadGrantsParams = { idx: number; org: string; start?: number; end?: number; divisions?: string[]; match?: string[]; terms?: string[]; sort?: string; order?: string; intersection?: boolean };\n\nexport type LoadTermCounts200 = {[key: string]: number};\n\nexport type LoadTermCountsParams = { org: string; match?: string[]; terms?: string[] };\n\nexport type LoadRelatedParams = { terms?: string[] };\n\nexport type LoadTypeaheadParams = { selected_terms?: string[] };\n\nexport type YearsParams = { org: string; terms?: string[]; divisions?: string[]; match?: string[]; intersection?: boolean };\n\nexport type SearchParams = { org: string; start?: number; end?: number; terms?: string[]; match?: string[]; intersection?: boolean };\n\nexport interface YearDivisionAggregate {\n key: number;\n count: number;\n amount: number;\n divisions: DivisionAggregate[];\n}\n\nexport interface YearAggregate {\n key: number;\n count: number;\n amount: number;\n}\n\nexport interface YearsResponse {\n per_year: YearAggregate[];\n}\n\nexport interface ValidationError {\n loc: string[];\n msg: string;\n type: string;\n}\n\nexport interface TermTopic {\n term: string;\n count: number;\n}\n\nexport interface Topic {\n terms: TermTopic[];\n}\n\nexport interface Term {\n term: string;\n stem: string;\n forms: string[];\n}\n\nexport interface SubDirectory {\n abbr: string;\n name: string;\n href: string;\n est?: number;\n desc?: string;\n}\n\nexport interface SearchResponse {\n bars: YearDivisionAggregate[];\n divisions: DirectoryAggregate[];\n}\n\nexport interface HTTPValidationError {\n detail?: ValidationError[];\n}\n\nexport interface Grant {\n id: string;\n grant_id: string;\n agency: string;\n score: number;\n title: string;\n date: string;\n amount: number;\n abstract?: string;\n cat1: string;\n cat1_raw: string;\n cat2?: string;\n cat2_raw?: string;\n cat3?: string;\n cat3_raw?: string;\n external_url?: string;\n investigators?: string;\n recipient_org?: string;\n}\n\nexport interface DivisionAggregate {\n key: string;\n count: number;\n amount: number;\n}\n\nexport interface Division {\n key: string;\n name: string;\n selected: boolean;\n}\n\nexport interface DirectoryAggregate {\n key: string;\n count: number;\n amount: number;\n divisions: DivisionAggregate[];\n}\n\nexport interface Directory {\n abbr: string;\n name: string;\n href: string;\n est?: number;\n desc?: string;\n departments: SubDirectory[];\n}\n\n\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AsyncReturnType<\nT extends (...args: any) => Promise\n> = T extends (...args: any) => Promise ? R : any;\n\n\n/**\n * @summary Divisions\n */\nexport const loadDivisions = (\n org: string, options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/divisions/${org}`,options\n );\n }\n\n\nexport const getLoadDivisionsQueryKey = (org: string,) => [`/divisions/${org}`];\n\n \nexport const useLoadDivisions = , TError = AxiosError>(\n org: string, options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getLoadDivisionsQueryKey(org);\n\n \n\n const queryFn: QueryFunction> = () => loadDivisions(org, axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, {enabled: !!(org), ...queryOptions})\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Get Topics\n */\nexport const getTopics = (\n options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/topics`,options\n );\n }\n\n\nexport const getGetTopicsQueryKey = () => [`/topics`];\n\n \nexport const useGetTopics = , TError = AxiosError>(\n options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getGetTopicsQueryKey();\n\n \n\n const queryFn: QueryFunction> = () => getTopics(axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, queryOptions)\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Divisions\n */\nexport const loadDirectory = (\n org: string, options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/directory/${org}`,options\n );\n }\n\n\nexport const getLoadDirectoryQueryKey = (org: string,) => [`/directory/${org}`];\n\n \nexport const useLoadDirectory = , TError = AxiosError>(\n org: string, options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getLoadDirectoryQueryKey(org);\n\n \n\n const queryFn: QueryFunction> = () => loadDirectory(org, axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, {enabled: !!(org), ...queryOptions})\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Search\n */\nexport const search = (\n params?: SearchParams, options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/search`,{\n params,\n ...options}\n );\n }\n\n\nexport const getSearchQueryKey = (params?: SearchParams,) => [`/search`, ...(params ? [params]: [])];\n\n \nexport const useSearch = , TError = AxiosError>(\n params?: SearchParams, options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getSearchQueryKey(params);\n\n \n\n const queryFn: QueryFunction> = () => search(params, axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, queryOptions)\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Years\n */\nexport const years = (\n params?: YearsParams, options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/years`,{\n params,\n ...options}\n );\n }\n\n\nexport const getYearsQueryKey = (params?: YearsParams,) => [`/years`, ...(params ? [params]: [])];\n\n \nexport const useYears = , TError = AxiosError>(\n params?: YearsParams, options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getYearsQueryKey(params);\n\n \n\n const queryFn: QueryFunction> = () => years(params, axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, queryOptions)\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Typeahead\n */\nexport const loadTypeahead = (\n prefix: string,\n params?: LoadTypeaheadParams, options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/keywords/typeahead/${prefix}`,{\n params,\n ...options}\n );\n }\n\n\nexport const getLoadTypeaheadQueryKey = (prefix: string,\n params?: LoadTypeaheadParams,) => [`/keywords/typeahead/${prefix}`, ...(params ? [params]: [])];\n\n \nexport const useLoadTypeahead = , TError = AxiosError>(\n prefix: string,\n params?: LoadTypeaheadParams, options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getLoadTypeaheadQueryKey(prefix,params);\n\n \n\n const queryFn: QueryFunction> = () => loadTypeahead(prefix,params, axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, {enabled: !!(prefix), ...queryOptions})\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Related\n */\nexport const loadRelated = (\n params?: LoadRelatedParams, options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/keywords/related`,{\n params,\n ...options}\n );\n }\n\n\nexport const getLoadRelatedQueryKey = (params?: LoadRelatedParams,) => [`/keywords/related`, ...(params ? [params]: [])];\n\n \nexport const useLoadRelated = , TError = AxiosError>(\n params?: LoadRelatedParams, options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getLoadRelatedQueryKey(params);\n\n \n\n const queryFn: QueryFunction> = () => loadRelated(params, axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, queryOptions)\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Count Terms\n */\nexport const loadTermCounts = (\n params?: LoadTermCountsParams, options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/keywords/count`,{\n params,\n ...options}\n );\n }\n\n\nexport const getLoadTermCountsQueryKey = (params?: LoadTermCountsParams,) => [`/keywords/count`, ...(params ? [params]: [])];\n\n \nexport const useLoadTermCounts = , TError = AxiosError>(\n params?: LoadTermCountsParams, options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getLoadTermCountsQueryKey(params);\n\n \n\n const queryFn: QueryFunction> = () => loadTermCounts(params, axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, queryOptions)\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Grant Data\n */\nexport const loadGrants = (\n params?: LoadGrantsParams, options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/grants`,{\n params,\n ...options}\n );\n }\n\n\nexport const getLoadGrantsQueryKey = (params?: LoadGrantsParams,) => [`/grants`, ...(params ? [params]: [])];\n\n \nexport const useLoadGrants = , TError = AxiosError>(\n params?: LoadGrantsParams, options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getLoadGrantsQueryKey(params);\n\n \n\n const queryFn: QueryFunction> = () => loadGrants(params, axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, queryOptions)\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Grant Download\n */\nexport const downloadGrants = (\n params?: DownloadGrantsParams, options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/grants/download`,{\n params,\n ...options}\n );\n }\n\n\nexport const getDownloadGrantsQueryKey = (params?: DownloadGrantsParams,) => [`/grants/download`, ...(params ? [params]: [])];\n\n \nexport const useDownloadGrants = , TError = AxiosError>(\n params?: DownloadGrantsParams, options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getDownloadGrantsQueryKey(params);\n\n \n\n const queryFn: QueryFunction> = () => downloadGrants(params, axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, queryOptions)\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Get Abstract\n */\nexport const loadAbstract = (\n id: unknown,\n params?: LoadAbstractParams, options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/abstract/${id}`,{\n params,\n ...options}\n );\n }\n\n\nexport const getLoadAbstractQueryKey = (id: unknown,\n params?: LoadAbstractParams,) => [`/abstract/${id}`, ...(params ? [params]: [])];\n\n \nexport const useLoadAbstract = , TError = AxiosError>(\n id: unknown,\n params?: LoadAbstractParams, options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getLoadAbstractQueryKey(id,params);\n\n \n\n const queryFn: QueryFunction> = () => loadAbstract(id,params, axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, {enabled: !!(id), ...queryOptions})\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n/**\n * @summary Send Api Json\n */\nexport const sendApiJsonGenerateOpenapiJsonGet = (\n options?: AxiosRequestConfig\n ): Promise> => {\n return axios.get(\n `/generate_openapi_json`,options\n );\n }\n\n\nexport const getSendApiJsonGenerateOpenapiJsonGetQueryKey = () => [`/generate_openapi_json`];\n\n \nexport const useSendApiJsonGenerateOpenapiJsonGet = , TError = AxiosError>(\n options?: { query?:UseQueryOptions, TError, TData>, axios?: AxiosRequestConfig}\n\n ): UseQueryResult & { queryKey: QueryKey } => {\n\n const {query: queryOptions, axios: axiosOptions} = options || {}\n\n const queryKey = queryOptions?.queryKey ?? getSendApiJsonGenerateOpenapiJsonGetQueryKey();\n\n \n\n const queryFn: QueryFunction> = () => sendApiJsonGenerateOpenapiJsonGet(axiosOptions);\n\n const query = useQuery, TError, TData>(queryKey, queryFn, queryOptions)\n\n return {\n queryKey,\n ...query\n }\n}\n\n\n","import { Box, Button, LinearProgress, List, ListItem, ListSubheader } from '@material-ui/core';\nimport { styled } from '@material-ui/system';\nimport { Science, Shuffle } from '@mui/icons-material';\nimport { useTermsQuery } from 'app/query';\nimport { useGetTopics } from '../../api';\nimport TermChip from './TermChip';\n\nconst StyledList = styled(List)(({ theme }) => `\n padding-bottom: 0;\n & .MuiListSubheader-root {\n display: flex;\n align-items: center;\n }\n & .MuiLinearProgress-root {\n margin-bottom: -4px;\n }\n & .MuiListItem-root {\n cursor: pointer;\n border-top: 1px solid ${theme.palette.grey[200]};\n display: flex;\n flex-wrap: wrap;\n & .MuiChip-root {\n margin-right: ${theme.spacing(1)};\n pointer-events: none;\n }\n &:hover {\n background-color: ${theme.palette.grey[200]};\n & .MuiChip-root {\n background-color: ${theme.palette.grey[400]};\n }\n }\n }\n`);\n\nconst TermsPreset = () => {\n \n const { data: topics, isFetching, refetch } = useGetTopics();\n const [ , setTerms ] = useTermsQuery();\n \n const handleSelectTopic = (topicIdx: number) => {\n if (topics?.data) {\n console.log(topics, topicIdx);\n setTerms(topics.data[topicIdx].terms.map(term => term.term));\n }\n };\n \n const handleShuffleTopics = () => refetch();\n\n return (\n \n \n \n Start searching a topic\n \n }\n >\n See new topics\n \n \n {isFetching && }\n {topics?.data.map((topic, i) => (\n handleSelectTopic(i)}>\n {topic.terms.map(term => (\n \n ))}\n \n ))}\n \n );\n};\n\nexport default TermsPreset;\n","import parse from 'autosuggest-highlight/parse';\nimport match from 'autosuggest-highlight/match';\n\ntype HighlightProps = {\n value: string\n query: string\n}\n\nconst Highlight = (props: HighlightProps) => (\n \n {parse(props.value, match(props.value, props.query)).map((part, idx) => (\n \n {part.text}\n \n ))}\n \n);\n\nexport default Highlight;","import { List, ListItem, ListItemIcon, ListItemText, ListSubheader, styled } from '@material-ui/core';\nimport { AddCircle } from '@mui/icons-material';\nimport Highlight from 'app/Highlight';\nimport { Flipped, Flipper } from 'react-flip-toolkit';\nimport anime from 'animejs';\nimport { Term } from 'api';\n\nconst StyledListItem = styled(ListItem)(({ theme }) => `\n background-color: white;\n border-top: 1px solid ${theme.palette.grey[200]};\n &:hover {\n cursor: pointer;\n background-color: ${theme.palette.grey[200]};\n }\n & .MuiListItemIcon-root {\n min-width: 0;\n }\n & .MuiListItemText-primary {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n & .forms {\n padding-left: ${theme.spacing(1)};\n color: ${theme.palette.text.disabled};\n }\n }\n`);\n\n// const animateIn = (e: HTMLElement) => (\n// animate(e, {\n// opacity: 100,\n// // transform: 'translate(0%, 100%)'\n// })\n// );\n// \n// const animateOut = (e: HTMLElement) => (\n// animate(e, {\n// opacity: 0,\n// // transform: 'translate(0%, -100%)'\n// // transform: 'scale(0%)'\n// })\n// );\n\nconst animateIn = (el, i) =>\n anime({\n targets: el,\n opacity: 1,\n delay: i * 15,\n easing: 'easeOutSine',\n duration: 100,\n });\n\nconst animateOut = (el, i, onComplete) => {\n anime({\n targets: el,\n opacity: 0,\n // delay: i * 10,\n easing: 'easeOutSine',\n duration: 100,\n complete: onComplete\n });\n};\n\nconst exitThenFlipAndEnter = ({\n hideEnteringElements,\n animateEnteringElements,\n animateExitingElements,\n animateFlippedElements\n}) => {\n hideEnteringElements();\n animateExitingElements()\n .then(() => {\n animateFlippedElements();\n animateEnteringElements();\n });\n};\n\ntype TermsListProps = {\n beta?: boolean,\n input: string,\n header: string,\n filter: string[],\n terms: Term[] | undefined,\n onAddChip: (term: string) => void,\n}\n\nconst TermsList = (props: TermsListProps) => (\n \n
\n \n {props.header}}>\n {props.terms\n ?.map(t => (\n \n
\n props.onAddChip(t.term)}\n >\n \n \n {props.beta &&\n \n {t.forms.join(', ')}\n \n }\n \n \n \n \n \n
\n \n ))}\n
\n \n
\n
\n);\n\nexport default TermsList;","import { QueryClient } from 'react-query';\nimport Axios from 'axios';\nimport { stringify } from 'query-string';\n\nAxios.defaults.paramsSerializer = (params) => stringify(params);\n\nexport const queryClient = new QueryClient();\n","import { useDivisionsQuery, useGrantsDialogQuery, useSearchQuery } from 'app/query';\n\nimport ChartTooltip, { TooltipProps } from './ChartTooltip';\nimport ChartLegend from './ChartLegend';\nimport { useEffect, useRef, useState } from 'react';\nimport BarChart from './D3Chart';\nimport styled from '@emotion/styled';\nimport { useSearch } from 'api';\nimport { isAgg } from 'app/sort';\nimport { useYears } from 'api';\nimport { useWizardRef } from 'app/wizard/wizard';\n\nlet vis: BarChart;\n\nconst ChartContainer = styled.div(({ theme }) => `\n flex-grow: 1;\n position: relative;\n .axis {\n font: Helvetica;\n font-size: 14px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 500;\n }\n .gridline {\n stroke: ${theme.palette.grey[100]};\n stroke-dasharray: 5 5;\n // shape-rendering: crispEdges;\n line {\n stroke: ${theme.palette.grey[400]};\n }\n .domain {\n display: none;\n }\n }\n .selected {\n outline-style: solid;\n outline-color: black;\n outline-width: 2px;\n outline-offset: -2px;\n }\n #legend {\n position: absolute;\n left: 96px;\n top: 32px;\n }\n #tooltip {\n pointer-events: none;\n position: absolute;\n visibility: hidden;\n width: 30em;\n &.visible {\n visibility: initial;\n } \n }\n`);\n\ntype ChartProps = {\n width: number\n height: number\n}\n\nconst Chart = (props: ChartProps) => {\n\n const visRef = useRef(null);\n const { ref: timelineRef, active } = useWizardRef('filterYears');\n const [ divisions ] = useDivisionsQuery();\n const [ query, setQuery ] = useSearchQuery();\n const [ , setDialogQuery ] = useGrantsDialogQuery();\n\n // TODO reimplement this?\n // const { counts, amounts } = useAppSelector(getLegendFilters);\n const { data } = useSearch(query, {\n query: {\n select: ({ data }) => ({\n chartData: data.bars.map(({ key, divisions }) => ({\n year: key,\n aggs: Object.fromEntries(divisions.map(({ key, ...aggs }) => [ key, aggs ]))\n })),\n divDomain: data.divisions\n .flatMap(d => d.divisions)\n .sort((a, b) => (a[query.sort] - b[query.sort]) * (query.direction === 'asc' ? 1 : -1))\n .map(d => d.key)\n .filter(key => divisions == undefined || divisions.includes(key))\n }),\n }\n });\n \n const { data: yearData } = useYears(query, {\n query: {\n select: ({ data }) => (\n data.per_year.map(agg => ({ ...agg, year: agg.key }))\n )\n }\n });\n\n // const highlightedDivision = useAppSelector(getHighlightedDivision);\n const [ tooltipProps, setTooltipProps ] = useState({});\n\n // update colors globally with new domain\n // TODO why are colors not persistent\n // useEffect(() => {\n // Object.values(colorScales).forEach(s => s.domain(divisions.map(d => d.key)));\n // }, [vis]);\n\n // mount chart on first load\n useEffect(() => {\n if (visRef.current && !vis) {\n vis = new BarChart({\n dimensions: props,\n containerEl: visRef.current,\n timelineRef,\n onTooltipEnter: handleTooltipEnter,\n // onTooltipLeave: handleTooltipLeave,\n onBarClick: handleBarClick,\n onBrushEnded: handleSetYearRange,\n });\n }\n }, [visRef.current]);\n \n // update data on filter changes\n useEffect(() => {\n if (data && vis) {\n if (isAgg(query.sort)) {\n vis.update(data.chartData, data.divDomain, query.sort);\n } else {\n vis.update(data.chartData, data.divDomain);\n }\n if (query.start && query.end) {\n vis.timeline.setYearRange(query.start, query.end);\n }\n }\n }, [vis, query.sort, data]);\n \n // update timeline on year change\n useEffect(() => {\n if (yearData && vis) {\n if (isAgg(query.sort)) {\n vis.timeline.update(yearData, query.sort);\n } else {\n vis.timeline.update(yearData);\n }\n }\n }, [vis, query.sort, yearData]);\n \n // update bar styles on highlight\n // useEffect(() => {\n // vis?.highlightGroup(highlightedDivision);\n // }, [highlightedDivision]);\n\n // update chart on window resize\n useEffect(() => {\n if (props.height) {\n vis.animationDur = vis.timeline.animationDur = 0;\n vis.measure(props.width, props.height);\n vis.animationDur = vis.timeline.animationDur = 1000;\n }\n }, [props.width, props.height]);\n\n const handleTooltipEnter = (dataKey: string, year: number) => {\n setTooltipProps({ dataKey, year });\n };\n\n // TODO maybe add callback\n // const handleTooltipLeave = (key: string, year: number) => {\n // // setTooltipProps({});\n // };\n \n const handleSetYearRange = ([ start, end ]: [ number, number ]) => {\n setQuery({ start, end });\n };\n\n const handleBarClick = (key: string, year: number) => {\n setDialogQuery({\n grantDialogOpen: true,\n grantDialogYear: year,\n grantDialogDivision: key,\n });\n };\n\n return (\n \n \n \n \n );\n};\n\nexport default Chart;\n","import { PopoverOrigin } from '@material-ui/core';\nimport { useTutorial } from 'app/query';\nimport { RefObject, useCallback, useEffect, useRef, useState } from 'react';\nimport { NumberParam, useQueryParam } from 'use-query-params';\n\ntype Step = {\n anchorOrigin: PopoverOrigin;\n transformOrigin?: PopoverOrigin;\n title: string;\n description?: string;\n}\n\nconst stepOrder = [\n 'hello',\n 'filterTerms',\n 'clearTerms',\n 'filterOrganizations',\n 'filterDivisions',\n 'chartToggles',\n 'anyAllSetting',\n 'filterYears',\n 'overflowMenu',\n] as const;\n\ntype Steps = Record;\n\nconst steps: Steps = {\n hello: {\n anchorOrigin: { vertical: 'bottom', horizontal: 'center' },\n transformOrigin: { vertical: 'top', horizontal: 'center' },\n title: 'Welcome to GrantExplorer!',\n },\n filterTerms: {\n anchorOrigin: { vertical: 'bottom', horizontal: 'center' },\n transformOrigin: { vertical: 'top', horizontal: 'center' },\n title: 'Search Terms',\n description: 'Enter keywords. The search bar will suggest related terms sorted by relevancy'\n },\n clearTerms: {\n anchorOrigin: { vertical: 'bottom', horizontal: 'left' },\n transformOrigin: { vertical: 'top', horizontal: 'right' },\n title: 'Clear All Keywords',\n description: 'Clear all keywords and start your search again',\n },\n filterOrganizations: {\n anchorOrigin: { vertical: 'bottom', horizontal: 'center' },\n transformOrigin: { vertical: 'top', horizontal: 'center' },\n title: 'Switch Organization',\n description: 'Switch between different funding agencies'\n },\n filterDivisions: {\n anchorOrigin: { vertical: 'bottom', horizontal: 'center' },\n transformOrigin: { vertical: 'top', horizontal: 'center' },\n title: 'Filter By Division',\n description: 'Select subset of divisions to view'\n },\n chartToggles: {\n anchorOrigin: { vertical: 'bottom', horizontal: 'right' },\n // transformOrigin: { vertical: 'top', horizontal: 'left' },\n title: 'Toggle Chart Settings',\n description: 'View aggregates by $ amount or count'\n },\n anyAllSetting: {\n anchorOrigin: { vertical: 'bottom', horizontal: 'right' },\n // transformOrigin: { vertical: 'top', horizontal: 'left' },\n title: 'Keywords: Any vs. All',\n description: 'Select whether included grants should contain *any* of the included keywords, or *all* of them'\n },\n filterYears: {\n anchorOrigin: { vertical: 'top', horizontal: 'center' },\n transformOrigin: { vertical: 'bottom', horizontal: 'center' },\n title: 'Filter By Year Range',\n description: 'Drag the box to adjust the date range'\n },\n overflowMenu: {\n anchorOrigin: { vertical: 'top', horizontal: 'left' },\n transformOrigin: { vertical: 'center', horizontal: 'right' },\n title: 'Extras',\n description: 'See detailed grant data and external links',\n }\n};\n\nconst refs: any[] = [];\n\nexport const useWizard = () => {\n \n const [ stepIdx, setStepIdx ] = useTutorial();\n\n const navigateForward = useCallback(() => {\n setStepIdx(idx => idx != undefined && idx < stepOrder.length - 1\n ? idx + 1\n : undefined\n );\n }, [setStepIdx]);\n\n const navigateBack = useCallback(() => {\n setStepIdx(idx => Math.max((idx ?? 0) - 1, 0));\n }, [setStepIdx]);\n\n const cancelWizard = useCallback(() => {\n setStepIdx(undefined);\n localStorage.setItem('tutorialViewed', 'true');\n }, [setStepIdx]);\n \n const tutorialNav = useCallback((e: KeyboardEvent) => {\n switch(e.key) {\n case 'Enter':\n case 'ArrowRight':\n case ' ': // spacebar\n navigateForward();\n break;\n case 'Backspace':\n case 'ArrowLeft':\n navigateBack();\n break;\n case 'Escape':\n case 'q':\n cancelWizard();\n break;\n }\n }, [navigateForward, navigateBack, cancelWizard]);\n\n // startup tutorial check\n useEffect(() => {\n const tutorialViewed = localStorage.getItem('tutorialViewed') === 'true';\n setStepIdx(tutorialViewed ? undefined : 0);\n // clean up listener on unmount\n return () => {\n window.removeEventListener('keydown', tutorialNav);\n };\n\n }, []);\n \n const prevStepIdx = useRef(stepIdx);\n \n useEffect(() => {\n if (stepIdx == undefined) {\n window.removeEventListener('keydown', tutorialNav);\n } else if (prevStepIdx.current == undefined) {\n window.addEventListener('keydown', tutorialNav);\n }\n prevStepIdx.current = stepIdx;\n }, [stepIdx, tutorialNav]);\n \n const step: Step | undefined = Object.values(steps)[stepIdx ?? -1];\n \n return {\n navigateBack: stepIdx != undefined && stepIdx > 0 ? navigateBack : undefined,\n navigateForward: stepIdx != undefined && stepIdx + 1 < stepOrder.length ? navigateForward : undefined,\n cancelWizard,\n step,\n ref: stepIdx != undefined ? refs[stepIdx] : {},\n };\n};\n\ntype WizardRef = {\n ref: RefObject;\n active: boolean;\n}\n\nexport const useWizardRef = (step: typeof stepOrder[number]): WizardRef => {\n const ref = useRef(null);\n const [ stepIdx, ] = useQueryParam('tutorial', NumberParam);\n const idx = stepOrder.indexOf(step);\n refs[idx] = ref;\n return {\n ref,\n active: stepIdx === idx\n };\n};\n","import { MouseEvent, ChangeEvent, useState } from 'react';\nimport { Flipper, Flipped } from 'react-flip-toolkit';\nimport { alpha, styled } from '@material-ui/core/styles';\n\nimport {\n Box,\n IconButton,\n Tooltip,\n} from '@material-ui/core';\n\nimport {\n Search,\n ClearAll,\n HighlightOff,\n Sort,\n SortByAlpha,\n} from '@mui/icons-material';\n\nimport { useDebounce } from 'app/hooks';\nimport { ArrayParam, useBeta, useQuery } from 'app/query';\nimport TermChip from './TermChip';\nimport TermsInput from './TermsInput';\nimport TermsPreset from './TermsPreset';\n// import { clearTypeahead } from 'app/dataReducer';\nimport { useQueryParam } from 'use-query-params';\nimport { useLoadTermCounts, useLoadRelated, useLoadTypeahead } from 'api';\nimport TermsList from './TermsList';\nimport { queryClient } from 'app/queryClient';\nimport { useWizardRef } from 'app/wizard/wizard';\n\nconst SearchContainer = styled('div')(({ theme }) => `\n min-width: 25em;\n flex-shrink: 1;\n // width: 100%;\n // max-height: 12em;\n overflow: hidden;\n display: flex;\n align-items: start;\n color: ${theme.palette.common.white};\n border-radius: ${theme.shape.borderRadius}px;\n background-color: ${alpha(theme.palette.common.white, 0.15)};\n &:hover {\n background-color: ${alpha(theme.palette.common.white, 0.25)};\n }\n margin-left: 0;\n ${theme.breakpoints.down('sm')} {\n width: 100%;\n max-height: 8em;\n }\n & .MuiIconButton-root {\n justify-self: end;\n padding: ${theme.spacing(1.5)};\n }\n // targets Flipper container\n & > div:nth-child(1) {\n flex-grow: 1;\n display: flex;\n }\n ${theme.breakpoints.down('sm')} {\n border-radius: 0;\n width: 100%;\n }\n`);\n\nconst ChipContainer = styled('div')(({ theme }) => `\n flex-grow: 1;\n display: flex;\n flex-wrap: wrap;\n padding-top: ${theme.spacing(1)};\n padding-left: ${theme.spacing(1)};\n & .MuiIconButton-root {\n margin-top: -8px;\n margin-left: -8px;\n }\n`);\n\nconst SearchIcon = styled('div')(({ theme }) => `\n padding: ${theme.spacing(0.5, 1)};\n pointer-events: none;\n`);\n\nconst exitThenFlipAndEnter = ({\n hideEnteringElements,\n animateEnteringElements,\n animateExitingElements,\n animateFlippedElements\n}) => {\n hideEnteringElements();\n animateExitingElements()\n .then(() => {\n animateFlippedElements();\n animateEnteringElements();\n });\n};\n\nconst TermsFilter = () => {\n\n const [ input, setInput ] = useState('');\n const [ beta ] = useBeta();\n const debouncedInput = useDebounce(input, 300);\n const { ref: filterTermsRef } = useWizardRef('filterTerms');\n const { ref: clearTermsRef } = useWizardRef('clearTerms');\n\n const [ terms, setTerms ] = useQueryParam('terms', ArrayParam);\n const [ sort, setSort ] = useState<'alpha' | 'count' | undefined>();\n const [{ org }] = useQuery();\n const selected = terms.find(term => term.match('~'));\n\n const { data: counts } = useLoadTermCounts({ org, terms }, {\n query: {\n keepPreviousData: true,\n enabled: terms.length > 0,\n select: ({ data }) => data\n }\n });\n\n const { data: typeahead, queryKey: typeaheadKey } = useLoadTypeahead(debouncedInput, { selected_terms: terms }, {\n query: {\n keepPreviousData: true,\n enabled: input.length > 0,\n select: ({ data = [] }) => data.filter(d => !terms.includes(d.term))\n }\n });\n\n const { data: related, queryKey: relatedKey } = useLoadRelated({ terms }, {\n query: {\n keepPreviousData: true,\n enabled: terms.length > 0,\n select: ({ data = [] }) => data.filter(d => !terms.includes(d.term))\n }\n }); \n\n const handleChangeInput = (e: ChangeEvent) => {\n setInput(e.target.value);\n };\n\n const handleClickChip = (e: MouseEvent, chip: string) => {\n e.preventDefault();\n setTerms(terms.map(term => {\n if (term === chip) return `~${term}~`;\n else return term.replaceAll('~', '');\n }));\n };\n\n const handleAddChip = (chipString: string) => {\n setInput('');\n const chips = chipString.split(',').filter(c => c.length > 0); \n if (terms.find(t => chips.includes(t))) {\n return;\n }\n setTerms(terms.concat(chips));\n };\n\n const handleDeleteChip = (term: string) => () => {\n setTerms(terms.filter(t => t !== term));\n };\n \n const handleClearInput = () => {\n queryClient.removeQueries(typeaheadKey);\n };\n \n const handleClearTerms = () => {\n queryClient.removeQueries(relatedKey);\n if (selected) {\n setTerms(terms.map(term => term.replaceAll('~', '')));\n } else {\n setTerms([]);\n }\n };\n \n const handleSortTerms = () => {\n setSort(sort => sort === 'alpha' ? 'count' : 'alpha');\n const compareAlpha = (t1: string, t2: string) => t1.localeCompare(t2);\n const compareCount = (t1: string, t2: string) => (counts?.[t2] ?? 0) - (counts?.[t1] ?? 0);\n setTerms(terms.sort(sort === 'alpha' ? compareCount : compareAlpha));\n };\n \n return (\n \n \n \n \n \n \n \n \n \n \n {terms.length > 0 && (\n \n \n {sort === 'count'\n ? \n : \n }\n \n \n )}\n \n \n {terms.map(term => (\n \n ))}\n \n : terms.length\n ? \n : beta\n ? \n : null\n\n }\n />\n \n \n \n \n \n {selected\n ? \n : \n }\n \n \n \n \n \n \n );\n};\n\nexport default TermsFilter;\n","export default __webpack_public_path__ + \"static/media/grant-explorer.93e8d33d.svg\";","export default __webpack_public_path__ + \"static/media/filter-divisions.4c4adc77.svg\";","import { Icon, IconButton, styled } from '@material-ui/core';\nimport { BarChart } from '@mui/icons-material';\nimport { BooleanParam, useQueryParam } from 'use-query-params';\nimport filter from '../images/filter-divisions.svg';\n\n\nconst ResponsiveButton = styled(IconButton)(({ theme }) => `\n ${theme.breakpoints.up('md')} {\n display: none;\n }\n`);\n \nconst DrawerToggle = () => {\n\n const [ drawerOpen, setDrawerOpen ] = useQueryParam('drawer', BooleanParam);\n \n return (\n setDrawerOpen(!drawerOpen)}>\n {drawerOpen \n ? \n : \n } \n \n );\n};\n\nexport default DrawerToggle;\n","import { \n AppBar,\n Toolbar,\n Tooltip,\n Typography,\n Box,\n Button,\n styled,\n Link,\n} from '@material-ui/core';\n\nimport TermsFilter from 'app/terms/TermsFilter';\n\nimport grantExplorer from 'app/images/grant-explorer.svg';\nimport DrawerToggle from './DrawerToggle';\nimport { forwardRef } from 'react';\nimport { useWizardRef } from 'app/wizard/wizard';\nimport { Info } from '@mui/icons-material';\nimport { useAbout } from 'app/query';\n\nconst StyledToolbar = styled(Toolbar)(({ theme }) => `\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n justify-content: end;\n padding: 0;\n gap: ${theme.spacing(1)};\n &:last-child {\n flex-grow: 1;\n }\n ${theme.breakpoints.up('md')} {\n padding: ${theme.spacing(1)};\n flex-direction: row;\n &:last-child {\n flex-grow: initial;\n }\n }\n`);\n\nconst Logo = styled('img')(({ theme }) => `\n margin-right: ${theme.spacing(2)};\n width: ${theme.spacing(4)};\n height: ${theme.spacing(4)};\n`);\n\nconst AboutButton = styled(Button)(({ theme }) => `\n color: white;\n border: 1px solid white;\n height: ${theme.spacing(6)};\n &:hover {\n background-color: rgba(255, 255, 255, 0.4);\n }\n`);\n\nconst TitleBar = styled(Box)(({ theme }) => `\n width: 100%;\n height: 3em;\n display: flex;\n flex-direction: row;\n align-items: center;\n & img {\n margin-left: auto;\n }\n & h6 {\n margin-right: auto;\n }\n ${theme.breakpoints.up('md')} {\n width: 15em;\n height: 100%\n & img {\n margin-left: default;\n }\n & h6 {\n margin-right: default;\n }\n }\n`);\n\nconst Title = styled(Typography)(({ theme }) => `\n display: inline;\n ${theme.breakpoints.up('md')} {\n display: block;\n }\n & .MuiLink-root {\n color: white;\n text-decoration: none;\n }\n`);\n\nconst SearchAppBar = forwardRef((props, ref) => {\n const { ref: titleBarRef } = useWizardRef('hello');\n const [ , setAboutOpen ] = useAbout();\n const handleClickAbout = () => {\n setAboutOpen(true);\n };\n console.log(window.location.href.split('/?')[0]);\n return (\n \n \n \n \n \n \n <Link href='?'>\n GrantExplorer\n </Link>\n \n \n \n \n }\n >\n About\n \n \n \n \n \n );\n});\n\nexport default SearchAppBar;\n","export default __webpack_public_path__ + \"static/media/nih-logo.2d78086b.svg\";","export default __webpack_public_path__ + \"static/media/nsf-logo.550cb2ce.svg\";","export default __webpack_public_path__ + \"static/media/dod-logo.4f6a3652.svg\";","import { ChangeEvent, useState } from 'react';\nimport { Box, Input, InputAdornment, ListItemIcon, MenuItem, Select, SelectChangeEvent, styled } from '@material-ui/core';\nimport { FilterList } from '@mui/icons-material';\n\nimport DrawerToggle from 'app/nav/DrawerToggle';\nimport nih from '../images/nih-logo.svg';\nimport nsf from '../images/nsf-logo.svg';\nimport dod from '../images/dod-logo.svg';\nimport { Organization } from 'app/query';\nimport { useWizardRef } from 'app/wizard/wizard';\n\nconst Toolbar = styled('div')(({ theme }) => `\n display: flex;\n flex-direction: column;\n padding: ${theme.spacing(2)};\n & .MuiInput-root {\n padding-top: ${theme.spacing(2)}\n }\n`);\n\nconst StyledSelect = styled(Select)(({ theme }) => `\n flex-grow: 1;\n & .MuiSelect-select {\n display: flex;\n align-items: center;\n font-size: 1.2em;\n padding: ${theme.spacing(1.5)};\n }\n`) as unknown as typeof Select; // bleck!\n \nconst Actions = styled('div')(({ theme }) => `\n color: ${theme.palette.text.secondary};\n`);\n\nconst Logo = styled('img')`\n width: 2em;\n height: 2em;\n filter: brightness(30%);\n margin-right: 24px;\n`;\n\ntype DivisionToolbarProps = {\n org: Organization\n filter: string\n numSelected: number\n onChangeOrg: (e: SelectChangeEvent) => void\n onChangeFilter: (e: ChangeEvent) => void\n}\n\nconst orgs = [\n { title: 'National Science Foundation', abbr: 'nsf', src: nsf },\n { title: 'National Institutes of Health', abbr: 'nih', src: nih },\n { title: 'Department of Defense', abbr: 'dod', src: dod}\n];\n\nconst DivisionToolbar = (props: DivisionToolbarProps) => {\n\n const { ref: organizationsRef, active: organizationsActive } = useWizardRef('filterOrganizations');\n const { ref: divisionsRef } = useWizardRef('filterDivisions');\n const [ open, setOpen ] = useState(false);\n return (\n \n \n setOpen(true)}\n onClose={() => setOpen(false)}\n open={organizationsActive || open}\n >\n {orgs.map(o => (\n \n \n \n \n {o.title}\n \n ))}\n \n \n \n \n \n \n \n \n }\n />\n \n );\n};\n\nexport default DivisionToolbar;","import { CheckboxState } from './DirectoryTableHead';\n\nexport const getNextCheckboxState = (checked?: CheckboxState) => {\n switch (checked) {\n case 'checked': return 'unchecked';\n case 'indeterminate': return 'checked';\n case 'unchecked': return 'checked';\n default: return 'checked';\n }\n};\n","import { MouseEvent } from 'react';\nimport { Box, Checkbox, styled, Typography } from '@material-ui/core';\nimport { format } from 'd3';\nimport { forwardRef, ReactNode } from 'react';\nimport { CheckboxState } from './DirectoryTableHead';\nimport { getNextCheckboxState } from './checkFSM';\n\ntype RowStyles = {\n tooltip?: boolean;\n selected?: boolean;\n checkable?: boolean;\n nohover?: boolean;\n scrollOffset?: number;\n}\n\nexport const Row = styled(Box)(({ theme, tooltip, checkable, selected, nohover, scrollOffset }) => `\n flex-grow: 1;\n cursor: pointer;\n display: grid;\n padding-right: ${scrollOffset ?? 0}px;\n grid-template-columns: ${(checkable ? '[checkbox] auto ' : '')\n + '[name] minmax(0, 1fr) [count] 4em [amount] 4em'};\n border-top: ${tooltip ? `1px solid ${theme.palette.grey[200]}` : 'none'};\n background-color: ${selected\n ? theme.palette.action.selected\n : 'white'};\n &:hover {\n background-color: ${nohover ? theme.palette.common.white : theme.palette.action.hover};\n }\n`);\n\ntype ColumnStyles = {\n column: string\n};\n\ntype TextStyles = {\n light: boolean\n backgroundColor?: string\n}\n\nexport const Column = styled(Box)(({ theme, column }) => `\n height: 3em;\n grid-column: ${column};\n display: flex;\n align-items: center;\n padding: ${column === 'checkbox' ? 0 : theme.spacing(0, 1)};\n`);\n\nexport const NumberColumn = styled(Column)(({ theme, light, backgroundColor }) => `\n color: ${light ? theme.palette.common.black : theme.palette.common.white};\n background-color: ${backgroundColor};\n`);\n\nexport type CellData = {\n name: string,\n value: number,\n fill?: string,\n};\n\ntype RowProps = RowStyles & {\n id?: string\n dataKey: string\n name: string | ReactNode\n cells: CellData[]\n header?: boolean\n onCheck?: (e: MouseEvent, key: string, checked: CheckboxState) => void\n onMouseOver?: (key: string) => void\n onMouseOut?: (key: string) => void\n checked?: CheckboxState\n}\n\n// return brightness of hex value to determine if text should be black or white to meet\n// contrast ratio accessibility requirement\nconst rgb2hsl = (hex?: string) => {\n if (hex === undefined || hex === 'white') return 1;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const [ r, g, b ] = /(\\w{2})(\\w{2})(\\w{2})/.exec(hex)!\n .map(v => parseInt(v, 16))\n .slice(1)\n .map(v => v / 255);\n const max = Math.max(r, g, b), min = Math.min(r, g, b);\n return max + min / 2;\n};\n\nconst formatColumn = (cell: CellData): string => {\n if (cell.value === 0) return '-';\n else if (cell.name === 'count') return cell.value.toString();\n else return format('$.2s')(cell.value).replace(/G/, 'B');\n};\n\nconst DivisionRow = forwardRef((props: RowProps, ref) => (\n props.onCheck?.(e, props.dataKey, getNextCheckboxState(props.checked))}\n onMouseOver={() => props.onMouseOver?.(props.dataKey)}\n onMouseOut={() => props.onMouseOut?.(props.dataKey)}\n >\n {props.onCheck && \n \n \n \n }\n \n \n {props.name}\n \n \n {props.cells.map(c => (\n 0.9}\n backgroundColor={props.header ? 'white' : c.fill}\n >\n \n {formatColumn(c)}\n \n \n ))}\n \n));\n\nexport default DivisionRow;","import { MouseEvent } from 'react';\nimport styled from '@emotion/styled';\nimport { Tooltip } from '@material-ui/core';\nimport { TreeItem, treeItemClasses, TreeItemProps } from '@material-ui/lab';\nimport { colorScales } from 'theme';\nimport DivisionRow from './DivisionRow';\nimport { KeyboardArrowDown, KeyboardArrowRight } from '@mui/icons-material';\nimport { CheckboxState } from './DirectoryTableHead';\nimport { Flipped } from 'react-flip-toolkit';\n\nconst DirectoryRoot = styled(TreeItem)(({ theme }) => `\n color: ${theme.palette.text.secondary};\n & .${treeItemClasses.content} {\n padding: 0;\n color: ${theme.palette.text.secondary};\n border-bottom: 1px solid ${theme.palette.grey[200]};\n font-weight: ${theme.typography.fontWeightMedium};\n &.Mui-expanded {\n font-weight: ${theme.typography.fontWeightRegular};\n }\n &:hover {\n background-color: ${theme.palette.action.hover};\n }\n &.Mui-focused, &.Mui-selected, &.Mui-selected.Mui-focused {\n background-color: ${theme.palette.action.selected};\n }\n & .${treeItemClasses.label} {\n padding: 0;\n font-weight: 'inherit';\n color: 'inherit';\n }\n }\n & .${treeItemClasses.group} {\n margin-left: 0;\n & .${treeItemClasses.content} {\n padding-left: ${theme.spacing(2)};\n }\n }\n & .${treeItemClasses.iconContainer} {\n margin: 0;\n padding: ${theme.spacing(1, 1, 1, 2)};\n height: 100%;\n }\n`);\n\n\ntype DirectoryProps = TreeItemProps & {\n name: React.ReactNode;\n desc?: string;\n checked: CheckboxState;\n count?: number;\n amount?: number;\n onCheck?: (e: MouseEvent, key: string, checked: CheckboxState) => void\n};\n\n\nconst DirectoryEntry = (props: DirectoryProps) => {\n const {\n nodeId,\n name,\n desc,\n children,\n checked,\n onCheck,\n ...other\n } = props;\n \n return (\n \n
\n \n }\n collapseIcon={}\n label={\n ({\n name: field,\n value: props[field],\n fill: colorScales[field](nodeId)\n }))}\n // tabIndex={-1}\n />\n }\n {...other}\n >\n {children}\n \n \n
\n
\n );\n};\n\nexport default DirectoryEntry;\n","import { \n TableSortLabel,\n Checkbox,\n Tooltip,\n IconButton,\n Box,\n styled,\n} from '@material-ui/core';\nimport { UnfoldLess, UnfoldMore } from '@mui/icons-material';\nimport { SortableKeys } from 'app/sort';\nimport { getNextCheckboxState } from './checkFSM';\nimport { Column, NumberColumn, Row } from './DivisionRow';\n\nconst ExpandButton = styled(IconButton)`\n width: 24px;\n height: 24px;\n margin-top: auto;\n margin-bottom: auto;\n margin-left: 4px;\n`;\n\nconst Container = styled(Box)(({ theme }) => `\n border-bottom: 1px solid ${theme.palette.grey[200]};\n display: flex;\n flex-direction: row;\n`);\n\ntype Columns = {\n Component: typeof Column | typeof NumberColumn,\n id: SortableKeys,\n numeric: boolean,\n label: string,\n desc: string,\n};\n\nconst columns: Columns[] = [\n { Component: Column, id: 'name', numeric: false, label: 'Name', desc: 'division name' },\n { Component: NumberColumn, id: 'count', numeric: true, label: 'Gnts', desc: 'number of grants' }, \n { Component: NumberColumn, id: 'amount', numeric: false, label: 'Amt', desc: 'total award amount' },\n];\n\nexport type CheckboxState = 'checked' | 'unchecked' | 'indeterminate'\n\ntype EnhancedTableHeadProps = {\n scrollOffset?: number\n orderBy: string,\n direction: 'desc' | 'asc',\n checked: CheckboxState,\n allExpanded: boolean,\n onRequestSort: (key: SortableKeys) => void,\n onSelectAll: (checked: CheckboxState) => void,\n onExpandAll: () => void,\n}\n\nconst DirectoryTableHead = (props: EnhancedTableHeadProps) => (\n \n \n {props.allExpanded\n ? \n : \n }\n \n \n \n props.onSelectAll(getNextCheckboxState(props.checked))}\n />\n \n {columns.map(c => (\n \n \n props.onRequestSort(c.id)}\n >\n {c.label}\n \n \n \n ))}\n \n \n);\n\nexport default DirectoryTableHead;\n","import { useLoadDirectory } from 'api';\nimport { StringParam, useQueryParam } from 'use-query-params';\n\nexport const useDirectory = () => {\n const [ org ] = useQueryParam('org', StringParam);\n const {\n data: {\n divisionMap,\n divisionTree,\n } = {\n divisionMap: {},\n divisionTree: {}\n },\n ...rest\n } = useLoadDirectory(org ?? 'nsf', {\n query: {\n // onSuccess: ({ data }) => {\n // setExpanded(data.map(d => d.abbr));\n // },\n keepPreviousData: true,\n select: ({ data }) => ({\n divisionMap: Object.fromEntries(data.flatMap(({ departments = [], ...d }) => (\n [[d.abbr, d]].concat(departments.map(d => [d.abbr, d]))\n ))),\n divisionTree: Object.fromEntries(data.map(dir => [\n dir.abbr,\n dir.departments?.map(d => d.abbr) ?? []\n ]))\n }),\n }\n });\n \n return {\n divisionMap,\n divisionTree,\n ...rest,\n };\n};\n","import { MouseEvent } from 'react';\nimport { Flipper } from 'react-flip-toolkit';\nimport match from 'autosuggest-highlight/match';\nimport { Box, LinearProgress, SelectChangeEvent, styled } from '@material-ui/core';\nimport { TreeView } from '@material-ui/lab';\n\nimport { SortableKeys } from 'app/sort';\nimport { useMeasure } from 'app/hooks';\nimport { Organization, useDivisionsQuery, useSearchQuery } from 'app/query';\nimport { SortDirection } from '@material-ui/core';\nimport { colorScales } from 'theme';\nimport { ChangeEvent, useState } from 'react';\nimport Highlight from 'app/Highlight';\nimport DivisionToolbar from './DivisionToolbar';\nimport { ArrowDropDown, ArrowRight } from '@mui/icons-material';\nimport DirectoryEntry from './Entry';\nimport DirectoryTableHead, { CheckboxState } from './DirectoryTableHead';\nimport { DivisionAggregate } from 'api';\nimport { useSearch } from 'api';\nimport { useDirectory } from './useDirectory';\n\nconst ScrollableDiv = styled('div')`\n overflow-y: scroll;\n height: 100%;\n`;\n\n// const DivisionChip = styled('span')`\n// background-color: lightgrey;\n// text-transform: uppercase;\n// border-radius: 16px;\n// margin-left: 4px;\n// padding: 2px 8px;\n// `;\n\nconst DirectoryTree = () => {\n\n const [ widthRef, scrollOffset ] = useMeasure();\n const [ query, setQuery ] = useSearchQuery();\n const [ divisions, setDivisions ] = useDivisionsQuery();\n const selectedDivisions = new Set(divisions);\n const [ divisionFilter, setDivisionFilter ] = useState('');\n const [ expanded, setExpanded ] = useState([]);\n\n const orderDivisions = (a: DivisionAggregate, b: DivisionAggregate) => (\n (a[query.sort] - b[query.sort]) \n * (query.direction === 'asc' ? 1 : -1)\n );\n\n const { data: divisionAggs } = useSearch(query, {\n query: {\n keepPreviousData: true,\n select: ({ data: { divisions }}) => {\n divisions.sort(orderDivisions);\n divisions.forEach(d => d.divisions.sort(orderDivisions));\n return divisions;\n } \n }\n });\n \n const { divisionMap, divisionTree, isLoading } = useDirectory();\n\n const handleRequestSort = (sort: SortableKeys) => {\n let direction: SortDirection | undefined;\n if (sort === 'name') {\n direction = query.sort === sort && query.direction === 'asc' ? 'desc' : 'asc';\n } else {\n direction = query.sort === sort && query.direction === 'desc' ? 'asc' : 'desc';\n }\n setQuery({ sort, direction });\n };\n \n const handleCheck = (e: MouseEvent, key: string, checked: CheckboxState) => {\n // don't trigger expand section\n const [ div, div2 ] = key.split('-');\n e.stopPropagation();\n setDivisions(checked === 'checked'\n ? (divisions ?? []).concat([div2])\n : (divisions ?? []).filter(d => d !== div2)\n );\n };\n\n const handleSelectGroup = (e: MouseEvent, key: string, checked: CheckboxState) => {\n e.stopPropagation();\n const group = [key].concat(divisionTree[key] ?? []);\n setDivisions(checked === 'checked'\n ? [...new Set((divisions ?? []).concat(group))]\n : (divisions ?? []).filter(d => !group.includes(d))\n );\n };\n \n const handleSelectAll = (checked: CheckboxState) => {\n switch (checked) {\n case 'checked':\n setDivisions(Object.keys(divisionMap));\n break;\n case 'indeterminate':\n case 'unchecked':\n setDivisions([]);\n break;\n }\n };\n \n const handleExpandAll = () => {\n const roots = Object.keys(divisionTree).filter(key => divisionAggs?.find(div => div.key === key));\n if (expanded.length < roots.length) {\n setExpanded(roots);\n } else {\n setExpanded([]);\n }\n };\n \n const handleToggle = (e: React.SyntheticEvent, keys: string[]) => {\n // TODO maybe adjust query based on toggle state?\n // let toggled: string;\n // let add: boolean;\n // if (keys.length < expanded.length) {\n // [ toggled ] = expanded.filter(e => !keys.includes(e));\n // add = false;\n // } else {\n // [ toggled ] = keys.filter(e => !expanded.includes(e));\n // add = true;\n // }\n // only selected nested elements if parent is selected\n // const nested = query.divisions.includes(toggled) ? depMap[toggled] : [];\n // const selected = add\n // ? query.divisions.concat(nested)\n // : query.divisions.filter(key => !nested.includes(key));\n\n // setQuery({ divisions: [...new Set(selected)] });\n setExpanded(keys);\n };\n\n const handleChangeOrg = (e: SelectChangeEvent) => {\n setQuery({ org: e.target.value as Organization });\n setDivisions(undefined);\n };\n\n const handleFilterDivisions = (e: ChangeEvent) => {\n setDivisionFilter(e.target.value);\n };\n \n const getDirectoryCheckState = (key: string) => {\n const checked = selectedDivisions.has(key);\n const children = divisionTree[key];\n // TODO\n if (!checked || !children) {\n return 'unchecked';\n } else if (children.every(div => selectedDivisions.has(div))) {\n return 'checked';\n } else {\n return 'indeterminate';\n }\n };\n \n let allChecked: CheckboxState = 'unchecked';\n if (selectedDivisions.size == Object.keys(divisionMap).length) allChecked = 'checked';\n else if (selectedDivisions.size > 0) allChecked = 'indeterminate';\n \n const isFiltered = (key: string) => !divisionFilter || match(divisionMap[key].name, divisionFilter).length > 0;\n const isDirFiltered = (key: string) => (divisionTree[key] ?? []).concat([key]).filter(isFiltered).length > 0;\n const isExpanded = (key: string) => expanded.includes(key);\n const isExpandedOrFiltered = (key: string) => isExpanded(key) || (divisionFilter && isDirFiltered(key));\n \n return (\n \n \n \n \n \n {!divisionAggs || isLoading \n ? \n : }\n defaultExpandIcon={}\n defaultEndIcon={
}\n expanded={Object.keys(divisionTree).filter(isExpandedOrFiltered)}\n multiSelect\n // selected={query.divisions}\n onNodeToggle={handleToggle}\n // onNodeSelect={handleSelect}\n >\n {divisionAggs\n .filter(div => (\n isDirFiltered(div.key)\n && divisionMap[div.key]\n ))\n .map(div => (\n }\n count={div.count}\n amount={div.amount}\n checked={getDirectoryCheckState(div.key)}\n onCheck={handleSelectGroup}\n >\n {div.divisions\n ?.filter(div2 => (\n isFiltered(div2.key) \n && divisionMap[div2.key]\n && div.divisions.length > 1\n ))\n ?.map(div2 => (\n \n : 'Other'\n )}\n count={div2.count}\n amount={div2.amount}\n checked={selectedDivisions.has(div2.key) ? 'checked' : 'unchecked'}\n onCheck={handleCheck}\n />\n ))\n }\n {/*divisionTree[div.key].length > div.divisions.length && (\n \n no hits in {' '}\n {divisionTree[div.key]\n .filter(key => !div.divisions.find(d => d.key === key))\n .map(key => key.toUpperCase())\n .join(', ')\n //.map(key => {key})\n }\n \n )*/}\n \n ))}\n \n }\n \n \n \n );\n};\n\nexport default DirectoryTree;","import { Drawer, useMediaQuery } from '@material-ui/core';\nimport { styled } from '@material-ui/core';\nimport DirectoryTree from 'app/divisions/DirectoryTree';\nimport { BooleanParam, useQueryParam } from 'use-query-params';\n \nconst Container = styled('nav')(({ theme }) => `\n & .MuiDrawer-paper {\n width: ${theme.drawerWidth};\n display: flex;\n flex-direction: column;\n ${theme.breakpoints.down('sm')} {\n width: 100%;\n }\n }\n`);\n\nconst DivisionDrawer = () => {\n \n const wideScreen = useMediaQuery('(min-width:960px)');\n const [ drawerOpen, setDrawerOpen ] = useQueryParam('drawer', BooleanParam);\n \n return (\n \n setDrawerOpen(false)}\n ModalProps={{\n keepMounted: true\n }}\n >\n \n \n \n );\n};\n\nexport default DivisionDrawer;","export default __webpack_public_path__ + \"static/media/moore-foundation-logo.fad7cf26.svg\";","export default __webpack_public_path__ + \"static/media/datalab-logo.24bc3aed.svg\";","import { styled, Box, Link, Typography } from '@material-ui/core';\nimport { forwardRef } from 'react';\nimport mooreLogo from '../images/moore-foundation-logo.svg';\nimport dataLabLogo from '../images/datalab-logo.svg';\n\nconst StyledFooter = styled(Box)(({ theme }) => `\n display: flex;\n align-items: center;\n font-size: 1.2em;\n img {\n padding: 0.5em;\n max-height: 3em;\n }\n p { \n padding: 12px;\n margin-right: 72px;\n }\n ${theme.breakpoints.down('lg')} {\n font-size: 0.8em;\n flex-direction: column;\n }\n`);\n\nconst Footer = forwardRef((props, ref) => (\n \n
\n \n
\n
\n \n
\n \n Developed by Jesse "Cole" Chamberlin, Jason Portenoy, Jevin West at the University of Washington DataLab\n
\n with sponsorship from the Moore Foundation\n
\n
\n));\n\nexport default Footer;","import { SortDirection } from '@material-ui/core';\nimport { AggFields } from './chart/D3Chart';\n\nconst desc = (a: T, b: T, key: SortableKeys) => {\n if (b[key] < a[key]) return -1;\n else if (b[key] > a[key]) return 1;\n else return 0;\n};\n\nexport const stableSort = (array: T[], key: SortableKeys, direction: SortDirection): T[] => {\n const stabilizedThis = array.map((el, index): [T, number] => [el, index]);\n const sign = direction === 'desc' ? 1 : -1;\n stabilizedThis.sort((a, b) => {\n const order = sign * desc(a[0], b[0], key);\n if (order !== 0) return order;\n return sign * (a[1] - b[1]);\n });\n return stabilizedThis.map(el => el[0]);\n};\n\nexport type SortableKeys = 'name' | 'count' | 'amount';\n\nexport const isAgg = (key: SortableKeys): key is keyof AggFields => ['count', 'amount'].includes(key);","import { Paper, styled } from '@material-ui/core';\nimport DivisionRow, { CellData } from 'app/divisions/DivisionRow';\nimport { useMeasure } from 'app/hooks';\nimport { useDivisionsQuery, useQuery } from 'app/query';\nimport { colorScales } from '../../theme';\nimport { Flipper, Flipped } from 'react-flip-toolkit';\nimport { useSearch } from 'api';\nimport { stableSort } from 'app/sort';\nimport { useDirectory } from 'app/divisions/useDirectory';\n\nexport type TooltipProps = {\n dataKey?: string\n year?: number\n}\n\nconst ScrollableDiv = styled('div')`\n max-height: 30em;\n overflow-y: auto;\n`;\n\ntype RowTuple = [ string, CellData[] ];\n\nconst ChartTooltip = (props: TooltipProps) => {\n\n const [ widthRef, scrollOffset ] = useMeasure();\n const { dataKey, year } = props;\n const [ divisions ] = useDivisionsQuery();\n const [ query ] = useQuery();\n const { data: divisionAggs } = useSearch(query, {\n query: {\n select: ({ data }) => stableSort(\n data.bars.find(d => d.key === year)?.divisions ?? [],\n query.sort,\n query.direction\n )\n }\n });\n const { divisionMap } = useDirectory();\n const legendFilter = { counts: true, amounts: true };\n const totals: CellData[] = [\n { name: 'count', value: 0 },\n { name: 'amount', value: 0 },\n ];\n\n const rows = divisionAggs\n ?.filter(d => divisions == null || (divisions.includes(d.key) && d.count > 0))\n ?.map((d): RowTuple => [\n d.key,\n ['count', 'amount'].map((field, i) => {\n totals[i].value += d[field];\n return {\n name: field,\n value: d[field],\n fill: colorScales[field](d.key),\n };\n })\n ]);\n \n const cells = totals.filter((t, i) => [legendFilter.counts, legendFilter.amounts][i]);\n \n if (!divisionMap || !rows) return null;\n\n return (\n \n \n \n \n
\n {rows.map(([ key, cells ]) => (\n \n
\n \n
\n
\n ))}\n \n \n \n );\n};\n\nexport default ChartTooltip;","import { FormControlLabel, styled, Radio, RadioGroup, Menu, IconButton, ListItem, ListItemIcon } from '@material-ui/core';\nimport { AttachMoney, InsertDriveFile, Settings } from '@mui/icons-material';\nimport { useQuery } from 'app/query';\nimport { SortableKeys } from 'app/sort';\nimport { useWizardRef } from 'app/wizard/wizard';\nimport { ChangeEvent, useState } from 'react';\n\n\nconst StyledMenu = styled(Menu)(({ theme }) => `\n transform: translate(-8px, -8px);\n & .MuiPaper-root {\n & .MuiList-root {\n & > div {\n padding: ${theme.spacing(1, 2)};\n display: flex;\n flex-direction: row;\n }\n }\n }\n`);\n\nconst Label = styled('div')`\n display: flex;\n flex-direction: row;\n align-items: center;\n`;\n\nconst units = [\n {\n value: 'count',\n label: 'Grants',\n icon: InsertDriveFile\n },\n {\n value: 'amount',\n label: 'Amounts',\n icon: AttachMoney,\n }\n];\n\nconst radio = [\n {\n value: 'any',\n label: 'Any',\n },\n {\n value: 'all',\n label: 'All',\n }\n];\n\nconst ChartLegend = () => {\n \n const [ query, setQuery ] = useQuery();\n const [ open, setOpen ] = useState(false);\n const { ref: togglesRef, active: chartTogglesActive } = useWizardRef('chartToggles');\n const { ref: anyAllRef, active: anyAllActive } = useWizardRef('anyAllSetting');\n \n const handleChangeAgg = (e: ChangeEvent) => {\n const { value } = e.currentTarget as HTMLInputElement;\n setQuery({ sort: value as SortableKeys });\n };\n \n const handleChangeBool = (e: ChangeEvent) => {\n const { value } = e.currentTarget as HTMLInputElement;\n setQuery({\n intersection: value === 'all'\n });\n };\n\n const handleToggle = () => {\n setOpen(open => !open);\n };\n\n return (\n <>\n \n \n \n \n \n \n \n \n Chart Settings\n \n
\n \n {units.map(u => (\n }\n label={}\n />\n ))}\n \n \n {radio.map(r => (\n \n }\n label={r.label}\n />\n ))}\n \n
\n \n \n );\n};\n\nexport default ChartLegend;","/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport * as d3 from 'd3';\nimport { AggFields } from './D3Chart';\nimport { Padding, Selection, TickFormat } from './D3utils';\n\nexport type BrushCallback = (selection: [ number, number ]) => void;\n\nexport type TimelineData = {\n key: number\n count: number\n amount: number\n}\n\n\n\ntype TimelineProps = {\n svg: Selection,\n chartWidth: number,\n chartHeight: number\n onBrushEnded?: BrushCallback\n padding: Padding\n tickFormat: TickFormat \n}\n\nexport default class D3Timeline {\n\n animationDur = 1000;\n chart: Selection;\n chartWidth: number;\n chartHeight: number;\n padding: Padding;\n x = d3.scaleBand().padding(0.2);\n y = d3.scaleLinear().nice();\n xAxis: Selection;\n yAxis: Selection;\n tickFormat: TickFormat;\n brush: d3.BrushBehavior;\n gb: Selection;\n data: TimelineData[] = [];\n years: number[] = [];\n yearRange: [ number, number ];\n max = 0;\n agg: keyof AggFields = 'count';\n\n constructor(props: TimelineProps) {\n \n this.chartHeight = props.chartHeight;\n this.chartWidth = props.chartWidth;\n this.padding = props.padding;\n this.chart = props.svg\n .append('g')\n .classed('timeline', true)\n .attr('transform', `translate(${props.padding.left}, ${props.padding.top})`);\n \n this.x.rangeRound([0, this.chartWidth]);\n \n this.y.rangeRound([this.chartHeight, 0]);\n\n // TODO set this dynamically\n this.yearRange = [1960, 2023];\n this.tickFormat = props.tickFormat;\n \n // setup brush\n this.brush = d3.brushX()\n .on('end', ({ target, sourceEvent, selection }) => {\n if (!sourceEvent || !selection) return;\n // inversed map is interval [s, e)\n this.yearRange = selection.map(this.xInverse);\n props.onBrushEnded?.(this.yearRange);\n //this.updateBrush();\n this.gb\n .transition()\n .duration(this.animationDur / 2)\n .call(target.move, this.yearRange.map(this.getBrushBounds));\n });\n \n this.gb = this.chart.append('g').raise();\n\n this.xAxis = this.chart.append('g')\n .attr('class', 'axis axis-x');\n\n this.yAxis = this.chart.append('g')\n .attr('class', 'axis axis-y');\n\n this.measure(this.padding, this.chartWidth, this.chartHeight);\n }\n\n /* ticks should show for min/max and every 5 years between\n * with boundary gap of 3 to prevent overlapping text\n */\n getXAxis = () => {\n const [ min, max ] = d3.extent(this.x.domain());\n const yearGap = 5;\n const boundaryYearGap = 3;\n return d3.axisBottom(this.x)\n //.tickFormat(this.tickFormat.x);\n .tickValues(this.x.domain().filter(d => (\n d === min \n || d === max\n || (\n d % yearGap === 0 \n && d - boundaryYearGap >= min! \n && d + boundaryYearGap <= max!\n )\n )));\n }\n\n /* only draw tick for maximum value */\n getYAxis = () => d3.axisLeft(this.y)\n .tickFormat(this.tickFormat.y)\n .tickValues(this.max !== Infinity ? [this.max] : []);\n\n setYearRange = (start: number, end: number) => {\n this.yearRange = [start, end];\n this.updateBrush();\n }\n\n updateBrush = () => {\n this.gb\n .raise()\n .call(this.brush);\n// ALEX NOTE: the below fails to compile. Doesn't seem to affect the UI at all so I'm leaving it commented out.\n// .call(this.brush.move, this.yearRange.map(this.getBrushBounds));\n };\n\n measure = (padding: Padding, width: number, height: number) => {\n this.padding = padding;\n this.chartWidth = width;\n this.chartHeight = height;\n this.chart\n .transition()\n .duration(this.animationDur)\n .attr('transform', `translate(${this.padding.left}, ${this.padding.top})`);\n\n this.x.rangeRound([0, this.chartWidth]);\n \n this.y.rangeRound([this.chartHeight, 0]);\n \n this.brush.extent([\n [0, 0],\n [this.chartWidth, this.chartHeight]\n ]);\n\n this.redraw();\n }\n\n updateAxes = () => {\n this.xAxis\n .transition()\n .duration(this.animationDur)\n .attr('transform', `translate(0, ${this.chartHeight})`)\n .call(this.getXAxis());\n\n this.yAxis\n .transition()\n .duration(this.animationDur)\n .call(this.getYAxis());\n }\n\n xInverse = (y: number, idx: number) => {\n // https://stackoverflow.com/a/50846323\n const domain = this.x.domain();\n const paddingOuter = this.x(domain[0])!;\n const eachBand = this.x.step();\n // subtract idx to get exclusive range [s, e + 1)\n const x = Math.round((y - paddingOuter) / eachBand) - idx;\n return domain[Math.max(0, Math.min(x, domain.length - 1))];\n }\n\n update = (data: TimelineData[], agg?: keyof AggFields) => {\n this.data = data;\n if (agg) this.agg = agg;\n this.years = data.map(d => d.key);\n // TODO see if this can be updated dynamically\n // this.yearRange = d3.extent(this.years) as [number, number];\n this.x.domain(this.years);\n this.max = Math.max(...data.map(d => d[this.agg]));\n this.y.domain([0, this.max]);\n // this.color.domain(this.divs);\n this.redraw();\n }\n\n redraw = () => {\n\n d3.select('.selection')\n .attr('stroke', '#777')\n .attr('stroke-width', '2px');\n this.updateAxes();\n this.updateBrush();\n\n this.chart.selectAll('.bar')\n .data(this.data, d => d.key)\n .join(\n enter => enter\n .append('rect')\n .call(enter => enter\n .attr('x', d => this.x(d.key)!)\n .attr('width', this.x.bandwidth())\n .attr('y', this.chartHeight)\n .attr('height', 0)\n // .transition()\n // .duration(this.animationDur)\n // .attr('height', 0)\n ),\n update => update,\n exit => exit.remove()\n )\n .classed('bar', true)\n .transition()\n .duration(this.animationDur)\n .attr('x', d => this.x(d.key)!)\n .attr('width', this.x.bandwidth())\n .attr('fill', this.agg === 'count' ? '#673AB7' : '#4CAF50')\n .attr('y', d => this.y(d[this.agg]))\n .attr('height', d => this.chartHeight - this.y(d[this.agg]));\n }\n \n getBrushBounds = (x: number | undefined, idx: number) => {\n if (x === undefined) return this.x(0);\n const padding = this.x.step() * this.x.padding();\n // make range inclusive [s, e]\n const endOffset = this.x.step() * idx;\n return this.x(x)! + endOffset - padding / 2 ?? 0;\n }\n}\n","import * as d3 from 'd3';\nimport { debounce } from './D3utils';\n\ntype ChartDimensions = {\n chart: DOMRect,\n bar: DOMRect,\n bandwidth: number,\n padding: number,\n}\n\nconst tooltipDebounce = debounce();\n\nexport const transitionTooltip = (key: string, { chart, bar, bandwidth, padding }: ChartDimensions) => {\n\n const tooltip = d3.select('#tooltip');\n\n tooltip.select(`#${key}-tooltip`).node()?.scrollIntoView({\n behavior: 'smooth',\n block: 'center',\n inline: 'nearest' \n });\n \n const node = tooltip.node();\n if (!node) return;\n const tipBbox = node.getBoundingClientRect();\n \n // compute left edge coordinate\n const chartRightEdge = chart.x + chart.width;\n const tipRightEdge = bar.x + bar.width + tipBbox.width;\n // determine tooltip justification\n const tipSide = tipRightEdge < chartRightEdge ? 'left' : 'right';\n const tipLeft = bar.x - chart.x + (\n tipSide === 'left'\n ? bandwidth + 2 * padding\n : -tipBbox.width - 2 * padding);\n \n // compute top edge coordinate\n const rectCenter = bar.y + bar.height / 2;\n const tipTop = Math.max(0, Math.min(rectCenter - tipBbox.height / 2, chart.height - tipBbox.height));\n\n // transition tooltip in\n tooltipDebounce(() => {\n tooltip\n .classed('visible', true)\n .transition()\n .duration(500)\n .style('opacity', 1)\n .style('left', `${tipLeft}px`)\n .style('top', `${tipTop}px`);\n }, 50);\n};\n \n// transition tooltip out\nexport const removeTooltip = () => {\n tooltipDebounce(() => {\n d3.select('#tooltip')\n .transition()\n .duration(200)\n .style('opacity', 0)\n .on('end', () => { \n d3.select('#tooltip')\n .classed('visible', false);\n });\n }, 50);\n};","import * as d3 from 'd3';\n\nexport type Selection<\n Element extends d3.BaseType,\n Datum = unknown,\n PElement extends d3.BaseType = null,\n PDatum = undefined\n> = d3.Selection;\n\nexport type Padding = {\n top: number,\n bottom: number,\n left: number,\n right: number,\n}\n\nexport type TickFormat = {\n x: (t: number) => string\n y: (t: number) => string\n}\n\nexport const debounce = () => {\n let timer: NodeJS.Timeout;\n return (fn: () => void, delay: number) => {\n clearTimeout(timer);\n timer = setTimeout(fn, delay);\n };\n};","import * as d3 from 'd3';\nimport { Selection } from './D3utils';\nimport D3Timeline, { BrushCallback } from './D3Timeline';\nimport { colorScales } from 'theme';\nimport { removeTooltip, transitionTooltip } from './D3Tooltip';\nimport { MutableRefObject } from 'react';\n\nexport type AggFields = {\n count: number\n amount: number\n}\n\nexport type Data = {\n year: number\n aggs: Record\n}\n\ntype Series = {\n key: string\n data: Data\n}\n\nexport type Dimensions = {\n width: number\n height: number\n}\n\ntype ChartCallback = (key: string, year: number) => void\n\ntype ChartProps = {\n dimensions: Dimensions\n containerEl: HTMLDivElement\n timelineRef?: MutableRefObject;\n onTooltipEnter?: ChartCallback\n onTooltipLeave?: ChartCallback\n onBarClick?: ChartCallback\n onBrushEnded?: BrushCallback\n};\n\nexport type Layout = {\n x: d3.ScaleBand;\n y: d3.ScaleLinear;\n stack: d3.Series[];\n divs: string[];\n invDivs: Record;\n years: number[];\n };\n \nexport default class BarChart {\n // DOM layout\n containerEl: HTMLDivElement;\n tooltip?: Selection;\n padding = { top: 24, bottom: 36, left: 72, right: 24 };\n timelineLayout = { height: 80, padding: this.padding };\n svg: Selection;\n chart: Selection;\n timeline: D3Timeline;\n // chart dimensions\n chartWidth: number;\n chartHeight: number;\n x = d3.scaleBand().padding(0.2);\n y = d3.scaleLinear().nice();\n // data\n stack: d3.Series[] = [];\n divs: string[] = [];\n invDivs: Record = {};\n offsets: Record = {};\n domainUpdated = false;\n years: number[] = [];\n agg: keyof AggFields = 'amount';\n color: d3.ScaleOrdinal = colorScales[this.agg];\n prev?: Layout;\n xAxis: Selection;\n yAxis: Selection;\n yLabel: Selection;\n gridLines: Selection;\n onTooltipEnter?: ChartCallback\n onTooltipLeave?: ChartCallback\n onBarClick?: ChartCallback\n animationDur = 1000;\n \n constructor(props: ChartProps) {\n \n this.containerEl = props.containerEl;\n // bind callbacks\n this.onTooltipEnter = props.onTooltipEnter;\n this.onTooltipLeave = props.onTooltipLeave;\n this.onBarClick = props.onBarClick;\n\n this.chartWidth = props.dimensions.width - this.padding.left - this.padding.right;\n // TODO better formula\n this.chartHeight = props.dimensions.height - this.padding.top - 2*this.padding.bottom - this.timelineLayout.height;\n\n const container = d3.select(this.containerEl);\n // react-dev-server keeps appending on hot-reload\n container.select('#chart-area').remove();\n \n // append elements\n this.svg = container.append('svg')\n .attr('id', 'chart-area')\n // .attr('xmlns', 'http://www.w3.org/2000/svg')\n // .attr('xmlns:xmlns:xlink', 'http://www.w3.org/1999/xlink')\n .attr('version', '1.1')\n .attr('xml:space', 'preserve');\n \n this.chart = this.svg\n .append('g')\n .classed('chart', true);\n\n this.gridLines = this.chart.append('g')\n .classed('gridline', true);\n\n this.xAxis = this.chart.append('g')\n .attr('class', 'axis axis-x');\n\n this.yAxis = this.chart.append('g')\n .attr('class', 'axis axis-y');\n \n this.yLabel = this.chart.append('text')\n .attr('transform', 'rotate(-90)')\n .attr('y', 0)\n .attr('x', -(this.chartHeight / 2))\n .attr('dy', '-3em')\n .style('text-anchor', 'middle')\n .attr('class', 'label label-y')\n .text(this.agg === 'count' ? 'number of grants' : 'award amount');\n \n this.timeline = new D3Timeline({\n svg: this.svg,\n padding: {\n ...this.padding,\n top: this.padding.top + this.chartHeight + this.padding.bottom\n },\n chartWidth: this.chartWidth,\n chartHeight: this.timelineLayout.height,\n onBrushEnded: props.onBrushEnded,\n tickFormat: this.tickFormat,\n });\n \n if (props.timelineRef) {\n props.timelineRef.current = this.timeline.chart.node();\n }\n \n const defs = this.svg.append('defs');\n \n defs.append('style')\n .attr('type', 'text/css')\n // eslint-disable-next-line quotes\n .text(\"@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700,800');\");\n \n // TODO implement filter for hover?\n defs.append('filter')\n .attr('id', 'shadow')\n .html(`\n \n \n \n \n `);\n \n this.measure(props.containerEl.clientWidth, props.containerEl.clientHeight);\n }\n \n // TODO better formatting of decimals\n tickFormat = {\n // x: d3.format('d'),\n x: (d: number) => {\n const [ min, max ] = d3.extent(this.x.domain());\n if (!min || !max) return '';\n const yearGap = Math.round((max - min) / this.chartWidth * 200);\n const boundaryYearGap = Math.ceil(yearGap / 2);\n\n const showTick = d === min \n || d === max\n || (\n d % yearGap === 0 \n && d - boundaryYearGap >= min\n && d + boundaryYearGap <= max\n );\n\n return showTick ? d.toString() : '';\n },\n y: (d: number) => (this.agg === 'amount' ? '$' : '') + d3.format('.2s')(d)\n .replace(/G/, 'B')\n .replace(/\\.0$/, '')\n .replace(/\\d+m/, '')\n }\n \n getGridLines = () => d3.axisLeft(this.y)\n .tickSize(-this.chartWidth)\n .tickFormat(() => '');\n\n // takes scale as prop to support animating between prev/next state\n getXAxis = (scale: d3.ScaleBand) => d3.axisBottom(scale)\n .tickFormat(this.tickFormat.x);\n\n getYAxis = () => d3.axisLeft(this.y)\n .tickFormat(this.tickFormat.y)\n .ticks(5);\n \n measure = (width: number, height: number) => {\n this.chartWidth = width - this.padding.left - this.padding.right;\n this.chartHeight = height - this.padding.top - 2*this.padding.bottom - this.timelineLayout.height;\n\n this.svg\n .attr('width', width)\n .attr('height', height);\n \n this.chart\n .attr('transform', `translate(${this.padding.left}, ${this.padding.top})`);\n \n this.x.rangeRound([0, this.chartWidth]);\n \n this.y.rangeRound([this.chartHeight, 0]);\n\n this.redraw();\n \n this.timeline.measure(\n {\n ...this.padding,\n top: this.padding.top + this.chartHeight + this.padding.bottom\n },\n this.chartWidth,\n this.timelineLayout.height,\n );\n }\n \n update = (data: Data[], divDomain: string[], agg?: keyof AggFields) => {\n\n this.years = data.map(d => d.year);\n this.divs = divDomain;\n this.invDivs = Object.fromEntries(this.divs.map((d, i) => [d, i]));\n this.offsets = this.getStackOrderOffsets();\n this.domainUpdated = !(\n this.prev?.years[0] === this.years[0] &&\n this.prev?.years.length === this.years.length\n );\n\n if (agg) this.agg = agg;\n\n this.stack = this.getStack(data, divDomain, this.agg);\n this.x.domain(this.years);\n this.y.domain([0, Math.max(...this.stack.flat().flat())]);\n this.color = colorScales[this.agg];\n this.color.domain(this.divs);\n this.redraw();\n }\n\n redraw = () => {\n \n this.updateAxes();\n\n // TODO it seems like this isn't needed?\n // const prevDivIndices = Object.fromEntries(this.prev?.divs.map((d, i) => [d, i]) ?? []);\n // const divIndices = Object.fromEntries(this.divs.map((d, i) => [d, i]));\n\n // const sameDomain = (\n // this.prev &&\n // this.prev.years[0] === this.years[0] &&\n // this.prev.years.length === this.years.length\n // );\n \n // const offsets = {};\n // if (this.prev && this.prev.divs.length !== this.divs.length) {\n // // determine whether groups were added or removed\n // const [ sub, sup ] = this.prev.divs.length < this.divs.length \n // ? [ this.prev.divs, this.divs ]\n // : [ this.divs, this.prev.divs ];\n // \n // let offset = 0; // track offset between sub/sup\n // sub.forEach((key, i) => {\n // while (key !== sup[i + offset]) {\n // offsets[sup[i + offset]] = offset;\n // offset += 1;\n // }\n // });\n // } else {\n // this.divs.forEach(d => {\n // offsets[d] = -1;\n // });\n // }\n \n const stacks = this.chart.selectAll('.bars')\n .data(this.stack, d => d.key)\n .join(\n enter => {\n const entered = enter.append('g')\n .attr('class', d => `bars ${d.key}`);\n \n return entered;\n \n // TODO\n // console.log(entered);\n // entered.each((div, i, stack) => {\n // console.log(stack[i]);\n // d3.select(stack[i])\n // .selectAll('.bar')\n // .data(d => d, d => d.data.year)\n // .append('rect')\n // .transition()\n // .duration(this.animationDur)\n // .attr('height', 0)\n // .attr('y', (d, i) => this.getYTransition(div.key, d, i, this.prev, this));\n // });\n // return entered;\n },\n update => update,\n // only applies to exiting div groups, not year stacks\n exit => {\n exit.each((div, i, stack) => {\n d3.select(stack[i])\n .selectAll('.bar')\n .transition()\n .duration(this.animationDur)\n .attr('height', 0)\n .attr('y', (d, i) => this.getYTransition(div.key, d, i, this, this.prev))\n .remove();\n });\n exit.transition()\n .duration(this.animationDur)\n .remove();\n }\n );\n \n stacks\n .transition()\n .duration(this.animationDur)\n .attr('fill', d => this.color(d.key));\n \n stacks.each((div, i, stack) => {\n const bars = d3.select(stack[i])\n .selectAll('.bar')\n .data(d => d, d => d.data.year)\n .join(\n enter => enter\n .append('rect')\n .classed('bar', true)\n .attr('cursor', 'pointer')\n .attr('x', d => this.getXTransition(d.data.year, this.prev))\n .attr('width', this.prev ? this.prev.x.bandwidth : this.x.bandwidth())\n // TODO we need these transitions for entering years\n // .attr('y', d => this.prev ? this.prev.y(d[1]) : 0)\n // .attr('height', d => this.prev ? this.prev.y(d[0]) - this.prev.y(d[1]) : 0)\n .attr('height', 0)\n // necessary to align new bars vertically during transition\n .attr('y', (d, i) => this.getYTransition(div.key, d, i, this.prev, this))\n // only fade in from sides\n .style('opacity', d => this.prev?.x(d.data.year) ? 1 : 0),\n update => update,\n // only applies to exiting year stacks, not div groups\n exit => exit\n .transition()\n .duration(this.animationDur)\n .attr('width', this.x.bandwidth())\n .attr('x', d => this.getXTransition(d.data.year, this))\n .attr('height', d => this.y(d[0]) - this.y(d[1]))\n .attr('y', d => this.y(d[1]))\n .style('opacity', 0)\n .remove()\n );\n \n bars\n .transition()\n .duration(this.animationDur)\n .attr('width', this.x.bandwidth())\n .attr('x', d => this.x(d.data.year) ?? 0)\n .attr('height', d => this.y(d[0]) - this.y(d[1]))\n .attr('y', d => this.y(d[1]))\n .style('opacity', 1);\n\n bars\n .on('mouseover', (e, d) => {\n const rect: SVGRectElement = e.target;\n d3.select(rect).classed('selected', true);\n\n this.onTooltipEnter?.(div.key, d.data.year);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const chart = this.svg.node()!.getBoundingClientRect();\n const bar = rect.getBoundingClientRect();\n const bandwidth = this.x.bandwidth();\n const padding = bandwidth * this.x.padding();\n transitionTooltip(div.key, {\n chart,\n bar,\n bandwidth,\n padding,\n });\n })\n .on('mouseleave', (e, d) => {\n d3.select(e.target).classed('selected', false);\n this.onTooltipLeave?.(d.key, d.data.year);\n removeTooltip();\n })\n .on('click', (e, d) => {\n d3.select(e.target).classed('selected', false);\n this.onBarClick?.(div.key, d.data.year);\n });\n });\n\n // save current state for next transition\n this.prev = {\n x: this.x.copy(),\n y: this.y.copy(),\n stack: this.stack,\n divs: this.divs,\n invDivs: this.invDivs,\n years: this.years,\n };\n }\n \n getStack = (data: Data[], domain: string[], agg: keyof AggFields) => (\n d3.stack()\n .keys(domain)\n .value((d, key) => d.aggs[key]?.[agg] ?? 0)\n .order(d3.stackOrderNone)(data)\n )\n \n getStackOrderOffsets = () => {\n if (this.prev && this.prev.divs.length !== this.divs.length) {\n // determine whether groups were added or removed\n const [ sub, sup ] = this.prev.divs.length < this.divs.length \n ? [ this.prev.divs, this.divs ]\n : [ this.divs, this.prev.divs ];\n \n return Object.fromEntries(sup.filter(s => !sub.includes(s)).map((s, i) => [s, i]));\n } else {\n return Object.fromEntries(this.divs.map(d => [d, 0]));\n }\n }\n\n // TODO make this implement ScaleBand interface\n getXTransition = (year: number, layout?: Layout) => {\n // layout is null on initial render\n if (layout) {\n const [ first, last ] = [\n layout.years[0],\n layout.years[layout.years.length - 1]\n ];\n const width = layout.x.step(); \n\n if (year < first) {\n return (year - first) * width;\n } else if (year > last) {\n return this.chartWidth + (year - last) * width;\n }\n }\n return this.x(year) ?? 0;\n }\n \n getYTransition = (\n key: string,\n d: Series,\n i: number,\n from?: Layout,\n to?: Layout,\n ) => {\n // to is null on initial render\n if (from && to) {\n const idx = to.invDivs[key];\n // will be undefined if bottom of stack\n const prevGroup = from.stack[idx - this.offsets[key]];\n if (prevGroup && !this.domainUpdated) {\n return from.y(prevGroup[i][0]);\n }\n } else if (from) {\n return from.y(d[0]);\n }\n // first group in stack, first load, or entering years\n return this.chartHeight;\n }\n \n updateAxes = () => {\n\n /*\n *const domain = this.x.domain();\n *const padding = this.x(domain[0])!;\n *const range = [-15, 15];\n *const newDomain = Array.from({ length: domain.length + range[1] - range[0] }, (x, i) => domain[0] + range[0] + i);\n *const newRange = range.map((r, i) => ((i + 1) * padding) + (this.x.bandwidth() * (r + i * newDomain.length)));\n *const x2 = d3.scaleBand()\n * .rangeRound(range.map((r, i) => padding + this.x.bandwidth() * (r + i * domain.length)))\n * .domain(newDomain)\n * .padding(0.2);\n */\n\n this.xAxis.transition()\n .duration(this.animationDur)\n .attr('transform', `translate(0, ${this.chartHeight})`)\n .call(this.getXAxis(this.x));\n \n this.yAxis.transition()\n .duration(this.animationDur)\n .call(this.getYAxis());\n\n this.yLabel.transition()\n .duration(this.animationDur)\n .attr('y', 0)\n .attr('x', -(this.chartHeight / 2))\n .text(this.agg === 'count' ? 'number of grants' : 'award amount');\n\n this.gridLines.transition()\n .duration(this.animationDur)\n .call(this.getGridLines());\n }\n \n highlightGroup = (group?: string) => {\n d3.selectAll('.bars')\n .selectAll('.bar')\n .classed('selected', false);\n \n if (group) {\n d3.selectAll(`.${group}-count`)\n .selectAll('.bar')\n .classed('selected', true);\n }\n }\n}\n","import Axios from 'axios';\nimport { useGrantsDialogQuery, useQuery } from 'app/query';\nimport { stringifyUrl } from 'query-string';\n\nconst useGrantsDownload = () => {\n const [ query ] = useQuery();\n const [ dialog ] = useGrantsDialogQuery();\n\n const url = stringifyUrl({\n url: `${Axios.defaults.baseURL}/grants/download`,\n query: {\n ...query,\n order: dialog.grantDirection,\n sort: dialog.grantSort,\n start: dialog.grantDialogYear ?? query.start,\n end: dialog.grantDialogYear ?? query.end,\n divisions: dialog.grantDialogDivision ? [dialog.grantDialogDivision] : query.divisions,\n }\n });\n \n return url;\n};\n\nexport default useGrantsDownload;","import { Link, SpeedDial, SpeedDialAction, styled, Tooltip } from '@material-ui/core';\nimport { Download, GitHub, Science, InsertDriveFile, Help, Info } from '@mui/icons-material';\nimport useGrantsDownload from 'app/grants/grantsDownload';\nimport { useAbout, useBeta, useGrantsDialogQuery, useTutorial } from 'app/query';\nimport { useWizardRef } from 'app/wizard/wizard';\nimport { MouseEvent, useState } from 'react';\n\nconst StyledAction = styled(SpeedDialAction)`\n & .MuiLink-root {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n`;\n\nconst Actions = () => {\n\n const [ beta, setBeta ] = useBeta();\n const [ , setTutorial ] = useTutorial();\n const grantsUrl = useGrantsDownload();\n const [ , setDialogQuery ] = useGrantsDialogQuery();\n const { ref: overflowMenuRef, active } = useWizardRef('overflowMenu');\n const [ open, setOpen ] = useState(false);\n const [ , setAboutOpen ] = useAbout();\n\n const actions = [\n // {\n // name: 'Download Tabular Data',\n // icon: ,\n // href: ''\n // },\n {\n name: 'Download Grant Data',\n icon: ,\n href: grantsUrl,\n handleClick: (e: MouseEvent) => e.stopPropagation()\n },\n {\n name: 'View Source',\n icon: ,\n href: 'https://github.com/jessecoleman/nsf-viz',\n handleClick: (e: MouseEvent) => e.stopPropagation()\n },\n {\n name: 'About Grant Explorer',\n icon: ,\n handleClick: (e: MouseEvent) => {\n e.stopPropagation();\n setAboutOpen(true);\n }\n },\n {\n name: 'View Tutorial',\n icon: ,\n handleClick: (e: MouseEvent) => {\n e.stopPropagation();\n setTutorial(0);\n }\n },\n {\n name: (beta ? 'Disable' : 'Enable') + ' Beta Features',\n icon: ,\n handleClick: (e: MouseEvent) => { e.stopPropagation(); setBeta(!beta); }\n }\n ];\n \n const handleOpen = () => {\n setOpen(true);\n };\n\n const handleClose = () => {\n setOpen(false);\n };\n \n const handleOpenGrants = (e: MouseEvent) => {\n // console.log(e.target, e.currentTarget.classList);\n if (e.currentTarget.classList.contains('MuiSpeedDial-root')) {\n setDialogQuery({ grantDialogOpen: true });\n }\n };\n \n return (\n \n }\n onClick={handleOpenGrants}\n onOpen={handleOpen}\n onClose={handleClose}\n >\n {actions.map((action) => (\n \n {action.icon}\n \n )}\n tooltipTitle={action.name}\n />\n ))}\n \n \n );\n};\n\nexport default Actions;","import { Button, Collapse, Dialog, DialogActions, DialogContent, DialogTitle, LinearProgress, styled, Typography } from '@material-ui/core';\nimport LaunchIcon from '@mui/icons-material/Launch';\nimport { useLoadAbstract } from 'api';\nimport { useBeta, useGrantIdQuery, useTermsQuery } from 'app/query';\nimport * as d3 from 'd3';\nimport { MouseEvent } from 'react';\n\nconst Title = styled(Typography)(({ theme }) => `\n color: ${theme.palette.text.primary};\n`);\n\nconst Subtitle = styled(Typography)(({ theme }) => `\n color: ${theme.palette.text.secondary};\n`);\n\nconst Abstract = styled(Typography)(({ theme }) => `\n line-height: 1.75;\n & em {\n display: inline-block;\n font-style: normal;\n background: ${theme.palette.grey[300]};\n padding: ${theme.spacing(0.25, 1)};\n border-radius: ${theme.spacing(2)};\n }\n & i {\n display: inline-block;\n box-sizing: border-box;\n font-style: normal;\n padding: ${theme.spacing(0.25, 1)};\n border: 1px solid ${theme.palette.grey[500]};\n border-radius: ${theme.spacing(2)};\n &:hover {\n cursor: pointer;\n background-color: ${theme.palette.grey[300]};\n }\n }\n`);\n\nconst AbstractDialog = () => {\n\n const [ beta ] = useBeta();\n const [ terms, setTerms ] = useTermsQuery();\n const [ grantId, setGrantId ] = useGrantIdQuery();\n const { data: grant, isLoading } = useLoadAbstract(grantId, { terms, beta }, {\n query: {\n keepPreviousData: true,\n enabled: grantId !== undefined,\n select: (d) => d.data\n }\n });\n \n const dismissDialog = () => {\n setGrantId(undefined);\n };\n\n const timeConvert = (date: string) => (\n d3.timeFormat('%b %e, %Y')(\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n d3.timeParse('%Y-%m-%d')(date)!\n )\n );\n \n const handleClick = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target.nodeName.toLowerCase() === 'i') {\n setTerms(terms.concat([target.innerText]));\n\n }\n };\n\n return (\n \n {grant && (\n <>\n \n \n {grant.title}\n {grant.external_url && (\n <a href={grant.external_url} target=\"_blank\" rel=\"noreferrer\"><LaunchIcon /></a>\n )}\n \n {grant.cat1_raw}\n {timeConvert(grant.date)}\n {d3.format('$,')(grant.amount)}\n {grant.recipient_org && (\n Recipient Organization: {grant.recipient_org}\n )}\n {grant.investigators && (\n Principal Investigator(s): {grant.investigators}\n )}\n \n \n \n \n \n \n \n \n \n \n )}\n {isLoading && }\n \n );\n};\n\nexport default AbstractDialog;\n","import { CSSProperties } from 'react';\nimport { alpha, styled, Typography } from '@material-ui/core';\nimport { Grant } from 'api';\nimport { timeFormat, timeParse, format } from 'd3';\nimport { useGrantIdQuery } from 'app/query';\nimport { useGrant } from './useInfiniteLoadGrants';\n\ntype Column = {\n id: keyof Grant\n format: (s: any) => string,\n label: string,\n}\n\nexport const cols: Column[] = [\n { id: 'title', format: t => t, label: 'Grant Title' },\n { id: 'date', format: d => timeFormat('%b %Y')(timeParse('%Y-%m-%d')(d)!), label: 'Date' },\n { id: 'amount', format: format('$,'), label: 'Amount' },\n { id: 'cat1_raw', format: d => d, label: 'Division' },\n];\n\nexport const GrantListItem = styled('div')(({ theme }) => `\n display: grid;\n grid-template-columns: [title] auto [date] 8rem [amount] 8rem [cat1_raw] 20rem;\n cursor: pointer;\n padding-left: ${theme.spacing(3)};\n padding-right: ${theme.spacing(1)};\n border-bottom: 1px solid ${theme.palette.grey[300]};\n &:hover {\n background-color: ${alpha(theme.palette.grey[900], 0.05)};\n }\n ${theme.breakpoints.down('sm')} {\n grid-template-columns: [title] auto [date] 5em;\n }\n`);\n\nexport const EndOfListItem = styled('div')(({ theme }) => `\n padding-left: ${theme.spacing(3)};\n padding-right: ${theme.spacing(1)};\n // border-bottom: 1px solid ${theme.palette.grey[300]};\n display: flex;\n align-items: center;\n justify-content: center;\n`);\n\ntype ColumnStyles = {\n column: string\n};\n\nexport const GrantColumn = styled('div')(({ theme, column }) => `\n position: relative;\n grid-column: ${column};\n display: flex;\n align-items: center;\n ${theme.breakpoints.down('sm')} {\n display: ${['amount', 'division'].includes(column) ? 'none' : 'initial'};\n }\n`);\n\ntype GrantRowProps = {\n index: number\n style: CSSProperties\n}\n\nconst GrantRow = (props: GrantRowProps) => {\n\n const { index, style } = props;\n\n const [ , setGrantId ] = useGrantIdQuery();\n const grant = useGrant(index);\n \n if (grant === undefined) return (\n \n \n {index} grants loaded\n \n \n );\n\n const setSelectedGrant = () => {\n setGrantId(grant.id);\n };\n\n return (\n \n {cols.map(({ format, id }) => (\n \n {format(grant[id])}\n \n ))}\n \n );\n};\n\nexport default GrantRow;\n","import { Grant, loadGrants } from 'api';\nimport { useGrantsDialogQuery, useQuery } from 'app/query';\nimport { queryClient } from 'app/queryClient';\nimport { useEffect, useMemo, useRef } from 'react';\nimport { useInfiniteQuery } from 'react-query';\nimport InfiniteLoader from 'react-window-infinite-loader';\n\nexport const useInfiniteLoadGrants = () => {\n const [ query ] = useQuery();\n const [ dialog ] = useGrantsDialogQuery();\n const hasMountedRef = useRef(false);\n const loaderRef = useRef(null);\n\n const loadMoreGrants = async ({ pageParam = 0 }) => {\n const { data } = await loadGrants({\n ...query,\n order: dialog.grantDirection,\n sort: dialog.grantSort,\n start: dialog.grantDialogYear ?? query.start,\n end: dialog.grantDialogYear ?? query.end,\n divisions: dialog.grantDialogDivision ? [dialog.grantDialogDivision] : query.divisions,\n idx: pageParam,\n });\n return data;\n };\n\n const { data, isError, ...rest } = useInfiniteQuery('grants', loadMoreGrants, {\n getNextPageParam: (lastPage, pages) => (\n pages.length === 0 \n ? 0\n : lastPage?.length === 50\n ? pages.length * 50\n : undefined\n )\n });\n \n const clearGrants = () => {\n loaderRef.current?.resetloadMoreItemsCache();\n queryClient.setQueryData('grants', () => ({\n pages: [],\n pageParams: undefined,\n }));\n rest.fetchNextPage();\n };\n\n // clear grants when any params change\n useEffect(() => {\n if (hasMountedRef.current && loaderRef.current) {\n clearGrants();\n }\n hasMountedRef.current = true;\n }, [\n JSON.stringify(dialog),\n JSON.stringify(query),\n hasMountedRef.current,\n ]);\n\n const count = (data?.pages?.reduce((count, page) => count += page.length, 0)) ?? 0;\n return {\n loaderRef,\n noMore: isError,\n count,\n data,\n clearGrants,\n ...rest,\n };\n};\n\nexport const useGrant = (index: number) => {\n // TODO figure out how to load on first render\n const data = queryClient.getQueryData('grants') as { pages: Grant[][] };\n const page = data?.pages[Math.floor(index / 50)];\n return useMemo(() => (\n page?.[index % 50]\n ), [page, index]);\n};\n","import { RefObject } from 'react';\nimport { FixedSizeList } from 'react-window';\nimport InfiniteLoader from 'react-window-infinite-loader';\n\nimport { useWindowDimensions } from 'app/hooks';\nimport GrantRow from './GrantRow';\nimport { useInfiniteLoadGrants } from './useInfiniteLoadGrants';\nimport { Collapse, LinearProgress, styled } from '@material-ui/core';\n\nconst ProgressBar = styled(LinearProgress)`\n margin-bottom: -4px;\n`;\n\ntype GrantsTableProps = {\n widthRef: RefObject\n};\n\nconst GrantsTable = (props: GrantsTableProps) => {\n\n const [ , height ] = useWindowDimensions();\n const { loaderRef, count, hasNextPage, isFetching, isFetchingNextPage, isFetchedAfterMount, fetchNextPage } = useInfiniteLoadGrants();\n\n const isLoaded = (idx: number) => !hasNextPage || (!isFetching && idx < count);\n const ITEM_SIZE = 64;\n\n const handleLoadGrants = async (idx: number) => {\n if (!isFetchingNextPage) {\n await fetchNextPage({ pageParam: idx });\n }\n };\n\n return (\n <>\n \n
\n \n {({ onItemsRendered, ref }) => (\n \n {GrantRow}\n \n )}\n \n
\n
\n {isFetching && hasNextPage && }\n \n );\n};\n\nexport default GrantsTable;\n","import { Chip, styled } from '@material-ui/core';\nimport { FilterList } from '@mui/icons-material';\n\nconst StyledChip = styled(Chip)(({ theme }) => `\n transition: ease 0.3s all; \n box-sizing: border-box;\n border: 16px solid lightgrey;\n position: absolute;\n margin-top: auto;\n margin-bottom: auto;\n top: 0;\n right: 16px;\n z-index: 2;\n width: 32px;\n & span, .MuiChip-deleteIcon {\n display: none;\n }\n & .MuiChip-avatar {\n margin: 4px;\n }\n &:hover {\n max-width: initial;\n width: initial;\n box-shadow: ${theme.shadows['2']};\n & span, .MuiChip-deleteIcon {\n display: initial;\n }\n & .MuiChip-deleteIcon {\n margin-right: -10px;\n }\n & .MuiChip-avatar {\n margin-left: -8px;\n }\n } \n`);\n\ntype FilterChipProps = {\n label: string,\n onClear: () => void,\n};\n\nconst FilterChip = (props: FilterChipProps) => {\n\n return (\n }\n label={props.label}\n />\n );\n};\n\nexport default FilterChip;","import { styled } from '@material-ui/core/styles';\nimport { \n Dialog,\n Button,\n TableSortLabel,\n DialogActions,\n Box,\n} from '@material-ui/core';\n\nimport { Grant } from 'api';\nimport { useMeasure } from 'app/hooks';\nimport { useGrantsDialogQuery } from 'app/query';\nimport AbstractDialog from './AbstractDialog';\nimport { cols, GrantColumn, GrantListItem } from './GrantRow';\nimport GrantsTable from './GrantsTable';\nimport FilterChip from './FilterChip';\nimport useGrantsDownload from './grantsDownload';\n\nconst TopAlignedDialog = styled(Dialog)`\n & .MuiDialog-container {\n align-items: start !important;\n }\n`;\n\ntype GrantListHeaderStyles = {\n scrollOffset?: number;\n}\n\nexport const GrantListHeader = styled(GrantListItem)(({ theme, scrollOffset }) => `\n height: 96px;\n font-size: ${theme.typography.h6.fontSize};\n padding-right: ${scrollOffset ?? 0}px;\n`);\n\nconst GrantsDialog = () => {\n\n const [ dialog, setDialogQuery ] = useGrantsDialogQuery();\n const url = useGrantsDownload();\n\n const [ widthRef, ] = useMeasure();\n \n const handleSort = (sort: keyof Grant) => () => {\n const direction = (\n dialog.grantSort === sort\n && dialog.grantDirection === 'asc' ? 'desc' : 'asc'\n );\n\n setDialogQuery({\n grantSort: sort,\n grantDirection: direction,\n });\n };\n\n const handleClose = () => {\n setDialogQuery({ grantDialogOpen: false });\n };\n\n const handleClearFilter = (key: keyof Grant) => () => {\n switch (key) {\n case 'date':\n setDialogQuery({ grantDialogYear: undefined });\n break;\n case'cat1_raw':\n setDialogQuery({ grantDialogDivision: undefined });\n break;\n }\n };\n\n const getFilterLabel = (field: keyof Grant) => {\n switch (field) {\n case 'cat1_raw':\n return dialog.grantDialogDivision?.toUpperCase() ?? '';\n case 'date':\n return dialog.grantDialogYear?.toString() ?? '';\n default:\n return '';\n }\n };\n\n return (\n <>\n \n \n {cols.map(({ id, label }) => (\n \n \n \n {label}\n \n {getFilterLabel(id) &&\n \n }\n \n \n ))}\n \n \n \n \n \n \n \n \n \n );\n};\n\nexport default GrantsDialog;\n","import styled from '@material-ui/styled-engine';\nimport { alpha, Box } from '@material-ui/system';\nimport { Button, DialogActions, DialogContent, DialogTitle, Menu, Typography } from '@material-ui/core';\nimport { Close, NavigateBefore, NavigateNext } from '@mui/icons-material';\nimport { useWizard } from './wizard';\n\n\nconst StyledActions = styled(DialogActions)(({ theme }) => `\n justify-content: space-between;\n`);\n\nconst Overlay = styled(Box)(({ theme }) => `\n z-index: 1500;\n background-color: ${alpha(theme.palette.common.black, 0.5)};\n mix-blend-mode: multiply;\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n`);\n\nconst StyledMenu = styled(Menu)(({ theme }) => `\n margin: ${theme.spacing(4)};\n z-index: 2000;\n & .MuiMenu-list {\n max-width: 18em;\n padding: ${theme.spacing(1)};\n }\n & .MuiDialogTitle-root {\n font-weight: bold;\n }\n & .MuiDialogTitle-root, .MuiDialogContent-root, .MuiDialogActions-root {\n padding: 0;\n }\n`);\n\ntype Dims = Record<'left' | 'top' | 'width' | 'height' | 'padding', number>;\n \nconst Spotlight = styled('div')(({ theme, left, top, width, height, padding }) => `\n background-color: white;\n position: fixed;\n border-radius: ${theme.spacing(2)};\n box-shadow: 0 0 ${theme.spacing(4, 4)} white;\n left: ${left - padding}px;\n top: ${top - padding}px;\n width: ${width + 2 * padding}px;\n height: ${height + 2 * padding}px;\n`);\n\nconst WizardTooltip = () => {\n\n const { step, ref, navigateForward, navigateBack, cancelWizard } = useWizard();\n if (!step || !ref?.current) return null;\n\n const bbox = ref.current.getBoundingClientRect();\n\n return (\n <>\n \n \n \n \n \n {step.title}\n \n {step.description &&\n \n {step.description}\n \n }\n \n }\n >\n {navigateBack ? 'end' : 'skip tutorial'}\n \n {navigateBack && (\n }\n >\n prev\n \n )}\n }\n >\n next\n \n \n \n \n );\n};\n\nexport default WizardTooltip;\n","import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Link } from '@material-ui/core';\nimport { Close } from '@mui/icons-material';\nimport { useAbout, useTutorial } from 'app/query';\nimport { MouseEvent } from 'react';\n\nconst About = () => {\n \n const [ aboutOpen, setAboutOpen ] = useAbout();\n const [ , setTutorial ] = useTutorial();\n const openTutorial = (e: MouseEvent) => {\n e.stopPropagation();\n setAboutOpen(false);\n setTutorial(0);\n };\n\n return (\n setAboutOpen(false)}>\n \n

About GrantExplorer

\n
\n \n

What is GrantExplorer?

\n

GrantExplorer is a free, open-source tool for examining the phrases funded by U.S. federal agencies. This includes more than a half-million grants from the National Science Foundation (NSF), National Institutes of Health (NIH), and Department of Defense (DoD).

\n

For example, one could ask the following questions: how much funding has been devoted to "data science" at the NSF? How many "mRNA" grants have been funded at the NIH? What defense agencies have funded "artificial intelligence"? What are related terms for "block chain"?

\n

Why did you create this tool and who is it aimed at?

\n

Grant data from many federal agencies is openly available. Anyone can run this kind of analysis on their own. However, it is not available in a form that is quick and easy to analyze. One would have to download large XML files, clean the data, and find the right software. We wanted to make it easy for anyone to examine this data in a web browser with the most up-to-date data. This could be useful for researchers applying for grants, philanthropists developing research portfolios, or government leaders wanting to assess technology trends.

\n

There are other similar (and great), free resources and websites that make grant data available, including USAspending.gov, but none of them provide the functionality for the type of research questions and term exploration that we were looking for.

\n

How do I use it?

\n

Click here to view the tutorial.

\n

Who created the tool?

\n

The tool was born following a conversation between Chris Mentzel and Adam Jones at the Moore Foundation and Jevin West at the University of Washington. There seemed to be no tool for easily exploring what terms are being funded, how those terms are changing, and what new terms are emerging. We are still working on adding new features, but the current version allows one to explore some aspects of these questions. This is important to philanthropists wanting to complement rather than replicate federal research funding. It also allows funders to track the growth of emergent terms in grant data.

\n

The tool itself was built by Jesse "Cole" Chamberlin and Jason Portenoy, both former students at the DataLab (Information School, University of Washington). Cole developed the language model and frontend and Jason aggregated and engineered the data backend.

\n

Is it really free?

\n

Yes, it is free. There is no cost and no freemium model. Our data and tools are openly available with this open source license [open source license]. The only thing we ask is that you cite the project if you use it in publications or elsewhere:

\n

Chamberlin, Jesse and Portenoy, Jason and West, Jevin. (2022) GrantExplorer.org. DataLab, Information School, University of Washington.

\n

Who funded the tool?

\n

The Moore Foundation funded the development of the tool.

\n

Will the data be updated and will new functionality be added?

\n

The NSF, NIH, and DoD grant data will be updated as it becomes available. We plan to expand to other federal agencies that make their grant data openly available.

\n

New functionality depends on time availability on our side but also need from users. If you would like us to add something new to the tool, please email us.

\n

When was the data last updated?

\n

\n

    \n
  • NSF: September 2023 (soon-to-be funded grants are included, which is why 2023 is listed)
  • \n
  • NIH: Oct, 2021 (R01 grants only)
  • \n
  • DoD: Jan, 2022
  • \n
\n

\n

So, what is one of the most funded terms?

\n

One of the most funded terms at the NSF over the last couple decades is "new" (only slightly behind terms such as "research", "development", and "project"). Funders really do seem to like newness.

\n

This kind of analysis is not so straightforward, though. Does one look at unigrams, bigrams, trigrams, etc? Do one focus on one year and one agency? What common terms should be removed?

\n

We are working on more sophisticated analyses of this data and know that others have done good work in this area. We plan to post on these soon. If you are interested in this data, we are happy to share.

\n

Want to test the beta features?

\n

\n Feel free to try out some beta features (that may be a little buggy). Just click on the green flask icon to the lower right. That will enable topic recommenders and other "new", experimental features.\n

\n

Who can I contact about the tool?

\n

Please feel free to email Jevin West if you have any questions or requests.

\n
\n \n \n \n
\n );\n};\n\nexport default About;","import NavigationBar from 'app/nav/NavigationBar';\nimport { Box, styled } from '@material-ui/core';\nimport DivisionDrawer from 'app/nav/Drawer';\nimport Footer from 'app/nav/Footer';\nimport Chart from 'app/chart/Chart';\nimport { useMeasureChart } from 'app/hooks';\nimport Actions from 'app/nav/Actions';\nimport GrantsDialog from 'app/grants/GrantsDialog';\nimport WizardTooltip from 'app/wizard/WizardTooltip';\nimport About from 'app/wizard/About';\n\nconst ResponsiveContainer = styled('div')(({ theme }) => `\n overflow: clip;\n height: 100vh;\n display: flex;\n flex-direction: column;\n ${theme.breakpoints.up('md')} {\n margin-left: ${theme.drawerWidth};\n }\n`);\n\nconst App = () => {\n\n const [ navbarRef, footerRef, dims ] = useMeasureChart();\n\n return (\n \n \n \n \n \n