Source: components/userComponents/monitoredArea/statistics/Statistics.js

import React, { Component } from 'react';
import TableOfTransits from '../statisticsTabs/TableOfTransits';
import FilterComponent from '../filter/FilterComponent';
import {
    fetchMonitoredArea,
    fetchMonitoredAreaList
} from "../../../restmodules/MonitoredAreaRestModule";
import {
    fetchAreaStatistics,
    fetchTransitTimeSeries
} from "../../../restmodules/StatisticsRestModule";
import Tab from "react-bootstrap/es/Tab";
import Tabs from "react-bootstrap/es/Tabs";
import GraphOfTransits from "../graph/ChartOfTransits";
import MapOfTransits from "../statisticsTabs/MapOfTransits";
import RealviewOfTransits from "../statisticsTabs/RealviewOfTransits";
import { withNamespaces } from 'react-i18next';
import { fetchMovementsMinMax } from '../../../restmodules/MovementsRestModule';
import PieGraphOfPasses from "../graph/PieGraphOfPasses";
import LoadEventSum from '../eventSum/LoadEventSum';
import TransitsTimeSeriesChart from '../graph/TransitsTimeSeriesChart';

/**
 * Form for creating new Monitored Area
 * @extends Component
 * @hideconstructor
 */
class Statistics extends Component {

  /**
   * @constructs
   * @param props
   */
    constructor(props) {
        super(props);
        this.state = {
            // id of selected monitored area
            id: undefined,
            // list of all monitored areas
            areas: [],
            // list of transits
            // transits: [],
            // // zones of selected area
            // zones: [],
	          area: undefined,
            aggregatedData: {},
            movementsMinMax: {},
            aggregateMovements: undefined,
            timeSeriesData: {},
            filter: {}
        };
    }

  /**
   *
   */
    componentWillUnmount() {
        clearInterval(this.interval);
    }

  /**
   *
   */
    componentDidMount() {
        //get list of all transits for monitoredArea from server
        this.synchronize(undefined)
    }

  /**
   *
   * @param filter
   */
    synchronize = (filter) => {
        fetchMonitoredAreaList().then(data => this.setState({areas: data}))
            .catch(error => this.setState({areas: [{name: error.toString()}]}));
        if (filter) {
            this.setState({
                filter: filter
            });
            if (filter.since !== undefined && filter.until !== undefined && filter.id !== undefined) {
                this.setState({
                    id: filter.id
                });
                fetchMonitoredArea(filter.id)
	                .then(data => this.setState({
		                area: data
	                }));
                fetchAreaStatistics(filter)
                    .then(data => {
                        this.setState({
                            aggregatedData: data
                        });

                    })
                    .catch(error => this.setState({
	                    aggregatedData: [{name: error.toString()}]
                    }));
                fetchMovementsMinMax(filter)
                .then(data => {
                    this.setState({
                        movementsMinMax: data.minMax,
                        aggregateMovements: data.cond
                    });
                });

                fetchTransitTimeSeries(filter)
                .then(data => {
                    this.setState({
                        timeSeriesData: data
                    })
                });
            }
        }
    };
  /**
   *
   * @param data
   */
    handleFilterChange = data => {
        this.synchronize(data);
    };
  /**
   *
   * @param filter
   */
    handleAutoRefresh = (filter) => {
        this.synchronize(filter);
    };
  /**
   *
   * @param zoneNumber
   * @param zones
   * @returns {*}
   */
    getZoneByZoneNumber = (zoneNumber, zones) => {
        if (zones && zones.length > 0) {
          const zone = zones.find(z => z.zoneNumber === zoneNumber);
          return zone;
        } else {

          return undefined;
        }
    };
  /**
   *
   * @param zoneNumbers
   * @param zones
   * @returns {string}
   */
    getZonesNameSequence = (zoneNumbers, zones) => {
        return zoneNumbers.map(zoneNumber => this.getZoneByZoneNumber(zoneNumber, zones))
        .filter(zone => zone)
        .map(zone => zone.name)
        .toString()
        .split(',')
        .join(' 🡢 ')
    };
  /**
   *
   * @param transits
   * @returns {Array}
   */
    transformData = (transits) => {
        return transits && transits.length > 0 ? transits.map(transit => {
            return {
	              zoneNumbersSequence: transit.zoneNumbersSequence,
                name: this.getZonesNameSequence(transit.zoneNumbersSequence, this.state.aggregatedData.zones),
                count: transit.count
            }
        }).sort((a, b) => b.count - a.count) : [];
    };
  /**
   *
   * @param timeSeries
   * @returns {*}
   */
    transformTimeSeries = (timeSeries) => {
        let data = [];
        let transits = [];
        if (!timeSeries.times) return data;
        timeSeries.transits.map(transit => transits.push(this.arrayToJoinedString(transit.zoneNames)));
        timeSeries.times.map( (time, index) => {
            let chartData = {
                date: Date.parse(time)
            };
            timeSeries.transits.map(transit => {
                chartData[this.arrayToJoinedString(transit.zoneNames)] = transit.counts[index];
            });
            data.push(chartData);
        });
        return {
            chartData: data,
            transits: transits
        };
    };

