Edward's Tech Site

this site made with Next.js 13, see the code

FORAY: Aug 14 - React
Get a React Flow showcase up and running
  • background
    • I'm working on a project that uses React Flow
    • so want to build a showcase with it from the ground up to learn the basics
  • infos
  • Quickstart
    • here is a video in 60 seconds
    • setting up site with Vite template
      • npx degit xyflow/vite-react-flow-template showcase-react-flow
      • npm i
      • npm audit fix
      • npm run dev
      • analyzing the code
        • fitView={true}, false makes it small
        • the main objects: gets from index.ts
          • import { initialNodes, nodeTypes } from './nodes';
            import { initialEdges, edgeTypes } from './edges';
        • initial nodes, delete and they are gone
        • nnn
  • React Flow Course in 30 minutes
    • from April 2024
    • vocabulary
      • nodes
      • handles
      • edge (line)
    • my project has the library @xyflow/react
      • apparently React Flow since version 12 is xyflow, see xyflow repo
    • must be inside a fixed container
    • App.tsx
      • import { ReactFlow, Node } from '@xyflow/react';
        import '@xyflow/react/dist/style.css';
         
        export default function App() {
         
        const nodes: Node[] = [{
        id: '1',
        data: {},
        position: { x: 100, y: 100 }
        }];
         
        return (
        <ReactFlow nodes={nodes} />
        );
        }
      • shows this:
      • hidden hides it
      • added edges
        • const edges: Edge[] = [
          {
          id: "2-3",
          source: "2",
          target: "3",
          style: { stroke: "black" },
          animated: true,
          },
          {
          id: "3-4",
          source: "3",
          target: "4",
          style: { stroke: "black" },
          },
          ];
    • his example for a custom type didn't work, so discontinuing:
  • Adding Interactivity
    • enabled boxes to have different background colors and to change these colors based on position
      • {
        id: "5",
        data: { label: "Current Position", bgcolor: "lightgreen" },
        type: "position-logger",
        position: { x: 20, y: 140 },
        height: 100,
        },
        {
        id: "6",
        data: { label: "Has handle", bgcolor: "lightblue", hasHandle: true },
        type: "position-logger",
        position: { x: 20, y: 240 },
        height: 100,
        },
        {
        id: "7",
        data: { label: "No handle", bgcolor: "beige", hasHandle: false },
        type: "position-logger",
        position: { x: 60, y: 540 },
        height: 100,
        },
      • works like this:
    • adding label to edge:
    • adding a line to the background
      • create compononent called DividerLine.tsx
        • export const DividerLine = () => {
          return (
          <svg
          style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', zIndex: -1 }}
          >
          <line x1="10%" y1="83%" x2="90%" y2="83%" stroke="tomato" strokeWidth="2" />
          </svg>
          );
          };
      • looks like this:
    • style nodes
      • add a style property
        • {
          id: "9",
          data: {
          label: "002",
          },
          position: { x: 556, y: 10 },
          width: 70,
          height: 70,
          style: {
          backgroundColor: "#10165c",
          color: "#ddd",
          fontSize: "1.3rem",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          textAlign: "center"
          },
          },
      • looks like this:
    • style edge labels
      • styled somewhat, but couldn't center the text
      • actually, that was Firefox, it's centered in Chrome:
      • it's also centered on my Chrome browser on my Samsung A52s phone
  • Custom Nodes
    • got custom nodes working which have text content that is loaded via a JSON file:
    • FlowArea2/nodes/index.ts
      • import { InfoNode } from "./InfoNode";
        import notes from "../data/notes.json";
        import * as tools from "../../../tools";
         
        export const initialNodes: AppNode[] = notes.map((note, index) => {
        const x = 5 * tools.getRandomNumberBetween(5, 20);
        const y = 5 * tools.getRandomNumberBetween(5, 20);
        const rotate = `${tools.getRandomNumberBetween(-20, 20)}deg`;
        return {
        id: `${index + 1}`,
        data: { label: note, rotate },
        type: "info-node",
        position: { x, y },
        height: 100,
        };
        });
         
        export const nodeTypes = {
        "info-node": InfoNode,
        } satisfies NodeTypes;
  • nnn
    • nnn
  • nnn
    • nnn
  • nnn
    • nnn
  • nnn
    • nnn
  • nnn
    • nnn
  • nnn
    • nnn
  • nnn
    • nnn