Skip to content

Commit

Permalink
Showing 7 changed files with 255 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import '../../../graph.scss';

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,
studiesTypes,
} from '../../../../../utils/constants';
import { withDomain, withtStudyType } from '../../../../../utils/helpers';
import WrapperChart from '../../../../WrapperChart';
import GraphComments from '../../../graph-comments';
import useGetData from './get-data';

HCExporting(Highcharts);
HCExportingData(Highcharts);

const Chart = ({ domain, hasComments, hasFooter, id, studyType }) => {
const chartRef = useRef();
const intl = useIntl();
const [chartComments, setChartComments] = useState('');
const { allData, isError, isLoading } = useGetData(studyType);
const { dataGraph6 } = allData;
const idWithDomain = withDomain(id, domain);
const idWithDomainAndStudyType = withtStudyType(idWithDomain, studyType);
const optionsGraph = chartOptions[id].getOptions(
idWithDomain,
intl,
dataGraph6,
studyType,
);

useEffect(() => {
setChartComments(customComments(allData, idWithDomainAndStudyType, intl));
}, [allData, idWithDomainAndStudyType, intl]);

return (
<WrapperChart
chartRef={chartRef}
domain={domain}
hasComments={false}
hasFooter={hasFooter}
id={id}
isError={isError}
isLoading={isLoading || !allData}
studyType={studyType}
>
<HighchartsReact
highcharts={Highcharts}
id={idWithDomainAndStudyType}
options={optionsGraph}
ref={chartRef}
/>
{hasComments && chartComments && (
<GraphComments comments={chartComments} hasFooter={hasFooter} />
)}
</WrapperChart>
);
};

Chart.defaultProps = {
domain: 'health',
hasComments: true,
hasFooter: true,
id: 'general.dynamique.chart-evolution-within-1-year-by-year',
studyType: 'Interventional',
};
Chart.propTypes = {
domain: PropTypes.oneOf(domains),
hasComments: PropTypes.bool,
hasFooter: PropTypes.bool,
id: PropTypes.oneOf(graphIds),
studyType: PropTypes.oneOf(studiesTypes),
};

