Skip to content

Commit

Permalink
Merge pull request #1552 from Vizzuality/MRXN23-488-fe-binary-raw-vs
Browse files Browse the repository at this point in the history
[MRXN23-488]: map legend: merges binary and continuous features
  • Loading branch information
agnlez authored Oct 26, 2023
2 parents 2ac1fc3 + ebf51e3 commit 00de4d4
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 282 deletions.
50 changes: 50 additions & 0 deletions app/hooks/map/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ export function usePUGridLayer({
puIncludedValue,
puExcludedValue,
puAvailableValue,
selectedFeatures = [],
preHighlightFeatures = [],
postHighlightFeatures = [],
runId,
Expand Down Expand Up @@ -764,6 +765,55 @@ export function usePUGridLayer({
],
},
})),
// features abundance
...selectedFeatures.map((featureId) => {
const {
visibility = true,
opacity = 1,
amountRange = { min: 50000, max: 1000000 },
} = restLayerSettings[featureId] || {};

return {
type: 'fill',
'source-layer': 'layer0',
layout: {
visibility: getLayerVisibility(visibility),
},
filter: ['all', ['in', featureId, ['get', 'featureList']]],
paint: {
'fill-outline-color': 'yellow',
'fill-color': [
'let',
'amount',
[
'to-number',
[
'let',
'idx',
['index-of', featureId, ['get', 'featureList']],
[
'slice',
['get', 'featureList'],
['+', ['index-of', ':', ['get', 'featureList'], ['var', 'idx']], 1],
['index-of', ';', ['get', 'featureList'], ['var', 'idx']],
],
],
],
[
'interpolate',
['linear'],
['var', 'amount'],
amountRange.min,
'white', // ! use COLORS.abundance.default instead when is available
amountRange.max,
'green',
// color, // ! enable the color variable when we receive it
],
],
'fill-opacity': opacity,
},
};
}),
]
: []),

Expand Down
7 changes: 6 additions & 1 deletion app/hooks/map/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ export interface UsePUGridLayer {
puExcludedValue?: string[];
puAvailableValue?: string[];
runId?: number;
features?: string[];
features?: Feature['id'][];
selectedFeatures?: Feature['id'][];
preHighlightFeatures?: Array<string>;
postHighlightFeatures?: Array<string>;
cost?: {
Expand Down Expand Up @@ -172,6 +173,10 @@ export interface UsePUGridLayer {
[key: string]: {
opacity?: number;
visibility?: boolean;
amountRange?: {
min: number;
max: number;
};
};
};
};
Expand Down
181 changes: 85 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,39 @@ export const useFeatureAbundanceLegend = () => {
pid,
{ sort: 'feature_class_name' },
{
select: ({ data }) => data,
select: ({ data }) => ({
binaryFeatures:
data?.filter(
(feature) => !Object.hasOwn(feature, 'min') && !Object.hasOwn(feature, 'max')
) || [],
continuousFeatures:
data?.filter(
(feature) => Object.hasOwn(feature, 'min') && Object.hasOwn(feature, '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 +174,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: `feature-abundance-${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['features-preview-new']({
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['features-abundance']({
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 +299,7 @@ export const useInventoryLegend = ({
layers: useConservationAreasLegend(),
},
{
name: 'Features (Continuous)',
layers: useFeatureAbundanceLegend(),
},
{
name: 'Features (Binary)',
name: 'Features',
layers: useFeaturesLegend(),
},
];
Expand Down
Loading

1 comment on commit 00de4d4

@vercel
Copy link

@vercel vercel bot commented on 00de4d4 Oct 26, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

marxan – ./

marxan-vizzuality1.vercel.app
marxan23.vercel.app
marxan-git-develop-vizzuality1.vercel.app

Please sign in to comment.