Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add learning by sector,regions bar chart and Map for learning #1577

Open
wants to merge 3 commits into
base: project/operational-learning-2.0
Choose a base branch
from

Conversation

roshni73
Copy link
Collaborator

@roshni73 roshni73 commented Dec 5, 2024

Addresses:

Changes

  • Add learning by sector, region, and source overtime chart.
  • Add Map view for operational learning

This PR doesn't introduce:

  • typos
  • conflict markers
  • unwanted comments
  • temporary files, auto-generated files or secret keys
  • console.log meant for debugging
  • codegen errors

Copy link

changeset-bot bot commented Dec 5, 2024

⚠️ No Changeset found

Latest commit: 10a77b8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
@samshara samshara self-requested a review December 10, 2024 09:58
@roshni73 roshni73 force-pushed the feature/add-charts-learnings branch from e80e0a5 to 3bde6b9 Compare December 11, 2024 04:21
@roshni73 roshni73 force-pushed the feature/add-charts-learnings branch from 3bde6b9 to 3ef7309 Compare December 11, 2024 05:44
@roshni73 roshni73 force-pushed the feature/add-charts-learnings branch from 3ef7309 to a9f5ebb Compare December 11, 2024 05:55
@roshni73 roshni73 force-pushed the feature/add-charts-learnings branch from a9f5ebb to 3071d1b Compare December 11, 2024 06:39
@roshni73 roshni73 force-pushed the feature/add-charts-learnings branch from 8ee38d7 to 6af5950 Compare December 12, 2024 05:27
@roshni73 roshni73 force-pushed the feature/add-charts-learnings branch from 6af5950 to 087c25b Compare December 12, 2024 05:38
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
app/src/views/OperationalLearning/index.tsx Outdated Show resolved Hide resolved
@tnagorra tnagorra changed the title Add learning by sector,regions bar chart and Map for learning feat: Add learning by sector,regions bar chart and Map for learning Dec 27, 2024
@roshni73 roshni73 force-pushed the feature/add-charts-learnings branch from ba0314f to 3d5b4bf Compare December 27, 2024 05:56
emergencyAppeal: styles.emergencyAppeal,
};
const now = new Date();
const startDate = new Date(now.getFullYear() - 20, 0, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add FIXME to decide start date properly

Comment on lines 328 to 330
query: {
...query,
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
query: {
...query,
},
query,

Comment on lines 337 to 361
const transformSourcesOvertimeData = (data: {
date: string;
type_display: string;
count: number;
}[]) => {
const groupedData: Record<string, { dref: number; emergencyAppeal: number }> = {};

data.forEach((entry: {
date: string | number | Date;
type_display: string;
count: number;
}) => {
const year = new Date(entry.date).getFullYear().toString();
if (!groupedData[year]) {
groupedData[year] = { dref: 0, emergencyAppeal: 0 };
}
if (entry.type_display === 'DREF') {
groupedData[year].dref = entry.count;
} else if (entry.type_display === 'Emergency Appeal') {
groupedData[year].emergencyAppeal += entry.count;
}
});

return groupedData;
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use useMemo

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or can be moved outside if this is a pure function

Comment on lines 56 to 59
interface Props {
className?: string;
learning: learningStatsResponse | undefined;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move props next to the main function

Comment on lines 119 to 129
const learningCount = useMemo(() => (
learning?.learning_by_country
.filter((country) => country.count > 0)
), [learning?.learning_by_country]);

const maxScaleValue = useMemo(() => (
Math.max(
...(learningCount
?.map((activity: { count: number; }) => activity.count)
.filter(isDefined) ?? []),
)), [learningCount]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both of these can go inside calculation of bluePointHaloCirclePaint

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, handle case when array length is zero.

Comment on lines 131 to 133
const {
bluePointHaloCirclePaint,
} = useMemo(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const {
bluePointHaloCirclePaint,
} = useMemo(
const bluePointHaloCirclePaint = useMemo(

Comment on lines 63 to 72
function getMaxLearning(learning: learningStatsResponse) {
const learningData = learning?.learning_by_country.filter(
({ count }) => isDefined(count),
);

const maxLearning = maxSafe(
learningData?.map(({ count }) => count),
);
return maxLearning;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this function inside to directly calculate getMaxLearning

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. We do not need a separate function that cannot be reused anywhere else.

Comment on lines +192 to +193
<BaseMap
baseLayers={(
<MapLayer
layerKey="admin-0"
hoverable
layerOptions={adminFillLayerOptions}
onClick={handleCountryClick}
/>
)}
>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use GlobalMap instead of BaseMap.
We are deprecating the use of BaseMap in the future.

Comment on lines 63 to 72
function getMaxLearning(learning: learningStatsResponse) {
const learningData = learning?.learning_by_country.filter(
({ count }) => isDefined(count),
);

const maxLearning = maxSafe(
learningData?.map(({ count }) => count),
);
return maxLearning;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. We do not need a separate function that cannot be reused anywhere else.

Comment on lines +89 to +101
const features = countryResponse
?.map((country) => {
const learningList = learning?.learning_by_country?.find(
(item: { country_id: number; }) => item.country_id === country.id,
);
if (isNotDefined(learningList)) {
return undefined;
}
const units = learningList.count;
return {
type: 'Feature' as const,
geometry: country.centroid as {
type: 'Point',
coordinates: [0, 0],
},
properties: {
country_id: country.id,
name: country.name,
operation_count: units,
},
};
})
.filter(isDefined) ?? [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mapping should be done the other way around and use a dict/map to find elements on a loop.

Comment on lines 119 to 122
const learningCount = useMemo(() => (
learning?.learning_by_country
.filter((country) => country.count > 0)
), [learning?.learning_by_country]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable learningCount does not hold count of learnings. Rename this to something appropriate.

Comment on lines 119 to 129
const learningCount = useMemo(() => (
learning?.learning_by_country
.filter((country) => country.count > 0)
), [learning?.learning_by_country]);

const maxScaleValue = useMemo(() => (
Math.max(
...(learningCount
?.map((activity: { count: number; }) => activity.count)
.filter(isDefined) ?? []),
)), [learningCount]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, handle case when array length is zero.

Comment on lines +124 to +148
const handleCountryClick = useCallback(
(feature: mapboxgl.MapboxGeoJSONFeature, lngLat: mapboxgl.LngLatLike) => {
setClickedPointProperties({
feature: feature as unknown as ClickedPoint['feature'],
lngLat,
});
return false;
},
[],
);
const handlePointClose = useCallback(() => {
setClickedPointProperties(undefined);
}, []);

const handlePointClick = useCallback(
(feature: mapboxgl.MapboxGeoJSONFeature, lngLat: mapboxgl.LngLatLike) => {
setClickedPointProperties({
feature: feature as unknown as ClickedPoint['feature'],
lngLat,
});
return true;
},
[setClickedPointProperties],
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if handleCountryClick and handlePointClick can be handled the same way. Do we even need handleCountryClick?

};
const now = new Date();

// FIX ME : ADD START DATE PROPERLY
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// FIX ME : ADD START DATE PROPERLY
// FIXME: ADD START DATE PROPERLY

Comment on lines 351 to 358
const {
error: learningStatsResponseError,
response: learningStatsResponse,
} = useRequest({
url: '/api/v2/ops-learning/stats/',
query,
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also handle pending state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants