Nested node structure for vizualiser

Summary: This structure makes sense for the vizualiser which itself is a nested structure. It also saves the awkward branch of there is no key in the map.

Reviewed By: lblasa

Differential Revision: D40670371

fbshipit-source-id: 6c1b960a77749be9e8a193decf6b8d50ce6c7968
This commit is contained in:
Luke De Feo
2022-11-14 07:05:58 -08:00
committed by Facebook GitHub Bot
parent 1398e2aa8a
commit bfe098485f
2 changed files with 61 additions and 32 deletions

View File

@@ -8,7 +8,7 @@
*/ */
import React from 'react'; import React from 'react';
import {Id, Snapshot, Tag, UINode} from '../types'; import {Id, NestedNode, Snapshot, Tag, UINode} from '../types';
import {styled, Layout, theme} from 'flipper-plugin'; import {styled, Layout, theme} from 'flipper-plugin';
export const Visualization2D: React.FC< export const Visualization2D: React.FC<
@@ -33,12 +33,16 @@ export const Visualization2D: React.FC<
modifierPressed, modifierPressed,
}) => { }) => {
//todo, do a bfs search for the first bounds found //todo, do a bfs search for the first bounds found
const rootBounds = nodes.get(rootId)?.bounds;
const rootSnapshot = snapshots.get(rootId);
if (!rootBounds) { const rootSnapshot = snapshots.get(rootId);
const root = toNestedNode(rootId, nodes);
if (!root) {
return null; return null;
} }
const rootBounds = root.bounds;
return ( return (
<div <div
onMouseLeave={(e) => { onMouseLeave={(e) => {
@@ -66,8 +70,7 @@ export const Visualization2D: React.FC<
/> />
) : null} ) : null}
<Visualization2DNode <Visualization2DNode
nodeId={rootId} node={root}
nodes={nodes}
snapshots={snapshots} snapshots={snapshots}
hoveredNode={hoveredNode} hoveredNode={hoveredNode}
selectedNode={selectedNode} selectedNode={selectedNode}
@@ -80,9 +83,7 @@ export const Visualization2D: React.FC<
}; };
function Visualization2DNode({ function Visualization2DNode({
parentId, node,
nodeId,
nodes,
snapshots, snapshots,
hoveredNode, hoveredNode,
selectedNode, selectedNode,
@@ -90,9 +91,7 @@ function Visualization2DNode({
onHoverNode, onHoverNode,
modifierPressed, modifierPressed,
}: { }: {
nodeId: Id; node: NestedNode;
parentId?: Id;
nodes: Map<Id, UINode>;
snapshots: Map<Id, Snapshot>; snapshots: Map<Id, Snapshot>;
modifierPressed: boolean; modifierPressed: boolean;
hoveredNode?: Id; hoveredNode?: Id;
@@ -100,38 +99,31 @@ function Visualization2DNode({
onSelectNode: (id?: Id) => void; onSelectNode: (id?: Id) => void;
onHoverNode: (id?: Id) => void; onHoverNode: (id?: Id) => void;
}) { }) {
const node = nodes.get(nodeId); const snapshot = snapshots.get(node.id);
const snapshot = snapshots.get(nodeId);
if (!node) { const isHovered = hoveredNode === node.id;
return null; const isSelected = selectedNode === node.id;
}
const isHovered = hoveredNode === nodeId; let nestedChildren: NestedNode[];
const isSelected = selectedNode === nodeId;
let childrenIds: Id[] = [];
//if there is an active child don't draw the other children //if there is an active child don't draw the other children
//this means we don't draw overlapping activities / tabs etc //this means we don't draw overlapping activities / tabs etc
if (node.activeChild) { if (node.activeChildIdx) {
childrenIds = [node.activeChild]; nestedChildren = [node.children[node.activeChildIdx]];
} else { } else {
childrenIds = node.children; nestedChildren = node.children;
} }
// stop drawing children if hovered with the modifier so you // stop drawing children if hovered with the modifier so you
// can see parent views without their children getting in the way // can see parent views without their children getting in the way
if (isHovered && modifierPressed) { if (isHovered && modifierPressed) {
childrenIds = []; nestedChildren = [];
} }
const children = childrenIds.map((childId) => ( const children = nestedChildren.map((child) => (
<Visualization2DNode <Visualization2DNode
parentId={nodeId} key={child.id}
key={childId} node={child}
nodeId={childId}
nodes={nodes}
snapshots={snapshots} snapshots={snapshots}
hoveredNode={hoveredNode} hoveredNode={hoveredNode}
onSelectNode={onSelectNode} onSelectNode={onSelectNode}
@@ -161,11 +153,11 @@ function Visualization2DNode({
}} }}
onMouseEnter={(e) => { onMouseEnter={(e) => {
e.stopPropagation(); e.stopPropagation();
onHoverNode(nodeId); onHoverNode(node.id);
}} }}
onMouseLeave={(e) => { onMouseLeave={(e) => {
e.stopPropagation(); e.stopPropagation();
onHoverNode(parentId); // onHoverNode(parentId);
}} }}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
@@ -232,3 +224,30 @@ const OuterBorder = styled.div({
function toPx(n: number) { function toPx(n: number) {
return `${n / 2}px`; return `${n / 2}px`;
} }
function toNestedNode(
rootId: Id,
nodes: Map<Id, UINode>,
): NestedNode | undefined {
function uiNodeToNestedNode(node: UINode): NestedNode {
const activeChildIdx = node.activeChild
? node.children.indexOf(node.activeChild)
: undefined;
return {
id: node.id,
name: node.name,
attributes: node.attributes,
children: node.children
.map((childId) => nodes.get(childId))
.filter((child) => child != null)
.map((child) => uiNodeToNestedNode(child!!)),
bounds: node.bounds,
tags: node.tags,
activeChildIdx: activeChildIdx,
};
}
const root = nodes.get(rootId);
return root ? uiNodeToNestedNode(root) : undefined;
}

View File

@@ -50,6 +50,16 @@ export type UpdateMetadataEvent = {
attributeMetadata: Record<MetadataId, Metadata>; attributeMetadata: Record<MetadataId, Metadata>;
}; };
export type NestedNode = {
id: Id;
name: string;
attributes: Record<string, Inspectable>;
children: NestedNode[];
bounds: Bounds;
tags: Tag[];
activeChildIdx?: number;
};
export type UINode = { export type UINode = {
id: Id; id: Id;
qualifiedName: string; qualifiedName: string;