Source

components/analytics/peakMonth/peakMonth.js

import React, { Component } from 'react'
import * as SwimFormulas from '../../../constants/graphFunctions/graphFunctions';
import { Bar } from 'react-chartjs-2';
import ReactTable from '../../../components/reactTable/reactTable';
import Container from 'react-bootstrap/Container';
import { defaults } from 'react-chartjs-2';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import { MONTH_NAMES } from '../../../constants/swimmingConstants/swimmingConstants';
import PropTypes from 'prop-types';


/**
 * Peak Month is responsible for handling the logic and displaying the graph that either,
 * Shows for a specific event the months over the year where best times were swam, or over all events the subcomponents of months over the year. 
 * @component
 * @example
 * const swimmerData = [
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37370,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "23.54",
    "__EMPTY_8": 23.54,
    "FINA 2019": 637,
    "__EMPTY_9": 1,
    "__EMPTY_10": 43813,
    "__EMPTY_11": "Toronto",
    "__EMPTY_12": "Ontario Junior International",
    "__EMPTY_13": "Oakville Aquatic Club"
  },
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37277,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "24.31",
    "__EMPTY_8": 24.31,
    "FINA 2019": 578,
    "__EMPTY_9": 2,
    "__EMPTY_10": 43792,
    "__EMPTY_11": "London",
    "__EMPTY_12": "LAC - Nothers Fall Invitational",
    "__EMPTY_13": "Oakville Aquatic Club"
  }
];
    * const allSwimmerData = [
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37370,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "23.54",
    "__EMPTY_8": 23.54,
    "FINA 2019": 637,
    "__EMPTY_9": 1,
    "__EMPTY_10": 43813,
    "__EMPTY_11": "Toronto",
    "__EMPTY_12": "Ontario Junior International",
    "__EMPTY_13": "Oakville Aquatic Club"
  },
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37277,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "24.31",
    "__EMPTY_8": 24.31,
    "FINA 2019": 578,
    "__EMPTY_9": 2,
    "__EMPTY_10": 43792,
    "__EMPTY_11": "London",
    "__EMPTY_12": "LAC - Nothers Fall Invitational",
    "__EMPTY_13": "Oakville Aquatic Club"
  },
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37370,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "23.54",
    "__EMPTY_8": 23.54,
    "FINA 2019": 637,
    "__EMPTY_9": 1,
    "__EMPTY_10": 43813,
    "__EMPTY_11": "Toronto",
    "__EMPTY_12": "Ontario Junior International",
    "__EMPTY_13": "Oakville Aquatic Club"
  },
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37277,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "24.31",
    "__EMPTY_8": 24.31,
    "FINA 2019": 578,
    "__EMPTY_9": 2,
    "__EMPTY_10": 43792,
    "__EMPTY_11": "London",
    "__EMPTY_12": "LAC - Nothers Fall Invitational",
    "__EMPTY_13": "Oakville Aquatic Club"
  },
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37370,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "23.54",
    "__EMPTY_8": 23.54,
    "FINA 2019": 637,
    "__EMPTY_9": 1,
    "__EMPTY_10": 43813,
    "__EMPTY_11": "Toronto",
    "__EMPTY_12": "Ontario Junior International",
    "__EMPTY_13": "Oakville Aquatic Club"
  },
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37277,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "24.31",
    "__EMPTY_8": 24.31,
    "FINA 2019": 578,
    "__EMPTY_9": 2,
    "__EMPTY_10": 43792,
    "__EMPTY_11": "London",
    "__EMPTY_12": "LAC - Nothers Fall Invitational",
    "__EMPTY_13": "Oakville Aquatic Club"
  }
]
    * const allSwimmerDataSub = [[
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37370,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "23.54",
    "__EMPTY_8": 23.54,
    "FINA 2019": 637,
    "__EMPTY_9": 1,
    "__EMPTY_10": 43813,
    "__EMPTY_11": "Toronto",
    "__EMPTY_12": "Ontario Junior International",
    "__EMPTY_13": "Oakville Aquatic Club"
  },
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37277,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "24.31",
    "__EMPTY_8": 24.31,
    "FINA 2019": 578,
    "__EMPTY_9": 2,
    "__EMPTY_10": 43792,
    "__EMPTY_11": "London",
    "__EMPTY_12": "LAC - Nothers Fall Invitational",
    "__EMPTY_13": "Oakville Aquatic Club"
  }
],
[
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37370,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "23.54",
    "__EMPTY_8": 23.54,
    "FINA 2019": 637,
    "__EMPTY_9": 1,
    "__EMPTY_10": 43813,
    "__EMPTY_11": "Toronto",
    "__EMPTY_12": "Ontario Junior International",
    "__EMPTY_13": "Oakville Aquatic Club"
  },
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37277,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "24.31",
    "__EMPTY_8": 24.31,
    "FINA 2019": 578,
    "__EMPTY_9": 2,
    "__EMPTY_10": 43792,
    "__EMPTY_11": "London",
    "__EMPTY_12": "LAC - Nothers Fall Invitational",
    "__EMPTY_13": "Oakville Aquatic Club"
  }
],
[
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37370,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "23.54",
    "__EMPTY_8": 23.54,
    "FINA 2019": 637,
    "__EMPTY_9": 1,
    "__EMPTY_10": 43813,
    "__EMPTY_11": "Toronto",
    "__EMPTY_12": "Ontario Junior International",
    "__EMPTY_13": "Oakville Aquatic Club"
  },
  {
    "Oakville Aquatic Club, Season 2020, Open": "SCM",
    "__EMPTY": "M",
    "__EMPTY_1": 50,
    "__EMPTY_2": "Fr",
    "__EMPTY_3": "**********",
    "__EMPTY_4": 37277,
    "__EMPTY_5": "CAN",
    "__EMPTY_6": "OAK",
    "__EMPTY_7": "24.31",
    "__EMPTY_8": 24.31,
    "FINA 2019": 578,
    "__EMPTY_9": 2,
    "__EMPTY_10": 43792,
    "__EMPTY_11": "London",
    "__EMPTY_12": "LAC - Nothers Fall Invitational",
    "__EMPTY_13": "Oakville Aquatic Club"
  }]
]

 * const event = '50m Fr';
 * return (
 *  <PeakMonth swimmerData={swimmerData} allSwimmerData={allSwimmerData} allSwimmerDataSubComponents={allSwimmerDataSub} event={event} />
 * )
 */

