Hone logo
Hone
Problems

Interactive Diagram Editor in React

This challenge requires you to build a foundational interactive diagram editor using React and TypeScript. A diagram editor allows users to visually represent relationships and elements, which is crucial for applications like flowcharts, mind maps, system architecture diagrams, and more. Your task is to implement core functionalities for creating, manipulating, and connecting visual elements.

Problem Description

You will create a React component that functions as a basic diagram editor. The editor should allow users to:

  1. Add Shapes: Users should be able to add different types of shapes (e.g., rectangles, circles) to the canvas.
  2. Select and Move Shapes: Users should be able to click on a shape to select it and then drag it to a new position on the canvas.
  3. Draw Connections: Users should be able to draw connecting lines between shapes. These connections should ideally "stick" to the shapes they are connected to, so they move with the shapes.
  4. Delete Shapes and Connections: Users should be able to select and delete shapes or connections.

Key Requirements:

  • React Components: The editor should be built using functional React components and TypeScript.
  • State Management: Manage the state of shapes, their positions, and connections effectively. Consider how to handle updates and rendering.
  • User Interaction: Implement event handling for mouse clicks, drags, and potentially keyboard events for deletion.
  • Visual Representation: Use basic SVG elements or HTML elements for rendering shapes and connections. SVG is generally preferred for this type of application.
  • Connection Logic: Implement logic to draw lines between selected points on shapes.

Expected Behavior:

  • When the user clicks on an empty area of the canvas, nothing should happen (or a new shape could be added, depending on future extensions).
  • Clicking on a shape should highlight it (e.g., with a border).
  • Dragging a selected shape should visually update its position on the canvas.
  • Clicking on a shape and then clicking on another shape should create a visual connection between them.
  • Deleting a selected shape or connection should remove it from the canvas.

Edge Cases:

  • What happens if a user tries to connect a shape to itself?
  • How should connections be handled if shapes are deleted?
  • What if shapes overlap significantly?

Examples

Example 1: Adding and Moving Shapes

  • Input State: An empty canvas.
  • User Action:
    1. Clicks a "Add Rectangle" button.
    2. Clicks on the canvas at coordinates (100, 50). A rectangle appears.
    3. Clicks on the rectangle to select it. A border appears.
    4. Drags the rectangle to coordinates (200, 150).
  • Output State: A single rectangle is now positioned at (200, 150) with a selection border.

Example 2: Drawing and Deleting Connections

  • Input State: Two rectangles, RectA at (50, 50) and RectB at (250, 50).
  • User Action:
    1. Selects RectA.
    2. Clicks on RectB.
    3. A line is drawn connecting RectA and RectB.
    4. Selects the line.
    5. Presses the "Delete" key.
  • Output State: The line connecting RectA and RectB is removed. RectA and RectB remain.

Example 3: Connection Persistence with Shape Movement

  • Input State: RectA at (50, 50) and RectB at (250, 50), connected by a line.
  • User Action:
    1. Selects RectA.
    2. Drags RectA to (150, 100).
  • Output State: RectA is now at (150, 100). The line connecting RectA and RectB has updated its starting point to (150, 100) while the ending point remains connected to RectB at (250, 50).

Constraints

  • The editor should be able to render at least 100 shapes and 500 connections without significant performance degradation (aim for smooth drag operations).
  • Shape positions will be represented by x and y coordinates (integers or floats).
  • Shapes will have a fixed width and height for simplicity in this initial challenge.
  • Connections should be simple straight lines for this challenge.

Notes

  • Consider using a state management library (like useState with reducers, or useReducer) to manage the complex state of shapes and connections.
  • SVG is highly recommended for rendering graphics. You'll likely use <rect>, <circle>, and <line> elements.
  • For drawing connections, you might need to calculate connection points on the shapes (e.g., center points, or edges).
  • Think about how to uniquely identify each shape and connection for selection and deletion.
  • The "sticking" behavior of connections can be implemented by recalculating the line's endpoints whenever a connected shape moves.
  • Focus on the core functionality first. Visual styling and advanced features (like different shape types, curved lines, text labels, grouping) can be considered for future extensions.
Loading editor...
typescript