import React, {Component} from 'react'; import './Footer.scss'; import { ChartContainer, ChartRow, Charts, LineChart, MultiBrush, Resizable, styler, YAxis } from "react-timeseries-charts"; import {TimeRange, TimeSeries} from "pondjs"; import backend from "../backend"; import ChoiceField from "../components/fields/ChoiceField"; import {withRouter} from "react-router-dom"; import log from "../log"; import dispatcher from "../dispatcher"; class Footer extends Component { state = { metric: "connections_per_service" }; constructor() { super(); this.disableTimeSeriesChanges = false; this.selectionTimeout = null; } filteredPort = () => { const urlParams = new URLSearchParams(this.props.location.search); return urlParams.get("service_port"); }; componentDidMount() { const filteredPort = this.filteredPort(); this.setState({filteredPort}); this.loadStatistics(this.state.metric, filteredPort).then(() => log.debug("Statistics loaded after mount")); dispatcher.register("connection_updates", payload => { this.setState({ selection: new TimeRange(payload.from, payload.to), }); }); } componentDidUpdate(prevProps, prevState, snapshot) { const filteredPort = this.filteredPort(); if (this.state.filteredPort !== filteredPort) { this.setState({filteredPort}); this.loadStatistics(this.state.metric, filteredPort).then(() => log.debug("Statistics reloaded after filtered port changes")); } } loadStatistics = async (metric, filteredPort) => { const urlParams = new URLSearchParams(); urlParams.set("metric", metric); let services = (await backend.get("/api/services")).json; if (filteredPort && services[filteredPort]) { const service = services[filteredPort]; services = {}; services[filteredPort] = service; } const ports = Object.keys(services); ports.forEach(s => urlParams.append("ports", s)); const metrics = (await backend.get("/api/statistics?" + urlParams)).json; const series = new TimeSeries({ name: "statistics", columns: ["time"].concat(ports), points: metrics.map(m => [new Date(m["range_start"])].concat(ports.map(p => m[metric][p] || 0))) }); this.setState({ metric, series, services, timeRange: series.range(), }); log.debug(`Loaded statistics for metric "${metric}" for services [${ports}]`); }; createStyler = () => { return styler(Object.keys(this.state.services).map(port => { return {key: port, color: this.state.services[port].color, width: 2}; })); }; handleTimeRangeChange = (timeRange) => { if (!this.disableTimeSeriesChanges) { this.setState({timeRange}); } }; handleSelectionChange = (timeRange) => { this.disableTimeSeriesChanges = true; this.setState({selection: timeRange}); if (this.selectionTimeout) { clearTimeout(this.selectionTimeout); } this.selectionTimeout = setTimeout(() => { dispatcher.dispatch("timeline_updates", { from: timeRange.begin(), to: timeRange.end() }); this.selectionTimeout = null; this.disableTimeSeriesChanges = false; }, 1000); }; aggregateSeries = (func) => { const values = this.state.series.columns().map(c => this.state.series[func](c)); return Math[func](...values); }; render() { return ( ); } } export default withRouter(Footer);