Skip to content

Commit

Permalink
Merge pull request #9 from dataesr/fundingRankingCharts
Browse files Browse the repository at this point in the history
add first chart - part 1
  • Loading branch information
jerem1508 authored Mar 11, 2024
2 parents 0d9612a + 0974baa commit 5c435f1
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 0 deletions.
9 changes: 9 additions & 0 deletions client/src/pages/european-projects/charts-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,14 @@
"source": "Commission européenne, Cordis",
"sourceURL": "https://cordis.europa.eu/",
"integrationURL": "/european-projects/components/pages/analysis/positioning/charts/top-10-beneficiaries"
},
{
"id": "fundingRankingSub",
"title": "",
"subtitle": "Subventions demandées et obtenues (M€) par pays",
"description": "Ad duis occaecat voluptate deserunt tempor enim nulla officia.",
"source": "Commission européenne, Cordis",
"sourceURL": "https://cordis.europa.eu/",
"integrationURL": "/european-projects/components/pages/analysis/positioning/charts/top-10-participating-organizations"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useQuery } from "@tanstack/react-query";

import Template from "./template";
import { GetData } from "./query";
import options from "./options";
import ChartWrapper from "../../../../../chart-wrapper";

export default function FundingRanking() {
const { data, isLoading } = useQuery({
queryKey: ["fundingRanking"],
queryFn: () => GetData()
})

if (isLoading || !data) return <Template />

const prepareData = (data, sortKey) => {
return data.sort((a, b) => b[sortKey] - a[sortKey]).slice(0, 10);
}

return (
<ChartWrapper
id="fundingRankingSub"
options={options(prepareData(data, "total_successful"))}
legend={(
<ul className="legend">
<li style={{ display: "flex", alignItems: "center", marginBottom: "5px" }}>
<div style={{ width: "20px", height: "20px", background: "#009099", marginRight: "10px" }} />
<span>Projets évalués</span>
</li>
<li style={{ display: "flex", alignItems: "center", marginBottom: "5px" }}>
<div style={{ width: "20px", height: "20px", background: "#233E41", marginRight: "10px" }} />
<span>Projets lauréats</span>
</li>
</ul>
)}
/>
)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
export default function Options(data) {
if (!data) return null;

return {
chart: {
type: "bar",
height: 500,
},
title: { text: "" },
legend: { enabled: false },
credits: { enabled: false },

xAxis: {
type: 'category',
labels: {
autoRotation: [-45, -90],
style: {
fontSize: '13px',
fontFamily: 'Verdana, sans-serif'
}
}
},
yAxis: {
min: 0,
title: {
text: 'Euros € (millions)'
}
},
tooltip: {
pointFormat: 'Total des subventions : <b>{point.y:.1f} €</b>'
},
plotOptions: {
series: { dataLabels: { enabled: true } }
},
series: [
{
name: 'Total subventions en euros',
colors: ['#009099'],
colorByPoint: true,
groupPadding: 0,
data: data.map((item) => ({
name: item.name,
y: item.total_evaluated,
rank_evaluated: item.rank_evaluated,
})),
dataLabels: [{
align: 'right',
format: '{point.rank_evaluated}e'
}],
},
{
name: 'Total subventions en euros',
colors: ['#233E41'],
colorByPoint: true,
groupPadding: 0,
data: data.map((item) => ({
name: item.name,
y: item.total_successful,
rank_successful: item.rank_successful,
})),
dataLabels: [{
align: 'right',
format: '{point.rank_successful}e'
}],
}
]
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const { VITE_APP_SERVER_URL } = import.meta.env;

export async function GetData() {
const url = `${VITE_APP_SERVER_URL}/european-projects/analysis-positioning-top-10-funding-ranking`;

return fetch(url).then((response) => (response.json()))
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Template() {
return (
<>
graph template
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useSearchParams } from "react-router-dom";

import Top10Beneficiaries from "./charts/top-10-beneficiaries";
import Intro from "./charts/intro";
import FundingRanking from "./charts/funding-ranking";

export default function Positioning() {
const [searchParams, setSearchParams] = useSearchParams();
Expand All @@ -21,6 +22,7 @@ export default function Positioning() {
<div className="fr-my-5w" />
<Top10Beneficiaries />
<div className="fr-my-5w" />
<FundingRanking />

</Container>
);
Expand Down
70 changes: 70 additions & 0 deletions server/src/routes/tableaux/european-projects/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,76 @@ router.route('/european-projects/countries')
res.json(data);
});

router.route('/european-projects/analysis-positioning-top-10-funding-ranking')
.get(async (req, res) => {
const data = await db.collection('EP-fr-esr-all-projects-synthese')
.aggregate([
{ $match: { country_code: { $nin: ["ZOE", "ZOI"] } } },
{
$group: {
_id: {
id: "$country_code",
label: "$country_name_fr",
stage: "$stage",
},
total_fund_eur: { $sum: "$fund_eur" },
},
},
{
$project: {
_id: 0,
id: "$_id.id",
label: "$_id.label",
total_fund_eur: 1,
stage: "$_id.stage",
}
},
{
$group: {
_id: {
id: "$id",
name: "$label",
},
total_successful: { $sum: { $cond: [{ $eq: ["$stage", "successful"] }, "$total_fund_eur", 0] } },
total_evaluated: { $sum: { $cond: [{ $eq: ["$stage", "evaluated"] }, "$total_fund_eur", 0] } },
}
},
{
$project: {
_id: 0,
id: "$_id.id",
name: "$_id.name",
total_successful: 1,
total_evaluated: 1,
}
},
]).toArray();

const dataWithRatio = data.map((el) => {
if (el.total_evaluated === 0) {
return { ...el, ratio: 0 }
}
return { ...el, ratio: el.total_successful / el.total_evaluated * 100 }
});

// sort by total_sccessful
const dataSortedSuccessful = dataWithRatio.sort((a, b) => b.total_successful - a.total_successful);

// add successful rank to returned data
for (let i = 0; i < dataSortedSuccessful.length; i++) {
dataWithRatio.find((el) => el.id === dataSortedSuccessful[i].id).rank_successful = i + 1;
}

// sort by total_evaluated
const dataSortedEvaluated = dataWithRatio.sort((a, b) => b.total_evaluated - a.total_evaluated);

// add evaluated rank to returned data
for (let i = 0; i < dataSortedEvaluated.length; i++) {
dataWithRatio.find((el) => el.id === dataSortedEvaluated[i].id).rank_evaluated = i + 1;
}

return res.json(dataWithRatio)
});

// TODO: remove this route
router.route('/european-projects/template')
Expand Down

0 comments on commit 5c435f1

Please sign in to comment.