class PeakMonth extends Component {

    render() {
        let swimmerData = this.props.swimmerData;
        let allSwimmerDataSubComponents = this.props.allSwimmerDataSubComponents;
        let event = [];
        let months = [];
        let numSwimmers = [];
        let monthsPercent = [];
        let allEvents = [];
        let eventOptions = [];
        let allEventsOptions = [];
        let colorArray;


        if (allSwimmerDataSubComponents === undefined || allSwimmerDataSubComponents.length === 0) {
            try {
                months = SwimFormulas.peakDistribution(swimmerData);
                numSwimmers = months.reduce((a, b) => a + b);
                monthsPercent = [...months].map(el => Math.floor((el / numSwimmers) * 100));

                console.log(monthsPercent)
                // * Data that will be passed to the Linegraph Component
                event = {
                    labels: MONTH_NAMES,
                    datasets: [{
                        label: this.props.event,
                        backgroundColor: 'rgb(255, 99, 132)',
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: months,
                        yAxisID: 'left-y-axis'
                    },
                    {
                        data: monthsPercent,
                        label: '% Occurrence',
                        backgroundColor: 'rgb(0,170,216)',
                        yAxisID: 'right-y-axis'
                    }]
                }
            } catch (e) {
                console.log('Error: ' + e);
            }
        } else {
            try {
                // * Hard Coding of the events needed in order to stack the bars and events appropriately and match to a color
                let fiftyFr = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[0]);
                let oneHundredFr = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[1]);
                let twoHundredFr = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[2]);
                let fourHundredFr = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[3]);
                let eightHundredFr = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[4]);
                let fifteenHundredFr = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[5]);
                let fiftyBk = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[6]);
                let oneHundredBk = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[7]);
                let twoHundredBk = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[8]);
                let fiftyBr = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[9]);
                let oneHundredBr = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[10]);
                let twoHundredBr = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[11]);
                let fiftyBu = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[12]);
                let oneHundredBu = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[13]);
                let twoHundredBu = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[14]);
                let oneHundredMe = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[15]);
                let twoHundredMe = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[16]);
                let fourHundredMe = SwimFormulas.peakDistribution(allSwimmerDataSubComponents[17]);

                // * Creates The Colors for the PieChart depending on how many distinct meets there are
                colorArray = SwimFormulas.colorArray(18)
                allEvents = {
                    labels: ['September', 'October', 'November', 'December', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',],
                    datasets: [{
                        stack: '2',
                        label: '50 Fr',
                        backgroundColor: colorArray[0],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: fiftyFr,
                    },
                    {
                        stack: '2',
                        label: '100 Fr',
                        backgroundColor: colorArray[1],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: oneHundredFr,
                    }
                        ,
                    {
                        stack: '2',
                        label: '200 Fr',
                        backgroundColor: colorArray[2],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: twoHundredFr,
                    }
                        ,
                    {
                        stack: '2',
                        label: '400 Fr',
                        backgroundColor: colorArray[3],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: fourHundredFr,
                    }
                        ,
                    {
                        stack: '2',
                        label: '800 Fr',
                        backgroundColor: colorArray[4],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: eightHundredFr,
                    }
                        ,
                    {
                        stack: '2',
                        label: '1500 Fr',
                        backgroundColor: colorArray[5],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: fifteenHundredFr,
                    }
                        ,
                    {
                        stack: '2',
                        label: '50 Bk',
                        backgroundColor: colorArray[6],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: fiftyBk,
                    }

                        ,
                    {
                        stack: '2',
                        label: '100 Bk',
                        backgroundColor: colorArray[7],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: oneHundredBk,
                    },
                    {
                        stack: '2',
                        label: '200 Bk',
                        backgroundColor: colorArray[8],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: twoHundredBk,
                    },

                    {
                        stack: '2',
                        label: '50 Br',
                        backgroundColor: colorArray[9],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: fiftyBr,
                    },
                    {
                        stack: '2',
                        label: '100 Br',
                        backgroundColor: colorArray[10],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: oneHundredBr,
                    },
                    {
                        stack: '2',
                        label: '200 Br',
                        backgroundColor: colorArray[11],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: twoHundredBr,
                    },
                    {
                        stack: '2',
                        label: '50 Bu',
                        backgroundColor: colorArray[12],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: fiftyBu,
                    },

                    {
                        stack: '2',
                        label: '100 Bu',
                        backgroundColor: colorArray[13],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: oneHundredBu
                    }

                        ,
                    {
                        stack: '2',
                        label: '200 Bu',
                        backgroundColor: colorArray[16],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: twoHundredBu,
                    },

                    {
                        stack: '2',
                        label: '100 Me',
                        backgroundColor: colorArray[14],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: oneHundredMe,
                    },

                    {
                        stack: '2',
                        label: '200 Me',
                        backgroundColor: colorArray[15],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: twoHundredMe,
                    }

                        ,
                    {
                        stack: '2',
                        label: '400 Me',
                        backgroundColor: colorArray[16],
                        pointBackgroundColor: ['rgb(255, 99, 132)'],
                        borderColor: 'rgb(255, 99, 132)',
                        fill: true,
                        data: fourHundredMe,
                    }
                    ]
                }

            } catch (error) {
                console.log('Error: ' + error + ' unable data graph data')
            }
        }
        // * Options for the selected events graph
        eventOptions = {
            tooltips: {
                callbacks: {
                    // * Updates the Tooltips (Graph Points) with the Name,Time
                    label: (tooltipItem, d) => {
                        let labelArr = [];
                        if (tooltipItem.datasetIndex === 1) {
                            labelArr.push(monthPercent[tooltipItem.index] + '%')
                        } else {
                            labelArr.push('PLACE         SWIMMER                  TIME')
                            // * Label Array is used to create multiple labels inside of data element in graph.
                            // * Index needs to be shifted to match the correct data. TODO Need to see if I can standardize data and index
                            let index = tooltipItem.index + 8;
                            if (index > 11) {
                                index -= 12;
                            }
                            // * Converts Excel data to usable date then filters if it matches the correct month
                            let swimmers = swimmerData.filter(el => new Date(Math.floor(el.__EMPTY_10 - (25567 + 2)) * 86400 * 1000).getMonth() === index).sort();

                            swimmers.map(el => {
                                el.__EMPTY_9 = (el.__EMPTY_9).toString().padEnd(15, ' ');
                                el.__EMPTY_3 = (el.__EMPTY_3.split(', ').map(el => el.charAt(0).toUpperCase() + el.slice(1).toLowerCase()).join(', ')).toString().padEnd(25, ' ');
                                el.__EMPTY_7 = (el.__EMPTY_7).toString().padEnd(15, ' ');
                                return el;
                            })
                            swimmers.forEach(el =>
                                labelArr.push(el.__EMPTY_9 + el.__EMPTY_3 + el.__EMPTY_7 + new Date(Math.floor(el.__EMPTY_10 - (25567 + 2)) * 86400 * 1000).toDateString().substring(4))
                            )
                        }
                        return labelArr;
                    },
                    bodyFontSize: 10,
                }
            },
            scales: {
                yAxes: [{
                    id: 'left-y-axis',
                    type: 'linear',
                    position: 'left',
                    scaleLabel: {
                        display: true,
                        labelString: 'Number Of Occurences'
                    }
                },
                {
                    ticks: {
                        // Include a dollar sign in the ticks
                        callback: function (value, index, values) {
                            return value + '%';
                        },
                        maxTicksLimit: 100
                    },
                    id: 'right-y-axis',
                    type: 'linear',
                    position: 'right',
                    scaleLabel: {
                        display: true,
                        labelString: 'Percentage Of Occurences'
                    }
                },

                ]
            }
        }
        // * Options for the all events graph 
        allEventsOptions = {
            scales: {
                xAxes: [
                    {
                        stacked: true,
                    },
                ],
                yAxes: [
                    {
                        stacked: true,
                    },
                ],
            }
        }

        // * If a specific event was selected it will only return the specific month distribution
        // * Otherwise it returns all events on as a bargraph with the subcomponents
        let selectedEvents;

        // * Creates the arrays that allow the React table for the distributions
        let meetKeys = [
            '__EMPTY_10',
            '__EMPTY_14',
            '__EMPTY_18'
        ];
        let monthName = [...MONTH_NAMES];
        let monthNum = [...months];
        let monthPercent = [...monthsPercent];
        let monthTable = [];

        months.forEach((month, index) => monthTable.push(Object({ '__EMPTY_10': monthName[index], '__EMPTY_14': monthNum[index], '__EMPTY_18': monthPercent[index] })))
        monthTable = monthTable.filter(el => el.__EMPTY_14 !== 0);

        if (allSwimmerDataSubComponents === undefined || allSwimmerDataSubComponents.length === 0) {
            selectedEvents = (
                <Row className="justify-content-md-center">
                    <Col className="mt-1" lg={9} xs={12}>
                        <div>
                            <h6 className="text-center">{this.props.event + ': Month of Best Time'} </h6>
                        </div>
                        <Bar name="Selected Events Best time over months chart" data={event} options={eventOptions} height={175} redraw />
                    </Col>
                    <Col lg={3} xs={12}>
                        <ReactTable tableData={monthTable} allowedKeys={meetKeys} />
                    </Col>
                </Row>
            )
        } else {
            selectedEvents = (
                <Row className="justify-content-md-center">
                    <Col className="mt-1" md={10} xs={12}>
                        <div>
                            <h6 className="text-center">{'All Events: (For selected age group and gender)'} </h6>
                        </div>
                        <Bar name="All Events Best time over months chart" data={allEvents} options={allEventsOptions} height={175} redraw />
                    </Col>
                </Row>

            )
        }

        return (
            <div>
                <Container fluid className="mt-1">
                    <Row>
                        <Col className="text-center"> <b><h4 className="formTitle">Distribution Of Best Times Over the Year  </h4></b> </Col>
                    </Row>
                    {selectedEvents}
                </Container>
            </div>
        )
    }
}

PeakMonth.propTypes = {
    /**
     *  swimmerData is an Array of Swimmer Objects from a specifc Sheet (aka. Specific event, 50m Fr, 100m Bk)
     */
    swimmerData: PropTypes.arrayOf(PropTypes.object),
    /**
     *  allSwimmerData is an Array of All the Swimmer Objects from all Sheets (aka. All Events)
     */
    allSwimmerData: PropTypes.arrayOf(PropTypes.object),
    /**
     * allSwimmerDataSubComponents is an Array of all the Sheets as SubComponents 
     */
    allSwimmerDataSubComponents: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.object)),
    /**
     *  Event is a string passed of the event name (ex. 50m Fr, 100m Bk)
     */
    event: PropTypes.string
}
export default PeakMonth;