feat: draw.io custom shapes analysis + buildable example plugin
- ANALYSIS.md: Full architecture analysis of draw.io shape systems (XML stencils vs JS shapes, plugin loading, desktop/web support) - Example plugin with 5 custom shapes demonstrating JS logic: - StatusIndicator: conditional rendering based on status param - ProgressBar: computed geometry (percentage-based fill) - DataFlowArrow: dynamic arrows with direction/speed params - HexagonCluster: loop-based hexagonal grid generation - MetricGauge: radial gauge with arc computation + zones - Webpack build pipeline (npm run build / build:dev / watch) - Pre-built dist/drawio-custom-shapes.js ready for installation - Full README with installation instructions for desktop + web
This commit is contained in:
@@ -1,3 +1,159 @@
|
||||
# drawio-custom-shapes
|
||||
# draw.io Custom Shapes Example Plugin
|
||||
|
||||
Analysis and example plugin for building custom draw.io shapes with JavaScript logic
|
||||
A fully buildable example plugin demonstrating how to create custom draw.io shapes with JavaScript logic.
|
||||
|
||||
## What This Is
|
||||
|
||||
A draw.io plugin that registers custom shapes with **programmatic rendering** — shapes that use conditionals, loops, computed geometry, and style-reactive behavior. Unlike XML stencils (which are purely declarative), these shapes have full JavaScript power.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Development build (with source maps)
|
||||
npm run build:dev
|
||||
|
||||
# Production build (minified)
|
||||
npm run build
|
||||
|
||||
# Watch mode (rebuild on changes)
|
||||
npm run watch
|
||||
```
|
||||
|
||||
Output: `dist/drawio-custom-shapes.js`
|
||||
|
||||
## Installation in draw.io
|
||||
|
||||
### Desktop App (Electron)
|
||||
|
||||
1. Build the plugin: `npm run build`
|
||||
2. Open draw.io desktop
|
||||
3. **Extras > Plugins**
|
||||
4. Enable external plugins if prompted
|
||||
5. Click **"Select File..."** → navigate to `dist/drawio-custom-shapes.js`
|
||||
6. Restart draw.io
|
||||
7. Find "Custom Shapes Example" palette in the sidebar
|
||||
|
||||
### Self-Hosted (Docker)
|
||||
|
||||
1. Build the plugin: `npm run build`
|
||||
2. Copy `dist/drawio-custom-shapes.js` to your draw.io plugins directory
|
||||
3. Set environment: `DRAWIO_PLUGINS_ALLOW_CUSTOM=true`
|
||||
4. Add to configuration:
|
||||
```json
|
||||
{
|
||||
"plugins": ["/plugins/drawio-custom-shapes.js"]
|
||||
}
|
||||
```
|
||||
5. Restart the container
|
||||
|
||||
### Web (URL parameter)
|
||||
|
||||
If you host the plugin file at a URL:
|
||||
```
|
||||
https://your-drawio.com/?p=YOUR_PLUGIN_KEY
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
├── src/
|
||||
│ ├── index.js # Plugin entry point (Draw.loadPlugin wrapper)
|
||||
│ ├── shapes/
|
||||
│ │ ├── StatusIndicator.js # Conditional rendering based on status
|
||||
│ │ ├── ProgressBar.js # Computed geometry (percentage-based)
|
||||
│ │ ├── DataFlowArrow.js # Dynamic arrow with animation markers
|
||||
│ │ ├── HexagonCluster.js # Loop-based hexagonal grid
|
||||
│ │ └── MetricGauge.js # Radial gauge with computed arcs
|
||||
│ └── palette.js # Sidebar palette registration
|
||||
├── dist/ # Build output
|
||||
├── webpack.config.js # Build configuration
|
||||
├── package.json
|
||||
├── ANALYSIS.md # Full architecture analysis
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Shape Catalog
|
||||
|
||||
### 1. Status Indicator (`customShapes.statusIndicator`)
|
||||
A shape that changes color and icon based on a `status` style parameter.
|
||||
- Styles: `status=ok|warning|error|unknown`
|
||||
- Demonstrates: conditional rendering, style reading
|
||||
|
||||
### 2. Progress Bar (`customShapes.progressBar`)
|
||||
A horizontal bar that fills based on a percentage value.
|
||||
- Styles: `progress=0..100`, `barColor=#4CAF50`
|
||||
- Demonstrates: computed geometry, value-based rendering
|
||||
|
||||
### 3. Data Flow Arrow (`customShapes.dataFlowArrow`)
|
||||
A directional arrow with animated flow indicators.
|
||||
- Styles: `direction=right|left|both`, `flowSpeed=fast|medium|slow`
|
||||
- Demonstrates: dynamic path generation, pattern rendering
|
||||
|
||||
### 4. Hexagon Cluster (`customShapes.hexCluster`)
|
||||
A grid of hexagons that adapts to the cell size.
|
||||
- Styles: `hexCount=7`, `hexFill=#E3F2FD`
|
||||
- Demonstrates: loop-based drawing, mathematical geometry
|
||||
|
||||
### 5. Metric Gauge (`customShapes.metricGauge`)
|
||||
A radial gauge (speedometer-style) showing a value within a range.
|
||||
- Styles: `value=75`, `minVal=0`, `maxVal=100`, `zones=green,yellow,red`
|
||||
- Demonstrates: arc computation, gradient zones, text rendering
|
||||
|
||||
## Customizing
|
||||
|
||||
### Adding a New Shape
|
||||
|
||||
1. Create a new file in `src/shapes/YourShape.js`:
|
||||
|
||||
```javascript
|
||||
import { registerShape, getValue } from '../utils';
|
||||
|
||||
export function YourShapeName() {
|
||||
mxShape.call(this);
|
||||
}
|
||||
|
||||
mxUtils.extend(YourShapeName, mxShape);
|
||||
|
||||
YourShapeName.prototype.paintVertexShape = function(c, x, y, w, h) {
|
||||
c.translate(x, y);
|
||||
|
||||
// Read style parameters
|
||||
var myParam = getValue(this.style, 'myParam', 'default');
|
||||
|
||||
// Draw with full JS logic
|
||||
c.begin();
|
||||
c.moveTo(0, 0);
|
||||
c.lineTo(w, h);
|
||||
c.stroke();
|
||||
};
|
||||
|
||||
// Register the shape
|
||||
registerShape('customShapes.yourShape', YourShapeName);
|
||||
```
|
||||
|
||||
2. Import it in `src/index.js`
|
||||
3. Add a palette entry in `src/palette.js`
|
||||
4. Rebuild: `npm run build`
|
||||
|
||||
### Style Parameters
|
||||
|
||||
Shapes read parameters from the cell's style string:
|
||||
```
|
||||
shape=customShapes.yourShape;myParam=value;fillColor=#fff;
|
||||
```
|
||||
|
||||
Access in code:
|
||||
```javascript
|
||||
var val = mxUtils.getValue(this.style, 'myParam', 'default');
|
||||
```
|
||||
|
||||
## Architecture Notes
|
||||
|
||||
See [ANALYSIS.md](./ANALYSIS.md) for the full technical analysis of how draw.io's shape systems work, including the stencil registry, cell renderer, and plugin loading mechanisms.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
Reference in New Issue
Block a user