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);