From 7d5516e75072729fa573205513fc45874d40e66d Mon Sep 17 00:00:00 2001 From: Bjarke Madsen <bjarke@nordu.net> Date: Tue, 5 Dec 2023 16:52:10 +0100 Subject: [PATCH] Update position of buttons and add to all pages --- .../src/components/DataPage.tsx | 12 ++- .../src/components/DownloadContainer.tsx | 15 ++++ .../components/DownloadImageChartButton.tsx | 4 +- compendium-frontend/src/main.scss | 24 +++--- compendium-frontend/src/pages/Budget.tsx | 14 +--- .../src/pages/ChargingStructure.tsx | 78 +++++++++---------- .../src/pages/ConnectedInstitutionsURLs.tsx | 42 +++++----- .../src/pages/ConnectedUser.tsx | 48 ++++++------ compendium-frontend/src/pages/ECProjects.tsx | 40 ++++------ .../src/pages/FundingSource.tsx | 43 +++++----- .../src/pages/ParentOrganisation.tsx | 40 ++++------ compendium-frontend/src/pages/Policy.tsx | 40 +++++----- compendium-frontend/src/pages/Services.tsx | 76 +++++++++--------- compendium-frontend/src/pages/StaffGraph.tsx | 50 +++++------- .../src/pages/SubOrganisation.tsx | 38 ++++----- .../src/pages/TrafficVolumePerNren.tsx | 33 +++----- 16 files changed, 282 insertions(+), 315 deletions(-) create mode 100644 compendium-frontend/src/components/DownloadContainer.tsx diff --git a/compendium-frontend/src/components/DataPage.tsx b/compendium-frontend/src/components/DataPage.tsx index deb30a5e..5a23cf90 100644 --- a/compendium-frontend/src/components/DataPage.tsx +++ b/compendium-frontend/src/components/DataPage.tsx @@ -12,6 +12,8 @@ import { usePreview } from "../helpers/usePreview"; import NetworkSidebar from "./NetworkSidebar"; import ConnectedUsersSidebar from "./ConnectedUsersSidebar"; import ServicesSidebar from "./ServicesSidebar"; +import DownloadContainer from "../components/DownloadContainer"; + ChartJS.defaults.font.size = 16; ChartJS.defaults.font.family = 'Open Sans'; @@ -22,10 +24,12 @@ interface inputProps { description?: string, filter: ReactElement, children: ReactElement, - category: Sections + category: Sections, + data?: any, + filename?: string, } -function DataPage({ title, description, filter, children, category }: inputProps): ReactElement { +function DataPage({ title, description, filter, children, category, data, filename }: inputProps): ReactElement { const preview = usePreview(); const locationWithoutPreview = window.location.origin + window.location.pathname; @@ -48,6 +52,10 @@ function DataPage({ title, description, filter, children, category }: inputProps <Row> <p className="p-md-4">{description}</p> </Row> + {data && filename && + <Row align="right" style={{position: 'relative'}}> + <DownloadContainer data={data} filename={filename} /> + </Row>} <Row> {filter} </Row> diff --git a/compendium-frontend/src/components/DownloadContainer.tsx b/compendium-frontend/src/components/DownloadContainer.tsx new file mode 100644 index 00000000..e9770573 --- /dev/null +++ b/compendium-frontend/src/components/DownloadContainer.tsx @@ -0,0 +1,15 @@ +import React from "react"; +import DownloadDataButton from "./DownloadDataButton"; +import DownloadImageChartButton from "./DownloadImageChartButton"; + +import { ExportType } from "../helpers/constants"; + +const DownloadContainer = ({ data, filename }) => { + return <div className="downloadcontainer"> + <DownloadDataButton data={data} filename={`${filename}.csv`} exportType={ExportType.CSV} /> + <DownloadDataButton data={data} filename={`${filename}.xlsx`} exportType={ExportType.EXCEL} /> + <DownloadImageChartButton filename={filename} /> + </div> +} + +export default DownloadContainer; \ No newline at end of file diff --git a/compendium-frontend/src/components/DownloadImageChartButton.tsx b/compendium-frontend/src/components/DownloadImageChartButton.tsx index 27cc1ced..9819d722 100644 --- a/compendium-frontend/src/components/DownloadImageChartButton.tsx +++ b/compendium-frontend/src/components/DownloadImageChartButton.tsx @@ -79,7 +79,7 @@ const DownloadImageChartButton: React.FC<DownloadImageChartProps> = ({ filename <button className={`downloadbutton downloadimage`} onClick={toggleDropdown}> IMAGE <FaDownload /> </button> - <div className={`image-options ${isOpen ? 'open' : ''}`}> + {isOpen && <div className={`image-options`}> <div className={`imageoption downloadpng`} onClick={() => downloadChartAsImage(ImageType.PNG)}> <span>PNG</span> </div> @@ -89,7 +89,7 @@ const DownloadImageChartButton: React.FC<DownloadImageChartProps> = ({ filename <div className={`imageoption downloadsvg`} onClick={() => downloadChartAsImage(ImageType.SVG)}> <span>SVG</span> </div> - </div> + </div>} </div> ); } diff --git a/compendium-frontend/src/main.scss b/compendium-frontend/src/main.scss index 9b5cbd4b..5f4ed77a 100644 --- a/compendium-frontend/src/main.scss +++ b/compendium-frontend/src/main.scss @@ -111,7 +111,7 @@ .downloadimage { background-color: deepskyblue; - width: 100%; + width: 10rem; } .downloadcsv { @@ -124,17 +124,14 @@ .image-dropdown { width: 10rem; -} - -.image-options.open { - display: flex; + display: inline-block; } .image-options { background-color: white; position: absolute; - width: 8.5rem; - display: none; + width: 10rem; + display: flex; flex-direction: column; border: deepskyblue 1px solid; z-index: 10; // make sure it's on top of everything else @@ -146,14 +143,23 @@ color: $dark-teal; font-weight: bold; } + // add margin left to text within imageoption -.imageoption > span { +.imageoption>span { margin-left: 0.25rem; - } + .imageoption::after { // have a line under each option content: ""; display: block; border-bottom: grey 1px solid; +} + +.downloadcontainer { + margin-bottom: 2rem; +} + +.downloadcontainer>* { + margin-right: .75rem; } \ No newline at end of file diff --git a/compendium-frontend/src/pages/Budget.tsx b/compendium-frontend/src/pages/Budget.tsx index 52969552..f65f0166 100644 --- a/compendium-frontend/src/pages/Budget.tsx +++ b/compendium-frontend/src/pages/Budget.tsx @@ -18,10 +18,8 @@ import { Budget } from "../Schema"; import { createBudgetDataset } 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 { Sections } from '../helpers/constants'; import { FilterSelectionContext } from '../helpers/FilterSelectionProvider'; -import DownloadImageChartButton from "../components/DownloadImageChartButton"; import ChartContainer from "../components/graphing/ChartContainer"; import { useData } from '../helpers/useData'; @@ -99,15 +97,11 @@ function BudgetPage(): ReactElement { <DataPage title="Budget of NRENs per Year" description='The graph shows the NRENs budget capita (in Million €) per year. On hovering over the graphs data points will give NRENs budget share in that year. This graph can be used to compare, selecting multiple NRENs to see the - fluctuation of budget over years and with other NRENs.' category={Sections.Organisation} filter={filterNode}> + fluctuation of budget over years and with other NRENs.' category={Sections.Organisation} filter={filterNode} + data={budgetResponse} filename="budget_data"> <> <Row> - <DownloadDataButton data={budgetResponse} filename="budget_data.csv" exportType={ExportType.CSV} /> - <DownloadDataButton data={budgetResponse} filename="budget_data.xlsx" - exportType={ExportType.EXCEL} /> - </Row> - <Row> - <DownloadImageChartButton filename="budget_data" /> + <ChartContainer> <Line data={budgetData} options={options} /> </ChartContainer> diff --git a/compendium-frontend/src/pages/ChargingStructure.tsx b/compendium-frontend/src/pages/ChargingStructure.tsx index 13b1ec55..1c002ba4 100644 --- a/compendium-frontend/src/pages/ChargingStructure.tsx +++ b/compendium-frontend/src/pages/ChargingStructure.tsx @@ -1,21 +1,19 @@ import React, { useContext } from "react"; -import {Row, Table} from "react-bootstrap"; +import { Table } from "react-bootstrap"; import { ChargingStructure } from "../Schema"; import { createMatrixDataLookup } from "../helpers/dataconversion"; import ColorPill from "../components/ColorPill"; import DataPage from "../components/DataPage"; import Filter from "../components/graphing/Filter"; -import {ExportType, Sections} from "../helpers/constants"; -import DownloadDataButton from "../components/DownloadDataButton"; +import { Sections } from "../helpers/constants"; import { FilterSelectionContext } from "../helpers/FilterSelectionProvider"; -import DownloadImageChartButton from "../components/DownloadImageChartButton"; import ChartContainer from "../components/graphing/ChartContainer"; import { useData } from "../helpers/useData"; function ChargingStructurePage(): React.ReactElement { - const {filterSelection, setFilterSelection } = useContext(FilterSelectionContext); - const {data: chargingStructureData, years, nrens} = useData<ChargingStructure>('/api/charging/', setFilterSelection); + const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext); + const { data: chargingStructureData, years, nrens } = useData<ChargingStructure>('/api/charging/', setFilterSelection); const selectedData = (chargingStructureData).filter(data => filterSelection.selectedYears.includes(data.year) && filterSelection.selectedNrens.includes(data.nren) @@ -34,52 +32,48 @@ function ChargingStructurePage(): React.ReactElement { return ( <DataPage title="Charging Mechanism of NRENs per Year" - description="The charging structure is the way in which NRENs charge their customers for the services they provide. + description="The charging structure is the way in which NRENs charge their customers for the services they provide. The charging structure can be based on a flat fee, usage based fee, a combination of both, or no direct charge. By selecting multiple years and NRENs, the table can be used to compare the charging structure of NRENs." - category={Sections.Organisation} filter={filterNode}> + category={Sections.Organisation} filter={filterNode} + data={chargingStructureData} filename="charging_mechanism_of_nrens_per_year"> <> - <Row> - <DownloadDataButton data={chargingStructureData} filename="charging_mechanism_of_nrens_per_year.csv" exportType={ExportType.CSV}/> - <DownloadDataButton data={chargingStructureData} filename="charging_mechanism_of_nrens_per_year.xlsx" exportType={ExportType.EXCEL} /> - </Row> - <DownloadImageChartButton filename="charging_mechanism_of_nrens_per_year"/> <ChartContainer> <Table className="charging-struct-table" striped bordered responsive> <colgroup> - <col span={1} style={{width: "10%"}}/> - <col span={1} style={{width: "18%"}}/> - <col span={1} style={{width: "18%"}}/> - <col span={1} style={{width: "18%"}}/> - <col span={1} style={{width: "18%"}}/> - <col span={1} style={{width: "18%"}}/> + <col span={1} style={{ width: "10%" }} /> + <col span={1} style={{ width: "18%" }} /> + <col span={1} style={{ width: "18%" }} /> + <col span={1} style={{ width: "18%" }} /> + <col span={1} style={{ width: "18%" }} /> + <col span={1} style={{ width: "18%" }} /> </colgroup> <thead> - <tr> - <th></th> - <th>Flat fee based on bandwidth</th> - <th>Usage based fee</th> - <th>Combination flat fee & usage basedfee</th> - <th>No Direct Charge</th> - <th>Other</th> - </tr> + <tr> + <th></th> + <th>Flat fee based on bandwidth</th> + <th>Usage based fee</th> + <th>Combination flat fee & usage basedfee</th> + <th>No Direct Charge</th> + <th>Other</th> + </tr> </thead> <tbody> - {Array.from(dataLookup.entries()).map(([nren, nrenMap]) => ( - <tr key={nren}> - <td>{nren}</td> - {["flat_fee", "usage_based_fee", "combination", "no_charge", "other"].map(column_key => ( - <td key={column_key}> - { nrenMap.has(column_key) && - showYears.map(year => { - const chargingYears = nrenMap.get(column_key)!; - return <ColorPill key={year} year={year} active={chargingYears.has(year)} />; - }) - } - </td> - ))} - </tr> - ))} + {Array.from(dataLookup.entries()).map(([nren, nrenMap]) => ( + <tr key={nren}> + <td>{nren}</td> + {["flat_fee", "usage_based_fee", "combination", "no_charge", "other"].map(column_key => ( + <td key={column_key}> + {nrenMap.has(column_key) && + showYears.map(year => { + const chargingYears = nrenMap.get(column_key)!; + return <ColorPill key={year} year={year} active={chargingYears.has(year)} />; + }) + } + </td> + ))} + </tr> + ))} </tbody> </Table> </ChartContainer> diff --git a/compendium-frontend/src/pages/ConnectedInstitutionsURLs.tsx b/compendium-frontend/src/pages/ConnectedInstitutionsURLs.tsx index 1629a226..df85e13f 100644 --- a/compendium-frontend/src/pages/ConnectedInstitutionsURLs.tsx +++ b/compendium-frontend/src/pages/ConnectedInstitutionsURLs.tsx @@ -1,13 +1,14 @@ -import React, { useContext} from 'react'; +import React, { useContext } from 'react'; import { Table } from "react-bootstrap"; -import {ConnectedInstitutionURLs} from "../Schema"; +import { ConnectedInstitutionURLs } from "../Schema"; import { createDataLookup } from '../helpers/dataconversion'; import DataPage from '../components/DataPage'; import Filter from "../components/graphing/Filter"; import { Sections } from '../helpers/constants'; import { FilterSelectionContext } from '../helpers/FilterSelectionProvider'; -import {useData} from "../helpers/useData"; +import { useData } from "../helpers/useData"; +import ChartContainer from '../components/graphing/ChartContainer'; function getJSXFromMap(data: Map<string, Map<number, ConnectedInstitutionURLs>>) { return Array.from(data.entries()).map(([nren, nrenMap]) => { @@ -31,8 +32,8 @@ function getJSXFromMap(data: Map<string, Map<number, ConnectedInstitutionURLs>>) } function ConnectedInstitutionsURLsPage() { - const {filterSelection, setFilterSelection } = useContext(FilterSelectionContext); - const {data: institutionData, years, nrens} = useData<ConnectedInstitutionURLs>('/api/institutions-urls/', setFilterSelection); + const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext); + const { data: institutionData, years, nrens } = useData<ConnectedInstitutionURLs>('/api/institutions-urls/', setFilterSelection); const selectedData = institutionData.filter(institution => @@ -49,20 +50,23 @@ function ConnectedInstitutionsURLsPage() { return ( <DataPage title="Connected Institutions URLs" - description='The table shows URLs of the institutions connected to NRENs. You can filter the data by years and by NRENs.' - category={Sections.ConnectedUsers} filter={filterNode}> - <Table borderless className='compendium-table'> - <thead> - <tr> - <th className='nren-column'>NREN</th> - <th className='year-column'>Year</th> - <th className='blue-column'>URLs</th> - </tr> - </thead> - <tbody> - {getJSXFromMap(institutionDataByYear)} - </tbody> - </Table> + description='The table shows URLs of the institutions connected to NRENs. You can filter the data by years and by NRENs.' + category={Sections.ConnectedUsers} filter={filterNode} + data={institutionData} filename="institution_urls"> + <ChartContainer> + <Table borderless className='compendium-table'> + <thead> + <tr> + <th className='nren-column'>NREN</th> + <th className='year-column'>Year</th> + <th className='blue-column'>URLs</th> + </tr> + </thead> + <tbody> + {getJSXFromMap(institutionDataByYear)} + </tbody> + </Table> + </ChartContainer> </DataPage> ); } diff --git a/compendium-frontend/src/pages/ConnectedUser.tsx b/compendium-frontend/src/pages/ConnectedUser.tsx index e5b0fa9c..be016350 100644 --- a/compendium-frontend/src/pages/ConnectedUser.tsx +++ b/compendium-frontend/src/pages/ConnectedUser.tsx @@ -1,20 +1,18 @@ import React, { useContext } from "react"; -import {Col, Row, Table} from "react-bootstrap"; -import {ConnectedProportion, ConnectivityCategory, Service, ServiceCategory} from "../Schema"; +import { ConnectedProportion, ConnectivityCategory } from "../Schema"; import { createConnectivityDataLookup, - createConnectivityDataLookupForCarrier, createConnectivityDataLookupForCommercial, - createMatrixDataLookup + createConnectivityDataLookupForCarrier, createConnectivityDataLookupForCommercial } from "../helpers/dataconversion"; import DataPage from "../components/DataPage"; import Filter from "../components/graphing/Filter"; -import { ExportType, Sections } from "../helpers/constants"; +import { Sections } from "../helpers/constants"; import { FilterSelectionContext } from "../helpers/FilterSelectionProvider"; import ChartContainer from "../components/graphing/ChartContainer"; import { useData } from "../helpers/useData"; -import {ConnectedUserData} from "../helpers/ConnectivityViewComponent"; -import {questionMap,dataKeyMap,displayTitle} from "../helpers/ConnectivityDisplayConstant"; +import { ConnectedUserData } from "../helpers/ConnectivityViewComponent"; +import { questionMap, dataKeyMap, displayTitle } from "../helpers/ConnectivityDisplayConstant"; @@ -22,11 +20,11 @@ interface inputProps { connectivity_category: string } -function ConnectedUserPage({ connectivity_category}: inputProps): React.ReactElement { +function ConnectedUserPage({ connectivity_category }: inputProps): React.ReactElement { const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext); const apiUrl = '/api/connectivity/' + connectivity_category; const { data: connectedProportion, years, nrens } = useData<ConnectedProportion>(apiUrl, setFilterSelection); - let isTickIcon =false + let isTickIcon = false const selectedData = (connectedProportion).filter(data => filterSelection.selectedYears.includes(data.year) && filterSelection.selectedNrens.includes(data.nren) @@ -36,24 +34,24 @@ function ConnectedUserPage({ connectivity_category}: inputProps): React.ReactEle selectedData.forEach(connectedProportion => { connectedProportionDict[connectedProportion.user_category] = connectedProportion.user_category; }); - let dataLookup:any; - let carrierCategoryList:any; - if(connectivity_category==ConnectivityCategory.ConnectionCarrier.toString()){ - dataLookup = createConnectivityDataLookupForCarrier(selectedData, 'user_category','carry_mechanism'); - carrierCategoryList = ['carry_mechanism'] - isTickIcon = true; + let dataLookup: any; + let carrierCategoryList: any; + if (connectivity_category == ConnectivityCategory.ConnectionCarrier.toString()) { + dataLookup = createConnectivityDataLookupForCarrier(selectedData, 'user_category', 'carry_mechanism'); + carrierCategoryList = ['carry_mechanism'] + isTickIcon = true; // console.log("Need to get filter data for ",dataLookup) - }else if(connectivity_category==ConnectivityCategory.CommercialConnectivity.toString()) { + } else if (connectivity_category == ConnectivityCategory.CommercialConnectivity.toString()) { const commercialConnectivityCategoryList = ['commercial_r_and_e', 'commercial_general', 'commercial_collaboration' , 'commercial_service_provider', 'university_spin_off'] isTickIcon = true; dataLookup = createConnectivityDataLookupForCommercial(selectedData, commercialConnectivityCategoryList); - }else if(connectivity_category==ConnectivityCategory.CommercialChargingLevel.toString()){ - const commercialChargingCategoryList =['collaboration','service_supplier','direct_peering'] + } else if (connectivity_category == ConnectivityCategory.CommercialChargingLevel.toString()) { + const commercialChargingCategoryList = ['collaboration', 'service_supplier', 'direct_peering'] isTickIcon = true; dataLookup = createConnectivityDataLookupForCommercial(selectedData, commercialChargingCategoryList); - }else { - dataLookup = createConnectivityDataLookup(selectedData, 'user_category'); + } else { + dataLookup = createConnectivityDataLookup(selectedData, 'user_category'); } const filterNode = <Filter @@ -68,14 +66,12 @@ function ConnectedUserPage({ connectivity_category}: inputProps): React.ReactEle return ( <DataPage title={displayTitle[connectivity_category]} - description="Hover over the elements for additional information." - category={Sections.ConnectedUsers} filter={filterNode}> + description="Hover over the elements for additional information." + category={Sections.ConnectedUsers} filter={filterNode} + data={connectedProportion} filename="nren_connectivity"> <> - {/*<DownloadDataButton data={serviceData} filename="nren_services.csv" exportType={ExportType.CSV} />*/} - {/*<DownloadDataButton data={serviceData} filename="nren_services.xlsx" exportType={ExportType.EXCEL} />*/} - {/*<DownloadImageChartButton filename="nren_services" />*/} <ChartContainer> - <div style={{fontSize:"16px",marginBottom:"10px",fontWeight:"bold"}}> + <div style={{ fontSize: "16px", marginBottom: "10px", fontWeight: "bold" }}> {questionMap[connectivity_category]} </div> <ConnectedUserData diff --git a/compendium-frontend/src/pages/ECProjects.tsx b/compendium-frontend/src/pages/ECProjects.tsx index db91cfdc..4b0870b3 100644 --- a/compendium-frontend/src/pages/ECProjects.tsx +++ b/compendium-frontend/src/pages/ECProjects.tsx @@ -1,14 +1,12 @@ import React, { useContext } from 'react'; -import {Row, Table} from "react-bootstrap"; +import { Table } from "react-bootstrap"; import { ECProject } from "../Schema"; import { createDataLookupList } 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 { Sections } from '../helpers/constants'; import { FilterSelectionContext } from '../helpers/FilterSelectionProvider'; -import DownloadImageChartButton from "../components/DownloadImageChartButton"; import ChartContainer from "../components/graphing/ChartContainer"; import { useData } from '../helpers/useData'; @@ -32,8 +30,8 @@ function getJSXFromMap(data: Map<string, Map<number, ECProject[]>>) { } function ECProjects() { - const {filterSelection, setFilterSelection } = useContext(FilterSelectionContext); - const {data: projectData, years, nrens} = useData<ECProject>('/api/ec-project/', setFilterSelection); + const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext); + const { data: projectData, years, nrens } = useData<ECProject>('/api/ec-project/', setFilterSelection); const selectedData = (projectData).filter(project => filterSelection.selectedYears.includes(project.year) && filterSelection.selectedNrens.includes(project.nren) @@ -47,31 +45,25 @@ function ECProjects() { /> return ( - <DataPage title="NREN Involvement in European Commission Projects" - description='The table shows the NRENs involvement in European Commission Projects Membership. By selecting multiple + <DataPage title="NREN Involvement in European Commission Projects" + description='The table shows the NRENs involvement in European Commission Projects Membership. By selecting multiple year and NRENs, the table can be used to compare the NRENs involvement in European Commission Projects Membership' - category={Sections.Organisation} filter={filterNode}> - <> - <Row> - <DownloadDataButton data={projectData} filename="nren_involvement_in_european_commission_projects.csv" exportType={ExportType.CSV}/> - <DownloadDataButton data={projectData} filename="nren_involvement_in_european_commission_projects.xlsx" exportType={ExportType.EXCEL}/> - </Row> - <DownloadImageChartButton filename="nren_involvement_in_european_commission_projects"/> - <ChartContainer> - <Table borderless className='compendium-table'> - <thead> + category={Sections.Organisation} filter={filterNode} + data={projectData} filename='nren_involvement_in_european_commission_projects'> + <ChartContainer> + <Table borderless className='compendium-table'> + <thead> <tr> <th className='nren-column'>NREN</th> <th className='year-column'>Year</th> <th className='blue-column'>EC Project Membership</th> </tr> - </thead> - <tbody> + </thead> + <tbody> {getJSXFromMap(projectDataByYear)} - </tbody> - </Table> - </ChartContainer> - </> + </tbody> + </Table> + </ChartContainer> </DataPage> ) } diff --git a/compendium-frontend/src/pages/FundingSource.tsx b/compendium-frontend/src/pages/FundingSource.tsx index ce7a96ed..66bb912a 100644 --- a/compendium-frontend/src/pages/FundingSource.tsx +++ b/compendium-frontend/src/pages/FundingSource.tsx @@ -8,11 +8,9 @@ import { FundingSource } from "../Schema"; import { createFundingSourceDataset } from "../helpers/dataconversion"; import DataPage from '../components/DataPage'; import Filter from "../components/graphing/Filter" -import {ExportType, Sections} from '../helpers/constants'; +import { Sections } from '../helpers/constants'; import ColorBadge from '../components/ColorBadge'; -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'; @@ -20,7 +18,7 @@ export const chartOptions = { maintainAspectRatio: false, layout: { padding: { - right: 60 + right: 60 } }, animation: { @@ -115,8 +113,8 @@ function FundingSourceLegend() { } function FundingSourcePage() { - const {filterSelection, setFilterSelection } = useContext(FilterSelectionContext); - const {data: fundingSourceData, years, nrens} = useData<FundingSource>('/api/funding/', setFilterSelection); + const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext); + const { data: fundingSourceData, years, nrens } = useData<FundingSource>('/api/funding/', setFilterSelection); const fundingSourceDataset = createFundingSourceDataset(fundingSourceData); @@ -151,25 +149,20 @@ function FundingSourcePage() { description='The graph shows the percentage share of their income that individual NRENs derived from different sources. On hovering over the graphs will give income share in that year. This can be used to compare selecting multiple years to see how the share has changed between the years.' - category={Sections.Organisation} filter={filterNode}> - <> - <Row> - <DownloadDataButton data={fundingSourceData} filename="income_source_of_nren_per_year.csv" exportType={ExportType.CSV}/> - <DownloadDataButton data={fundingSourceData} filename="income_source_of_nren_per_year.xlsx" exportType={ExportType.EXCEL}/> - </Row> - <DownloadImageChartButton filename="income_source_of_nren_per_year"/> - <ChartContainer> - <FundingSourceLegend/> - <div className="chart-container" style={{'height': `${height}rem`}}> - <Bar - plugins={[ChartDataLabels]} - data={fundingSourceDataset} - options={chartOptions} - /> - </div> - <FundingSourceLegend/> - </ChartContainer> - </> + category={Sections.Organisation} filter={filterNode} + data={fundingSourceData} filename='income_source_of_nren_per_year'> + + <ChartContainer> + <FundingSourceLegend /> + <div className="chart-container" style={{ 'height': `${height}rem` }}> + <Bar + plugins={[ChartDataLabels]} + data={fundingSourceDataset} + options={chartOptions} + /> + </div> + <FundingSourceLegend /> + </ChartContainer> </DataPage> ); } diff --git a/compendium-frontend/src/pages/ParentOrganisation.tsx b/compendium-frontend/src/pages/ParentOrganisation.tsx index 76a18381..02c1445f 100644 --- a/compendium-frontend/src/pages/ParentOrganisation.tsx +++ b/compendium-frontend/src/pages/ParentOrganisation.tsx @@ -1,14 +1,12 @@ import React, { useContext } from 'react'; -import {Row, Table} from "react-bootstrap"; +import { Table } from "react-bootstrap"; import { Organisation } from "../Schema"; import { createDataLookup } 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 { Sections } from '../helpers/constants'; import { FilterSelectionContext } from '../helpers/FilterSelectionProvider'; -import DownloadImageChartButton from "../components/DownloadImageChartButton"; import ChartContainer from "../components/graphing/ChartContainer"; import { useData } from '../helpers/useData'; @@ -25,8 +23,8 @@ function getJSXFromMap(data: Map<string, Map<number, Organisation>>) { }) } function ParentOrganisation() { - const {filterSelection, setFilterSelection } = useContext(FilterSelectionContext); - const {data: organisationData, years, nrens} = useData<Organisation>('/api/organization/parent', setFilterSelection); + const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext); + const { data: organisationData, years, nrens } = useData<Organisation>('/api/organization/parent', setFilterSelection); const selectedData = organisationData.filter(data => filterSelection.selectedYears.includes(data.year) && filterSelection.selectedNrens.includes(data.nren) @@ -41,31 +39,25 @@ function ParentOrganisation() { /> return ( - <DataPage title="NREN Parent Organisations" - description='The table shows the NRENs parent organisation. You can select only one year at a time + <DataPage title="NREN Parent Organisations" + description='The table shows the NRENs parent organisation. You can select only one year at a time and multiple NRENs. This table can be used to compare the parent organisation of NRENs.' - category={Sections.Organisation} filter={filterNode}> - <> - <Row> - <DownloadDataButton data={organisationData} filename="nren_parent_organisations.csv" exportType={ExportType.CSV}/> - <DownloadDataButton data={organisationData} filename="nren_parent_organisations.xlsx" exportType={ExportType.EXCEL}/> - </Row> - <DownloadImageChartButton filename='nren_parent_organisations'/> - <ChartContainer> - <Table borderless className='compendium-table'> - <thead> + category={Sections.Organisation} filter={filterNode} + data={organisationData} filename="nren_parent_organisations"> + <ChartContainer> + <Table borderless className='compendium-table'> + <thead> <tr> <th className='nren-column'>NREN</th> <th className='year-column'>Year</th> <th className='blue-column'>Parent Organisation</th> </tr> - </thead> - <tbody> + </thead> + <tbody> {getJSXFromMap(organisationDataset)} - </tbody> - </Table> - </ChartContainer> - </> + </tbody> + </Table> + </ChartContainer> </DataPage> ); diff --git a/compendium-frontend/src/pages/Policy.tsx b/compendium-frontend/src/pages/Policy.tsx index 11f40513..37d3ff1c 100644 --- a/compendium-frontend/src/pages/Policy.tsx +++ b/compendium-frontend/src/pages/Policy.tsx @@ -8,6 +8,7 @@ import Filter from "../components/graphing/Filter" import { Sections } from '../helpers/constants'; import { FilterSelectionContext } from '../helpers/FilterSelectionProvider'; import { useData } from '../helpers/useData'; +import ChartContainer from '../components/graphing/ChartContainer'; function getJSXFromMap(data: Map<string, Map<number, Policy>>) { const policies = [ @@ -45,8 +46,8 @@ function getJSXFromMap(data: Map<string, Map<number, Policy>>) { } function PolicyPage() { - const {filterSelection, setFilterSelection } = useContext(FilterSelectionContext); - const {data: policyData, years, nrens} = useData<Policy>('/api/policy/', setFilterSelection); + const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext); + const { data: policyData, years, nrens } = useData<Policy>('/api/policy/', setFilterSelection); const selectedData = policyData.filter(project => filterSelection.selectedYears.includes(project.year) && filterSelection.selectedNrens.includes(project.nren) @@ -60,22 +61,25 @@ function PolicyPage() { /> return ( - <DataPage title="NREN Policies" - description='The table shows the NRENs policies. By selecting multiple year and NRENs, - the table can be used to compare the NRENs policies over years of selected NRENs.' - category={Sections.Policy} filter={filterNode}> - <Table borderless className='compendium-table'> - <thead> - <tr> - <th className='nren-column'>NREN</th> - <th className='year-column'>Year</th> - <th className='blue-column'>Policies</th> - </tr> - </thead> - <tbody> - {getJSXFromMap(policyDataByYear)} - </tbody> - </Table> + <DataPage title="NREN Policies" + description='The table shows the NRENs policies. By selecting multiple year and NRENs, + the table can be used to compare the NRENs policies over years of selected NRENs.' + category={Sections.Policy} filter={filterNode} + data={policyData} filename='nren_policies'> + <ChartContainer> + <Table borderless className='compendium-table'> + <thead> + <tr> + <th className='nren-column'>NREN</th> + <th className='year-column'>Year</th> + <th className='blue-column'>Policies</th> + </tr> + </thead> + <tbody> + {getJSXFromMap(policyDataByYear)} + </tbody> + </Table> + </ChartContainer> </DataPage> ) } diff --git a/compendium-frontend/src/pages/Services.tsx b/compendium-frontend/src/pages/Services.tsx index ce402216..90d9f382 100644 --- a/compendium-frontend/src/pages/Services.tsx +++ b/compendium-frontend/src/pages/Services.tsx @@ -6,10 +6,8 @@ import { createMatrixDataLookup } from "../helpers/dataconversion"; import ColorBadgeService from "../components/ColorBadgeService"; import DataPage from "../components/DataPage"; import Filter from "../components/graphing/Filter"; -import { ExportType, Sections } from "../helpers/constants"; -import DownloadDataButton from "../components/DownloadDataButton"; +import { Sections } from "../helpers/constants"; import { FilterSelectionContext } from "../helpers/FilterSelectionProvider"; -import DownloadImageChartButton from "../components/DownloadImageChartButton"; import ChartContainer from "../components/graphing/ChartContainer"; import { useData } from "../helpers/useData"; @@ -58,50 +56,46 @@ function ServicesPage({ category }: inputProps): React.ReactElement { return ( <DataPage title={"NREN " + CategoryFriendlyNames[category] + " services matrix"} description="Hover over the elements for additional information." - category={Sections.Services} filter={filterNode}> - <> - <DownloadDataButton data={serviceData} filename="nren_services.csv" exportType={ExportType.CSV} /> - <DownloadDataButton data={serviceData} filename="nren_services.xlsx" exportType={ExportType.EXCEL} /> - <DownloadImageChartButton filename="nren_services" /> - <ChartContainer> - <Table className="charging-struct-table" striped bordered> - <colgroup> - <col span={1} style={{ width: "10%" }} /> - {/* <col span={1} style={{width: "18%"}}/> + category={Sections.Services} filter={filterNode} + data={serviceData} filename="nren_services"> + <ChartContainer> + <Table className="charging-struct-table" striped bordered> + <colgroup> + <col span={1} style={{ width: "10%" }} /> + {/* <col span={1} style={{width: "18%"}}/> <col span={1} style={{width: "18%"}}/> <col span={1} style={{width: "18%"}}/> <col span={1} style={{width: "18%"}}/> <col span={1} style={{width: "18%"}}/> */} - </colgroup> - <thead> - <tr> - <th></th> - {servicesList.map(([serviceName, serviceDescription]) => ( - <th key={serviceName} data-description={serviceDescription} className="bottom-tooltip">{serviceName}</th> + </colgroup> + <thead> + <tr> + <th></th> + {servicesList.map(([serviceName, serviceDescription]) => ( + <th key={serviceName} data-description={serviceDescription} className="bottom-tooltip">{serviceName}</th> + ))} + </tr> + </thead> + <tbody> + {Array.from(dataLookup.entries()).map(([nren, nrenServiceMap]) => ( + <tr key={nren}> + <td>{nren}</td> + {servicesList.map(([serviceName, _]) => ( + <td key={serviceName}> + {nrenServiceMap.has(serviceName) && + showYears.map(year => { + const serviceYears = nrenServiceMap.get(serviceName)!; + const serviceInfo = serviceYears.get(year); + return <ColorBadgeService key={year} year={year} active={serviceYears.has(year)} serviceInfo={serviceInfo} />; + }) + } + </td> ))} </tr> - </thead> - <tbody> - {Array.from(dataLookup.entries()).map(([nren, nrenServiceMap]) => ( - <tr key={nren}> - <td>{nren}</td> - {servicesList.map(([serviceName, _]) => ( - <td key={serviceName}> - {nrenServiceMap.has(serviceName) && - showYears.map(year => { - const serviceYears = nrenServiceMap.get(serviceName)!; - const serviceInfo = serviceYears.get(year); - return <ColorBadgeService key={year} year={year} active={serviceYears.has(year)} serviceInfo={serviceInfo} />; - }) - } - </td> - ))} - </tr> - ))} - </tbody> - </Table> - </ChartContainer> - </> + ))} + </tbody> + </Table> + </ChartContainer> </DataPage> ); } diff --git a/compendium-frontend/src/pages/StaffGraph.tsx b/compendium-frontend/src/pages/StaffGraph.tsx index cb508acf..2994a256 100644 --- a/compendium-frontend/src/pages/StaffGraph.tsx +++ b/compendium-frontend/src/pages/StaffGraph.tsx @@ -6,13 +6,10 @@ import { NrenStaff } from "../Schema"; import { createNRENStaffDataset } from "../helpers/dataconversion"; import DataPage from '../components/DataPage'; import Filter from "../components/graphing/Filter" -import {ExportType, Sections} from '../helpers/constants'; +import { Sections } from '../helpers/constants'; import WithLegend from '../components/WithLegend'; import htmlLegendPlugin from '../plugins/HTMLLegendPlugin'; -import {Row} from "react-bootstrap"; -import DownloadDataButton from "../components/DownloadDataButton"; import { FilterSelectionContext } from '../helpers/FilterSelectionProvider'; -import DownloadImageChartButton from "../components/DownloadImageChartButton"; import { useData } from '../helpers/useData'; ChartJS.register( @@ -108,8 +105,8 @@ interface inputProps { } function StaffGraph({ roles = false }: inputProps) { - const {filterSelection, setFilterSelection } = useContext(FilterSelectionContext); - const {data: staffData, years, nrens} = useData<NrenStaff>('/api/staff/', setFilterSelection); + const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext); + const { data: staffData, years, nrens } = useData<NrenStaff>('/api/staff/', setFilterSelection); const nrenStaffDataset = createNRENStaffDataset(staffData, roles, filterSelection.selectedYears[0]); @@ -141,33 +138,28 @@ function StaffGraph({ roles = false }: inputProps) { const height = Math.max(numNrens * heightPerBar, 20); const title = roles - ? "Roles of NREN employees" - : "Types of employment for NRENs"; + ? "Roles of NREN employees" + : "Types of employment for NRENs"; const description = roles - ? "The graph shows the roles of NREN employees. On hovering over the graph will give the percentage of employees in that role. This graph can be used to compare, selecting multiple NRENs to see the fluctuation of roles over selected year and with other NRENs." - : "The graph shows the types of employment for NREN employees. On hovering over the graphs will give the percentage of employees in that type of employment. This graph can be used to compare, selecting multiple NRENs to see the fluctuation of types of employment over selected year and with other NRENs."; + ? "The graph shows the roles of NREN employees. On hovering over the graph will give the percentage of employees in that role. This graph can be used to compare, selecting multiple NRENs to see the fluctuation of roles over selected year and with other NRENs." + : "The graph shows the types of employment for NREN employees. On hovering over the graphs will give the percentage of employees in that type of employment. This graph can be used to compare, selecting multiple NRENs to see the fluctuation of types of employment over selected year and with other NRENs."; const filename = roles ? "roles_of_nren_employees" : "types_of_employment_for_nrens"; return ( - <DataPage title={title} - description={description} - category={Sections.Organisation} filter={filterNode}> - <> - <Row> - <DownloadDataButton data={staffData} filename={filename} exportType={ExportType.CSV}/> - <DownloadDataButton data={staffData} filename={filename} exportType={ExportType.EXCEL}/> - </Row> - <DownloadImageChartButton filename={filename}/> - <WithLegend> - <div className="chart-container" style={{'height': `${height}rem`}}> - <Bar - data={nrenStaffDataset} - options={chartOptions} - plugins={[htmlLegendPlugin]} - /> - </div> - </WithLegend> - </> + <DataPage title={title} + description={description} + category={Sections.Organisation} filter={filterNode} + data={staffData} filename={filename}> + + <WithLegend> + <div className="chart-container" style={{ 'height': `${height}rem` }}> + <Bar + data={nrenStaffDataset} + options={chartOptions} + plugins={[htmlLegendPlugin]} + /> + </div> + </WithLegend> </DataPage> ); } diff --git a/compendium-frontend/src/pages/SubOrganisation.tsx b/compendium-frontend/src/pages/SubOrganisation.tsx index cbe5fbb8..80078f26 100644 --- a/compendium-frontend/src/pages/SubOrganisation.tsx +++ b/compendium-frontend/src/pages/SubOrganisation.tsx @@ -1,14 +1,12 @@ import React, { useContext } from 'react'; -import {Row, Table} from "react-bootstrap"; +import { Table } from "react-bootstrap"; import { Organisation } from "../Schema"; import { createDataLookupList } 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 { Sections } from '../helpers/constants'; import { FilterSelectionContext } from '../helpers/FilterSelectionProvider'; -import DownloadImageChartButton from "../components/DownloadImageChartButton"; import ChartContainer from "../components/graphing/ChartContainer"; import { useData } from '../helpers/useData'; @@ -31,8 +29,8 @@ function getJSXFromMap(data: Map<string, Map<number, Organisation[]>>) { } function SubOrganisation() { - const {filterSelection, setFilterSelection } = useContext(FilterSelectionContext); - const {data: organisationData, years, nrens} = useData<Organisation>('/api/organization/sub', setFilterSelection); + const { filterSelection, setFilterSelection } = useContext(FilterSelectionContext); + const { data: organisationData, years, nrens } = useData<Organisation>('/api/organization/sub', setFilterSelection); const selectedData = organisationData.filter(data => filterSelection.selectedYears.includes(data.year) && filterSelection.selectedNrens.includes(data.nren) @@ -47,30 +45,24 @@ function SubOrganisation() { return ( <DataPage title="NREN Suborganisations" - description='The table shows the NRENs suborganisations. You can select multiple years and NRENs to get a + description='The table shows the NRENs suborganisations. You can select multiple years and NRENs to get a tabular view of NRENs suborganisations over the years.' - category={Sections.Organisation} filter={filterNode}> - <> - <Row> - <DownloadDataButton data={organisationData} filename="nren_suborganisations.csv" exportType={ExportType.CSV}/> - <DownloadDataButton data={organisationData} filename="nren_suborganisations.xlsx" exportType={ExportType.EXCEL}/> - </Row> - <DownloadImageChartButton filename="nren_suborganisations"/> - <ChartContainer> - <Table borderless className='compendium-table'> - <thead> + category={Sections.Organisation} filter={filterNode} + data={organisationData} filename='nren_suborganisations'> + <ChartContainer> + <Table borderless className='compendium-table'> + <thead> <tr> <th className='nren-column'>NREN</th> <th className='year-column'>Year</th> <th className='blue-column'>Suborganisation and Role</th> </tr> - </thead> - <tbody> + </thead> + <tbody> {getJSXFromMap(organisationDataset)} - </tbody> - </Table> - </ChartContainer> - </> + </tbody> + </Table> + </ChartContainer> </DataPage> ); } diff --git a/compendium-frontend/src/pages/TrafficVolumePerNren.tsx b/compendium-frontend/src/pages/TrafficVolumePerNren.tsx index 5b7a7c6e..f01e6f29 100644 --- a/compendium-frontend/src/pages/TrafficVolumePerNren.tsx +++ b/compendium-frontend/src/pages/TrafficVolumePerNren.tsx @@ -1,6 +1,5 @@ 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'; @@ -8,10 +7,8 @@ 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 { Sections } from '../helpers/constants'; import { FilterSelectionContext } from '../helpers/FilterSelectionProvider'; -import DownloadImageChartButton from "../components/DownloadImageChartButton"; import ChartContainer from "../components/graphing/ChartContainer"; import { useData } from '../helpers/useData'; @@ -102,23 +99,17 @@ function TrafficVolumePage() { 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> - </> + category={Sections.Network} filter={filterNode} + data={trafficVolumeData} 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> ); } -- GitLab