Skip to content

Commit

Permalink
feat(react): adding "nodeExtra" option
Browse files Browse the repository at this point in the history
  • Loading branch information
ZachCutler04 committed Jul 17, 2023
1 parent d26ca05 commit d1a8456
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 102 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ tmp

# dependencies
node_modules
yarn.lock

# IDEs and editors
/.idea
.project
.vscode
.classpath
.c9/
*.launch
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/components/AnimatedIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function AnimatedIcon<T, S extends string>({
setHover,
colorMap,
xOffset,
extraHeight,
}: {
width: number;
depth: number;
Expand All @@ -32,6 +33,7 @@ export function AnimatedIcon<T, S extends string>({
setHover: (node: NodeId | null) => void;
colorMap: Record<S | 'Root', string>;
xOffset: number;
extraHeight: number;
}) {
const transitions = useTransition([node], {
config: {
Expand Down Expand Up @@ -61,7 +63,7 @@ export function AnimatedIcon<T, S extends string>({
update: {
opacity: 1,
transform: `translate(${-width * config.gutter + xOffset} , ${
depth * config.verticalSpace + yOffset
depth * config.verticalSpace + yOffset + extraHeight
})`,
},
});
Expand Down
215 changes: 120 additions & 95 deletions packages/react/src/components/NodeDescription.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Stack, Text, Tooltip } from '@mantine/core';
import { Box, Group, Stack, Text, Tooltip } from '@mantine/core';
import { NodeId, ProvenanceNode, isStateNode } from '@trrack/core';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { animated, easings, useSpring } from 'react-spring';
import { AnnotationButton } from './AnnotationButton';
import { BookmarkButton } from './BookmarkButton';
import { ProvVisConfig } from './ProvVis';
import { useResizeObserver } from '@mantine/hooks';

export function NodeDescription<T, S extends string>({
depth,
Expand All @@ -15,6 +16,9 @@ export function NodeDescription<T, S extends string>({
isHover,
setHover,
colorMap,
isCurrent,
extraHeight,
setExtraHeight,
}: {
depth: number;
yOffset: number;
Expand All @@ -25,30 +29,37 @@ export function NodeDescription<T, S extends string>({
isHover: boolean;
setHover: (node: NodeId | null) => void;
colorMap: Record<S | 'Root', string>;
isCurrent: boolean;
extraHeight: number;
setExtraHeight: (n: number) => void;
}) {
const [ref, { width, height }] = useResizeObserver();

const style = useSpring({
config: {
duration: config.animationDuration,
easing: easings.easeInOutSine,
},
from: {
opacity: 0,
top:
depth * config.verticalSpace +
config.marginTop +
yOffset -
config.verticalSpace / 2,
},
to: {
opacity: 1,
top:
depth * config.verticalSpace +
config.marginTop +
yOffset -
config.verticalSpace / 2,
top:
depth * config.verticalSpace +
config.marginTop +
yOffset -
config.verticalSpace / 2 +
extraHeight,
});

const extraNodeOpacity = useSpring({
config: {
duration: config.animationDuration,
easing: easings.easeInOutSine,
},
opacity: isCurrent ? 1 : 0,
});

useEffect(() => {
if (isCurrent) setExtraHeight(height);
}, [height, isCurrent, setExtraHeight]);

const [isAnnotationOpen, setIsAnnotationOpen] = useState<boolean>(false);

return (
Expand All @@ -57,8 +68,6 @@ export function NodeDescription<T, S extends string>({
...style,
cursor: 'pointer',
position: 'absolute',
display: 'flex',
flexDirection: 'row',
height: config.verticalSpace,
alignContent: 'center',
flexWrap: 'wrap',
Expand All @@ -70,89 +79,105 @@ export function NodeDescription<T, S extends string>({
onMouseEnter={() => setHover(node.id)}
onMouseLeave={() => setHover(null)}
>
<Tooltip
position="top-start"
openDelay={200}
withinPortal={true}
withArrow
color="gray"
multiline
sx={{ maxWidth: '200px' }}
label={
<Stack spacing={0}>
<Text weight={600}>{node.label}</Text>
{config.getAnnotation(node.id).length > 0 ? (
<Text size="xs">
{config.getAnnotation(node.id)}
</Text>
) : null}
</Stack>
}
>
<div
style={{
width: `calc(100% - ${config.marginRight}px)`,
display: 'flex',
flexDirection: 'row',
}}
>
<div
style={{
alignItems: 'start',
justifyContent: 'center',
display: 'flex',
flexDirection: 'column',
marginRight: 'auto',
width: '100%',
}}
<Stack style={{ height: '100%' }} spacing={0}>
<Group noWrap>
<Tooltip
position="top-start"
openDelay={200}
withinPortal={true}
withArrow
color="gray"
multiline
sx={{ maxWidth: '200px' }}
label={
<Stack spacing={0}>
<Text weight={600}>{node.label}</Text>
{config.getAnnotation(node.id).length > 0 ? (
<Text size="xs">
{config.getAnnotation(node.id)}
</Text>
) : null}
</Stack>
}
>
<p
<div
style={{
maxWidth: `100%`,
margin: 0,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
width: `calc(100% - ${config.marginRight}px)`,
display: 'flex',
flexDirection: 'row',
}}
>
{node.label}
</p>

{isStateNode(node) ? (
<p
<div
style={{
maxWidth: `${config.labelWidth}px`,
margin: 0,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
color: 'gray',
fontSize: 10,
alignItems: 'start',
justifyContent: 'center',
display: 'flex',
flexDirection: 'column',
marginRight: 'auto',
width: '100%',
}}
>
{config.getAnnotation(node.id)}
</p>
) : null}
</div>
</div>
</Tooltip>
{config.bookmarkNode !== null &&
(isHover || isAnnotationOpen || config.isBookmarked(node.id)) ? (
<BookmarkButton
color={colorMap[node.event]}
isBookmarked={config.isBookmarked(node.id)}
onClick={() => config.bookmarkNode?.(node.id)}
/>
) : null}
{config.annotateNode !== null && (isHover || isAnnotationOpen) ? (
<AnnotationButton
color="cornflowerblue"
annotationOpen={isAnnotationOpen}
setAnnotationOpen={(b: boolean) => setIsAnnotationOpen(b)}
setAnnotation={(s) => config.annotateNode?.(node.id, s)}
annotation={config.getAnnotation(node.id)}
/>
) : null}
<p
style={{
maxWidth: `100%`,
margin: 0,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
{node.label}
</p>

{isStateNode(node) ? (
<p
style={{
maxWidth: `${config.labelWidth}px`,
margin: 0,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
color: 'gray',
fontSize: 10,
}}
>
{config.getAnnotation(node.id)}
</p>
) : null}
</div>
</div>
</Tooltip>
{config.bookmarkNode !== null &&
(isHover ||
isAnnotationOpen ||
config.isBookmarked(node.id)) ? (
<BookmarkButton
color={colorMap[node.event]}
isBookmarked={config.isBookmarked(node.id)}
onClick={() => config.bookmarkNode?.(node.id)}
/>
) : null}
{config.annotateNode !== null &&
(isHover || isAnnotationOpen) ? (
<AnnotationButton
color="cornflowerblue"
annotationOpen={isAnnotationOpen}
setAnnotationOpen={(b: boolean) =>
setIsAnnotationOpen(b)
}
setAnnotation={(s) =>
config.annotateNode?.(node.id, s)
}
annotation={config.getAnnotation(node.id)}
/>
) : null}
</Group>
{isCurrent ? (
<animated.div style={{ ...extraNodeOpacity }} ref={ref}>
{config.nodeExtra[node.event]}
</animated.div>
) : null}
</Stack>
</animated.div>
);
}
2 changes: 2 additions & 0 deletions packages/react/src/components/ProvVis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface ProvVisConfig<T, S extends string> {
annotateNode: ((id: NodeId, annotation: string) => void) | null;
getAnnotation: (id: NodeId) => string;
isBookmarked: (id: NodeId) => boolean;
nodeExtra: Record<S, React.ReactElement | null>;
}

const defaultConfig: ProvVisConfig<any, any> = {
Expand All @@ -47,6 +48,7 @@ const defaultConfig: ProvVisConfig<any, any> = {
annotateNode: null,
getAnnotation: () => '',
isBookmarked: () => false,
nodeExtra: {},
};

export function ProvVis<T, S extends string>({
Expand Down
Loading

0 comments on commit d1a8456

Please sign in to comment.