Skip to content

Commit

Permalink
filter geometries by category - WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
andresgnlez committed Mar 20, 2024
1 parent 989a654 commit 326141f
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 48 deletions.
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"@types/chroma-js": "2.1.3",
"@types/d3-format": "3.0.1",
"@types/d3-scale": "4.0.2",
"@types/geojson": "7946.0.14",
"@types/lodash-es": "4.17.6",
"@types/node": "16.11.6",
"@types/react": "18.2.28",
Expand Down
67 changes: 29 additions & 38 deletions client/src/containers/analysis-eudr/category-list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,68 +6,60 @@ import SuppliersWithNoLocationDataBreakdown from './breakdown/suppliers-with-no-

import { Button } from '@/components/button';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import { cn } from '@/lib/utils';
import { useEUDRData } from '@/hooks/eudr';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { eudr, setTableFilters } from '@/store/features/eudr';
import { themeColors } from '@/utils/colors';

import type { EUDRState } from '@/store/features/eudr';

export const CATEGORIES = [
{
name: 'Deforestation-free suppliers',
key: 'dfs',
color: themeColors.blue[400],
},
{
name: 'Suppliers with deforestation alerts',
key: 'sda',
color: '#FFC038',
},
{
name: 'Suppliers with no location data',
key: 'tpl',
color: '#8561FF',
},
] as const;

const CATEGORY_TO_FILTER: Record<
(typeof CATEGORIES)[number]['name'],
Partial<keyof EUDRState['table']['filters']>
> = {
[CATEGORIES[0].name]: 'dfs',
[CATEGORIES[1].name]: 'sda',
[CATEGORIES[2].name]: 'tpl',
} as const;

type CategoryState = Record<(typeof CATEGORIES)[number]['name'], boolean>;
type CategoryState = Record<(typeof CATEGORIES)[number]['key'], boolean>;

