Skip to content

Commit 3bde6b9

Browse files
committed
Add learning by sector and regions bar chart
1 parent cbe00a9 commit 3bde6b9

File tree

3 files changed

+179
-2
lines changed

3 files changed

+179
-2
lines changed

app/src/views/OperationalLearning/i18n.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
"failedToCreateExport": "Failed to generate export.",
2121
"disclaimerMessage": "This is an updated implementation of the Operational Learning project started by the DREF and PER teams at IFRC. The previous dashboard can be found {link}.",
2222
"here": "here",
23-
"beta": "beta"
23+
"beta": "beta",
24+
"learningBySector": "learnings by sectors",
25+
"learningByRegions": "learnings by regions",
26+
"sourceOvertime": "Sources Overtime"
2427
}
2528
}

app/src/views/OperationalLearning/index.tsx

Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
} from 'react';
66
import { InfoIcon } from '@ifrc-go/icons';
77
import {
8+
BarChart,
89
Button,
910
Chip,
1011
Container,
@@ -18,9 +19,12 @@ import {
1819
TabPanel,
1920
Tabs,
2021
TextOutput,
22+
TimeSeriesChart,
2123
} from '@ifrc-go/ui';
2224
import { useTranslation } from '@ifrc-go/ui/hooks';
2325
import {
26+
getDatesSeparatedByMonths,
27+
getFormattedDateKey,
2428
hasSomeDefinedValue,
2529
numericIdSelector,
2630
resolveToComponent,
@@ -98,6 +102,83 @@ const disasterTypeKeySelector = (type: DisasterType) => type.id;
98102
const disasterTypeLabelSelector = (type: DisasterType) => type.name ?? '?';
99103

100104
/** @knipignore */
105+
106+
const sectorData = [
107+
{
108+
id: 1,
109+
name: 'Health',
110+
value: 23,
111+
},
112+
{
113+
id: 2,
114+
name: 'Recovery',
115+
value: 55,
116+
},
117+
{
118+
id: 3,
119+
name: 'Education',
120+
value: 60,
121+
},
122+
{
123+
id: 4,
124+
name: 'DRR',
125+
value: 35,
126+
},
127+
128+
];
129+
130+
const timeSeriesDataKeys = [
131+
{
132+
date: '2024-12',
133+
count: 2,
134+
},
135+
{
136+
date: '2024-11',
137+
count: 8,
138+
},
139+
{
140+
date: '2024-10',
141+
count: 27,
142+
},
143+
{
144+
date: '2024-09',
145+
count: 48,
146+
},
147+
{
148+
date: '2024-01',
149+
count: 23,
150+
},
151+
{
152+
date: '2024-08',
153+
count: 70,
154+
},
155+
{
156+
date: '2024-07',
157+
count: 85,
158+
},
159+
{
160+
date: '2024-06',
161+
count: 84,
162+
},
163+
{
164+
date: '2024-05',
165+
count: 73,
166+
},
167+
];
168+
const oneYearAgo = new Date();
169+
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
170+
oneYearAgo.setDate(1);
171+
oneYearAgo.setMonth(oneYearAgo.getMonth() + 1);
172+
oneYearAgo.setHours(0, 0, 0, 0);
173+
const timeseriesChartClassNameSelector = () => styles.sourceChart;
174+
const xAxisFormatter = (date: Date) => date.toLocaleString(
175+
navigator.language,
176+
{ month: 'short' },
177+
);
178+
const keySelector = (item) => item.id;
179+
const valueSelector = (item) => item.value;
180+
const labelSelector = (item) => item.name;
181+
101182
// eslint-disable-next-line import/prefer-default-export
102183
export function Component() {
103184
const strings = useTranslation(i18n);
@@ -281,7 +362,22 @@ export function Component() {
281362
setFilterPristine(true);
282363
setQuery(undefined);
283364
}, [resetFilter]);
284-
365+
const dateList = useMemo(
366+
() => {
367+
const startDate = oneYearAgo;
368+
const endDate = new Date();
369+
return getDatesSeparatedByMonths(startDate, endDate);
370+
},
371+
[],
372+
);
373+
const timeSeriesValueSelector = useCallback(
374+
(_: string, date: Date) => timeSeriesDataKeys?.find(
375+
(source) => (
376+
getFormattedDateKey(source.date) === getFormattedDateKey(date)
377+
),
378+
)?.count ?? 0,
379+
[],
380+
);
285381
return (
286382
<Page
287383
className={styles.operationalLearning}
@@ -444,6 +540,55 @@ export function Component() {
444540
</>
445541
)}
446542
/>
543+
<div className={styles.learningOverview}>
544+
<Container
545+
heading="Map"
546+
547+
/>
548+
<div className={styles.charts}>
549+
<Container
550+
heading={strings.learningBySector}
551+
className={styles.learningChart}
552+
withHeaderBorder
553+
withInternalPadding
554+
>
555+
<BarChart
556+
data={sectorData}
557+
keySelector={keySelector}
558+
valueSelector={valueSelector}
559+
labelSelector={labelSelector}
560+
/>
561+
</Container>
562+
<Container
563+
heading={strings.learningByRegions}
564+
className={styles.learningChart}
565+
withHeaderBorder
566+
withInternalPadding
567+
>
568+
<BarChart
569+
data={sectorData}
570+
keySelector={keySelector}
571+
valueSelector={valueSelector}
572+
labelSelector={labelSelector}
573+
/>
574+
</Container>
575+
<Container
576+
heading={strings.sourceOvertime}
577+
className={styles.learningChart}
578+
withHeaderBorder
579+
withInternalPadding
580+
>
581+
<TimeSeriesChart
582+
className={styles.timeSeriesChart}
583+
timePoints={dateList}
584+
dataKeys={timeSeriesDataKeys}
585+
valueSelector={timeSeriesValueSelector}
586+
classNameSelector={timeseriesChartClassNameSelector}
587+
xAxisFormatter={xAxisFormatter}
588+
/>
589+
</Container>
590+
</div>
591+
</div>
447592
{showKeyInsights && (
448593
<KeyInsights
449594
opsLearningSummaryResponse={opsLearningSummaryResponse}

app/src/views/OperationalLearning/styles.module.css

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,34 @@
7373
display: inline;
7474
}
7575
}
76+
.learning-overview{
77+
display: flex;
78+
flex-direction: row;
79+
justify-content: space-between;
80+
.charts {
81+
display: grid;
82+
grid-gap: var(--go-ui-spacing-md);
83+
grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
84+
@media screen and (max-width: 30rem) {
85+
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
86+
}
87+
.learning-chart{
88+
border-radius: var(--go-ui-border-radius-lg);
89+
box-shadow: var(--go-ui-box-shadow-md);
90+
91+
.time-series-chart {
92+
width: 100%;
93+
height: 10rem;
94+
95+
.source-chart {
96+
color: var(--go-ui-color-primary-red);
97+
stroke: var(--go-ui-color-primary-red);
98+
stroke-width: var(1pt);
99+
fill: none;
100+
}
101+
}
102+
}
103+
}
104+
}
76105
}
77106

0 commit comments

Comments
 (0)