Select Git revision
TrafficVolumePerNren.tsx
Remco Tukker authored
TrafficVolumePerNren.tsx 4.37 KiB
import React, { useContext } from 'react';
import { Bar } from 'react-chartjs-2';
import { Col, Row } from "react-bootstrap";
import { Chart as ChartJS } from 'chart.js';
import ChartDataLabels from 'chartjs-plugin-datalabels';
import { TrafficVolume } from "../Schema";
import { createTrafficVolumeDataset } from "../helpers/dataconversion";
import DataPage from '../components/DataPage';
import Filter from "../components/graphing/Filter"
import { ExportType, Sections } from '../helpers/constants';
import DownloadDataButton from "../components/DownloadDataButton";
import { FilterSelectionContext } from '../helpers/FilterSelectionProvider';
import DownloadImageChartButton from "../components/DownloadImageChartButton";
import ChartContainer from "../components/graphing/ChartContainer";
import { useData } from '../helpers/useData';
export const chartOptions = {
maintainAspectRatio: false,
layout: {
padding: {
right: 60
}
},
animation: {
duration: 0,
},
plugins: {
legend: {
display: false
}
},
scales: {
x: {
position: "top" as const
},
xBottom: {
grid: {
drawOnChartArea: false
},
afterDataLimits: function (axis) {
const indices = Object.keys(ChartJS.instances)
// initial values should be far outside possible range
let max = -99999999
let min = 99999999
for (const index of indices) {
if (ChartJS.instances[index] && axis.chart.scales.xBottom) {
min = Math.min(ChartJS.instances[index].scales.x.min, min);
max = Math.max(ChartJS.instances[index].scales.x.max, max);
}
}
axis.chart.scales.xBottom.options.min = min;
axis.chart.scales.xBottom.options.max = max;
axis.chart.scales.xBottom.min = min;
axis.chart.scales.xBottom.max = max;
},
},
y: {
ticks: {
autoSkip: false
},
}
},
indexAxis: "y" as const,
};
function TrafficVolumePage() {
const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext);
const { data: trafficVolumeData, years, nrens } = useData<TrafficVolume>('/api/traffic/', setFilterSelection);
const trafficVolumeDataset = createTrafficVolumeDataset(trafficVolumeData);
trafficVolumeDataset.datasets.forEach(dataset => {
dataset.hidden = !filterSelection.selectedYears.includes(parseInt(dataset.label));
});
// remove the datapoints and labels for the nrens that aren't selected
// unfortunately we cannot just hide them because chart.js doesn't want
// to create a stack from a single dataset
trafficVolumeDataset.datasets.forEach(dataset => {
dataset.data = dataset.data.filter((e, i) => {
return filterSelection.selectedNrens.includes(trafficVolumeDataset.labels[i]);
});
});
trafficVolumeDataset.labels = trafficVolumeDataset.labels.filter((e) => filterSelection.selectedNrens.includes(e));
const filterNode = <Filter
filterOptions={{ availableYears: [...years], availableNrens: [...nrens.values()] }}
filterSelection={filterSelection}
setFilterSelection={setFilterSelection}
/>
const numNrens = filterSelection.selectedNrens.length;
const numYears = filterSelection.selectedYears.length;
const heightPerBar = 2; // every added bar should give this much additional height
console.log(trafficVolumeDataset)
// set a minimum height of 20rem, additional years need some more space
const height = numNrens * numYears * heightPerBar + 5;
return (
<DataPage title="Traffic Volume Of NRENs per Year"
description='Total yearly traffic volume in terabyte per NREN'
category={Sections.Network} filter={filterNode}>
<>
<Row>
<DownloadDataButton data={trafficVolumeData} filename="traffic_volume_of_nren_per_year.csv" exportType={ExportType.CSV} />
<DownloadDataButton data={trafficVolumeData} filename="traffic_volume_of_nren_per_year.xlsx" exportType={ExportType.EXCEL} />
</Row>
<DownloadImageChartButton filename="traffic_volume_of_nren_per_year" />
<ChartContainer>
<div className="chart-container" style={{ 'height': `${height}rem` }}>
<Bar
plugins={[ChartDataLabels]}
data={trafficVolumeDataset}
options={chartOptions}
/>
</div>
</ChartContainer>
</>
</DataPage>
);
}
export default TrafficVolumePage;