Skip to content

Commit

Permalink
feat(graphs): Add graph about publications with at least one explicit…
Browse files Browse the repository at this point in the history
… mention
  • Loading branch information
annelhote committed Sep 20, 2024
1 parent 89a15e7 commit e136c67
Show file tree
Hide file tree
Showing 11 changed files with 574 additions and 373 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ const Chart = ({ domain, hasComments, hasFooter, id }) => {
const chartRef = useRef();
const intl = useIntl();
const [chartComments, setChartComments] = useState('');
const { beforeLastObservationSnap, lastObservationSnap } = useGlobals();
const { lastObservationSnap } = useGlobals();
const { allData, isError, isLoading } = useGetData(
beforeLastObservationSnap,
lastObservationSnap,
domain,
);
Expand Down Expand Up @@ -74,7 +73,7 @@ Chart.defaultProps = {
domain: '',
hasComments: true,
hasFooter: true,
id: 'data.general.mentions.datasets-with-implicit-mentions-only',
id: 'data.general.mentions.datasets-with-at-least-one-explicit-mention',
};
Chart.propTypes = {
domain: PropTypes.oneOf(domains),
Expand Down
25 changes: 11 additions & 14 deletions src/components/Charts/data/general/mentions/get-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@ import { useIntl } from 'react-intl';

import { ES_API_URL, HEADERS } from '../../../../../config/config';
import getFetchOptions from '../../../../../utils/chartFetchOptions';
import {
capitalize,
getCSSValue,
getObservationLabel,
} from '../../../../../utils/helpers';
import { capitalize, getCSSValue } from '../../../../../utils/helpers';

function useGetData(beforeLastObservationSnap, observationSnap, domain) {
function useGetData(observationSnap, domain) {
const intl = useIntl();
const [allData, setData] = useState({});
const [isError, setError] = useState(false);
Expand All @@ -19,7 +15,7 @@ function useGetData(beforeLastObservationSnap, observationSnap, domain) {
const getDataForLastObservationSnap = useCallback(
async (lastObservationSnap) => {
const query = getFetchOptions({
key: 'datasetsWithImplicitMentionsOnly',
key: 'datasetsWithAtLeastOneExplicitMention',
domain,
parameters: [lastObservationSnap],
objectType: ['publications'],
Expand All @@ -30,7 +26,7 @@ function useGetData(beforeLastObservationSnap, observationSnap, domain) {
);
const bsoDomain = intl.formatMessage({ id: `app.bsoDomain.${domain}` });
const years = [];
const shared = [];
const publications = [];
const noOutline = {
style: {
textOutline: 'none',
Expand All @@ -47,15 +43,16 @@ function useGetData(beforeLastObservationSnap, observationSnap, domain) {
years.push(el.key);
const numberOfDatasetsWithImplicitMentionsOnly = el.is_implicit.buckets.find((item) => item.key === 1)?.doc_count
|| 0;
const numberOfDatasetsWithMixedMentions = el.is_implicit.buckets.find((item) => item.key === 0)?.doc_count
const numberOfDatasetsWithAtLeastOneExplicitMention = el.is_implicit.buckets.find((item) => item.key === 0)?.doc_count
|| 0;
const numberOfDatasets = numberOfDatasetsWithImplicitMentionsOnly
+ numberOfDatasetsWithMixedMentions;
shared.push({
+ numberOfDatasetsWithAtLeastOneExplicitMention;
publications.push({
y:
(numberOfDatasetsWithImplicitMentionsOnly / numberOfDatasets)
(numberOfDatasetsWithAtLeastOneExplicitMention
/ numberOfDatasets)
* 100,
y_abs: numberOfDatasetsWithImplicitMentionsOnly,
y_abs: numberOfDatasetsWithAtLeastOneExplicitMention,
y_tot: numberOfDatasets,
x: el.key,
bsoDomain,
Expand All @@ -69,7 +66,7 @@ function useGetData(beforeLastObservationSnap, observationSnap, domain) {
id: 'app.publication',
}),
),
data: shared,
data: publications,
color: getCSSValue('--publication-100'),
dataLabels: noOutline,
},
Expand Down
103 changes: 103 additions & 0 deletions src/components/Charts/software/general/mentions/get-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import Axios from 'axios';
import { useCallback, useEffect, useState } from 'react';
import { useIntl } from 'react-intl';

import { ES_API_URL, HEADERS } from '../../../../../config/config';
import getFetchOptions from '../../../../../utils/chartFetchOptions';
import { capitalize, getCSSValue } from '../../../../../utils/helpers';

function useGetData(observationSnap, domain) {
const intl = useIntl();
const [allData, setData] = useState({});
const [isError, setError] = useState(false);
const [isLoading, setLoading] = useState(true);

const getDataForLastObservationSnap = useCallback(
async (lastObservationSnap) => {
const query = getFetchOptions({
key: 'codeWithAtLeastOneExplicitMention',
domain,
parameters: [lastObservationSnap],
objectType: ['publications'],
});
const res = await Axios.post(ES_API_URL, query, HEADERS);
const data = res.data.aggregations.by_publication_year.buckets.sort(
(a, b) => a.key - b.key,
);
const bsoDomain = intl.formatMessage({ id: `app.bsoDomain.${domain}` });
const years = [];
const publications = [];
const noOutline = {
style: {
textOutline: 'none',
},
};
data
.filter(
(el) => el.key > 2012
&& lastObservationSnap.length
&& parseInt(el.key, 10)
< parseInt(lastObservationSnap?.substring(0, 4), 10),
)
.forEach((el) => {
years.push(el.key);
const numberOfSoftwareWithImplicitMentionsOnly = el.is_implicit.buckets.find((item) => item.key === 1)?.doc_count
|| 0;
const numberOfSoftwareWithAtLeastOneExplicitMention = el.is_implicit.buckets.find((item) => item.key === 0)?.doc_count
|| 0;
const numberOfSoftware = numberOfSoftwareWithImplicitMentionsOnly
+ numberOfSoftwareWithAtLeastOneExplicitMention;
publications.push({
y:
(numberOfSoftwareWithAtLeastOneExplicitMention
/ numberOfSoftware)
* 100,
y_abs: numberOfSoftwareWithAtLeastOneExplicitMention,
y_tot: numberOfSoftware,
x: el.key,
bsoDomain,
});
});

const dataGraph = [
{
name: capitalize(
intl.formatMessage({
id: 'app.publication',
}),
),
data: publications,
color: getCSSValue('--publication-100'),
dataLabels: noOutline,
},
];

return {
categories: years,
dataGraph,
};
},
[domain, intl],
);

useEffect(() => {
async function getData() {
try {
const dataGraph = await getDataForLastObservationSnap(observationSnap);
setData(dataGraph);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
setError(true);
} finally {
setLoading(false);
}
}
getData();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [observationSnap]);

return { allData, isError, isLoading };
}

export default useGetData;
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import Highcharts from 'highcharts';
import HCExportingData from 'highcharts/modules/export-data';
import HCExporting from 'highcharts/modules/exporting';
import HighchartsReact from 'highcharts-react-official';
import PropTypes from 'prop-types';
import React, { useEffect, useRef, useState } from 'react';
import { useIntl } from 'react-intl';

import customComments from '../../../../../utils/chartComments';
import { chartOptions } from '../../../../../utils/chartOptions';
import { domains, graphIds } from '../../../../../utils/constants';
import { getObservationLabel, withDomain } from '../../../../../utils/helpers';
import useGlobals from '../../../../../utils/Hooks/useGetGlobals';
import WrapperChart from '../../../../WrapperChart';
import GraphComments from '../../../graph-comments';
import useGetData from './get-data';

HCExporting(Highcharts);
HCExportingData(Highcharts);

const Chart = ({ domain, hasComments, hasFooter, id }) => {
const chartRef = useRef();
const intl = useIntl();
const [chartComments, setChartComments] = useState('');
const { lastObservationSnap } = useGlobals();
const { allData, isError, isLoading } = useGetData(
lastObservationSnap,
domain,
);
const { categories, dataGraph } = allData;
const dataTitle = {
observationYear: getObservationLabel(lastObservationSnap, intl),
};
const idWithDomain = withDomain(id, domain);
const optionsGraph = chartOptions[id].getOptions(
idWithDomain,
intl,
categories,
dataGraph,
dataTitle,
);
const hasBeta = true;
useEffect(() => {
setChartComments(customComments(allData, idWithDomain, intl));
}, [allData, idWithDomain, intl]);

return (
<WrapperChart
chartRef={chartRef}
dataTitle={dataTitle}
domain={domain}
hasBeta={hasBeta}
hasComments={false}
hasFooter={hasFooter}
id={id}
isError={isError}
isLoading={isLoading || !dataGraph || !categories}
>
<HighchartsReact
highcharts={Highcharts}
id={idWithDomain}
options={optionsGraph}
ref={chartRef}
/>
{hasComments && chartComments && (
<GraphComments comments={chartComments} hasFooter={hasFooter} />
)}
</WrapperChart>
);
};

Chart.defaultProps = {
domain: '',
hasComments: true,
hasFooter: true,
id: 'software.general.mentions.software-with-at-least-one-explicit-mention',
};
Chart.propTypes = {
domain: PropTypes.oneOf(domains),
hasComments: PropTypes.bool,
hasFooter: PropTypes.bool,
id: PropTypes.oneOf(graphIds),
};

export default Chart;
4 changes: 1 addition & 3 deletions src/pages/BaroNational/NationalResearchData/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,19 +155,17 @@ export default function NationalResearchData() {
<QuestionSection
anchorId='general.statement'
backgroundColor={blueSoft25}
glossaryKeys={['archive-ouverte']}
intlKey='app.national-data.general.statement'
>
<BSOChart id='data.general.voies-ouverture.chart-availibility' />
</QuestionSection>
<QuestionSection
anchorId='general.mentions'
backgroundColor={blueSoft50}
glossaryKeys={['archive-ouverte']}
intlKey='app.national-data.general.mentions'
isDisplayed={!isInProduction()}
>
<BSOChart id='data.general.mentions.datasets-with-implicit-mentions-only' />
<BSOChart id='data.general.mentions.datasets-with-at-least-one-explicit-mention' />
</QuestionSection>
</GraphContent>
</GraphItem>
Expand Down
10 changes: 9 additions & 1 deletion src/pages/BaroNational/NationalSoftwareCode/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import QuestionSection from '../../../components/question-section';
import ScrollTop from '../../../components/ScrollTop';
import GlossaryEntries from '../../../translations/glossary.json';
import { mobileButtonLabel } from '../../../utils/constants';
import { getCSSValue } from '../../../utils/helpers';
import { getCSSValue, isInProduction } from '../../../utils/helpers';
import useLang from '../../../utils/Hooks/useLang';

export default function NationalSoftwareCode() {
Expand Down Expand Up @@ -145,6 +145,14 @@ export default function NationalSoftwareCode() {
>
<BSOChart id='software.general.voies-ouverture.chart-software-created' />
</QuestionSection>
<QuestionSection
anchorId='general.mentions'
backgroundColor={blueSoft50}
intlKey='app.national-software.general.mentions'
isDisplayed={!isInProduction()}
>
<BSOChart id='software.general.mentions.software-with-at-least-one-explicit-mention' />
</QuestionSection>
</GraphContent>
</GraphItem>

Expand Down
7 changes: 4 additions & 3 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,7 @@
"app.data.navigation.editeurs.statement": "Data availability statement",
"app.data.navigation.partage": "Datasets sharing",
"app.data.navigation.statement": "Data availability statement",
"app.data.navigation.mentions": "Explicit references to datasets",
"app.data.navigation.utilisation": "Datasets use",
"app.doi": "with a Crossref DOI",
"app.doi-hal": "with a Crossref DOI or hal ID",
Expand Down Expand Up @@ -1324,8 +1325,8 @@
"app.national-data.general.voies-ouverture.chart-availibility.tooltip": "<b>Publication year {point.x}</b><br>{point.y:.2f}% of publications ((commentsName)) have a Data Availability Statement<br>({point.y_abs} / {point.y_tot} analysed publications)",
"app.national-data.general.voies-ouverture.chart-availibility.comments": "This graph shows the proportion of publications that report making data available (mention of a Data Availability Statement identified), by publication year. The presence of a Data Availability Statement in the body of the publication does not mean that the authors of the publication actually share their data when requested. This detection is achieved through an automatic analysis of the full text by the GROBID tool.",
"app.national-data.general.mentions.title": "Are the datasets mentioned by name?",
"app.national-data.general.mentions.datasets-with-implicit-mentions-only.title": "Proportion of publications containing only implicit references to datasets",
"app.national-data.general.mentions.datasets-with-implicit-mentions-only.tooltip": "{point.y:.2f}% of French publications published in <b>{point.x}</b> and mentioning datasets<br />mention them <b>implicitly only</b><br />({point.y_abs} / {point.y_tot} publications mentioning datasets)",
"app.national-data.general.mentions.datasets-with-at-least-one-explicit-mention.title": "Proportion of publications with at least one explicit reference to a dataset",
"app.national-data.general.mentions.datasets-with-at-least-one-explicit-mention.tooltip": "{point.y:.2f} % of French publications published in <b>{point.x}</b> mention<br />at least one dataset explicitly<br />({point.y_abs} / {point.y_tot} publications mentioning datasets)",
"app.national-data.disciplines.utilisation.title": "What is the level of data usage by discipline?",
"app.national-data.disciplines.creation.title": "What is the level of data production by discipline?",
"app.national-data.disciplines.partage.title": "What is the level of data sharing by discipline?",
Expand Down Expand Up @@ -1388,7 +1389,7 @@
"app.national-thesis.general.dynamique-ouverture.description": "The open access rate of French PhD theses shows a clear trend towards more and more openness. A small half of the theses defended in 2010 are open, while about ¾ of the theses defended at the end of the 2010s are open. The embargo periods temporarily show a slight decrease of the opening rate for the most recent years of defences.<linebreak></linebreak>The majority of doctoral theses are available in open access on the Internet, sometimes after a period of restriction. The temporal restrictions in the diffusion are of two kinds, embargo or confidentiality, and depend on the type of diffusion, free or restricted, chosen by the author:<linebreak></linebreak>- the embargo applies only to theses intended to be disseminated on the Internet. During the embargo period, the thesis must be disseminated in restricted access, in the French academic community.<linebreak></linebreak>- the confidentiality can apply as well to the theses intended to be diffused in free access on internet as to the theses intended to be diffused in restricted access within the premises of the institution of defense or of the French university community. During the period of confidentiality, no one can have access to the thesis. For the most recent years, the opening rate appears slightly lower, notably because of the embargo periods of one year on average.",
"app.national-thesis.general.dynamique-ouverture.title": "What are the trends of the opening of doctoral theses in France?",
"app.publications.local": "publications {commentsName}",
"app.implicit-mentions-only": "Proportion of publications containing only implicit references to datasets",
"app.with-at-least-one-explicit-mention": "Proportion of publications with at least one explicit reference to a dataset",
"app.created-data": "Proportion of publications mentionning a production of data",
"app.shared-data": "Proportion of publications mentionning a share of data",
"app.created-software": "Proportion of publications mentionning a code or software creation",
Expand Down
7 changes: 4 additions & 3 deletions src/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"app.data.navigation.creation": "Production de jeux de données",
"app.data.navigation.utilisation": "Utilisation des données",
"app.data.navigation.statement": "Data availability statement",
"app.data.navigation.mentions": "Mentions explicites de jeux de données",
"app.data.navigation.disciplines.partage": "Partage des jeux de données",
"app.data.navigation.disciplines.creation": "Production de jeux de données",
"app.data.navigation.disciplines.utilisation": "Utilisation des données",
Expand Down Expand Up @@ -120,8 +121,8 @@
"app.national-data.general.voies-ouverture.chart-availibility.tooltip": "<b>Année de publication {point.x}</b><br>{point.y:.2f} % des publications ((commentsName)) présentent un Data Availability Statement<br>({point.y_abs} / {point.y_tot} publications analysées)",
"app.national-data.general.voies-ouverture.chart-availibility.comments": "Ce graphique montre la proportion de publications qui déclarent rendre disponibles les données (mention d'un Data Availability Statement identifiée), par année de publication. La présence d'un Data Availability Statement dans le corps de la publication ne signifie pas pour autant que les auteurs de la publication partagent effectivement leurs données quand la demande leur en est faite. Cette détection est réalisée grâce à une analyse automatique du texte intégral par l'outil GROBID.",
"app.national-data.general.mentions.title": "Les jeux de données mentionnés le sont-ils nommément ?",
"app.national-data.general.mentions.datasets-with-implicit-mentions-only.title": "Proportion de publications comportant exclusivement des mentions implicites de jeux de données",
"app.national-data.general.mentions.datasets-with-implicit-mentions-only.tooltip": "{point.y:.2f} % des publications françaises parues en <b>{point.x}</b> et mentionnant des jeux de données<br />ne les mentionnent qu'<b>implicitement uniquement</b><br />({point.y_abs} / {point.y_tot} publications mentionnant des jeux de données)",
"app.national-data.general.mentions.datasets-with-at-least-one-explicit-mention.title": "Proportion des publications avec au moins une mention explicite à un jeu de données",
"app.national-data.general.mentions.datasets-with-at-least-one-explicit-mention.tooltip": "{point.y:.2f} % des publications françaises parues en <b>{point.x}</b> mentionnent<br />au moins un jeu de données de façon explicite<br />({point.y_abs} / {point.y_tot} publications mentionnant des jeux de données)",
"app.national-data.disciplines.utilisation.title": "Quel est le niveau d'utilisation de données par discipline ?",
"app.national-data.disciplines.creation.title": "Quel est le niveau de production de données par discipline ?",
"app.national-data.disciplines.partage.title": "Quel est le niveau de partage de données par discipline ?",
Expand Down Expand Up @@ -1279,7 +1280,7 @@
"app.publications.global": "publications françaises (tous domaines)",
"app.publications.health": "publications françaises en santé",
"app.publications.local": "publications {commentsName}",
"app.implicit-mentions-only": "Proportion des publications comportant exclusivement des mentions implicites de jeux de données",
"app.with-at-least-one-explicit-mention": "Proportion des publications avec au moins une mention explicite à un jeu de données",
"app.publishers": "éditeurs et plateformes",
"app.publishers-filter-label": "Sélectionner un éditeur",
"app.publishers.apc-gold": "APC Gold",
Expand Down
Loading

0 comments on commit e136c67

Please sign in to comment.