import React from 'react'; import {Motion, spring} from 'react-motion'; import dagre from 'dagre'; // import prettyFormat from 'pretty-format'; // import reactElement from 'pretty-format/plugins/ReactElement'; function getFiberColor(fibers, id) { if (fibers.currentIDs.indexOf(id) > -1) { return 'lightgreen'; } if (id === fibers.workInProgressID) { return 'yellow'; } return 'lightyellow'; } function Graph(props) { const {rankdir, trackActive} = props.settings; var g = new dagre.graphlib.Graph(); g.setGraph({ width: 1000, height: 1000, nodesep: 50, edgesep: 150, ranksep: 100, marginx: 100, marginy: 100, rankdir, }); var edgeLabels = {}; React.Children.forEach(props.children, function (child) { if (!child) { return; } if (child.type.isVertex) { g.setNode(child.key, { label: child, width: child.props.width, height: child.props.height, }); } else if (child.type.isEdge) { const relationshipKey = child.props.source + ':' + child.props.target; if (!edgeLabels[relationshipKey]) { edgeLabels[relationshipKey] = []; } edgeLabels[relationshipKey].push(child); } }); Object.keys(edgeLabels).forEach(key => { const children = edgeLabels[key]; const child = children[0]; g.setEdge(child.props.source, child.props.target, { label: child, allChildren: children.map(c => c.props.children), weight: child.props.weight, }); }); dagre.layout(g); var activeNode = g .nodes() .map(v => g.node(v)) .find(node => node.label.props.isActive); const [winX, winY] = [window.innerWidth / 2, window.innerHeight / 2]; var focusDx = trackActive && activeNode ? winX - activeNode.x : 0; var focusDy = trackActive && activeNode ? winY - activeNode.y : 0; var nodes = g.nodes().map(v => { var node = g.node(v); return ( {interpolatingStyle => React.cloneElement(node.label, { x: interpolatingStyle.x + props.dx, y: interpolatingStyle.y + props.dy, vanillaX: node.x, vanillaY: node.y, }) } ); }); var edges = g.edges().map(e => { var edge = g.edge(e); let idx = 0; return ( { bag[idx + ':x'] = props.isDragging ? point.x + focusDx : spring(point.x + focusDx); bag[idx + ':y'] = props.isDragging ? point.y + focusDy : spring(point.y + focusDy); idx++; return bag; }, {})} key={edge.label.key}> {interpolatedStyle => { let points = []; Object.keys(interpolatedStyle).forEach(key => { const [idx, prop] = key.split(':'); if (!points[idx]) { points[idx] = {x: props.dx, y: props.dy}; } points[idx][prop] += interpolatedStyle[key]; }); return React.cloneElement(edge.label, { points, id: edge.label.key, children: edge.allChildren.join(', '), }); }} ); }); return (
{edges} {nodes}
); } function Vertex(props) { if (Number.isNaN(props.x) || Number.isNaN(props.y)) { return null; } return (
{props.children}
); } Vertex.isVertex = true; const strokes = { alt: 'blue', child: 'green', sibling: 'darkgreen', return: 'red', fx: 'purple', }; function Edge(props) { var points = props.points; var path = 'M' + points[0].x + ' ' + points[0].y + ' '; if (!points[0].x || !points[0].y) { return null; } for (var i = 1; i < points.length; i++) { path += 'L' + points[i].x + ' ' + points[i].y + ' '; if (!points[i].x || !points[i].y) { return null; } } var lineID = props.id; return ( {'     '} {props.children} ); } Edge.isEdge = true; function formatPriority(priority) { switch (priority) { case 1: return 'synchronous'; case 2: return 'task'; case 3: return 'hi-pri work'; case 4: return 'lo-pri work'; case 5: return 'offscreen work'; default: throw new Error('Unknown priority.'); } } export default function Fibers({fibers, show, graphSettings, ...rest}) { const items = Object.keys(fibers.descriptions).map( id => fibers.descriptions[id] ); const isDragging = rest.className.indexOf('dragging') > -1; const [_, sdx, sdy] = rest.style.transform.match(/translate\((-?\d+)px,(-?\d+)px\)/) || []; const dx = Number(sdx); const dy = Number(sdy); return (
{items.map(fiber => [
{fiber.tag} #{fiber.id}
{fiber.type}
{fibers.currentIDs.indexOf(fiber.id) === -1 ? ( {fiber.pendingWorkPriority !== 0 && [ Needs: {formatPriority(fiber.pendingWorkPriority)} ,
, ]} {fiber.memoizedProps !== null && fiber.pendingProps !== null && [ fiber.memoizedProps === fiber.pendingProps ? 'Can reuse memoized.' : 'Cannot reuse memoized.',
, ]}
) : ( Committed )} {fiber.flags && [
, Effect: {fiber.flags}, ]}
, fiber.child && show.child && ( child ), fiber.sibling && show.sibling && ( sibling ), fiber.return && show.return && ( return ), fiber.nextEffect && show.fx && ( nextFx ), fiber.firstEffect && show.fx && ( firstFx ), fiber.lastEffect && show.fx && ( lastFx ), fiber.alternate && show.alt && ( alt ), ])}
); }