Provenance Tracking
ReVISit has integrated provenance tracking with Trrack, a state-based provenance tracking library maintained by the same team that maintains reVISit. For more detailed information on Trrack and its API, visit the Trrack documentation.
Integrating into a React and HTML component​
Building off the Stroop color experiment from the React stimulus tutorial, we add provenance tracking to record each keystroke and enable replay.
1. Define state and create Trrack with useMemo​
Because Trrack is state-based, you must define a state for your tracked application. For the Stroop text input:
interface StroopState {
response: string;
}
Create the Trrack registry, action, and instance once using useMemo (empty deps). This ensures the instance is stable across renders:
const { actions, trrack } = useMemo(() => {
const reg = Registry.create();
const setResponseAction = reg.register('setResponse', (state, nextResponse: string) => {
state.response = nextResponse;
return state;
});
const trrackInst = initializeTrrack({
registry: reg,
initialState: { response: '' },
});
return {
actions: { setResponseAction },
trrack: trrackInst,
};
}, []);
2. Call the action and pass provenanceGraph to setAnswer​
When the user types, call the Trrack action and include provenanceGraph in setAnswer so reVISit stores the provenance. Use a useCallback to keep the handler stable:
const updateAnswer = useCallback((value: string) => {
setResponseText(value);
trrack.apply('Set response', actions.setResponseAction(value));
setAnswer({
status: value.trim().length > 0,
provenanceGraph: trrack.graph.backend,
answers: { stroopAnswer: value },
});
}, [actions, setAnswer, trrack]);
3. Sync from provenanceState for replay​
During replay, reVISit passes provenanceState with the restored state. Sync it to your textbox so the input updates visibly when the user seeks through the timeline:
useEffect(() => {
if (provenanceState) {
setResponseText(provenanceState.response);
}
}, [provenanceState]);
Full component example​
For the complete Stroop component with provenance tracking, see DemoReactTrrack.tsx.
For a basic HTML + D3 example, see our Dots example. Creating a Trrack instance and actions works the same as above, just without the React hooks.
Using Trrack for undo/redo​
The above example shows the basic use case for Trrack if you just want to store provenance and enable replay. With a little more effort, Trrack can also give your stimulus undo/redo and full study rehydration.
For this, use Trrack as your central storage instead of React state. Where you would normally call setState, call the Trrack action instead:
trrack.apply('Set response', setResponseAction(value));
To update the frontend when the current node changes (e.g., when undo or redo are called), add an observer:
trrack.currentChange(() => {
const response = trrack.getState().response;
setResponseText(response);
});
Add undo/redo via buttons or keybinds:
trrack.undo();
trrack.redo();