Skip to main content

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>
);
}