    arrayToJoinedString = (array) => {
      return array.toString()
      .split(',')
      .join(' 🡢 ');
    };
  /**
   *
   * @param areaStatistics
   * @returns {*}
   */
	transformAreaStatistics = (areaStatistics) => {
		if(areaStatistics && areaStatistics.passes) {
        return {
            passes: areaStatistics.passes.map(pass => {
                return {
	                transits : this.transformData(pass.transits),
	                count : pass.count,
	                zoneNumbersSequence : pass.zoneNumbersSequence,
                  name: this.getZoneNamesFromSequence(pass.zoneNumbersSequence, areaStatistics.zones)
                }
            }),
            transits: areaStatistics.transits,
            zones: areaStatistics.zones
        }
    }
		return undefined;
	};
  /**
   *
   * @param zoneNumbers
   * @param zones
   * @returns {string}
   */
    getZoneNamesFromSequence = (zoneNumbers, zones) => {
        return zoneNumbers.map(zoneNumber => this.findZoneByZoneNumber(zoneNumber, zones))
        .filter(zone => zone)
        .map(zone => zone.name)
        .toString()
        .split(',')
        .join(' 🡢 ')
    };
  /**
   *
   * @param zoneNumber
   * @param zones
   * @returns {*}
   */
    findZoneByZoneNumber = (zoneNumber, zones) => {
        if (zones && zones.length > 0) {
            const zone = zones.find(z => z.zoneNumber === zoneNumber);
            return zone;
        } else {
            console.log("ERROR findZoneByZoneNumber: " + zoneNumber + ": " + JSON.stringify(zones));
            return undefined;
        }
    };

  /**
   *
   * @returns {*}
   */
	render() {
      const { t } = this.props;
        return (
            <div>
                <div className="content-wrapper">
                    <section className="content-header">
                        <h1>
                            {t('monitoredArea.monitoredAreas')}
                            <small>{t('monitoredArea.chooseAreaSetDateAndTimeGetResults')}</small>
                        </h1>

                        <ol className="breadcrumb">
                            <li><a href="/"><i className="fa fa-dashboard"></i> {t('sidebar.dashboard')}</a></li>
                            <li><a href="/MonitoredArea">{t('monitoredArea.monitoredAreas')}</a></li>
                        </ol>

                        <br/>

                        <div className="row">
                            <section className="col-xs-12 col-md-6">
                              <div className="">
                                <FilterComponent areas={this.state.areas}
                                                 defaultValues={this.state.filter}
                                                 onFilterChanged={this.handleFilterChange}
                                                 onAutoRefreshChange={this.handleAutoRefresh}/>
                              </div>

                              <div className="">
                                <LoadEventSum data={this.transformData(this.state.aggregatedData.transits)}/>
                              </div>
                            </section>
                            <section className="col-xs-12 col-md-6">
                              <div>
                                <PieGraphOfPasses passes={this.transformData(this.state.aggregatedData.passes)}/>
                              </div>
                            </section>

                        </div>

                      <div className="row">
                            <div className="col-lg-12">
                                <Tabs
                                  mountOnEnter={true}
                                  unmountOnExit={true}
                                    id="Table of transits">
                                    <Tab eventKey={3} title={t('monitoredArea.mapOfTransits')}>
                                    <MapOfTransits
                                        area={this.state.area}
                                        zones={this.state.zones}
                                        areaStatistics={this.transformAreaStatistics(this.state.aggregatedData)}
                                    />
                                    </Tab>
                                    <Tab eventKey={4} title={t('monitoredArea.cameraViewOfTransits')}>
                                      <RealviewOfTransits
                                        areaId={this.state.id}
                                        zones={this.state.zones}
                                        aggregatedData={this.transformAreaStatistics(this.state.aggregatedData)}
                                        movementsMinMax={this.state.movementsMinMax}
                                        aggregateMovements={this.state.aggregateMovements}
                                        filter={this.state.filter}
                                      />
                                    </Tab>
                                    <Tab eventKey={2} title={t('monitoredArea.chartOfTransits')}>
                                        <GraphOfTransits data={this.transformData(this.state.aggregatedData.transits)}/>
                                    </Tab>
                                    <Tab eventKey={1} title={t('monitoredArea.tableOfTransits')}>
                                        <TableOfTransits data={this.transformData(this.state.aggregatedData.transits)}/>
                                    </Tab>
                                    <Tab eventKey={5} title={t('monitoredArea.transitsTimeSeries')}>
                                        <TransitsTimeSeriesChart
                                          data={this.transformTimeSeries(this.state.timeSeriesData)}
                                        />
                                    </Tab>

                                </Tabs>
                            </div>
                        </div>
                    </section>
                </div>
            </div>

        )
    }
}

export default withNamespaces()(Statistics);