Hooks for view implementation
Basic coordination
useCoordination
This hook returns both the values and setter functions for the coordination objects in a particular coordination scope mapping.
Parameters:
viewUid
(string
) - The unique identifier for a view.coordinationTypes
(string[]
) - Array of coordination types.
Returns:
- Type:
[Record<string, any>, Record<string, Function>]
Returns a tuple [values, setters]
where the keys of values
are the input coordinationTypes
.
The keys of setters
are the keys of coordinationTypes
with the prefix set
.
const [
{ someValue },
{ setSomeValue }
] = useCoordination(viewUid, ["someValue"]);
useInitialCoordination
Use values from the coordination space as they appeared at initialization. This can be used to do things such as reset values to their initial state.
Parameters:
viewUid
(string
) - The unique identifier for a view.coordinationTypes
(string[]
) - Array of coordination types.
Returns:
- Type:
Record<string, any>
Returns values
where the keys are the input coordinationTypes
.
const { someValue } = useInitialCoordination(viewUid, ["someValue"]);
Multi-coordination
useCoordinationScopes
Get the ordered list of coordination scopes for a particular coordination type. Scopes are filtered out if their value in the coordination space is null.
Parameters:
viewUid
(string
) - The unique identifier for a view.coordinationType
(string
) - A single coordination type for a view.
Returns:
- Type:
string[]
The coordination scopes mapped to the specified coordination type for a view.
const channelScopes = useCoordinationScopes(viewUid, "channel");
useCoordinationObject
Get a mapping from (multiple) coordination scopes to their values for a particular coordination type.
Parameters:
viewUid
(string
) - The unique identifier for a view.coordinationType
(string
) - A single coordination type for a view.
Returns:
- Type:
Record<string, any>
The mapping from coordination scopes (the keys of the returned object) to their values for the specified coordination type and view.
const channelObject = useCoordinationObject(viewUid, "channel");
Multi-level coordination (First level)
useCoordinationL1
Use coordination values and coordination setter functions corresponding to {coordinationType}-specific coordination scopes for each coordination type.
Parameters:
viewUid
(string
) - The unique identifier for a view.primaryType
(string
) - The {coordinationType} to use for per-{coordinationType} coordination scope mappings.secondaryTypes
(string[]
) - An array of coordination types supported by a view.
Returns:
- Type:
[Record<string, Record<string, any>>, Record<string, Record<string, Function>>]
[cValues, cSetters]
where
cValues
is a mapping from coordination scope name to { coordinationType: coordinationValue }
,
and cSetters
is a mapping from coordination scope name to { setCoordinationType }
setter functions. The keys of cValues
and cSetters
are the coordination scopes for the byType
coordination type.
const channelCoordination = useCoordinationL1(viewUid, "channel", ["channelValue"])
useCoordinationScopesL1
Filters out primary and secondary scopes from the results if their value in the coordination space is null
.
Parameters:
viewUid
(string
) - The unique identifier for a view.primaryType
(string
)secondaryType
(string
)
Returns:
- Type:
[string[], Record<string, string[]>]
[primaryScopesArr, primaryToSecondaryScopesArr]
where
primaryScopesArr
is an array of coordination scopes for the primary coordination type, and
primaryToSecondaryScopesArr
is a mapping from each of the primary scopes to a list of secondary scopes { [primaryScope]: secondaryScopesArr }
.
const [imageLayerScopes, imageChannelScopesByLayer] = useCoordinationScopesL1(
viewUid, "imageLayer", "imageChannel"
);
Multi-level coordination (Second level)
These functions support a two-level hierarchy of multi-coordination. For example, a first layer of coordination might be an array of image layers, where each layer has its own array of image channels.
These hooks will automatically fall back to the values in the first level of the hierarchy when values are not present in the second level of the hierarchy.
useCoordinationL2
Use coordination values and coordination setter functions corresponding to two levels of coordination hierarchy.
Parameters:
viewUid
(string
) - The unique identifier for a view.primaryType
(string
) - The first-level coordination type, such as spatialImageLayer.secondaryType
(string
) - The second-level coordination type, such as spatialImageChannel.tertiaryTypes
(string[]
) - An array of coordination types supported by a view.
Returns:
- Type:
[Record<string, Record<string, Record<string, any>>>, Record<string, Record<string, Record<string, Function>>>]
[nestedValues, nestedSetters]
where
nestedValues
is a mapping from the primary scope names to { [secondaryScopeName]: { coordinationType: coordinationValue } }
,
and nestedSetters
is a mapping from the primary scope names to { [secondaryScopeName]: { setCoordinationType } }
setter functions.
const imageLayerCoordination = useCoordinationL1(
viewUid, "imageLayer",
[
"imageChannel",
"spatialLayerVisible",
"spatialLayerOpacity",
"spatialLayerColormap",
],
);
const imageChannelCoordination = useCoordinationL2(
viewUid, "imageLayer", "imageChannel",
[
"spatialTargetC",
"spatialChannelVisible",
"spatialChannelColor",
],
);
Advanced usage
useRawViewMapping
This hook can be used to get the "raw" (i.e., pre-meta-coordination) coordination scope mapping object for a view.
const [coordinationScopes, coordinationScopesBy] = useRawViewMapping(viewUid);
useViewMapping
This hook can be used to get the "computed" (i.e., post-meta-coordination) coordination scope mapping object for a view.
const [coordinationScopes, coordinationScopesBy] = useViewMapping(viewUid);
Underscore-prefixed hooks
Many of the above hooks internally call useViewMapping
to get the coordination scope mapping information based on the viewUid
.
This is convenient, but using multiple hooks that call useViewMapping
in the same view will result in redundant lookup (and meta-coordination resolution) operations.
We provide a set of underscore-prefixed hooks that take the result of useViewMapping
as input.
const [coordinationScopes] = useViewMapping(viewUid);
const [
{ someValue },
{ setSomeValue }
] = _useCoordination(coordinationScopes, ["someValue"]);
The full list of underscore-prefixed hooks:
_useCoordination(coordinationScopes, coordinationTypes)
_useInitialCoordination(coordinationScopes, coordinationTypes)
_useCoordinationScopes(coordinationScopes, coordinationType)
_useCoordinationL1(coordinationScopes, coordinationScopesBy, primaryType, secondaryTypes)
_useCoordinationL2(coordinationScopes, coordinationScopesBy, primaryType, secondaryType, tertiaryTypes)
_useCoordinationScopesL1(coordinationScopes, coordinationScopesBy, primaryType, secondaryType)
Definition of custom hooks
Custom hooks can be defined to provide the lowest-level of control over the coordination implementation. This can be useful to define custom multi-level coordination logic.
First, define custom action(s) in the Zustand store using the onCreateStore
prop of the coordination provider.
function onCreateStore(set) {
return {
selectBar: (viewUid, letter) => set((state) => {
const { coordinationSpace, viewCoordination } = state.spec;
const newSpec = // ... custom logic
return { spec: newSpec };
}),
unselectBar: (viewUid, letter) => set((state) => {
const { coordinationSpace, viewCoordination } = state.spec;
const newSpec = // ... custom logic
return { spec: newSpec };
}),
};
}
Then, wrap the custom actions in custom hook functions:
import { useCoordinationStore } from '@use-coordination/all';
export function useSelectBar() {
return useCoordinationStore(state => state.selectBar);
}
export function useUnselectBar() {
return useCoordinationStore(state => state.unselectBar);
}
Finally, import these into your view components to use:
import { useSelectBar, useUnselectBar } from './path/to/my-custom-hooks.js';
export function MyView(props) {
const { viewUid } = props;
const selectBar = useSelectBar();
const unselectBar = useUnselectBar();
return (
<button onClick={() => selectBar(viewUid, "A")}>Select the letter A</button>
);
}