diff --git a/compendium_v2/routes/budget.py b/compendium_v2/routes/budget.py index 457536643a9f9ef2c65a1e67eb4c32bb290e6845..90a7b258553c3f33233329a2020cb03bc6b8741f 100644 --- a/compendium_v2/routes/budget.py +++ b/compendium_v2/routes/budget.py @@ -97,6 +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'])) - dict_obj = {"data": entries} - return jsonify(dict_obj) + for entry in session.query(model.BudgetEntry)], + key=lambda d: (d['BUDGET_YEAR'], d['NREN'])) + return jsonify(entries) diff --git a/webapp/src/Schema.tsx b/webapp/src/Schema.tsx index 9105f43db1625ab0b16f50f178b5804e35d0f866..192bfd5ed9fc418c93ab5c25d8aa0c43ac430e1f 100644 --- a/webapp/src/Schema.tsx +++ b/webapp/src/Schema.tsx @@ -7,11 +7,11 @@ export interface ServiceMatrix { export interface Nren { name: string - nren_id:number + nren_id: number tags: string[] } -export interface BudgetMatrix{ +export interface BudgetMatrix { data: { labels: string[], datasets: { @@ -20,19 +20,17 @@ export interface BudgetMatrix{ backgroundColor: string }[] }, - description : string, + description: string, id: string, settings: Record<string, unknown>, - title:string + title: string } -export interface Budget{ - data: { - BUDGET: string, - BUDGET_YEAR: number, - NREN: string, - id: number - }[] +export interface Budget { + BUDGET: string, + BUDGET_YEAR: number, + NREN: string, + id: number } @@ -48,24 +46,24 @@ export interface DataEntrySection { export interface Service { compendium_id: number, - country_code:string, - country_name:string, - created_at:Date, - id:number, - identifier:string, + country_code: string, + country_name: string, + created_at: Date, + id: number, + identifier: string, kpi: string[], - nren_abbreviation:string - nren_id:number, - public:boolean, - question_id:number, - question_style:string, - response_id:number, - short:string, - status:number, - tags:string[], - title:string, - title_detailed:string, - updated_at:Date, - url:string, - value:string + nren_abbreviation: string + nren_id: number, + public: boolean, + question_id: number, + question_style: string, + response_id: number, + short: string, + status: number, + tags: string[], + title: string, + title_detailed: string, + updated_at: Date, + url: string, + value: string } diff --git a/webapp/src/pages/DataAnalysis.tsx b/webapp/src/pages/DataAnalysis.tsx index 44779b2b96821b566d85ae1a2e9bcf9ef9ede1e7..9a0cfdac48e4d247289e8fe3259e7afeacf4d8a7 100644 --- a/webapp/src/pages/DataAnalysis.tsx +++ b/webapp/src/pages/DataAnalysis.tsx @@ -1,9 +1,9 @@ -import React, {ReactElement, useEffect, useState} from 'react'; -import {Accordion, Col, Container, ListGroup, Row} from "react-bootstrap"; +import React, { ReactElement, useEffect, useState } from 'react'; +import { Accordion, Col, Container, ListGroup, Row } from "react-bootstrap"; import BarGraph from "../components/graphing/BarGraph"; import LineGraph from "../components/graphing/LineGraph"; -import {BudgetMatrix, DataEntrySection,Budget} from "../Schema"; +import { BudgetMatrix, DataEntrySection, Budget } from "../Schema"; // import {evaluateInteractionItems} from "chart.js/dist/core/core.interaction"; import barGraph from "../components/graphing/BarGraph"; @@ -37,45 +37,45 @@ function DataAnalysis(): ReactElement { }) } const [budgetMatrixResponse, setBudgetMatrixResponse] = useState<BudgetMatrix>(); - const [budgetResponse, setBudget] = useState<Budget>(); + const [budgetResponse, setBudget] = useState<Budget[]>(); const [dataEntrySection, setDataEntrySection] = useState<DataEntrySection>(); const [selectedDataEntry, setSelectedDataEntry] = useState<number>(0); useEffect(() => { // let timeoutRef = 0; const getDataEntries = () => { - const dataEntrySectionResponse: DataEntrySection={ - description:"Org", - items:[ + const dataEntrySectionResponse: DataEntrySection = { + description: "Org", + items: [ { - id:2, - title:"NREN Budgets per year, in Millions EUR", - url:"/api/data-entries/item/2" + 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" + ], + name: "Organisation" } setDataEntrySection(dataEntrySectionResponse); - console.log("getDataEntries "+dataEntrySection); + console.log("getDataEntries " + dataEntrySection); // Autoload the first graph if (dataEntrySectionResponse.items.length > 0) { setSelectedDataEntry(dataEntrySectionResponse.items[0].id); } } const loadData = () => { - console.log("selectedDataEntry "+selectedDataEntry) + console.log("selectedDataEntry " + selectedDataEntry) if (selectedDataEntry == 0) { getDataEntries(); return; } - console.log("budgetResponse "+budgetResponse) - if(budgetResponse==undefined) { - api<Budget>('/api/budget', { + console.log("budgetResponse " + budgetResponse) + if (budgetResponse == undefined) { + api<Budget[]>('/api/budget', { referrerPolicy: "unsafe-url", headers: { "Access-Control-Allow-Origin": "*", @@ -85,17 +85,17 @@ function DataAnalysis(): ReactElement { } }) - .then((budget: Budget) => { + .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) + console.log("API positive response Budget : " + budget) convertToBudgetPerYearDataResponse(budget) }) .catch(error => { console.log(`Error fetching from API: ${error}`); }) - }else { + } else { convertToBudgetPerYearDataResponse(budgetResponse) } @@ -107,35 +107,33 @@ function DataAnalysis(): ReactElement { data: { datasets: [ { - backgroundColor:'', - data:[], - label:'' - }], - labels:[] + backgroundColor: '', + data: [], + label: '' + }], + labels: [] }, description: "", id: "", - settings:{}, - title:"" + settings: {}, + title: "" } - const empty_budget_response = { - data: [{ - BUDGET: "", - BUDGET_YEAR: 0, - NREN: "", - id: 0 - }] - } + const empty_budget_response = [{ + 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 convertToBudgetPerYearDataResponse = (budgetResponse: Budget[]) => { + console.log("convertToBudgetPerYearDataResponse budgetResponse " + budgetResponse); + const barResponse = budgetResponse != undefined ? budgetResponse : empty_budget_response; + const labelsYear = [...new Set(barResponse.map((item) => item.BUDGET_YEAR))]; + const labelsNREN = [...new Set(barResponse.map((item) => item.NREN))]; - console.log("convertToBudgetPerYearDataResponse "+barResponse); + console.log("convertToBudgetPerYearDataResponse " + barResponse); function getRandomColor() { @@ -146,40 +144,40 @@ function DataAnalysis(): ReactElement { } - function dataForNRENForYear(year:number,nren :string){ - const budget = barResponse.data.find(function (entry,index){ - if(entry.BUDGET_YEAR== year && entry.NREN== nren) { + function dataForNRENForYear(year: number, nren: string) { + const budget = barResponse.find(function (entry, index) { + if (entry.BUDGET_YEAR == year && entry.NREN == nren) { return Number(entry.BUDGET); } }) - return budget !== undefined?Number(budget.BUDGET):null; + return budget !== undefined ? Number(budget.BUDGET) : null; } - const datasetPerYear = labelsYear.map(function (year){ + const datasetPerYear = labelsYear.map(function (year) { const randomColor = getRandomColor(); return { backgroundColor: randomColor, - borderColor:randomColor, - data: labelsNREN.map(nren => dataForNRENForYear(year,nren)), - label:year.toString() + borderColor: randomColor, + data: labelsNREN.map(nren => dataForNRENForYear(year, nren)), + label: year.toString() } }) - const datasetPerNREN = labelsNREN.map(function (nren){ + const datasetPerNREN = labelsNREN.map(function (nren) { const randomColor = getRandomColor(); return { backgroundColor: randomColor, - borderColor:randomColor, - data: labelsYear.map(year => dataForNRENForYear(year,nren)), - label:nren + borderColor: randomColor, + data: labelsYear.map(year => dataForNRENForYear(year, nren)), + label: nren } }) - if(selectedDataEntry==2){ - const dataResponse : BudgetMatrix ={ + if (selectedDataEntry == 2) { + const dataResponse: BudgetMatrix = { data: { datasets: datasetPerNREN, - labels: labelsYear.map(l=>l.toString()) + labels: labelsYear.map(l => l.toString()) }, description: "The numbers are based on 30 NRENs that " + "reported their budgets continuously throughout this" + @@ -191,16 +189,16 @@ function DataAnalysis(): ReactElement { " percentage change is based on the previous year’s" + " budget.", id: "3", - settings:{}, - title:'NREN Budgets per NREN, in Millions EUR' + settings: {}, + title: 'NREN Budgets per NREN, in Millions EUR' } setBudgetMatrixResponse(dataResponse); } - else{ - const dataResponse : BudgetMatrix ={ + else { + const dataResponse: BudgetMatrix = { data: { datasets: datasetPerYear, - labels: labelsNREN.map(l=>l.toString()) + labels: labelsNREN.map(l => l.toString()) }, description: "The numbers are based on 30 NRENs that reported their " + @@ -212,8 +210,8 @@ function DataAnalysis(): ReactElement { " 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' + settings: {}, + title: 'NREN Budgets per year, in Millions EUR' } setBudgetMatrixResponse(dataResponse); }