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

Merge branch 'saket_be' into develop

parents 5f6400ea 4a55a0de
No related branches found
No related tags found
No related merge requests found
......@@ -97,7 +97,6 @@ def budget_view() -> Any:
with db.session_scope() as session:
entries = sorted([_extract_data(entry)
for entry in session.query(model.BudgetEntry)],
key=lambda d: (d['BUDGET_YEAR'], d['NREN']))
return jsonify(entries)
for entry in session.query(model.BudgetEntry)], key=lambda d: (d['BUDGET_YEAR'], d['NREN']))
dict_obj = {"data": entries}
return jsonify(dict_obj)
......@@ -26,6 +26,16 @@ export interface BudgetMatrix{
title:string
}
export interface Budget{
data: {
BUDGET: string,
BUDGET_YEAR: number,
NREN: string,
id: number
}[]
}
export interface DataEntrySection {
name: string,
description: string,
......
......@@ -3,8 +3,9 @@ import {Accordion, Col, Container, ListGroup, Row} from "react-bootstrap";
import BarGraph from "../components/graphing/BarGraph";
import LineGraph from "../components/graphing/LineGraph";
import {BudgetMatrix, DataEntrySection} from "../Schema";
import {BudgetMatrix, DataEntrySection,Budget} from "../Schema";
// import {evaluateInteractionItems} from "chart.js/dist/core/core.interaction";
import barGraph from "../components/graphing/BarGraph";
export const options = {
......@@ -35,84 +36,201 @@ function DataAnalysis(): ReactElement {
return response.json() as Promise<T>;
})
}
const [budgetResponse, setBudgetMatrix] = useState<BudgetMatrix>();
const [budgetMatrixResponse, setBudgetMatrixResponse] = useState<BudgetMatrix>();
const [budgetResponse, setBudget] = useState<Budget>();
const [dataEntrySection, setDataEntrySection] = useState<DataEntrySection>();
const [selectedDataEntry, setSelectedDataEntry] = useState<number>(0);
// const [services, setServices] = useState<Service[][]>();
useEffect(() => {
// let timeoutRef = 0;
const getDataEntries = () => {
api<DataEntrySection>('/api/data-entries/sections/1', {
referrerPolicy: "unsafe-url",
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "text/plain"
}
}).then( (dataEntrySectionResponse: DataEntrySection) => {
setDataEntrySection(dataEntrySectionResponse);
// Autoload the first graph
if (dataEntrySectionResponse.items.length > 0) {
setSelectedDataEntry(dataEntrySectionResponse.items[0].id);
}
})
const dataEntrySectionResponse: DataEntrySection={
description:"Org",
items:[
{
id:2,
title:"NREN Budgets per year, in Millions EUR",
url:"/api/data-entries/item/2"
}
// {
// id:3,
// title:"NREN Budgets per NREN, in Millions EUR",
// url:"/api/data-entries/item/3"
// }
],
name:"Organisation"
}
setDataEntrySection(dataEntrySectionResponse);
console.log("getDataEntries "+dataEntrySection);
// Autoload the first graph
if (dataEntrySectionResponse.items.length > 0) {
setSelectedDataEntry(dataEntrySectionResponse.items[0].id);
}
}
const loadData = () => {
console.log("selectedDataEntry "+selectedDataEntry)
if (selectedDataEntry == 0) {
getDataEntries();
return;
}
console.log("budgetResponse "+budgetResponse)
if(budgetResponse==undefined) {
api<Budget>('/api/budget', {
referrerPolicy: "unsafe-url",
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "text/plain",
"Access-Control-Allow-Methods": "GET, POST, PATCH, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Origin, Content-Type, X-Auth-Token"
api<BudgetMatrix>('/api/budget' + selectedDataEntry,{
referrerPolicy: "unsafe-url",
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "text/plain"
}
})
.then((budgetMatrix :BudgetMatrix)=>{
options.plugins.title.text = budgetMatrix.title;
setBudgetMatrix(budgetMatrix)
}
})
.then((budget: Budget) => {
if (selectedDataEntry == 2)
options.plugins.title.text = 'NREN Budgets per year, in Millions EUR';
setBudget(budget)
console.log("API positive response Budget : "+ budget)
convertToBudgetPerYearDataResponse(budget)
})
.catch(error => {
console.log(`Error fetching from API: ${error}`);
})
}else {
convertToBudgetPerYearDataResponse(budgetResponse)
}
}
loadData()
}, [selectedDataEntry]);
const empty_bar_response = {
'data': {
'datasets': [
{
'backgroundColor':'',
'data':[],
'label':''
}],
'labels':[]
},
'description': "",
'id': "",
'settings':{},
'title':''
}
data: {
datasets: [
{
backgroundColor:'',
data:[],
label:''
}],
labels:[]
},
description: "",
id: "",
settings:{},
title:""
}
const empty_budget_response = {
data: [{
BUDGET: "",
BUDGET_YEAR: 0,
NREN: "",
id: 0
}]
}
const convertToBudgetPerYearDataResponse = (budgetResponse:Budget) => {
console.log("convertToBudgetPerYearDataResponse budgetResponse "+budgetResponse);
const barResponse=budgetResponse!=undefined?budgetResponse:empty_budget_response;
const labelsYear = [...new Set(barResponse.data.map((item ) => item.BUDGET_YEAR))];
const labelsNREN = [...new Set(barResponse.data.map((item ) => item.NREN))];
const barResponse: BudgetMatrix = budgetResponse !== undefined ? budgetResponse : empty_bar_response;
console.log("convertToBudgetPerYearDataResponse "+barResponse);
function getRandomColor() {
const red = Math.floor(Math.random() * 256).toString(16).padStart(2, '0'); // generates a value between 00 and ff
const green = Math.floor(Math.random() * 256).toString(16).padStart(2, '0');
const blue = Math.floor(Math.random() * 256).toString(16).padStart(2, '0');
return `#${red}${green}${blue}`;
}
function dataForNRENForYear(year:number,nren :string){
const budget = barResponse.data.find(function (entry,index){
if(entry.BUDGET_YEAR== year && entry.NREN== nren) {
return Number(entry.BUDGET);
}
})
return budget !== undefined?Number(budget.BUDGET):null;
}
const datasetPerYear = labelsYear.map(function (year){
const randomColor = getRandomColor();
return {
backgroundColor: randomColor,
borderColor:randomColor,
data: labelsNREN.map(nren => dataForNRENForYear(year,nren)),
label:year.toString()
}
})
const datasetPerNREN = labelsNREN.map(function (nren){
const randomColor = getRandomColor();
return {
backgroundColor: randomColor,
borderColor:randomColor,
data: labelsYear.map(year => dataForNRENForYear(year,nren)),
label:nren
}
})
if(selectedDataEntry==2){
const dataResponse : BudgetMatrix ={
data: {
datasets: datasetPerNREN,
labels: labelsYear.map(l=>l.toString())
},
description: "The numbers are based on 30 NRENs that " +
"reported their budgets continuously throughout this" +
" period. This means that some larger NRENs are not" +
" included and therefore the actual total budgets will" +
" have been higher. (For comparison, the total budget" +
" according to the 2021 survey results based on the data" +
" for all responding NRENs that year is €555 M). The" +
" percentage change is based on the previous year’s" +
" budget.",
id: "3",
settings:{},
title:'NREN Budgets per NREN, in Millions EUR'
}
setBudgetMatrixResponse(dataResponse);
}
else{
const dataResponse : BudgetMatrix ={
data: {
datasets: datasetPerYear,
labels: labelsNREN.map(l=>l.toString())
},
description:
"The numbers are based on 30 NRENs that reported their " +
"budgets continuously throughout this period. This " +
"means that some larger NRENs are not included and " +
"therefore the actual total budgets will have been " +
"higher. (For comparison, the total budget according to" +
" the 2021 survey results based on the data for all" +
" responding NRENs that year is €555 M). The percentage" +
" change is based on the previous year’s budget.",
id: "2",
settings:{},
title:'NREN Budgets per year, in Millions EUR'
}
setBudgetMatrixResponse(dataResponse);
}
}
const barResponse: BudgetMatrix = budgetMatrixResponse !== undefined
? budgetMatrixResponse : empty_bar_response;
return (
<div>
<h1>Data Analysis</h1>
<Container>
<Row>
<Col>
<Row>
<BarGraph data={barResponse.data} />
</Row>
<Row>
<LineGraph data={barResponse.data} />
</Row>
<Row>{budgetResponse?.description}</Row>
<Row>{budgetMatrixResponse?.description}</Row>
</Col>
<Col xs={3}>
......
{
"compilerOptions": {
"target": "ES6",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"allowSyntheticDefaultImports": true,
......
......@@ -85,7 +85,7 @@ const config: Configuration = {
// Allow SPA urls to work with dev-server
historyApiFallback: true,
proxy: {
"/api": "http://127.0.0.1:5000",
"/api": "http://127.0.0.1:33333",
},
},
plugins: [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment