collab/mermaid/docs/adding-new-shape.mdblame
View source
6dd74de1> **Warning**
6dd74de2>
6dd74de3> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
6dd74de4>
6dd74de5> ## Please edit the corresponding file in [/packages/mermaid/src/docs/adding-new-shape.md](../packages/mermaid/src/docs/adding-new-shape.md).
6dd74de6
6dd74de7# Custom SVG Shapes Library
6dd74de8
6dd74de9This library provides a collection of custom SVG shapes, utilities, and helpers for generating diagram components. The shapes are designed to be used within an SVG container and include a variety of common and complex shapes.
6dd74de10
6dd74de11## Overview
6dd74de12
6dd74de13## Shape Helpers and Utilities
6dd74de14
6dd74de15Before starting with shape creation, it's essential to familiarize yourself with the utilities provided in the `utils.ts` file from `packages/mermaid/src/rendering-util/rendering-elements/shapes/util.js`. These utilities are designed to assist with various aspects of SVG shape manipulation and ensure consistent and accurate rendering.
6dd74de16
6dd74de17## Available Utilities
6dd74de18
6dd74de19### 1. `labelHelper`
6dd74de20
6dd74de21- **Purpose**: This function creates and inserts labels inside SVG shapes.
6dd74de22- **Features**:
6dd74de23 - Handles both HTML labels and plain text.
6dd74de24 - Calculates the bounding box dimensions of the label.
6dd74de25 - Ensures proper positioning of labels within shapes.
6dd74de26
6dd74de27### 2. `updateNodeBounds`
6dd74de28
6dd74de29- **Purpose**: Updates the bounding box dimensions (width and height) of a node.
6dd74de30- **Usage**:
6dd74de31 - Adjusts the size of the node to fit the content or shape.
6dd74de32 - Useful for ensuring that shapes resize appropriately based on their content.
6dd74de33
6dd74de34### 3. `insertPolygonShape`
6dd74de35
6dd74de36- **Purpose**: Inserts a polygon shape into an SVG container.
6dd74de37- **Features**:
6dd74de38 - Handles the creation and insertion of complex polygonal shapes.
6dd74de39 - Configures the shape's appearance and positioning within the SVG container.
6dd74de40
6dd74de41### 4. `getNodeClasses`
6dd74de42
6dd74de43- **Purpose**: Returns the appropriate CSS classes for a node based on its configuration.
6dd74de44- **Usage**:
6dd74de45 - Dynamically applies CSS classes to nodes for styling purposes.
6dd74de46 - Ensures that nodes adhere to the desired design and theme.
6dd74de47
6dd74de48### 5. `createPathFromPoints`
6dd74de49
6dd74de50- **Purpose**: Generates an SVG path string from an array of points.
6dd74de51- **Usage**:
6dd74de52 - Converts a list of points into a smooth path.
6dd74de53 - Useful for creating custom shapes or paths within the SVG.
6dd74de54
6dd74de55### 6. `generateFullSineWavePoints`
6dd74de56
6dd74de57- **Purpose**: Generates points for a sine wave, useful for creating wavy-edged shapes.
6dd74de58- **Usage**:
6dd74de59 - Facilitates the creation of shapes with wavy or sine-wave edges.
6dd74de60 - Can be used to add decorative or dynamic edges to shapes.
6dd74de61
6dd74de62## Getting Started
6dd74de63
6dd74de64To utilize these utilities, simply import them from the `utils.ts` file into your shape creation script. These helpers will streamline the process of building and customizing SVG shapes, ensuring consistent results across your projects.
6dd74de65
6dd74de66```typescript
6dd74de67import {
6dd74de68 labelHelper,
6dd74de69 updateNodeBounds,
6dd74de70 insertPolygonShape,
6dd74de71 getNodeClasses,
6dd74de72 createPathFromPoints,
6dd74de73 generateFullSineWavePoints,
6dd74de74} from './utils.ts';
6dd74de75```
6dd74de76
6dd74de77## Example Usage
6dd74de78
6dd74de79Here’s a basic example of how you might use some of these utilities:
6dd74de80
6dd74de81```typescript
6dd74de82import { labelHelper, insertPolygonShape } from './utils.ts';
6dd74de83
6dd74de84const svgContainer = document.getElementById('svgContainer');
6dd74de85
6dd74de86// Insert a polygon shape
6dd74de87insertPolygonShape(svgContainer /* shape-specific parameters */);
6dd74de88
6dd74de89// Create and insert a label inside the shape
6dd74de90labelHelper(svgContainer /* label-specific parameters */);
6dd74de91```
6dd74de92
6dd74de93## Adding New Shapes
6dd74de94
6dd74de95### 1. Create the Shape Function
6dd74de96
6dd74de97To add a new shape:
6dd74de98
6dd74de99- **Create the shape function**: Create a new file of name of the shape and export a function in the `shapes` directory that generates your shape. The file and function should follow the pattern used in existing shapes and return an SVG element.
6dd74de100
6dd74de101- **Example**:
6dd74de102
6dd74de103 ```typescript
6dd74de104 import { Node, RenderOptions } from '../../types.ts';
6dd74de105
6dd74de106 export const myNewShape = async (
6dd74de107 parent: SVGAElement,
6dd74de108 node: Node,
6dd74de109 renderOptions: RenderOptions
6dd74de110 ) => {
6dd74de111 // Create your shape here
6dd74de112 const shape = parent.insert('g').attr('class', 'my-new-shape');
6dd74de113 // Add other elements or styles as needed
6dd74de114 return shape;
6dd74de115 };
6dd74de116 ```
6dd74de117
6dd74de118### 2. Register the Shape
6dd74de119
6dd74de120- **Register the shape**: Add your shape to the `shapes` object in the [main shapes module](../rendering-util/rendering-elements/shapes.ts). This allows your shape to be recognized and used within the system.
6dd74de121
6dd74de122- **Example**:
6dd74de123
6dd74de124 ```typescript
6dd74de125 import { myNewShape } from './shapes/myNewShape';
6dd74de126
6dd74de127 const shapes = {
6dd74de128 ...,
6dd74de129 {
6dd74de130 semanticName: 'My Shape',
6dd74de131 name: 'Shape Name',
6dd74de132 shortName: '<short-name>',
6dd74de133 description: '<Description for the shape>',
6dd74de134 aliases: ['<alias-one>', '<al-on>', '<alias-two>', '<al-two>'],
6dd74de135 handler: myNewShape,
6dd74de136 },
6dd74de137 };
6dd74de138 ```
6dd74de139
6dd74de140# Shape Intersection Algorithms
6dd74de141
6dd74de142This contains algorithms and utilities for calculating intersection points for various shapes in SVG. Arrow intersection points are crucial for accurately determining where arrows connect with shapes. Ensuring precise intersection points enhances the clarity and accuracy of flowcharts and diagrams.
6dd74de143
6dd74de144## Shape Intersection Functions
6dd74de145
6dd74de146### 1. `Ellipse`
6dd74de147
6dd74de148Calculates the intersection points for an ellipse.
6dd74de149
6dd74de150**Usage**:
6dd74de151
6dd74de152```javascript
6dd74de153import intersectEllipse from './intersect-ellipse.js';
6dd74de154
6dd74de155const intersection = intersectEllipse(node, rx, ry, point);
6dd74de156```
6dd74de157
6dd74de158- **Parameters**:
6dd74de159 - `node`: The SVG node element.
6dd74de160 - `rx`: The x-radius of the ellipse.
6dd74de161 - `ry`: The y-radius of the ellipse.
6dd74de162 - `point`: The point from which the intersection is calculated.
6dd74de163
6dd74de164### 2. `intersectRect`
6dd74de165
6dd74de166Calculates the intersection points for a rectangle.
6dd74de167
6dd74de168**Usage**:
6dd74de169
6dd74de170```javascript
6dd74de171import intersectRect from './intersect-rect.js';
6dd74de172
6dd74de173const intersection = intersectRect(node, point);
6dd74de174```
6dd74de175
6dd74de176- **Parameters**:
6dd74de177 - `node`: The SVG node element.
6dd74de178 - `point`: The point from which the intersection is calculated.
6dd74de179
6dd74de180### 3. `intersectPolygon`
6dd74de181
6dd74de182Calculates the intersection points for a polygon.
6dd74de183
6dd74de184**Usage**:
6dd74de185
6dd74de186```javascript
6dd74de187import intersectPolygon from './intersect-polygon.js';
6dd74de188
6dd74de189const intersection = intersectPolygon(node, polyPoints, point);
6dd74de190```
6dd74de191
6dd74de192- **Parameters**:
6dd74de193 - `node`: The SVG node element.
6dd74de194 - `polyPoints`: Array of points defining the polygon.
6dd74de195 - `point`: The point from which the intersection is calculated.
6dd74de196
6dd74de197## Cypress Tests
6dd74de198
6dd74de199To ensure the robustness of the flowchart shapes, there are implementation of comprehensive Cypress test cases in `newShapes.spec.ts` file. These tests cover various aspects such as:
6dd74de200
6dd74de201- **Shapes**: Testing new shapes like `bowTieRect`, `waveRectangle`, `trapezoidalPentagon`, etc.
6dd74de202- **Looks**: Verifying shapes under different visual styles (`classic` and `handDrawn`).
6dd74de203- **Directions**: Ensuring correct rendering in all flow directions of arrows :
6dd74de204 - `TB` `(Top -> Bottom)`
6dd74de205 - `BT` `(Bottom -> Top)`
6dd74de206 - `LR` `(Left -> Right)`
6dd74de207 - `RL` `(Right -> Left)`
6dd74de208- **Labels**: Testing shapes with different labels, including:
6dd74de209 - No labels
6dd74de210 - Short labels
6dd74de211 - Very long labels
6dd74de212 - Markdown with `htmlLabels:true` and `htmlLabels:false`
6dd74de213- **Styles**: Applying custom styles to shapes and verifying correct rendering.
6dd74de214- **Class Definitions**: Using `classDef` to apply custom classes and testing their impact.
6dd74de215
6dd74de216### Running the Tests
6dd74de217
6dd74de218To run the Cypress tests, follow these steps:
6dd74de219
6dd74de2201. Ensure you have all dependencies installed by running:
6dd74de221
6dd74de222 ```bash
6dd74de223 pnpm install
6dd74de224 ```
6dd74de225
6dd74de2262. Start the Cypress test runner:
6dd74de227
6dd74de228 ```bash
6dd74de229 cypress open --env updateSnapshots=true
6dd74de230
6dd74de231 ```
6dd74de232
6dd74de2333. Select the test suite from the Cypress interface to run all the flowchart shape tests.