import React from 'react'
import PropTypes from 'prop-types'
import formatBytes from 'pretty-bytes'
import formatDate from 'date-fns/format'
import parseDate from 'date-fns/parse'
import formatNumber from './utils/formatNumber'
import formatPercent from './utils/formatPercent'
import { continents, countries } from 'countries-list'
const getCountriesByContinent = (continent) =>
Object.keys(countries).filter(country => countries[country].continent === continent)
const sumKeyValues = (hash, keys) =>
keys.reduce((n, key) => n + (hash[key] || 0), 0)
const sumValues = (hash) =>
Object.keys(hash).reduce((memo, key) => memo + hash[key], 0)
class Stats extends React.Component {
static propTypes = {
data: PropTypes.object
}
state = {
minPackageRequests: 100000,
minCountryRequests: 1000000
}
render() {
const { data } = this.props
if (data == null)
return null
const totals = data.totals
// Summary data
const since = parseDate(totals.since)
const until = parseDate(totals.until)
// Packages
const packageRows = []
Object.keys(totals.requests.package).sort((a, b) => {
return totals.requests.package[b] - totals.requests.package[a]
}).forEach(packageName => {
const requests = totals.requests.package[packageName]
const bandwidth = totals.bandwidth.package[packageName]
if (requests >= this.state.minPackageRequests) {
packageRows.push(
{packageName}
{formatNumber(requests)} ({formatPercent(requests / totals.requests.all)}%)
{bandwidth
? {formatBytes(bandwidth)} ({formatPercent(bandwidth / totals.bandwidth.all)}%)
: -
}
)
}
})
// Protocols
const protocolRows = Object.keys(totals.requests.protocol).sort((a, b) => {
return totals.requests.protocol[b] - totals.requests.protocol[a]
}).map(protocol => {
const requests = totals.requests.protocol[protocol]
return (
{protocol}
{formatNumber(requests)} ({formatPercent(requests / sumValues(totals.requests.protocol))}%)
)
})
// Regions
const regionRows = []
const continentsData = Object.keys(continents).reduce((memo, continent) => {
const localCountries = getCountriesByContinent(continent)
memo[continent] = {
countries: localCountries,
requests: sumKeyValues(totals.requests.country, localCountries),
bandwidth: sumKeyValues(totals.bandwidth.country, localCountries)
}
return memo
}, {})
const topContinents = Object.keys(continentsData).sort((a, b) => {
return continentsData[b].requests - continentsData[a].requests
})
topContinents.forEach(continent => {
const continentName = continents[continent]
const continentData = continentsData[continent]
if (continentData.requests > this.state.minCountryRequests && continentData.bandwidth !== 0) {
regionRows.push(
{continentName}
{formatNumber(continentData.requests)} ({formatPercent(continentData.requests / totals.requests.all)}%)
{formatBytes(continentData.bandwidth)} ({formatPercent(continentData.bandwidth / totals.bandwidth.all)}%)
)
const topCountries = continentData.countries.sort((a, b) => {
return totals.requests.country[b] - totals.requests.country[a]
})
topCountries.forEach(country => {
const countryRequests = totals.requests.country[country]
const countryBandwidth = totals.bandwidth.country[country]
if (countryRequests > this.state.minCountryRequests) {
regionRows.push(
{countries[country].name}
{formatNumber(countryRequests)} ({formatPercent(countryRequests / totals.requests.all)}%)
{formatBytes(countryBandwidth)} ({formatPercent(countryBandwidth / totals.bandwidth.all)}%)
)
}
})
}
})
return (
From {formatDate(since, 'MMM D')} to {formatDate(until, 'MMM D')} unpkg served {formatNumber(totals.requests.all)} requests and a total of {formatBytes(totals.bandwidth.all)} of data to {formatNumber(totals.uniques.all)} unique visitors, {formatPercent(totals.requests.cached / totals.requests.all, 0)}% of which were served from the cache.
Packages
Include only packages that received at least this.setState({ minPackageRequests: parseInt(event.target.value, 10) })}
>
0
1,000
10,000
100,000
1,000,000
requests.
Package
Requests (% of total)
Bandwidth (% of total)
{packageRows}
Protocols
Protocol
Requests (% of total)
{protocolRows}
Regions
Include only countries that made at least this.setState({ minCountryRequests: parseInt(event.target.value, 10) })}
>
0
100,000
1,000,000
10,000,000
100,000,000
requests.
Region
Requests (% of total)
Bandwidth (% of total)
{regionRows}
)
}
}
export default Stats