Skip to content
Snippets Groups Projects
Commit 7104a54a authored by Remco Tukker's avatar Remco Tukker
Browse files

Merge branch 'feature/COMP-249-download-excel-functionality' into 'develop'

added excel download button to the pages

See merge request !62
parents 6e1e70cf 4b2385e5
No related branches found
No related tags found
1 merge request!62added excel download button to the pages
This diff is collapsed.
......@@ -54,7 +54,8 @@
"react-chartjs-2": "^5.1.0",
"react-dom": "^18.2.0",
"react-icons": "4.8.0",
"react-router-dom": "^6.5.0"
"react-router-dom": "^6.5.0",
"xlsx": "^0.18.5"
},
"description": "## development environment",
"main": "index.js",
......
import React from 'react';
import * as XLSX from "xlsx";
import {ExportType} from "../helpers/constants";
interface DownloadCSVProps {
interface DownloadProps {
data: any[];
filename?: string;
filename: string;
exportType: ExportType;
}
......@@ -36,12 +40,48 @@ function convertToCSV(jsonData: any[]): string {
return [header.join(','), ...rows].join('\r\n');
}
function convertToExcel(jsonData: any[], sheetName = "Sheet1"): Blob {
const ws = XLSX.utils.json_to_sheet(jsonData);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, sheetName);
const wbout = XLSX.write(wb, {bookType: 'xlsx', type: 'binary'});
const buffer = new ArrayBuffer(wbout.length);
const view = new Uint8Array(buffer);
for (let i = 0; i < wbout.length; i++) {
// Convert each character of the binary workbook string to an 8-bit integer and store in the Uint8Array 'view' for blob creation.
view[i] = wbout.charCodeAt(i) & 0xFF;
}
return new Blob([buffer], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'});
}
const DownloadDataButton: React.FC<DownloadProps> = ({data, filename, exportType}) => {
const downloadData = () => {
let convertedData;
let fileType;
let contentType ;
switch (exportType) {
case ExportType.EXCEL: {
convertedData = convertToExcel(data);
fileType = 'xlsx';
contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8';
break;
}
case ExportType.CSV:
default: {
convertedData = convertToCSV(data);
fileType = 'csv';
contentType = 'text/csv;charset=UTF-8';
break;
}
}
const DownloadCSVButton: React.FC<DownloadCSVProps> = ({ data, filename = 'data.csv' }) => {
const blob = new Blob([convertedData], {type: contentType});
filename = filename.endsWith(fileType) ? filename : `${filename}.${fileType}`;
const downloadCSV = () => {
const csv = convertToCSV(data);
const blob = new Blob([csv], { type: 'text/csv' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
......@@ -52,9 +92,9 @@ const DownloadCSVButton: React.FC<DownloadCSVProps> = ({ data, filename = 'data.
return (
<>
<button onClick={downloadCSV}>Download CSV</button>
<button onClick={downloadData}>Download {exportType}</button>
</>
);
}
export default DownloadCSVButton;
export default DownloadDataButton;
......@@ -4,4 +4,9 @@ export enum Sections {
ConnectedUsers = 'CONNECTED USERS',
Network = 'NETWORK',
Services = 'SERVICES',
}
export enum ExportType {
CSV = "CSV",
EXCEL = "EXCEL",
}
\ No newline at end of file
......@@ -6,8 +6,8 @@ import { createBudgetDataset, getYearsAndNrens, loadDataWithFilterNrenSelectionF
import DataPage from '../components/DataPage';
import Filter from "../components/graphing/Filter";
import LineGraph from "../components/graphing/LineGraph";
import { Sections } from '../helpers/constants';
import DownloadCSVButton from "../components/DownloadCSVButton";
import {ExportType, Sections} from '../helpers/constants';
import DownloadDataButton from "../components/DownloadDataButton";
interface inputProps {
filterSelection: FilterSelection
......@@ -46,7 +46,8 @@ function BudgetPage({ filterSelection, setFilterSelection }: inputProps): ReactE
fluctuation of budget over years and with other NRENs.' category={Sections.Organisation} filter={filterNode}>
<>
<Row>
<DownloadCSVButton data={budgetResponse} filename="budget_data.csv"/>
<DownloadDataButton data={budgetResponse} filename="budget_data.csv" exportType={ExportType.CSV}/>
<DownloadDataButton data={budgetResponse} filename="budget_data.xlsx" exportType={ExportType.EXCEL}/>
</Row>
<Row>
<LineGraph data={budgetData} />
......
......@@ -7,8 +7,8 @@ import { createChargingStructureDataLookup, getYearsAndNrens, loadDataWithFilter
import ColorPill from "../components/ColorPill";
import DataPage from "../components/DataPage";
import Filter from "../components/graphing/Filter";
import { Sections } from "../helpers/constants";
import DownloadCSVButton from "../components/DownloadCSVButton";
import {ExportType, Sections} from "../helpers/constants";
import DownloadDataButton from "../components/DownloadDataButton";
ChartJS.register(
......@@ -58,7 +58,8 @@ function ChargingStructurePage({ filterSelection, setFilterSelection }: inputPro
category={Sections.Organisation} filter={filterNode}>
<>
<Row>
<DownloadCSVButton data={chargingStructureData} filename="charging_mechanism_of_nrens_per_year.csv"/>
<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>
<Table className="charging-struct-table" striped bordered responsive>
<colgroup>
......
......@@ -5,8 +5,8 @@ import { ECProject, FilterSelection } from "../Schema";
import { createECProjectsDataLookup, getYearsAndNrens, loadDataWithFilterSelectionFallback } from '../helpers/dataconversion';
import DataPage from '../components/DataPage';
import Filter from "../components/graphing/Filter"
import { Sections } from '../helpers/constants';
import DownloadCSVButton from "../components/DownloadCSVButton";
import {ExportType, Sections} from '../helpers/constants';
import DownloadDataButton from "../components/DownloadDataButton";
interface inputProps {
......@@ -62,7 +62,8 @@ function ECProjects({ filterSelection, setFilterSelection }: inputProps) {
category={Sections.Organisation} filter={filterNode}>
<>
<Row>
<DownloadCSVButton data={projectData} filename="nren_involvement_in_european_commission_projects.csv"/>
<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>
<Table borderless className='compendium-table'>
<thead>
......
......@@ -8,9 +8,9 @@ import { FundingSource, FilterSelection } from "../Schema";
import { createFundingSourceDataset, getYearsAndNrens, loadDataWithFilterSelectionFallback } from "../helpers/dataconversion";
import DataPage from '../components/DataPage';
import Filter from "../components/graphing/Filter"
import { Sections } from '../helpers/constants';
import {ExportType, Sections} from '../helpers/constants';
import ColorBadge from '../components/ColorBadge';
import DownloadCSVButton from "../components/DownloadCSVButton";
import DownloadDataButton from "../components/DownloadDataButton";
export const chartOptions = {
maintainAspectRatio: false,
......@@ -157,7 +157,8 @@ function FundingSourcePage({ filterSelection, setFilterSelection }: inputProps)
category={Sections.Organisation} filter={filterNode}>
<>
<Row>
<DownloadCSVButton data={fundingSourceData} filename="income_source_of_nren_per_year.csv"/>
<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>
<div>
<FundingSourceLegend/>
......
import React, { useEffect, useMemo, useState } from 'react';
import React, {useEffect, useMemo, useState} from 'react';
import {Row, Table} from "react-bootstrap";
import { Organisation, FilterSelection } from "../Schema";
import { createOrganisationDataLookup, getYearsAndNrens, loadDataWithFilterSelectionFallback } from "../helpers/dataconversion";
import DataPage from '../components/DataPage';
import Filter from "../components/graphing/Filter"
import { Sections } from '../helpers/constants';
import DownloadCSVButton from "../components/DownloadCSVButton";
import {ExportType, Sections} from '../helpers/constants';
import DownloadDataButton from "../components/DownloadDataButton";
function getJSXFromMap(data: Map<string, Map<number, Organisation[]>>) {
......@@ -57,7 +57,8 @@ function ParentOrganisation({ filterSelection, setFilterSelection }: inputProps)
category={Sections.Organisation} filter={filterNode}>
<>
<Row>
<DownloadCSVButton data={organisationData} filename="nren_parent_organisations.csv"/>
<DownloadDataButton data={organisationData} filename="nren_parent_organisations.csv" exportType={ExportType.CSV}/>
<DownloadDataButton data={organisationData} filename="nren_parent_organisations.xlsx" exportType={ExportType.EXCEL}/>
</Row>
<Table borderless className='compendium-table'>
<thead>
......
......@@ -6,11 +6,11 @@ import { NrenStaff, FilterSelection } from "../Schema";
import { createNRENStaffDataset, getYearsAndNrens, loadDataWithFilterSelectionFallback } from "../helpers/dataconversion";
import DataPage from '../components/DataPage';
import Filter from "../components/graphing/Filter"
import { Sections } from '../helpers/constants';
import {ExportType, Sections} from '../helpers/constants';
import WithLegend from '../components/WithLegend';
import htmlLegendPlugin from '../plugins/HTMLLegendPlugin';
import {Row} from "react-bootstrap";
import DownloadCSVButton from "../components/DownloadCSVButton";
import DownloadDataButton from "../components/DownloadDataButton";
ChartJS.register(
CategoryScale,
......@@ -153,14 +153,15 @@ function StaffGraph({ filterSelection, setFilterSelection, roles = false }: inpu
? "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.csv" : "types_of_employment_for_nren.csv";
const filename = roles ? "roles_of_nren_employees" : "types_of_employment_for_nrens";
return (
<DataPage title={title}
description={description}
category={Sections.Organisation} filter={filterNode}>
<>
<Row>
<DownloadCSVButton data={staffData} filename={filename}/>
<DownloadDataButton data={staffData} filename={filename} exportType={ExportType.CSV}/>
<DownloadDataButton data={staffData} filename={filename} exportType={ExportType.EXCEL}/>
</Row>
<WithLegend>
<div className="chart-container" style={{'height': `${height}rem`}}>
......
......@@ -5,8 +5,8 @@ import { Organisation, FilterSelection } from "../Schema";
import { createOrganisationDataLookup, getYearsAndNrens, loadDataWithFilterSelectionFallback } from "../helpers/dataconversion";
import DataPage from '../components/DataPage';
import Filter from "../components/graphing/Filter"
import { Sections } from '../helpers/constants';
import DownloadCSVButton from "../components/DownloadCSVButton";
import {ExportType, Sections} from '../helpers/constants';
import DownloadDataButton from "../components/DownloadDataButton";
function getJSXFromMap(data: Map<string, Map<number, Organisation[]>>) {
......@@ -62,7 +62,8 @@ function SubOrganisation({ filterSelection, setFilterSelection }: inputProps) {
category={Sections.Organisation} filter={filterNode}>
<>
<Row>
<DownloadCSVButton data={organisationData} filename="nren_suborganisations.csv"/>
<DownloadDataButton data={organisationData} filename="nren_suborganisations.csv" exportType={ExportType.CSV}/>
<DownloadDataButton data={organisationData} filename="nren_suborganisations.xlsx" exportType={ExportType.EXCEL}/>
</Row>
<Table borderless className='compendium-table'>
<thead>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment