Skip to content
Snippets Groups Projects
Commit 0c2be01b authored by Bjarke Madsen's avatar Bjarke Madsen
Browse files

Rewrite staff page to use data from a fixed year.

Simplify the creation of the dataset by sorting at the start
parent 330985d2
No related branches found
No related tags found
1 merge request!13publisher v1 staffing migration
This diff is collapsed.
......@@ -179,40 +179,9 @@ export function createOrganisationDataLookup(organisationEntries: Organisation[]
}
export const createNRENStaffDataset = (data: NrenStaff[], roles: boolean) => {
function CreateDataLookup(data: NrenStaff[]) {
const dataLookup = new Map<string, Map<string, number>>();
data.forEach((item: NrenStaff) => {
const lookupKey = `${item.nren}/${item.year}`
let NrenStaffMap = dataLookup.get(lookupKey)
if (!NrenStaffMap) {
NrenStaffMap = new Map<string, number>();
}
const total = item.non_technical_fte + item.technical_fte
const technical_percentage = Math.round(((item.technical_fte / total) || 0) * 100)
const non_technical_percentage = Math.round(((item.non_technical_fte / total) || 0) * 100)
const contractor_total = item.subcontracted_fte + item.permanent_fte
const permanent_percentage = Math.round(((item.permanent_fte / contractor_total) || 0) * 100)
const subcontracted_percentage = Math.round(((item.subcontracted_fte / contractor_total) || 0) * 100)
NrenStaffMap.set("Technical FTE", technical_percentage)
NrenStaffMap.set("Non-technical FTE", non_technical_percentage)
NrenStaffMap.set("Permanent FTE", permanent_percentage)
NrenStaffMap.set("Subcontracted FTE", subcontracted_percentage)
dataLookup.set(lookupKey, NrenStaffMap)
})
return dataLookup
}
const dataLookup = CreateDataLookup(data)
const labelsYear = [...new Set(data.map((item: NrenStaff) => item.year))];
const labelsNREN = [...new Set(data.map((item: NrenStaff) => item.nren))];
export const createNRENStaffDataset = (data: NrenStaff[], roles: boolean, selectedYear: Number) => {
let categories;
if (roles) {
categories = [
"Technical FTE",
......@@ -223,9 +192,91 @@ export const createNRENStaffDataset = (data: NrenStaff[], roles: boolean) => {
"Permanent FTE",
"Subcontracted FTE"
]
}
function CreateDataLookup(data: NrenStaff[]) {
const fields = {
"Technical FTE": "technical_fte",
"Non-technical FTE": "non_technical_fte",
"Permanent FTE": "permanent_fte",
"Subcontracted FTE": "subcontracted_fte"
}
const dataLookup = new Map<string, Map<string, number>>();
data.forEach((item: NrenStaff) => {
if (selectedYear !== item.year) {
// only include data for the selected year
return;
}
const nren = item.nren;
let categoryMap = dataLookup.get(nren)
if (!categoryMap) {
categoryMap = new Map<string, number>();
}
// get the values for the two categories
const [category1, category2] = categories
const [category1Field, category2Field] = [fields[category1], fields[category2]]
const category1Value = item[category1Field]
const category2Value = item[category2Field]
// calculate the percentages
const total = category1Value + category2Value
let category1_percentage = ((category1Value / total) || 0) * 100
let category2_percentage = ((category2Value / total) || 0) * 100
// round to 2 decimal places
category1_percentage = Math.round(Math.floor(category1_percentage * 100)) / 100
category2_percentage = Math.round(Math.floor(category2_percentage * 100)) / 100
categoryMap.set(category1, category1_percentage)
categoryMap.set(category2, category2_percentage)
dataLookup.set(nren, categoryMap)
})
return dataLookup
}
const dataLookup = CreateDataLookup(data)
const labelsYear = [selectedYear];
const labelsNREN = [...new Set(data.map((item: NrenStaff) => item.nren))].sort((nrenA, nrenB) => {
const categoryMapNrenA = dataLookup.get(nrenA)
const categoryMapNrenB = dataLookup.get(nrenB)
if (categoryMapNrenA && categoryMapNrenB) {
const [category1, category2] = categories
const nrenAData = {
category1: categoryMapNrenA.get(category1)!,
category2: categoryMapNrenA.get(category2)!
}
const nrenBData = {
category1: categoryMapNrenB.get(category1)!,
category2: categoryMapNrenB.get(category2)!
}
if (nrenAData.category1 === nrenBData.category1) {
return nrenBData.category2 - nrenAData.category1;
}
return nrenBData.category1 - nrenAData.category1;
} else {
// put NRENs with no data at the end
if (categoryMapNrenA) {
return -1
}
if (categoryMapNrenB) {
return 1
}
return 0
}
});
const categoriesPerYear = cartesianProduct(categories, labelsYear)
......@@ -233,28 +284,25 @@ export const createNRENStaffDataset = (data: NrenStaff[], roles: boolean) => {
let color = ""
if (category === "Technical FTE") {
// color = dark blue
color = 'rgba(40, 40, 250, 0.8)'
} else if (category === "Permanent FTE") {
color = 'rgba(159, 129, 235, 1)'
} else if (category === "Subcontracted FTE") {
color = 'rgba(173, 216, 229, 1)'
}
else {
// light blue
} else if (category === "Non-technical FTE") {
color = 'rgba(116, 216, 242, 0.54)'
}
return {
backgroundColor: color,
label: `${category} (${year})`,
data: labelsNREN.map(nren => {
// ensure that the data is in the same order as the labels
const lookupKey = `${nren}/${year}`
const dataForYear = dataLookup.get(lookupKey)
if (!dataForYear) {
const dataForNren = dataLookup.get(nren)
if (!dataForNren) {
return 0
}
return dataForYear.get(category) ?? 0
return dataForNren.get(category) ?? 0
}),
stack: year,
borderRadius: 10,
......@@ -268,47 +316,8 @@ export const createNRENStaffDataset = (data: NrenStaff[], roles: boolean) => {
const dataset: NrenStaffDataset = {
datasets: nrenStaffDataset,
labels: labelsNREN.map(l => l.toString())
}
function sortDatasetByTechnicalFTE(dataset: NrenStaffDataset) {
// sort dataset by Technical FTE value descending and ensure labels are in the same order
const sortedDataset = { ...dataset }
const uniqueYears = [...new Set(dataset.datasets.map(d => d.stack))]
for (const year of uniqueYears) {
const technicalFTEIndex = dataset.datasets.findIndex(d => d.label === `Technical FTE (${year})` || d.label === `Permanent FTE (${year})`)
if (technicalFTEIndex === -1) {
continue
}
const nonTechnicalFTEIndex = dataset.datasets.findIndex(d => d.label === `Non-technical FTE (${year})` || d.label === `Subcontracted FTE (${year})`)
if (nonTechnicalFTEIndex === -1) {
continue
}
const datasetForYearTechnical = dataset.datasets[technicalFTEIndex];
const datasetForYearNonTechnical = dataset.datasets[nonTechnicalFTEIndex];
const dataByYear = datasetForYearTechnical.data.map((d, i) => ({
datatechnical: d,
datanontechnical: datasetForYearNonTechnical.data[i],
label: dataset.labels[i],
}))
function sortfunc(a: any, b: any) {
return b.datatechnical - a.datatechnical;
}
const sortedDataByYear = dataByYear.sort(sortfunc)
sortedDataset.datasets[technicalFTEIndex].data = sortedDataByYear.map(d => d.datatechnical)
sortedDataset.datasets[nonTechnicalFTEIndex].data = sortedDataByYear.map(d => d.datanontechnical)
sortedDataset.labels = sortedDataByYear.map(d => d.label)
}
return sortedDataset
labels: labelsNREN
}
const sortedDataset = sortDatasetByTechnicalFTE(dataset)
return sortedDataset;
return dataset;
}
......@@ -105,7 +105,7 @@ function StaffGraph({ filterSelection, setFilterSelection, roles=false }: inputP
() => getYearsAndNrens(staffData || []),
[staffData]
);
const nrenStaffDataset = createNRENStaffDataset(staffData || [], roles);
const nrenStaffDataset = createNRENStaffDataset(staffData || [], roles, filterSelection.selectedYears[0]);
nrenStaffDataset.datasets.forEach(dataset => {
dataset.hidden = !filterSelection.selectedYears.includes(parseInt(dataset.stack));
......
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment