Skip to content
Snippets Groups Projects
Commit 04c3ccf0 authored by Saket Agrahari's avatar Saket Agrahari
Browse files

COMP-42 Nren Budget Charts

parent 17fb034a
No related branches found
No related tags found
No related merge requests found
{
"data":{
"datasets":[
{
"backgroundColor":"#fd7f6f",
"data":[
null,
null,
5.5,
0.2,
13.97,
1.0,
0.3,
10.39,
1.1,
24.41,
40.0,
6.3,
1.9,
23.0,
7.0,
21.0,
74.0,
0.3,
12.0,
10.5,
0.06,
19.0,
null,
0.4,
19.2,
2.0,
1.82,
0.4,
0.15,
0.1,
0.3,
33.27,
30.0,
4.95,
5.5,
4.0,
18.4,
5.4,
2.5,
null,
null
],
"label":"2012"
},
{
"backgroundColor":"#7eb0d5",
"data":[
null,
null,
5.6,
0.2,
13.05,
1.0,
0.4,
12.59,
1.0,
22.98,
43.0,
6.4,
1.6,
9.0,
7.2,
22.0,
104.76,
0.3,
11.0,
10.01,
6.0,
21.0,
null,
0.4,
17.6,
1.6,
1.85,
0.7,
0.15,
0.1,
0.5,
34.53,
0.25,
5.0,
null,
1.5,
19.2,
4.9,
2.4,
null,
null
],
"label":"2013"
},
{
"backgroundColor":"#b2e061",
"data":[
1.5,
null,
5.6,
null,
18.45,
null,
0.6,
10.0,
0.8,
13.0,
43.0,
6.6,
1.3,
8.0,
8.2,
21.0,
111.0,
0.3,
8.0,
10.0,
8.0,
22.7,
null,
0.4,
22.99,
1.3,
1.71,
0.7,
0.2,
null,
null,
30.95,
26.0,
5.6,
1.5,
1.0,
18.0,
4.9,
2.3,
null,
null
],
"label":"2014"
},
{
"backgroundColor":"#bd7ebe",
"data":[
1.2,
null,
5.6,
0.23,
16.46,
1.0,
0.4,
12.0,
0.4,
22.86,
40.0,
7.4,
1.3,
8.0,
7.4,
21.0,
86.4,
0.2,
7.0,
11.6,
8.0,
22.0,
null,
0.5,
23.0,
1.6,
1.65,
0.7,
0.2,
0.1,
0.5,
34.0,
22.54,
6.8,
1.5,
1.4,
18.0,
5.4,
2.4,
null,
null
],
"label":"2015"
},
{
"backgroundColor":"#ffb55a",
"data":[
null,
null,
5.7,
0.23,
13.57,
null,
0.41,
13.0,
0.87,
14.0,
49.0,
7.92,
2.5,
8.0,
7.0,
28.0,
null,
0.25,
6.5,
null,
8.0,
15.0,
null,
null,
23.2,
1.6,
2.08,
null,
0.22,
null,
null,
36.0,
30.0,
8.1,
2.0,
1.7,
null,
5.6,
1.9,
null,
null
],
"label":"2016"
},
{
"backgroundColor":"#ffee65",
"data":[
null,
0.15,
5.7,
null,
null,
null,
0.82,
14.0,
0.7,
14.0,
45.0,
null,
2.3,
8.0,
7.5,
29.0,
null,
0.3,
6.5,
34.3,
12.0,
29.0,
null,
null,
21.7,
2.0,
2.0,
null,
0.38,
null,
null,
40.0,
30.0,
8.0,
2.0,
1.7,
null,
6.0,
1.9,
18.0,
0.12
],
"label":"2017"
},
{
"backgroundColor":"#beb9db",
"data":[
0.8,
0.25,
6.1,
null,
15.52,
null,
0.72,
14.0,
3.6,
17.88,
42.0,
7.41,
2.34,
8.0,
7.5,
33.9,
null,
0.3,
6.9,
20.1,
12.0,
25.06,
3.72,
null,
22.15,
2.28,
3.48,
1.04,
0.34,
0.08,
0.33,
40.5,
20.0,
14.25,
2.0,
2.03,
19.0,
7.5,
1.98,
21.0,
0.15
],
"label":"2018"
},
{
"backgroundColor":"#fdcce5",
"data":[
0.8,
0.48,
6.1,
null,
14.48,
null,
0.924,
13.457,
0.92,
18.974,
42.343,
null,
4.772,
8.0,
7.9,
32.2,
65.23,
0.4,
6.9,
36.446,
48.0,
25.591,
3.48,
null,
22.329,
2.275,
4.027,
1.241,
0.38,
0.075,
0.955,
52.857,
null,
16.249,
2.0,
2.47,
24.0,
8.0,
1.98,
17.0,
0.176
],
"label":"2019"
}
],
"labels":[
"AL",
"AM",
"AT",
"BA",
"BE",
"BG",
"BY",
"CH",
"CY",
"CZ",
"DE",
"DK",
"EE",
"ES",
"FI",
"FR",
"GB",
"GE",
"GR",
"HR",
"HU",
"IE",
"IL",
"IS",
"IT",
"LT",
"LU",
"LV",
"MD",
"ME",
"MK",
"NL",
"NO",
"PT",
"RO",
"RS",
"SE",
"SI",
"SK",
"TR",
"UA"
]
},
"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 \u20ac555 M). The percentage change is based on the previous year\u2019s budget.",
"id":2,
"settings":{
},
"title":"NREN Budgets per year, in Millions EUR"
}
...@@ -14,6 +14,9 @@ import binascii ...@@ -14,6 +14,9 @@ import binascii
import hashlib import hashlib
import random import random
import time import time
import os
import logging
import json
from flask import Blueprint, jsonify from flask import Blueprint, jsonify
...@@ -21,6 +24,19 @@ from compendium_v2.routes import common ...@@ -21,6 +24,19 @@ from compendium_v2.routes import common
routes = Blueprint('compendium-v2-api', __name__) routes = Blueprint('compendium-v2-api', __name__)
DUMMY_DATA_FILENAME = os.path.abspath(os.path.join(
os.path.dirname(__file__),
'..',
'datasources',
'dummy-analysis.json'
))
logger = logging.getLogger(__name__)
file_name = open(DUMMY_DATA_FILENAME)
budget_matrix_response = json.loads(file_name.read())
THING_LIST_SCHEMA = { THING_LIST_SCHEMA = {
'$schema': 'http://json-schema.org/draft-07/schema#', '$schema': 'http://json-schema.org/draft-07/schema#',
...@@ -46,11 +62,75 @@ THING_LIST_SCHEMA = { ...@@ -46,11 +62,75 @@ THING_LIST_SCHEMA = {
} }
BUDGET_MATRIX_SCHEMA = {
'$schema': 'http://json-schema.org/draft-07/schema#',
'type': 'object',
'properties': {
'data': {
'type': 'object',
'properties': {
'datasets': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'backgroundColor': {
'type': 'string'
},
'data': {
'type': 'array',
"items": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
},
'label': {
'type': 'string'
}
}
}
},
'labels': {
'type': 'array',
'items': {
'type': 'string'
}
}
}
},
'description': {
'type': 'string'
},
'id': {
'type': 'number'
},
'settings': {
'type': 'object',
'properties': {}
},
'title': {
'type': 'string'
}
}
}
@routes.after_request @routes.after_request
def after_request(resp): def after_request(resp):
return common.after_request(resp) return common.after_request(resp)
@routes.route('/things', methods=['GET', 'POST']) @routes.route('/things', methods=['GET', 'POST'])
@common.require_accepts_json @common.require_accepts_json
def things(): def things():
...@@ -64,23 +144,25 @@ def things(): ...@@ -64,23 +144,25 @@ def things():
:return: :return:
""" """
return budget_matrix_response
def _hash(s, length):
m = hashlib.sha256() #
m.update(s.encode('utf-8')) # def _hash(s, length):
digest = binascii.b2a_hex(m.digest()).decode('utf-8') # m = hashlib.sha256()
return digest[-length:].upper() # m.update(s.encode('utf-8'))
# digest = binascii.b2a_hex(m.digest()).decode('utf-8')
def _make_thing(idx): # return digest[-length:].upper()
six_months = 24 * 3600 * 180 #
return { # def _make_thing(idx):
'id': _hash(f'id-{idx}', 4), # six_months = 24 * 3600 * 180
'time': int(time.time() + random.randint(-six_months, six_months)), # return {
'state': bool(idx % 2), # 'id': _hash(f'id-{idx}', 4),
'data1': _hash(f'data1-{idx}', 2), # 'time': int(time.time() + random.randint(-six_months, six_months)),
'data2': _hash(f'data2-{idx}', 8), # 'state': bool(idx % 2),
'data3': _hash(f'data3-{idx}', 32) # 'data1': _hash(f'data1-{idx}', 2),
} # 'data2': _hash(f'data2-{idx}', 8),
# 'data3': _hash(f'data3-{idx}', 32)
response = map(_make_thing, range(20)) # }
return jsonify(list(response)) #
# response = map(_make_thing, range(20))
# return jsonify(list(response))
Source diff could not be displayed: it is too large. Options to address this: view the blob.
import React, {ReactElement} from 'react'; import React, {ReactElement, useEffect, useState} from 'react';
import {Accordion, Col, Container, Form, Row} from "react-bootstrap"; import {Accordion, Col, Container, Form, Row} from "react-bootstrap";
import {Bar} from 'react-chartjs-2'; import {Bar} from 'react-chartjs-2';
...@@ -12,6 +12,7 @@ import { ...@@ -12,6 +12,7 @@ import {
Tooltip, Tooltip,
Legend, Legend,
} from 'chart.js'; } from 'chart.js';
import {BudgetMatrix, Nren, Service, ServiceMatrix} from "./Schema";
ChartJS.register( ChartJS.register(
CategoryScale, CategoryScale,
...@@ -22,6 +23,25 @@ ChartJS.register( ...@@ -22,6 +23,25 @@ ChartJS.register(
Legend Legend
); );
// const api_url = "http://[::1]:33333";
const api_url = "https://test-compendium01.geant.org";
const empty_bar_response = {
'data': {
'datasets': [
{
'backgroundColor':'',
'data':[],
'label':''
}],
'labels':[]
},
'description': "",
'id': "",
'settings':{},
'title':''
}
// Test colour pallets // Test colour pallets
const colour_palettes = [ const colour_palettes = [
["#ea5545", "#f46a9b", "#ef9b20", "#edbf33", "#ede15b", "#bdcf32", "#87bc45", "#27aeef", "#b33dc6"], ["#ea5545", "#f46a9b", "#ef9b20", "#edbf33", "#ede15b", "#bdcf32", "#87bc45", "#27aeef", "#b33dc6"],
...@@ -86,6 +106,45 @@ export const data = { ...@@ -86,6 +106,45 @@ export const data = {
function DataAnalysis(): ReactElement { function DataAnalysis(): ReactElement {
function api<T>(url: string, options: RequestInit): Promise<T> {
return fetch(url, options)
.then((response) => {
console.log(response)
if (!response.ok) {
return response.text().then((message) => {
console.error(`Failed to load datax: ${message}`, response.status);
throw new Error("The data could not be loaded, check the logs for details.");
});
}
return response.json() as Promise<T>;
})
}
const [budgetResponse, setBudgetMatrix] = useState<BudgetMatrix>();
// const [services, setServices] = useState<Service[][]>();
useEffect(() => {
// let timeoutRef = 0;
const loadData = () => {
api<BudgetMatrix>(api_url+'/api/things',{
referrerPolicy: "unsafe-url",
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "text/plain"
}
})
.then((budgetMatrix :BudgetMatrix)=>{
console.log('got response==>data');
console.log(budgetMatrix.data);
setBudgetMatrix(budgetMatrix)
})
}
loadData()
}, []);
const barResponse: BudgetMatrix = budgetResponse !== undefined ? budgetResponse : empty_bar_response;
return ( return (
<div> <div>
<h1>Data Analysis</h1> <h1>Data Analysis</h1>
...@@ -93,10 +152,10 @@ function DataAnalysis(): ReactElement { ...@@ -93,10 +152,10 @@ function DataAnalysis(): ReactElement {
<Row> <Row>
<Col> <Col>
<Row> <Row>
<Bar data={data} options={options}/> <Bar data={barResponse.data} options={options}/>
</Row> </Row>
<Row>{dataViewItem.description}</Row> <Row>{budgetResponse?.description}</Row>
</Col> </Col>
<Col xs={3}> <Col xs={3}>
......
...@@ -11,6 +11,21 @@ export interface Nren { ...@@ -11,6 +11,21 @@ export interface Nren {
tags: string[] tags: string[]
} }
export interface BudgetMatrix{
data: {
labels: string[],
datasets: {
label: string,
data: (number | null)[],
backgroundColor: string
}[]
},
description : string,
id: string,
settings: Record<string, unknown>,
title:string
}
export interface Service { export interface Service {
compendium_id: number, compendium_id: number,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment