diff --git a/api-editor/gui/src/app/App.tsx b/api-editor/gui/src/app/App.tsx index 118d2628a..5ee2b1598 100644 --- a/api-editor/gui/src/app/App.tsx +++ b/api-editor/gui/src/app/App.tsx @@ -51,6 +51,7 @@ import { selectShowUsageImportDialog, selectUI, selectShowAddFilterDialog, + selectShowStatistics, } from '../features/ui/uiSlice'; import { initializeUsages, persistUsages, selectUsages } from '../features/usages/usageSlice'; import { initializePythonPackage, selectRawPythonPackage } from '../features/packageData/apiSlice'; @@ -69,6 +70,7 @@ import { AbstractPythonFilter } from '../features/filter/model/AbstractPythonFil import { UsageCountStore } from '../features/usages/model/UsageCountStore'; import { PythonDeclaration } from '../features/packageData/model/PythonDeclaration'; import { SaveFilterDialog } from '../features/filter/SaveFilterDialog'; +import { StatisticsView } from '../features/packageData/selectionView/StatisticsView'; export const App: React.FC = function () { useIndexedDB(); @@ -93,25 +95,26 @@ export const App: React.FC = function () { const showUsagesImportDialog = useAppSelector(selectShowUsageImportDialog); const batchMode = useAppSelector(selectBatchMode); const showAddFilterDialog = useAppSelector(selectShowAddFilterDialog); + const showStatistics = useAppSelector(selectShowStatistics); return ( <> - + } - + {batchMode === BatchMode.None && } @@ -196,7 +199,21 @@ export const App: React.FC = function () { )} - + {showStatistics && ( + + + + + + )} + {currentUserAction.type === 'none' && } diff --git a/api-editor/gui/src/common/MenuBar.tsx b/api-editor/gui/src/common/MenuBar.tsx index af6dd5a6e..a35ee8592 100644 --- a/api-editor/gui/src/common/MenuBar.tsx +++ b/api-editor/gui/src/common/MenuBar.tsx @@ -23,6 +23,7 @@ import { BatchMode, HeatMapMode, selectHeatMapMode, + selectShowStatistics, selectSortingMode, setBatchMode, setHeatMapMode, @@ -30,11 +31,11 @@ import { SortingMode, toggleAnnotationImportDialog, toggleAPIImportDialog, + toggleStatisticsView, toggleUsageImportDialog, } from '../features/ui/uiSlice'; import { DeleteAllAnnotations } from './DeleteAllAnnotations'; import { GenerateAdapters } from './GenerateAdapters'; -import { useNavigate } from 'react-router-dom'; import { FilterControls } from '../features/filter/FilterControls'; interface MenuBarProps { @@ -44,11 +45,11 @@ interface MenuBarProps { export const MenuBar: React.FC = function ({ displayInferErrors }) { const { colorMode, toggleColorMode } = useColorMode(); const dispatch = useAppDispatch(); - const navigate = useNavigate(); const annotationStore = useAppSelector(selectAnnotationStore); const sortingMode = useAppSelector(selectSortingMode); const heatMapMode = useAppSelector(selectHeatMapMode); + const showStatistics = useAppSelector(selectShowStatistics); const exportAnnotations = () => { const a = document.createElement('a'); @@ -60,13 +61,12 @@ export const MenuBar: React.FC = function ({ displayInferErrors }) a.click(); }; - const setStatisticsViewPath = () => { - navigate(`/statistics-view`); - }; - - const colorModeArray: string[] = []; + const visualSettings: string[] = []; if (colorMode === 'dark') { - colorModeArray.push('darkMode'); + visualSettings.push('darkMode'); + } + if (showStatistics) { + visualSettings.push('statistics'); } return ( @@ -133,19 +133,25 @@ export const MenuBar: React.FC = function ({ displayInferErrors }) - - }> Settings - - - Dark Mode - - + + + + Dark Mode + + dispatch(toggleStatisticsView())} + > + Show Statistics + + + - - - ); - } if (!declaration) { return null; diff --git a/api-editor/gui/src/features/packageData/selectionView/StatisticsView.tsx b/api-editor/gui/src/features/packageData/selectionView/StatisticsView.tsx index e7eca57bc..1bf5dde4f 100644 --- a/api-editor/gui/src/features/packageData/selectionView/StatisticsView.tsx +++ b/api-editor/gui/src/features/packageData/selectionView/StatisticsView.tsx @@ -12,7 +12,7 @@ import { import { Bar, Line } from 'react-chartjs-2'; import { PythonPackage } from '../model/PythonPackage'; import { UsageCountStore } from '../../usages/model/UsageCountStore'; -import { Box, Flex, Button, Heading, VStack, Wrap, WrapItem } from '@chakra-ui/react'; +import { Box, Button, Flex, Heading, SimpleGrid, VStack } from '@chakra-ui/react'; import { selectAnnotationStore } from '../../annotations/annotationSlice'; import { useAppDispatch, useAppSelector } from '../../../app/hooks'; import { selectFilterString, setFilterString } from '../../ui/uiSlice'; @@ -64,21 +64,24 @@ export const StatisticsView: React.FC = function () { rawPythonPackage, thresholds, usages.getNumberOfUsedPublicClasses, - 'Classes per Threshold', + 'Classes', + 'Minimum usefulness', ); const functionLineChart = createLineChart( usages, rawPythonPackage, thresholds, usages.getNumberOfUsedPublicFunctions, - 'Functions per Threshold', + 'Functions', + 'Minimum usefulness', ); const parameterLineChart = createLineChart( usages, rawPythonPackage, thresholds, usages.getNumberOfUsefulPublicParameters, - 'Parameters per Threshold', + 'Parameters', + 'Minimum usefulness', ); const filterAction = (annotation: string) => { @@ -100,9 +103,34 @@ export const StatisticsView: React.FC = function () { }; return ( - - - Statistics + + + Annotations + + + + + + + + + + + + + + + + + + + API Size @@ -117,6 +145,9 @@ export const StatisticsView: React.FC = function () { + + API Size per Minimum Usefulness Threshold + @@ -130,65 +161,6 @@ export const StatisticsView: React.FC = function () { - - Annotations - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); }; @@ -272,6 +244,7 @@ let createLineChart = function ( labels: number[], getValue: Function, title: string, + xAxisLabel: string, ): ReactElement { const options = { responsive: true, @@ -284,6 +257,14 @@ let createLineChart = function ( text: title, }, }, + scales: { + x: { + title: { + display: true, + text: xAxisLabel, + }, + }, + }, }; const dataValues = new Map(); diff --git a/api-editor/gui/src/features/ui/uiSlice.ts b/api-editor/gui/src/features/ui/uiSlice.ts index 6f533625c..eeaca0000 100644 --- a/api-editor/gui/src/features/ui/uiSlice.ts +++ b/api-editor/gui/src/features/ui/uiSlice.ts @@ -26,6 +26,7 @@ export interface UIState { filterList: Filter[]; sortingMode: SortingMode; batchMode: BatchMode; + showStatistics: boolean; } type UserAction = @@ -147,6 +148,7 @@ export const initialState: UIState = { heatMapMode: HeatMapMode.None, sortingMode: SortingMode.Alphabetical, batchMode: BatchMode.None, + showStatistics: true, }; // Thunks -------------------------------------------------------------------------------------------------------------- @@ -330,6 +332,9 @@ const uiSlice = createSlice({ setBatchMode(state, action: PayloadAction) { state.batchMode = action.payload; }, + toggleStatisticsView(state) { + state.showStatistics = !state.showStatistics; + }, }, extraReducers(builder) { builder.addCase(initializeUI.fulfilled, (state, action) => action.payload); @@ -371,6 +376,7 @@ export const { removeFilter, setSortingMode, setBatchMode, + toggleStatisticsView, } = actions; export const uiReducer = reducer; @@ -406,3 +412,4 @@ export const selectFilter = createSelector( ); export const selectSortingMode = (state: RootState): SortingMode => selectUI(state).sortingMode; export const selectBatchMode = (state: RootState): BatchMode => selectUI(state).batchMode; +export const selectShowStatistics = (state: RootState): boolean => selectUI(state).showStatistics;