Skip to content

Commit

Permalink
feat: Click to highlight state [PT-187321073]
Browse files Browse the repository at this point in the history
Clicking on a state highlights the state and connected inbound and outbound arrows and sets the unselected states and inbound and outbound arrows to a lower opacity.
  • Loading branch information
dougmartin committed Apr 2, 2024
1 parent 8de4c19 commit 455d4a9
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 77 deletions.
48 changes: 32 additions & 16 deletions src/components/app.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { clsx } from "clsx";

import { useCODAP } from "../hooks/use-codap";
import { useGraph } from "../hooks/use-graph";
import { Graph, orangeColor } from "./graph";
import { Graph } from "./graph";
import { useGenerator } from "../hooks/use-generator";
import { Edge, Node } from "../type";
import { Drawing } from "./drawing";
Expand Down Expand Up @@ -58,11 +58,11 @@ export const App = () => {
const [delimiter, setDelimiter] = useState("");
const [startingState, setStartingState] = useState("");
const [sequenceGroups, setSequenceGroups] = useState<SequenceGroup[]>([]);
const [selectedNodeId, _setSelectedNodeId] = useState<string>();
const [highlightNode, setHighlightNode] = useState<Node>();
const [highlightLoopOnNode, setHighlightLoopOnNode] = useState<Node>();
const [highlightEdge, setHighlightEdge] = useState<Edge>();
const [highlightAllNextNodes, setHighlightAllNextNodes] = useState(false);
const [highlightColor, setHighlightColor] = useState(orangeColor);
const [generationMode, setGenerationMode] = useState<GenerationMode>("ready");
const prevAnimatedSequenceGroups = useRef<SequenceGroup[]>([]);
const currentAnimatedSequenceGroup = useRef<SequenceGroup>();
Expand All @@ -80,6 +80,20 @@ export const App = () => {
const { generate } = useGenerator();
const innerOutputRef = useRef<HTMLDivElement | null>(null);

const animating = useMemo(() => {
return generationMode !== "ready";
}, [generationMode]);

const setSelectedNodeId = useCallback((id?: string, skipToggle?: boolean) => {
if (!animating) {
if ((!id || (id === selectedNodeId)) && !skipToggle) {
_setSelectedNodeId(undefined);
} else {
_setSelectedNodeId(id);
}
}
}, [_setSelectedNodeId, selectedNodeId, animating]);

useEffect(() => {
if (viewMode === "drawing") {
notifyStateIsDirty();
Expand Down Expand Up @@ -133,7 +147,6 @@ export const App = () => {
if (inBeforeStep()) {
setHighlightNode(currentNode);
setHighlightEdge(undefined);
setHighlightColor(orangeColor);
// highlight all the possible edges if we have a next node
setHighlightAllNextNodes(!!nextNode);
setHighlightLoopOnNode(currentNode);
Expand All @@ -143,7 +156,6 @@ export const App = () => {
: undefined;
setHighlightEdge(edge);
setHighlightNode(nextNode);
setHighlightColor(orangeColor);
setHighlightAllNextNodes(false);
setHighlightLoopOnNode(nextNode === currentNode ? nextNode : undefined);
}
Expand Down Expand Up @@ -408,23 +420,27 @@ export const App = () => {
highlightNode={highlightNode}
highlightLoopOnNode={highlightLoopOnNode}
highlightEdge={highlightEdge}
highlightColor={highlightColor}
highlightAllNextNodes={highlightAllNextNodes}
selectedNodeId={selectedNodeId}
animating={animating}
setGraph={setGraph}
setHighlightNode={setHighlightNode}
setSelectedNodeId={setSelectedNodeId}
/>
:
<Graph
mode="dataset"
graph={graph}
highlightNode={highlightNode}
highlightLoopOnNode={highlightLoopOnNode}
highlightEdge={highlightEdge}
highlightColor={highlightColor}
highlightAllNextNodes={highlightAllNextNodes}
allowDragging={true}
autoArrange={true}
/>
mode="dataset"
graph={graph}
highlightNode={highlightNode}
highlightLoopOnNode={highlightLoopOnNode}
highlightEdge={highlightEdge}
highlightAllNextNodes={highlightAllNextNodes}
selectedNodeId={selectedNodeId}
animating={animating}
allowDragging={true && !animating}
autoArrange={true}
setSelectedNodeId={setSelectedNodeId}
/>
}
</div>
<div className="right">
Expand Down
22 changes: 13 additions & 9 deletions src/components/drawing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,22 @@ interface Props {
highlightNode?: Node,
highlightLoopOnNode?: Node,
highlightEdge?: Edge,
highlightColor: string
highlightAllNextNodes: boolean;
graph: GraphData;
selectedNodeId?: string;
animating: boolean;
setGraph: React.Dispatch<React.SetStateAction<GraphData>>;
setHighlightNode: React.Dispatch<React.SetStateAction<Node | undefined>>
setSelectedNodeId: (id?: string, skipToggle?: boolean) => void;
}

export const Drawing = (props: Props) => {
const {highlightNode, highlightLoopOnNode, highlightEdge, highlightColor, highlightAllNextNodes,
graph, setGraph, setHighlightNode} = props;
const {highlightNode, highlightLoopOnNode, highlightEdge, highlightAllNextNodes,
graph, setGraph, setHighlightNode, setSelectedNodeId, selectedNodeId, animating} = props;
const [drawingMode, setDrawingMode] = useState<DrawingMode>("select");
const [firstEdgeNode, setFirstEdgeNode] = useState<Node|undefined>(undefined);
const [rubberBand, setRubberBand] = useState<RubberBand|undefined>(undefined);
const [selectedNode, setSelectedNode] = useState<Node|undefined>(undefined);
const [selectedNodeForModal, setSelectedNodeForModal] = useState<Node|undefined>(undefined);

const sidebarRef = useRef<HTMLDivElement|null>(null);

Expand Down Expand Up @@ -186,7 +188,7 @@ export const Drawing = (props: Props) => {

const handleNodeDoubleClicked = useCallback((id: string) => {
if (drawingMode === "select") {
setSelectedNode(getNode(id));
setSelectedNodeForModal(getNode(id));
}
if (drawingMode === "addEdge") {
addEdge({from: id, to: id});
Expand Down Expand Up @@ -225,7 +227,7 @@ export const Drawing = (props: Props) => {
});
}, [setGraph]);

const handleClearSelectedNode = useCallback(() => setSelectedNode(undefined), [setSelectedNode]);
const handleClearSelectedNode = useCallback(() => setSelectedNodeForModal(undefined), [setSelectedNodeForModal]);

const handleChangeNode = useCallback((id: string, newNode: Node, newEdges: Edge[]) => {
setGraph(prev => {
Expand Down Expand Up @@ -279,22 +281,24 @@ export const Drawing = (props: Props) => {
graph={graph}
highlightNode={highlightNode}
highlightEdge={highlightEdge}
highlightColor={highlightColor}
highlightAllNextNodes={highlightAllNextNodes}
highlightLoopOnNode={highlightLoopOnNode}
allowDragging={drawingMode === "select"}
allowDragging={drawingMode === "select" && !animating}
autoArrange={false}
rubberBand={rubberBand}
selectedNodeId={selectedNodeId}
animating={animating}
onClick={handleClicked}
onMouseUp={handleMouseUp}
onNodeClick={handleNodeClicked}
onNodeDoubleClick={handleNodeDoubleClicked}
onEdgeClick={handleEdgeClicked}
onDragStop={handleDragStop}
setSelectedNodeId={setSelectedNodeId}
/>
<DragIcon drawingMode={drawingMode} />
<NodeModal
node={selectedNode}
node={selectedNodeForModal}
graph={graph}
onChange={handleChangeNode}
onCancel={handleClearSelectedNode}
Expand Down
Loading

0 comments on commit 455d4a9

Please sign in to comment.