export default Chart;
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ const Chart = ({ domain, hasComments, hasFooter, id, studyType }) => {
return (
<WrapperChart
chartRef={chartRef}
dataTitle={{ year: allData?.comments?.yearMax2 ?? 0 }}
dataTitle={{ year: allData?.comments?.yearMax ?? 0 }}
domain={domain}
hasComments={false}
hasFooter={hasFooter}
122 changes: 112 additions & 10 deletions src/components/Charts/studies/general/dynamique-ouverture/get-data.js
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ function useGetData(studyType, sponsor = '*') {
queries.push(Axios.post(ES_STUDIES_API_URL, query3, HEADERS));
const query4 = getFetchOptions({
key: 'studiesDynamiqueOuvertureWithin1Year',
parameters: [studyType, yearMin2, yearMax2],
parameters: [studyType, yearMin, yearMax],
objectType: ['clinicalTrials'],
});
queries.push(Axios.post(ES_STUDIES_API_URL, query4, HEADERS));
@@ -75,10 +75,10 @@ function useGetData(studyType, sponsor = '*') {
);
const academicWith4 = academic4?.by_has_results_within_1_year.buckets
.find((ele) => ele.key === 1)
?.by_completion_year.buckets.find((ele) => ele.key === yearMax2);
?.by_completion_year.buckets.find((ele) => ele.key === yearMax);
const academicWithout4 = academic4?.by_has_results_within_1_year.buckets
.find((ele) => ele.key === 0)
?.by_completion_year.buckets.find((ele) => ele.key === yearMax2);
?.by_completion_year.buckets.find((ele) => ele.key === yearMax);
const academicTotal4 = (academicWith4?.doc_count || 0) + (academicWithout4?.doc_count || 0);
const indus = data1.by_sponsor_type.buckets.find(
(ele) => ele.key === 'industriel',
@@ -99,10 +99,10 @@ function useGetData(studyType, sponsor = '*') {
);
const indusWith4 = indus4?.by_has_results_within_1_year.buckets
.find((el) => el.key === 1)
?.by_completion_year.buckets.find((ele) => ele.key === yearMax2);
?.by_completion_year.buckets.find((ele) => ele.key === yearMax);
const indusWithout4 = indus4?.by_has_results_within_1_year.buckets
.find((el) => el.key === 0)
?.by_completion_year.buckets.find((ele) => ele.key === yearMax2);
?.by_completion_year.buckets.find((ele) => ele.key === yearMax);
const indusTotal4 = (indusWith4?.doc_count || 0) + (indusWithout4?.doc_count || 0);
const spons = data2;
const sponsWith = spons?.by_has_result.buckets.find((el) => el.key === 1);
@@ -179,7 +179,7 @@ function useGetData(studyType, sponsor = '*') {
y: allLeadSponsorRate4,
y_abs: (academicWith4?.doc_count ?? 0) + (indusWith4?.doc_count ?? 0),
y_tot: academicTotal4 + indusTotal4,
yearMax: yearMax2,
yearMax,
});
const publicLeadSponsorsRate4 = 100 * ((academicWith4?.doc_count ?? 0) / academicTotal4);
series4[0].data.push({
@@ -188,7 +188,7 @@ function useGetData(studyType, sponsor = '*') {
y: publicLeadSponsorsRate4,
y_abs: academicWith4?.doc_count ?? 0,
y_tot: academicTotal4,
yearMax: yearMax2,
yearMax,
});
const privateLeadSponsorsRate4 = 100 * ((indusWith4?.doc_count ?? 0) / indusTotal4);
series4[0].data.push({
@@ -197,7 +197,7 @@ function useGetData(studyType, sponsor = '*') {
y: privateLeadSponsorsRate4,
y_abs: indusWith4?.doc_count ?? 0,
y_tot: indusTotal4,
yearMax: yearMax2,
yearMax,
});
if (sponsor !== '*') {
series1[0].data.push({
@@ -224,8 +224,7 @@ function useGetData(studyType, sponsor = '*') {
y: 100 * ((sponsWith?.doc_count ?? 0) / spons?.doc_count),
y_abs: sponsWith?.doc_count ?? 0,
y_tot: spons?.doc_count ?? 0,
yearMax: yearMax2,
yearMin: yearMin2,
yearMax,
});
categories.push(sponsor);
}
@@ -334,6 +333,107 @@ function useGetData(studyType, sponsor = '*') {
];
const dataGraph5 = { categories: categories5, series: series5 };

const categories6 = data4.by_sponsor_type.buckets[0].by_has_results_within_1_year.buckets[0].by_completion_year.buckets
.sort((a, b) => a.key - b.key)
.filter((y) => y.key >= 2010 && y.key <= currentYear)
.map((item) => item.key);
const academic6 = data4.by_sponsor_type.buckets.find(
(item) => item.key === 'academique',
);
const academicData6 = [];
const industrial6 = data4.by_sponsor_type.buckets.find(
(item) => item.key === 'industriel',
);
const industrialData6 = [];
const allTypesData6 = [];

categories6.forEach((year) => {
const academicDataWithResultsForYear = academic6?.by_has_results_within_1_year?.buckets
?.find((item) => item.key === 1)
?.by_completion_year.buckets?.find((item) => item.key === year)
?.doc_count ?? 0;
const academicDataWithoutResultsForYear = academic6?.by_has_results_within_1_year?.buckets
?.find((item) => item.key === 0)
?.by_completion_year.buckets?.find((item) => item.key === year)
?.doc_count ?? 0;
const industrialDataWithResultsForYear = industrial6?.by_has_results_within_1_year?.buckets
?.find((item) => item.key === 1)
?.by_completion_year.buckets?.find((item) => item.key === year)
?.doc_count ?? 0;
const industrialDataWithoutResultsForYear = industrial6?.by_has_results_within_1_year?.buckets
?.find((item) => item.key === 0)
?.by_completion_year.buckets?.find((item) => item.key === year)
?.doc_count ?? 0;
academicData6.push({
y:
100
* (academicDataWithResultsForYear
/ (academicDataWithResultsForYear
+ academicDataWithoutResultsForYear)),
y_abs: academicDataWithResultsForYear,
y_tot:
academicDataWithResultsForYear + academicDataWithoutResultsForYear,
year,
});
industrialData6.push({
year,
y:
100
* (industrialDataWithResultsForYear
/ (industrialDataWithResultsForYear
+ industrialDataWithoutResultsForYear)),
y_abs: industrialDataWithResultsForYear,
y_tot:
industrialDataWithResultsForYear
+ industrialDataWithoutResultsForYear,
yearMax,
yearMin,
});
allTypesData6.push({
year,
y:
100
* ((academicDataWithResultsForYear + industrialDataWithResultsForYear)
/ (academicDataWithResultsForYear
+ academicDataWithoutResultsForYear
+ industrialDataWithResultsForYear
+ industrialDataWithoutResultsForYear)),
y_abs:
academicDataWithResultsForYear + industrialDataWithResultsForYear,
y_tot:
academicDataWithResultsForYear
+ academicDataWithoutResultsForYear
+ industrialDataWithResultsForYear
+ industrialDataWithoutResultsForYear,
yearMax,
yearMin,
});
});

const series6 = [
{
id: 'public',
color: getCSSValue('--lead-sponsor-public'),
data: academicData6,
name: capitalize(intl.formatMessage({ id: 'app.sponsor.academique' })),
pointPlacement: -0.2,
},
{
id: 'prive',
color: getCSSValue('--lead-sponsor-privee'),
data: industrialData6,
name: capitalize(intl.formatMessage({ id: 'app.sponsor.industriel' })),
},
{
id: 'main',
color: getCSSValue('--blue-soft-100'),
data: allTypesData6,
name: capitalize(intl.formatMessage({ id: 'app.all-sponsor-types' })),
pointPlacement: 0.2,
},
];
const dataGraph6 = { categories: categories6, series: series6 };

let allLeadSponsorRate = '';
let privateLeadSponsorsRate = '';
let publicLeadSponsorsRate = '';
@@ -366,6 +466,7 @@ function useGetData(studyType, sponsor = '*') {
privateLeadSponsorsRate3: privateLeadSponsorsRate3.toFixed(0),
publicLeadSponsorsRate,
publicLeadSponsorsRate3: publicLeadSponsorsRate3.toFixed(0),
yearMax,
yearMin2,
yearMax2,
};
@@ -376,6 +477,7 @@ function useGetData(studyType, sponsor = '*') {
dataGraph3,
dataGraph4,
dataGraph5,
dataGraph6,
};
}

6 changes: 6 additions & 0 deletions src/pages/BaroSante/EssaisCliniques/index.js
Original file line number Diff line number Diff line change
@@ -124,6 +124,12 @@ function EssaisCliniques() {
isDisplayed={!isInProduction()}
studyType='Interventional'
/>
<BSOChart
id='general.dynamique.chart-evolution-within-1-year-by-year'
domain='health'
isDisplayed={!isInProduction()}
studyType='Interventional'
/>
</QuestionSection>

<QuestionSection
2 changes: 2 additions & 0 deletions src/translations/fr.json
Original file line number Diff line number Diff line change
@@ -590,6 +590,8 @@
"app.health-interventional.general.dynamique.chart-evolution-within-1-year.title": "Part d'essais cliniques enregistrés, terminés en {year}, ayant posté un résultat et/ou déclaré une publication scientifique dans l'année après la fin de l'essai clinique",
"app.health-interventional.general.dynamique.chart-evolution-within-1-year.tooltip": "<b>Essais cliniques terminés en {point.yearMax}<br>{point.name}</b><br><b>{point.y:.2f} %</b> des essais cliniques enregistrés ont posté un résultat<br>et/ou déclaré une publication scientifique dans l'année après la fin de l'essai clinique<b> ({point.y_abs} / {point.y_tot})</b>.",
"app.health-interventional.general.dynamique.chart-evolution-within-1-year.comments": "L'observation de la part d'essais cliniques terminés qui ont posté ou publié des résultats dans l'année après la fin de l'essai clinique s'élève à {allLeadSponsorRate3} %. Ces valeurs sont faibles. Elles sont plus élevées chez les promoteurs industriels ({privateLeadSponsorsRate3} %), tandis qu'elles sont basses chez les promoteurs publiés qui partagent beaucoup moins leurs résultats ({publicLeadSponsorsRate3} %)",
"app.health-interventional.general.dynamique.chart-evolution-within-1-year-by-year.title": "Part d'essais cliniques enregistrés et terminés ayant posté un résultat et/ou déclaré une publication scientifique dans l'année après la fin de l'essai clinique par année de fin",
"app.health-interventional.general.dynamique.chart-evolution-within-1-year-by-year.tooltip": "<b>Essais cliniques terminés en {point.year}<br>{point.name}</b><br><b>{point.y:.2f} %</b> des essais cliniques enregistrés ont posté un résultat<br>et/ou déclaré une publication scientifique dans l'année après la fin de l'essai clinique par année de fin<b> ({point.y_abs} / {point.y_tot})</b>.",
"app.health-interventional.general.sankey.Active, not recruiting.label": "Actif, ne recrute plus",
"app.health-interventional.general.sankey.Completed.label": "Essais cliniques enregistrés publiquement<br>et terminés",
"app.health-interventional.general.sankey.Enrolling by invitation.label": "Sur invitation",
5 changes: 5 additions & 0 deletions src/utils/chartComponents.js
Original file line number Diff line number Diff line change
@@ -153,6 +153,9 @@ const ChartEvolutionWithin3YearsByYearStudies = lazy(() => import(
const ChartEvolutionWithin1YearStudies = lazy(() => import(
'../components/Charts/studies/general/dynamique-ouverture/chart-evolution-within-1-year'
));
const ChartEvolutionWithin1YearByYearStudies = lazy(() => import(
'../components/Charts/studies/general/dynamique-ouverture/chart-evolution-within-1-year-by-year'
));
const ChartRepartitionStudies = lazy(() => import('../components/Charts/studies/general/trajectoires/chart-repartition'));
const ChartDynamiqueNombreStudies = lazy(() => import(
'../components/Charts/studies/promoteurs/dynamique-ouverture/chart-evolution-nombre'
@@ -384,6 +387,8 @@ const chartComponents = {
ChartEvolutionWithin3YearsByYearStudies,
'general.dynamique.chart-evolution-within-1-year':
ChartEvolutionWithin1YearStudies,
'general.dynamique.chart-evolution-within-1-year-by-year':
ChartEvolutionWithin1YearByYearStudies,
'general.trajectoires.chart-repartition': ChartRepartitionStudies,
'caracteristiques.quand.chart-evolution-temporalites':
ChartEvolutionTemporalitesStudies,
45 changes: 45 additions & 0 deletions src/utils/chartOptions.js
Original file line number Diff line number Diff line change
@@ -2403,6 +2403,51 @@ export const chartOptions = {
return options;
},
},
'general.dynamique.chart-evolution-within-1-year-by-year': {
getOptions: (id, intl, data, studyType, dataTitle) => {
const options = getGraphOptions({ id, intl, studyType, dataTitle });
options.chart = {
type: 'bar',
height: '950px',
};
options.plotOptions = {
series: {
grouping: false,
dataLabels: {
enabled: false,
},
pointWidth: 15,
},
bar: {
dataLabels: {
enabled: true,
format: '{point.y:.0f} %',
},
},
};
options.yAxis = getPercentageYAxis(true);
options.xAxis = {
type: 'category',
categories: data?.categories || [],
title: {
text: intl.formatMessage({ id: 'app.study-completion-year' }),
},
lineWidth: 0,
tickWidth: 0,
reversed: false,
labels: {
style: {
color: getCSSValue('--g800'),
fontSize: '12px',
fontWeight: 'bold',
},
},
};
options.legend.reversed = true;
options.series = data?.series || [];
return options;
},
},
'general.trajectoires.chart-repartition': {
getOptions: (id, intl, data, studyType) => {
const nodeColor = {

0 comments on commit a268d55

Please sign in to comment.