export const CategoryList = (): JSX.Element => {
const {
viewBy,
filters: { dates, suppliers, origins, materials, plots },
table: { filters: tableFilters },
} = useAppSelector(eudr);

const [categories, toggleCategory] = useState<CategoryState>(
CATEGORIES.reduce(
(acc, category) => ({
...acc,
[category.name]: false,
[category.key]: tableFilters[category.key],
}),
{} as CategoryState,
),
);

const {
viewBy,
filters: { dates, suppliers, origins, materials, plots },
table: { filters: tableFilters },
} = useAppSelector(eudr);
const dispatch = useAppDispatch();

const onClickCategory = useCallback(
(category: (typeof CATEGORIES)[number]) => {
toggleCategory((prev) => ({
...prev,
[category.name]: !prev[category.name],
[category.key]: !prev[category.key],
}));

dispatch(
setTableFilters({
[CATEGORY_TO_FILTER[category.name]]: !tableFilters[CATEGORY_TO_FILTER[category.name]],
[category.key]: !tableFilters[category.key],
}),
);
},
Expand All @@ -91,19 +83,23 @@ export const CategoryList = (): JSX.Element => {
const parsedData = useMemo(() => {
const dataByView = data?.[viewBy] || [];

return Object.keys(dataByView).map((key) => ({
name: key,
...dataByView[key],
color: CATEGORIES.find((category) => category.name === key)?.color || '#000',
}));
return Object.keys(dataByView).map((key) => {
const category = CATEGORIES.find((category) => category.name === key);
return {
name: key,
...dataByView[key],
key: category?.key,
color: category?.color || '#000',
};
});
}, [data, viewBy]);

return (
<>
{parsedData.map((category) => (
<Collapsible
key={category.name}
className="rounded-xl bg-gray-50 p-5"
key={category.key}
className="group rounded-xl bg-gray-50 p-5"
onOpenChange={() => onClickCategory(category)}
>
<CollapsibleTrigger asChild>
Expand Down Expand Up @@ -140,21 +136,16 @@ export const CategoryList = (): JSX.Element => {
type="button"
size="xs"
variant="white"
className={cn(
'w-[98px] rounded-md border-none text-sm text-gray-500 shadow-none transition-colors hover:shadow-none',
{
'bg-navy-400 text-white hover:bg-navy-600': categories[category.name],
},
)}
className="w-[98px] rounded-md border-none text-sm text-gray-500 shadow-none transition-colors hover:shadow-none group-data-[state=open]:bg-navy-400 group-data-[state=open]:text-white group-data-[state=open]:hover:bg-navy-600"
>
{categories[category.name] ? 'Close detail' : 'View detail'}
{categories[category.key] ? 'Close detail' : 'View detail'}
</Button>
</div>
</CollapsibleTrigger>
<CollapsibleContent>
{category.name === CATEGORIES[0].name && <DeforestationFreeSuppliersBreakdown />}
{category.name === CATEGORIES[1].name && <SuppliersWithDeforestationAlertsBreakdown />}
{category.name === CATEGORIES[2].name && <SuppliersWithNoLocationDataBreakdown />}
{categories['dfs'] && <DeforestationFreeSuppliersBreakdown />}
{categories['sda'] && <SuppliersWithDeforestationAlertsBreakdown />}
{categories['tpl'] && <SuppliersWithNoLocationDataBreakdown />}
</CollapsibleContent>
</Collapsible>
))}
Expand Down
39 changes: 33 additions & 6 deletions client/src/containers/analysis-eudr/map/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const EUDRMap = () => {
supplierLayer,
contextualLayers,
filters: { suppliers, materials, origins, plots, dates },
table: { filters: tableFilters },
} = useAppSelector((state) => state.eudr);

const [hoverInfo, setHoverInfo] = useState<PickingInfo>(null);
Expand Down Expand Up @@ -74,9 +75,17 @@ const EUDRMap = () => {
};
}

const filteredData = data?.table.filter((dataRow) => {
if (Object.values(tableFilters).every((filter) => !filter)) return true;

if (tableFilters.dfs && dataRow.dfs > 0) return true;
if (tableFilters.sda && dataRow.sda > 0) return true;
if (tableFilters.tpl && dataRow.tpl > 0) return true;
});

return {
dfs: data.table.map((row) => row.plots.dfs.flat()).flat(),
sda: data.table.map((row) => row.plots.sda.flat()).flat(),
dfs: filteredData.map((row) => row.plots.dfs.flat()).flat(),
sda: filteredData.map((row) => row.plots.sda.flat()).flat(),
};
},
},
Expand All @@ -91,12 +100,30 @@ const EUDRMap = () => {
geoRegionIds: plots?.map(({ value }) => value),
});

const eudrSupplierLayer = useMemo(() => {
const filteredGeometries: typeof plotGeometries.data = useMemo(() => {
if (!plotGeometries.data || !data) return null;

return new GeoJsonLayer({
if (params?.supplierId) return plotGeometries.data;

return {
type: 'FeatureCollection',
features: plotGeometries.data.features.filter((feature) => {
if (Object.values(tableFilters).every((filter) => !filter)) return true;

if (tableFilters.dfs && data.dfs.indexOf(feature.properties.id) > -1) return true;
if (tableFilters.sda && data.sda.indexOf(feature.properties.id) > -1) return true;
return false;
}),
};
}, [data, plotGeometries.data, tableFilters, params]);

const eudrSupplierLayer = useMemo(() => {
if (!filteredGeometries?.features || !data) return null;

return new GeoJsonLayer<(typeof filteredGeometries)['features'][number]>({
id: 'full-plots-layer',
data: plotGeometries.data,
// @ts-expect-error will fix this later...
data: filteredGeometries,
// Styles
filled: true,
getFillColor: ({ properties }) => {
Expand Down Expand Up @@ -132,7 +159,7 @@ const EUDRMap = () => {
onHover: setHoverInfo,
opacity: supplierLayer.opacity,
});
}, [plotGeometries.data, data, supplierLayer.active, supplierLayer.opacity]);
}, [filteredGeometries, data, supplierLayer.active, supplierLayer.opacity]);

const basemapPlanetLayer = new TileLayer({
id: 'top-planet-monthly-layer',
Expand Down
7 changes: 4 additions & 3 deletions client/src/hooks/eudr/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useQuery } from '@tanstack/react-query';

import { apiService } from 'services/api';

import type { FeatureCollection, Geometry } from 'geojson';
import type { Supplier as SupplierRow } from '@/containers/analysis-eudr/supplier-list-table/table';
import type { MaterialTreeItem, OriginRegion, Supplier } from '@/types';
import type { UseQueryOptions } from '@tanstack/react-query';
Expand Down Expand Up @@ -33,15 +34,15 @@ export const useEUDRSuppliers = <T = Supplier[]>(
);
};

export const usePlotGeometries = <T = Supplier[]>(
export const usePlotGeometries = (
params?: EUDRParams,
options: UseQueryOptions<Supplier[], unknown, T> = {},
options?: UseQueryOptions<FeatureCollection<Geometry, { id: string }>>,
) => {
return useQuery(
['eudr-geo-features-collection', params],
() =>
apiService
.request<{ geojson }>({
.request<{ geojson: FeatureCollection<Geometry, { id: string }> }>({
method: 'GET',
url: '/eudr/geo-features/collection',
params,
Expand Down
3 changes: 2 additions & 1 deletion client/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2791,7 +2791,7 @@ __metadata:
languageName: node
linkType: hard

"@types/geojson@npm:^7946.0.13":
"@types/geojson@npm:7946.0.14, @types/geojson@npm:^7946.0.13":
version: 7946.0.14
resolution: "@types/geojson@npm:7946.0.14"
checksum: ae511bee6488ae3bd5a3a3347aedb0371e997b14225b8983679284e22fa4ebd88627c6e3ff8b08bf4cc35068cb29310c89427311ffc9322c255615821a922e71
Expand Down Expand Up @@ -7892,6 +7892,7 @@ __metadata:
"@types/chroma-js": 2.1.3
"@types/d3-format": 3.0.1
"@types/d3-scale": 4.0.2
"@types/geojson": 7946.0.14
"@types/lodash-es": 4.17.6
"@types/node": 16.11.6
"@types/react": 18.2.28
Expand Down

0 comments on commit 326141f

Please sign in to comment.