Skip to content
This repository has been archived by the owner on Jan 17, 2025. It is now read-only.

Commit

Permalink
docs: add technical information (#91)
Browse files Browse the repository at this point in the history
New contents:
  - information from draw.io and the implementation of this repository
  - class diagram

Also mark the repository as archived.
  • Loading branch information
tbouffard authored Jan 17, 2025
1 parent a67abc8 commit 175f552
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 4 deletions.
102 changes: 98 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<h1 align="center">MxGraph Sketch</h1> <br>
<p align="center">
<p align="center">
<img title="MxGraph Sketch" src="diagram-example.png" width="812" height="170">
<img title="MxGraph Sketch" src="docs/diagram-example.png" width="812" height="170">
</p>
<p align="center">
<a href="https://github.com/process-analytics/mxgraph-sketch/releases">
Expand All @@ -23,11 +23,105 @@
</p>
</p>

Used with the [MxGraph](https://github.com/jgraph/mxgraph) library, this library updates the render with a Sketch style.

| Archived on 2025-01-17 | We no longer maintain this repository. |
| -------- | -------- |


Used with the [mxGraph](https://github.com/jgraph/mxgraph) library, this library updates the render with a Sketch style.

## 🎨 Features

:warning: **THIS LIBRARY IS CURRENTLY UNDER DEVELOPMENT** :warning:
⚠️ **THIS LIBRARY IS CURRENTLY UNDER DEVELOPMENT** ⚠️

This is a demo only.


## 🚢 Build and run locally

Run `npm install` to install the dependencies.

The, run `npm start` to start the development server.


## 🧩 Technical details (from draw.io)

### Technical Analysis: Sketch and Hand Jiggle Implementation

See [Introducing draw.io’s new sketch feature](https://drawio-app.com/introducing-draw-ios-new-sketch-feature/). It leverages [Rough.js](https://roughjs.com/) to create hand-drawn effects. The feature can be applied to the entire graph or specific elements by defining a style. For compatibility, the property names used in draw.io's styles have been retained.

### Key Details of draw.io’s Implementation

- **Style Property**:
Draw.io introduces a `sketchStyle` property in its style definitions, which can take the values `'comic'` or `'rough'`. By default, it falls back to `'rough'` if not explicitly set.
The visual difference is notable: the `'sketch'` style creates a more pronounced effect than `'comic'`.
This behavior was observed by modifying the `sketchStyle` value in draw.io—replacing `sketch=1` with `comic=1`.

- **Canvas Handling**:
The `sketchStyle` property determines which type of `handJiggleCanvas` (comic or rough) is created and used for rendering.

- **New Functionality**:
A new function, `mxShape.createHandJiggle`, is introduced, as seen in the draw.io codebase:
[Relevant code in Editor.js](https://github.com/jgraph/drawio/blob/acd938b1e42cff3be3b629e6239cdec9a9baddcc/src/main/webapp/js/diagramly/Editor.js#L1412).

### draw.io’s Sketch Feature: Implementation Details

1. **New Concept: HandJiggle**
- This concept introduces hand-drawn effects applied via **canvas**.
- A new field, `defaultJiggle`, is added to shapes. Default values are set to `1.5` for `mxShape` and `2` for `mxRhombus`.
- A new `createHandJiggle` function is added to `mxShape`. If the style is set to `sketch`, this function is called.

2. **Testing the Style**:
- The `jiggle` property defines the "noise" level for sketch effects. This can be tested manually by modifying styles using the “Update Style” button and entering values in the input window.

3. **Comic Mode**:
- Comic effects are entirely coded manually in a class named `HandJiggle`.
- This class takes an `mxCanvas` as a parameter and performs additional actions for rendering.

### Rough.js and Fill Styles

When using Rough.js for sketch effects, specific styles can be applied to **fills**, showcasing various visual options.
In the `Editor` class, the supported fill styles are defined as follows:

```javascript
/**
* All fill styles supported by rough.js.
*/
Editor.roughFillStyles = [
{val: 'auto', dispName: 'Auto'},
{val: 'hachure', dispName: 'Hachure'},
{val: 'solid', dispName: 'Solid'},
{val: 'zigzag', dispName: 'ZigZag'},
{val: 'cross-hatch', dispName: 'Cross Hatch'},
{val: 'dots', dispName: 'Dots'},
{val: 'dashed', dispName: 'Dashed'},
{val: 'zigzag-line', dispName: 'ZigZag Line'}
];
```

This allows for showcasing custom fill effects, such as colorized fills, which are visually appealing.

### Adapter for Rough.js Integration

1. **RoughCanvas Adapter**:
A new adapter, `RoughCanvas`, is introduced to handle calls to Rough.js. It converts mxGraph styles to Rough.js styles.
For example, the `jiggle` property is transformed into `roughness` for Rough.js.

2. **SVG Canvas Integration**:
An implementation extends `mxSvgCanvas2D` to proxy an `mxCanvas`. This implementation delegates certain rendering tasks to `RoughCanvas` when needed.


## 🛠️ Technical details about the implementation of `mxgraph-sketch`

This implementation is inspired by **draw.io's sketch feature** and uses the same style properties to ensure potential compatibility with draw.io.

The `src/mxgraph-sketch.ts` file provides functions to override certain prototypes and add support for the sketch style by applying a dedicated `mxSvgCanvas2D`.

A specialized `SketchySvgCanvas` (extending `mxSvgCanvas2D`) is responsible for enabling the sketch style. It recalculates paths and applies sketchy effects to the rendering.

The concept of **`passThrough`** is introduced to manage styles seamlessly, whether the sketch style is enabled or not.

![class diagram](docs/mxgraph-sketch_class_diagram.png)


## 🔧 Contributing
Expand All @@ -38,7 +132,7 @@ The repository contains configuration for [Eclipse Theia](https://theia-ide.org/

You can find more detail in our [Contributing guide](CONTRIBUTING.md). Participation in this open source project is subject to a [Code of Conduct](https://github.com/process-analytics/.github/blob/main/CODE_OF_CONDUCT.md).

:sparkles: A BIG thanks to all our contributors :slightly_smiling_face:
A BIG thanks to all our contributors 🙂


## 📃 License
Expand Down
File renamed without changes
89 changes: 89 additions & 0 deletions docs/mxgraph-sketch_class_diagram.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0" version="26.0.6">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="1125" dy="627" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-2" value="mxSvgCanvas2D" style="swimlane;fontStyle=0;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;rounded=0;shadow=0;strokeWidth=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="590" y="260" width="190" height="60" as="geometry">
<mxRectangle x="550" y="140" width="160" height="26" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-3" value="mxXmlCanvas2D" style="swimlane;fontStyle=0;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;rounded=0;shadow=0;strokeWidth=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="150" y="260" width="190" height="60" as="geometry">
<mxRectangle x="550" y="140" width="160" height="26" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-4" value="mxHtmlCanvas2D" style="swimlane;fontStyle=0;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;rounded=0;shadow=0;strokeWidth=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="370" y="260" width="190" height="60" as="geometry">
<mxRectangle x="550" y="140" width="160" height="26" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-6" value="mxAbstractCanvas2D" style="swimlane;fontStyle=0;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;rounded=0;shadow=0;strokeWidth=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="240" y="80" width="190" height="60" as="geometry">
<mxRectangle x="550" y="140" width="160" height="26" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-7" value="SketchySvgCanvas" style="swimlane;fontStyle=0;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;rounded=0;shadow=0;strokeWidth=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="590" y="390" width="190" height="60" as="geometry">
<mxRectangle x="550" y="140" width="160" height="26" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-8" value="RoughJsAdaptor" style="swimlane;fontStyle=0;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;rounded=0;shadow=0;strokeWidth=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="880" y="390" width="190" height="60" as="geometry">
<mxRectangle x="550" y="140" width="160" height="26" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-10" value="" style="endArrow=block;endSize=10;endFill=0;shadow=0;strokeWidth=1;rounded=0;curved=0;edgeStyle=elbowEdgeStyle;elbow=vertical;exitX=0.579;exitY=0;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="Xe0Wl5o48xgf-3U-y1-q-4">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="480" y="192" as="sourcePoint" />
<mxPoint x="340" y="140" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-11" value="" style="endArrow=block;endSize=10;endFill=0;shadow=0;strokeWidth=1;rounded=0;curved=0;edgeStyle=elbowEdgeStyle;elbow=vertical;exitX=0.25;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="622.5" y="260" as="sourcePoint" />
<mxPoint x="340" y="140" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-12" value="" style="endArrow=block;endSize=10;endFill=0;shadow=0;strokeWidth=1;rounded=0;curved=0;edgeStyle=elbowEdgeStyle;elbow=vertical;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="638" y="390" as="sourcePoint" />
<mxPoint x="638" y="320" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-13" value="" style="endArrow=block;endSize=10;endFill=0;shadow=0;strokeWidth=1;rounded=0;curved=0;edgeStyle=elbowEdgeStyle;elbow=vertical;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="Xe0Wl5o48xgf-3U-y1-q-3">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="245" y="260" as="sourcePoint" />
<mxPoint x="340" y="140" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-14" value="" style="endArrow=block;endSize=10;endFill=0;shadow=0;strokeWidth=1;rounded=0;curved=0;edgeStyle=elbowEdgeStyle;elbow=vertical;entryX=0.75;entryY=0;entryDx=0;entryDy=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;startArrow=diamond;startFill=1;jumpSize=6;startSize=10;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="Xe0Wl5o48xgf-3U-y1-q-2" target="Xe0Wl5o48xgf-3U-y1-q-7">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="722.47" y="320" as="sourcePoint" />
<mxPoint x="720.0000000000002" y="400.02" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-15" value="" style="endArrow=block;endSize=10;endFill=0;shadow=0;strokeWidth=1;rounded=0;curved=0;edgeStyle=elbowEdgeStyle;elbow=vertical;entryX=0;entryY=0.5;entryDx=0;entryDy=0;startArrow=diamond;startFill=1;jumpSize=6;startSize=10;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" target="Xe0Wl5o48xgf-3U-y1-q-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="780" y="420" as="sourcePoint" />
<mxPoint x="847.5" y="420" as="targetPoint" />
<Array as="points">
<mxPoint x="800" y="420" />
<mxPoint x="807.5" y="510" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-16" value="&lt;i&gt;&lt;b&gt;To save the mxGraphView to XML&lt;/b&gt;&lt;/i&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="40" y="320" width="220" height="30" as="geometry" />
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-17" value="&lt;i&gt;&lt;b&gt;IE support with VML&lt;/b&gt;&lt;/i&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="370" y="330" width="130" height="30" as="geometry" />
</mxCell>
<mxCell id="Xe0Wl5o48xgf-3U-y1-q-18" value="&lt;i&gt;&lt;b&gt;Renderer for modern browsers&lt;br&gt;&lt;/b&gt;&lt;/i&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="720" y="230" width="190" height="30" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
Binary file added docs/mxgraph-sketch_class_diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 175f552

Please sign in to comment.