Skip to content

Commit 35f6a29

Browse files
authored
Merge pull request #6 from Hatzen/vibe-code-single-boxplot
Vibe code single boxplot
2 parents 360a186 + ef49327 commit 35f6a29

69 files changed

Lines changed: 213255 additions & 11623 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package-lock.json

Lines changed: 4272 additions & 11304 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/app.tsx

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ interface AppState {
1919
usePlot: number
2020
}
2121

22-
class App extends React.Component<any, AppState> {
22+
class App extends React.Component<Record<string, unknown>, AppState> {
2323
private controlPane: React.RefObject<AllotmentHandle>
2424
private uiStore: UiStore
2525

26-
constructor(props: any) {
26+
constructor(props: Record<string, unknown>) {
2727
super(props)
28-
this.controlPane = React.createRef()
28+
this.controlPane = React.createRef<AllotmentHandle>()
2929
this.state ={
3030
components: [0, 1],
3131
usePlot: 0
@@ -36,7 +36,7 @@ class App extends React.Component<any, AppState> {
3636
}
3737

3838
render(): JSX.Element {
39-
const fitAll = {position: 'absolute' as any, top:0, left:0, bottom: 0, right:0}
39+
const fitAll: React.CSSProperties = {position: 'absolute', top:0, left:0, bottom: 0, right:0}
4040
const stores: StoreProps = {
4141
entryStore,
4242
controlStore,
@@ -57,17 +57,19 @@ class App extends React.Component<any, AppState> {
5757
if (pane === 0) {
5858
return (
5959
<Allotment.Pane key={pane}>
60-
<div style={{position: 'relative', top: 0, left: 0, right: 0}} >
61-
<Tabs
62-
value={''}
63-
onChange={this.changePlot.bind(this)}>
64-
<Tab label="Salary" />
65-
<Tab label="Participation" />
66-
</Tabs>
67-
</div>
68-
<div style={{position: 'relative', top: 0, left: 0, right: 0, height: 'calc(100% - 48px)'}}>
69-
{this.state.usePlot === 0 ? <BoxPlot></BoxPlot> : <BarPlot></BarPlot>}
70-
</div>
60+
<div style={{position: 'relative', top: 0, left: 0, right: 0}} >
61+
<Tabs
62+
value={this.state.usePlot}
63+
onChange={this.changePlot}>
64+
<Tab label="Salary" />
65+
<Tab label="Participation" />
66+
</Tabs>
67+
</div>
68+
<div style={{position: 'relative', top: 0, left: 0, right: 0, height: 'calc(100% - 48px)', width: '100%'}}>
69+
<div style={{width: '100%', height: '100%'}}>
70+
{this.state.usePlot === 0 ? <BoxPlot></BoxPlot> : <BarPlot></BarPlot>}
71+
</div>
72+
</div>
7173
</Allotment.Pane>
7274
)
7375
} else {
@@ -85,18 +87,12 @@ class App extends React.Component<any, AppState> {
8587
)
8688
}
8789

88-
private changePlot(): void {
89-
let showPlot: number
90-
if (this.state.usePlot === 1) {
91-
showPlot = 0
92-
} else {
93-
showPlot = 1
94-
}
95-
this.setState({usePlot: showPlot})
96-
}
90+
private changePlot = (event: React.ChangeEvent<{}>, newValue: number | string) => {
91+
this.setState({usePlot: Number(newValue)});
92+
};
9793

9894
private toggleControls(): void {
99-
if ((this.state as any).components.length === 1) {
95+
if (this.state.components.length === 1) {
10096
this.setState({
10197
components: [0 ,1]
10298
})

src/components/appBar.tsx

Lines changed: 74 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,21 @@ import Loader from 'react-loader-spinner'
1212
export interface MenuAppBarProps extends StoreProps {
1313
menuClicked: () => void
1414
}
15+
16+
interface NetworkState {
17+
since: string
18+
online: boolean
19+
rtt: number
20+
type: string
21+
saveData: boolean
22+
downLink: number
23+
downLinkMax: number
24+
effectiveType: string
25+
}
26+
1527
// https://medium.com/@vivekjoy/usenetwork-create-a-custom-react-hook-to-detect-online-and-offline-network-status-and-get-network-4a2e12c7e58b
1628
// https://v1.mui.com/demos/app-bar/
1729
class MenuAppBar extends React.Component<MenuAppBarProps> {
18-
19-
/*
20-
constructor(props: MenuAppBarProps) {
21-
super(props)
22-
/*const [state, setState] = useState(() => {
23-
return {
24-
since: undefined,
25-
online: navigator.onLine,
26-
...this.getNetworkConnectionInfo(),
27-
}
28-
})
29-
// const info = this.getNetworkConnectionInfo()
30-
//
31-
}
32-
*/
33-
3430

3531
render(): JSX.Element {
3632
// TODO: Info Button explain all relevant aspects to consider the salary which are not matched by the survey..
@@ -53,27 +49,42 @@ class MenuAppBar extends React.Component<MenuAppBarProps> {
5349
}
5450

5551
get loader(): JSX.Element {
56-
const maxChunks = Object.values(CHUNK_COUNT_PER_YEAR)
57-
.reduce((previousValue: number, currentValue: number) => {
58-
return 0 + previousValue + currentValue
59-
})
60-
//
61-
const chunksDownloaded = Object.values(this.props.entryStore!.parsedDataByYear)
62-
.map((resultSetForYear) => resultSetForYear.chunksParsed)
63-
.reduce((previousValue: number, currentValue: number) => {
64-
return 0 + previousValue + currentValue
65-
}, 0)
66-
const loadingPercentage = Math.round(chunksDownloaded / maxChunks * 100)
67-
if (loadingPercentage > 99) {
52+
// If entryStore or controlStore is not available, show no loader
53+
if (!this.props.entryStore || !this.props.controlStore) {
54+
return <div></div>
55+
}
56+
57+
// Get the currently selected year
58+
const selectedYearStr = this.props.controlStore.controlState.selectedYear;
59+
if (!selectedYearStr) {
60+
return <div></div>
61+
}
62+
63+
// Get max chunks for the selected year
64+
const maxChunks = CHUNK_COUNT_PER_YEAR[selectedYearStr] || 0;
65+
if (maxChunks === 0) {
66+
return <div></div>
67+
}
68+
69+
// Get chunks parsed for the selected year
70+
const yearData = this.props.entryStore.parsedDataByYear[parseInt(selectedYearStr, 10)];
71+
const chunksDownloaded = yearData ? yearData.chunksParsed : 0;
72+
73+
// Calculate loading percentage
74+
const loadingPercentage = Math.round((chunksDownloaded / maxChunks) * 100);
75+
76+
// Hide loader when loading is complete
77+
if (loadingPercentage >= 100) {
6878
return <div></div>
6979
}
80+
7081
return (
7182
<div style={{padding: 'auto', position: 'absolute', right: '25px'}}>
72-
<Typography variant='body1'>
73-
<div style={{}}>
83+
<div style={{}}>
84+
<Typography variant='body1'>
7485
{loadingPercentage} %
75-
</div>
76-
</Typography>
86+
</Typography>
87+
</div>
7788
<Loader
7889
type="Audio"
7990
color="#F48024"
@@ -84,13 +95,21 @@ class MenuAppBar extends React.Component<MenuAppBarProps> {
8495
)
8596
}
8697

87-
getNetworkConnectionInfo(): any {
88-
const connection = this.getNetworkConnection()
98+
getNetworkConnectionInfo(): NetworkState {
99+
const defaults: NetworkState = {
100+
since: new Date().toString(),
101+
online: false,
102+
rtt: 0, type: '', saveData: false,
103+
downLink: 0, downLinkMax: 0, effectiveType: '',
104+
}
105+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
106+
const connection: any = this.getNetworkConnection()
89107
if (!connection) {
90-
return {}
108+
return defaults
91109
}
92-
//
93110
return {
111+
since: new Date().toString(),
112+
online: navigator.onLine,
94113
rtt: connection.rtt,
95114
type: connection.type,
96115
saveData: connection.saveData,
@@ -99,38 +118,27 @@ class MenuAppBar extends React.Component<MenuAppBarProps> {
99118
effectiveType: connection.effectiveType,
100119
}
101120
}
102-
103-
useNetwork(): any {
104-
const [state, setState] = useState(() => {
105-
return {
106-
since: undefined,
107-
online: navigator.onLine,
108-
...this.getNetworkConnectionInfo(),
109-
}
110-
})
121+
122+
useNetwork(): NetworkState {
123+
const [state, setState] = useState(this.getNetworkConnectionInfo())
111124
useEffect(() => {
112125
const handleOnline = (): void => {
113-
setState(
114-
(prevState: any): any => ({
115-
...prevState,
116-
online: true,
117-
since: new Date().toString(),
118-
}) as any)
126+
setState((prevState: NetworkState): NetworkState => ({
127+
...prevState,
128+
online: true,
129+
}))
119130
}
120-
const handleOffline = (): any => {
121-
setState(
122-
(prevState: any): any => (
123-
{
124-
...prevState,
125-
online: false,
126-
since: new Date().toString(),
127-
})
128-
)
131+
const handleOffline = (): void => {
132+
setState((prevState: NetworkState): NetworkState => ({
133+
...prevState,
134+
online: false,
135+
}))
129136
}
130-
const handleConnectionChange = (): any => {
131-
setState((prevState: any) => ({
137+
const handleConnectionChange = (_event: Event): void => {
138+
const networkInfo = this.getNetworkConnectionInfo()
139+
setState((prevState: NetworkState) => ({
132140
...prevState,
133-
...this.getNetworkConnectionInfo(),
141+
...networkInfo,
134142
}))
135143
}
136144
window.addEventListener('online', handleOnline)
@@ -146,16 +154,10 @@ class MenuAppBar extends React.Component<MenuAppBarProps> {
146154
return state
147155
}
148156

149-
getNetworkConnection(): NetworkInformation & any {
150-
return (
151-
navigator.connection
152-
// ||
153-
//navigator.mozConnection ||
154-
// navigator.webkitConnection ||
155-
// null
156-
)
157+
getNetworkConnection(): EventTarget {
158+
return null as unknown as EventTarget // navigator.connection!
157159
}
158160

159161
}
160162

161-
export default inject(...injectClause)(observer(MenuAppBar))
163+
export default inject(...injectClause)(observer(MenuAppBar))

src/components/barplot.tsx

Lines changed: 28 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,67 +8,43 @@ class BarPlot extends React.Component<StoreProps> {
88
render(): JSX.Element {
99
return (
1010
<div style={{position: 'absolute', top: 0, bottom: 0, left:0, right: 0, overflow: 'auto'}}>
11-
<Plot
12-
data={this.data}
13-
layout={ {barmode: 'group', width: this.width, height: this.height, title: '', showlegend: false} }
14-
// TODO: Check Layout.template
15-
// TODO: Check Config.static for temporary disable?
16-
/>
11+
<Plot
12+
data={this.data}
13+
layout={{barmode: 'group', showlegend: false}}
14+
style={{width: '100%', height: '100%'}}
15+
/>
1716
</div>
1817
)
1918
}
2019

21-
private get data(): any { // TODO: Plotty Data
22-
const resultList = this.props.entryStore!.parsedDataByYear
23-
const filteredList = this.props.uiStore!.filteredData
20+
private get data(): Array<Record<string, unknown>> { // TODO: Plotty Data
21+
const selectedYearStr = this.props.controlStore!.controlState.selectedYear;
22+
const selectedYearNum = parseInt(selectedYearStr, 10);
2423

25-
const displayYears = this.props.controlStore?.controlState.selectedYears
24+
const resultList = this.props.entryStore!.parsedDataByYear;
25+
const filteredList = this.props.uiStore!.filteredData;
2626

27-
const invalidNumbers = Object.keys(resultList)
28-
.filter(year => displayYears![year as any] === true)
29-
.map(key => resultList[key as any].invalidEntryCount)
27+
// Get the data for the selected year from entryStore.parsedDataByYear (by number key)
28+
const yearEntrySet = resultList[selectedYearNum];
29+
// Get the data for the selected year from uiStore.filteredData (by string key)
30+
const filteredYearList = filteredList[selectedYearNum];
3031

31-
const overallNumbers = Object.keys(resultList)
32-
.filter(year => displayYears![year as any] === true)
33-
.map(key => resultList[key as any].overallEntryCount)
34-
35-
const matchingFilterNumbers = Object.keys(filteredList)
36-
.filter(year => displayYears![year as any] === true)
37-
.map(key => filteredList[key as any].length)
38-
39-
const trace1 = {
40-
x: displayYears,
41-
y: overallNumbers,
42-
name: 'allParticipations',
43-
type: 'bar'
44-
}
45-
46-
const trace2 = {
47-
x: displayYears,
48-
y: invalidNumbers,
49-
name: 'considered invalid',
50-
type: 'bar'
51-
}
52-
53-
const trace3 = {
54-
x: displayYears,
55-
y: matchingFilterNumbers,
56-
name: 'matching filter',
57-
type: 'bar'
32+
// If we don't have data for the selected year, return empty traces?
33+
if (!yearEntrySet || !filteredYearList) {
34+
return [];
5835
}
59-
60-
return [trace3, trace1, trace2]
61-
}
6236

63-
get width(): number {
64-
return window.innerWidth * 0.8 - 50
65-
}
66-
67-
get height(): number {
68-
const appBarHeight = 50
69-
const diagramSelectionHeight = 30
70-
return window.document.documentElement.clientHeight - (appBarHeight + diagramSelectionHeight)
37+
const overallNumbers = [yearEntrySet.overallEntryCount];
38+
const invalidNumbers = [yearEntrySet.invalidEntryCount];
39+
const matchingFilterNumbers = [filteredYearList.length];
40+
41+
const traces: Array<Record<string, unknown>> = [
42+
{ y: matchingFilterNumbers, name: 'matching filter', type: 'bar' },
43+
{ y: overallNumbers, name: 'allParticipations', type: 'bar' },
44+
{ y: invalidNumbers, name: 'considered invalid', type: 'bar' },
45+
];
46+
return traces;
7147
}
7248
}
7349

74-
export default inject(...injectClause)(observer(BarPlot))
50+
export default inject(...injectClause)(observer(BarPlot))

0 commit comments

Comments
 (0)