Skip to content

Commit

Permalink
map legend: merges binary and continuous features
Browse files Browse the repository at this point in the history
  • Loading branch information
agnlez committed Oct 27, 2023
1 parent a12c0e4 commit 1c2c21f
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 190 deletions.
6 changes: 3 additions & 3 deletions app/hooks/map/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ export const LEGEND_LAYERS = {
}));
},

'features-preview-new': (options: {
'binary-features': (options: {
items: { id: string; name: string; color: string }[];
onChangeVisibility: (featureId: Feature['id']) => void;
}) => {
Expand Down Expand Up @@ -314,7 +314,7 @@ export const LEGEND_LAYERS = {
},
}),
// ANALYSIS
['features-abundance']: (options: {
['continuous-features']: (options: {
items: {
id: Feature['id'];
amountRange: { min: number; max: number };
Expand All @@ -326,7 +326,7 @@ export const LEGEND_LAYERS = {
const { items, onChangeVisibility } = options;

return items?.map(({ id, name, amountRange, color }) => ({
id: `feature-abundance-${id}`,
id,
name,
type: 'gradient' as LegendItemType,
settingsManager: {
Expand Down
8 changes: 4 additions & 4 deletions app/hooks/map/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,8 @@ export function usePUGridLayer({
const {
visibility = true,
opacity = 1,
amountRange = { min: 50000, max: 1000000 },
amountRange,
color,
} = restLayerSettings[featureId] || {};

return {
Expand Down Expand Up @@ -804,10 +805,9 @@ export function usePUGridLayer({
['linear'],
['var', 'amount'],
amountRange.min,
'white', // ! use COLORS.abundance.default instead when is available
COLORS.abundance.default,
amountRange.max,
'green',
// color, // ! enable the color variable when we receive it
color,
],
],
'fill-opacity': opacity,
Expand Down
1 change: 1 addition & 0 deletions app/hooks/map/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export interface UsePUGridLayer {
min: number;
max: number;
};
color?: string;
};
};
};
Expand Down
1 change: 1 addition & 0 deletions app/layout/projects/show/map/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export const ProjectMap = (): JSX.Element => {
sublayers: [
...(sid1 && !sid2 ? ['frequency'] : []),
...(!!selectedCostSurface ? ['cost'] : []),
...(!!selectedFeaturesIds.length ? ['features'] : []),
],
options: {
cost: { min: 1, max: 100 },
Expand Down
184 changes: 88 additions & 96 deletions app/layout/projects/show/map/legend/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ export const useConservationAreasLegend = () => {
});
};

export const useFeatureAbundanceLegend = () => {
export const useFeaturesLegend = () => {
const { selectedFeatures } = useAppSelector((state) => state['/projects/[id]']);
const { query } = useRouter();
const { pid } = query as { pid: string };

Expand All @@ -125,18 +126,42 @@ export const useFeatureAbundanceLegend = () => {
pid,
{ sort: 'feature_class_name' },
{
select: ({ data }) => data,
select: ({ data }) => ({
binaryFeatures:
data?.filter(
(feature) =>
!Object.hasOwn(feature.amountRange, 'min') &&
!Object.hasOwn(feature.amountRange, 'max')
) || [],
continuousFeatures:
data?.filter(
(feature) =>
Object.hasOwn(feature.amountRange, 'min') && Object.hasOwn(feature.amountRange, 'max')
) || [],
}),
}
);

const { layerSettings, selectedFeatures: visibleFeatures } = useAppSelector(
(state) => state['/projects/[id]']
);
const totalItems =
projectFeaturesQuery.data?.binaryFeatures.length +
projectFeaturesQuery.data?.continuousFeatures.length || 0;

const totalItems = projectFeaturesQuery.data?.length || 0;
const binaryFeaturesItems =
projectFeaturesQuery.data?.binaryFeatures?.map(({ id, featureClassName }, index) => {
const color =
totalItems > COLORS['features-preview'].ramp.length
? chroma.scale(COLORS['features-preview'].ramp).colors(totalItems)[index]
: COLORS['features-preview'].ramp[index];

const items =
projectFeaturesQuery.data?.map(
return {
id,
name: featureClassName,
color,
};
}) || [];

const continuousFeaturesItems =
projectFeaturesQuery.data?.continuousFeatures.map(
({ id, featureClassName, amountRange = { min: 5000, max: 100000 } }, index) => {
const color =
totalItems > COLORS['features-preview'].ramp.length
Expand All @@ -152,91 +177,62 @@ export const useFeatureAbundanceLegend = () => {
}
) || [];

return LEGEND_LAYERS['features-abundance']({
items,
onChangeVisibility: (featureId: Feature['id']) => {
const { color, amountRange } = items.find(({ id }) => id === featureId) || {};

const newSelectedFeatures = [...visibleFeatures];
const isIncluded = newSelectedFeatures.includes(featureId);
if (!isIncluded) {
newSelectedFeatures.push(featureId);
} else {
const i = newSelectedFeatures.indexOf(featureId);
newSelectedFeatures.splice(i, 1);
}
dispatch(setSelectedFeatures(newSelectedFeatures));

dispatch(
setLayerSettings({
id: featureId,
settings: {
visibility: !layerSettings[featureId]?.visibility,
amountRange,
color,
},
})
);
},
});
};

export const useFeaturesLegend = () => {
const { selectedFeatures } = useAppSelector((state) => state['/projects/[id]']);
const { query } = useRouter();
const { pid } = query as { pid: string };

const dispatch = useAppDispatch();
const projectFeaturesQuery = useAllFeatures(
pid,
{ sort: 'feature_class_name' },
{
select: ({ data }) => data,
}
);

const totalItems = projectFeaturesQuery.data?.length || 0;

const items =
projectFeaturesQuery.data?.map(({ id, featureClassName }, index) => {
const color =
totalItems > COLORS['features-preview'].ramp.length
? chroma.scale(COLORS['features-preview'].ramp).colors(totalItems)[index]
: COLORS['features-preview'].ramp[index];

return {
id,
name: featureClassName,
color,
};
}) || [];

return LEGEND_LAYERS['features-preview-new']({
items,
onChangeVisibility: (featureId: Feature['id']) => {
const newSelectedFeatures = [...selectedFeatures];
const isIncluded = newSelectedFeatures.includes(featureId);
if (!isIncluded) {
newSelectedFeatures.push(featureId);
} else {
const i = newSelectedFeatures.indexOf(featureId);
newSelectedFeatures.splice(i, 1);
}
dispatch(setSelectedFeatures(newSelectedFeatures));
return [
...LEGEND_LAYERS['binary-features']({
items: binaryFeaturesItems,
onChangeVisibility: (featureId: Feature['id']) => {
const newSelectedFeatures = [...selectedFeatures];
const isIncluded = newSelectedFeatures.includes(featureId);
if (!isIncluded) {
newSelectedFeatures.push(featureId);
} else {
const i = newSelectedFeatures.indexOf(featureId);
newSelectedFeatures.splice(i, 1);
}
dispatch(setSelectedFeatures(newSelectedFeatures));

const { color } = binaryFeaturesItems.find(({ id }) => id === featureId) || {};

const { color } = items.find(({ id }) => id === featureId) || {};
dispatch(
setLayerSettings({
id: featureId,
settings: {
visibility: !isIncluded,
color,
},
})
);
},
}),
...LEGEND_LAYERS['continuous-features']({
items: continuousFeaturesItems,
onChangeVisibility: (featureId: Feature['id']) => {
const { color, amountRange } =
continuousFeaturesItems.find(({ id }) => id === featureId) || {};

const newSelectedFeatures = [...selectedFeatures];
const isIncluded = newSelectedFeatures.includes(featureId);
if (!isIncluded) {
newSelectedFeatures.push(featureId);
} else {
const i = newSelectedFeatures.indexOf(featureId);
newSelectedFeatures.splice(i, 1);
}
dispatch(setSelectedFeatures(newSelectedFeatures));

dispatch(
setLayerSettings({
id: featureId,
settings: {
visibility: !isIncluded,
color,
},
})
);
},
});
dispatch(
setLayerSettings({
id: featureId,
settings: {
visibility: !isIncluded,
amountRange,
color,
},
})
);
},
}),
];
};

export const useComparisonScenariosLegend = ({
Expand Down Expand Up @@ -306,11 +302,7 @@ export const useInventoryLegend = ({
layers: useConservationAreasLegend(),
},
{
name: 'Features (Continuous)',
layers: useFeatureAbundanceLegend(),
},
{
name: 'Features (Binary)',
name: 'Features',
layers: useFeaturesLegend(),
},
];
Expand Down
10 changes: 8 additions & 2 deletions app/layout/scenarios/edit/map/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export const ScenariosEditMap = (): JSX.Element => {
const sublayers = useMemo(() => {
return [
...(layerSettings['wdpa-percentage']?.visibility ? ['wdpa-percentage'] : []),
...(layerSettings['features']?.visibility ? ['features'] : []),
...(layerSettings['features']?.visibility || selectedFeatures?.length ? ['features'] : []),
...(preHighlightFeatures?.length || postHighlightFeatures?.length ? ['features'] : []),
...(selectedCostSurface ? ['cost'] : []),
...(layerSettings['lock-in']?.visibility ? ['lock-in'] : []),
Expand All @@ -165,7 +165,13 @@ export const ScenariosEditMap = (): JSX.Element => {
...(layerSettings['frequency']?.visibility ? ['frequency'] : []),
...(layerSettings['solution']?.visibility ? ['solution'] : []),
];
}, [layerSettings, selectedCostSurface, preHighlightFeatures, postHighlightFeatures]);
}, [
layerSettings,
selectedCostSurface,
preHighlightFeatures,
postHighlightFeatures,
selectedFeatures,
]);

const featuresIds = useMemo(() => {
if (allGapAnalysisData) {
Expand Down
Loading

0 comments on commit 1c2c21f

Please sign in to comment.