Skip to content

Commit 71153ca

Browse files
committed
Update docs for @reactodia/workspace@0.30:
* Add pages for keyboard hotkeys, form input components; * Add sections for command buses, element and link template customization, element decorations, exporting the canvas content; * Add links to command bus topics from relevant components; * Add `style-customization` example; * Update feature screenshots, add separate screenshots for light/dark themes;
1 parent 0adc70a commit 71153ca

49 files changed

Lines changed: 1201 additions & 251 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ charset = utf-8
88
trim_trailing_whitespace = true
99
insert_final_newline = true
1010

11-
[*.{js,jsx,ts,tsx}]
11+
[*.{js,jsx,ts,tsx,md,mdx}]
1212
indent_style = space
1313
indent_size = 2

docs/components/canvas.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,53 @@ title: <Canvas />
66

77
[`<Canvas />`](/docs/api/workspace/functions/Canvas) is a main component to display a scrollable canvas for the diagram with [elements](/docs/concepts/graph-model.md), [links](/docs/concepts/graph-model.md) and additional widgets.
88

9+
## Customizing element and link appearance {#customization}
10+
11+
It is possible to customize how elements (nodes) and links (edges) are rendered on the canvas by providing `elementTemplateResolver` ([`TypedElementResolver`](/docs/api/workspace/type-aliases/TypedElementResolver.md)) and/or `linkTemplateResolver` ([`LinkTemplateResolver`](/docs/api/workspace/type-aliases/LinkTemplateResolver.md)) props to the `<Canvas />`.
12+
13+
An element or link template is an object with rendering function (returning a React component to display it) and additional rendering settings such as element shape, link markers, etc.
14+
15+
An **element template** is an [`ElementTemplate`](/docs/api/workspace/interfaces/ElementTemplate.md) object with rendering function (returning a React component to display the element) and additional settings, such as element shape (rectangular or elliptical).
16+
17+
A **link template** is a [`LinkTemplate`](/docs/api/workspace/interfaces/LinkTemplate.md) object with rendering function (returning a React component to display the link) and additional settings, such as link markers (mini-shapes on its endpoints, e.g. arrowheads) and path spline type (straight or smooth).
18+
19+
The library provides the following built-in templates:
20+
21+
| Template | Type | Description |
22+
|----------------------|------|-------------|
23+
| [`StandardTemplate`](/docs/api/workspace/variables/StandardTemplate.md) | element | Default (fallback) template for an element; supports single entity elements and [entity groups](/docs/concepts/graph-model.md#data-graph).<br />Uses [`StandardEntity`](/docs/api/workspace/functions/StandardEntity.md) and [`StandardEntityGroup`](/docs/api/workspace/functions/StandardEntityGroup.md) components to render elements. |
24+
| [`ClassicTemplate`](/docs/api/workspace/variables/ClassicTemplate.md) | element | Element template component with classic "look and feel" which was used for elements before v0.8; does not support entity groups.<br />Uses [`ClassicEntity`](/docs/api/workspace/functions/ClassicEntity.md) component to render elements. |
25+
| [`RoundTemplate`](/docs/api/workspace/variables/RoundTemplate.md) | element | Basic element template with an round (elliptical) shape; does not support entity groups.<br />Uses [`RoundEntity`](/docs/api/workspace/functions/RoundEntity.md) component to render elements. |
26+
| [`DefaultLinkTemplate`](/docs/api/workspace/variables/DefaultLinkTemplate.md) | link | Default (fallback) template for a link; supports single relation links and [relation groups](/docs/concepts/graph-model.md#data-graph).<br />Uses [`DefaultLink`](/docs/api/workspace/functions/DefaultLink.md) component to render links which uses [`LinkPath`](/docs/api/workspace/functions/LinkPath.md), [`LinkLabel`](/docs/api/workspace/functions/LinkLabel.md) and [`LinkVertices`](/docs/api/workspace/functions/LinkVertices.md) components inside to display the link connection itself, the labels and vertices (to change link geometry). |
27+
28+
Additionally, it is possible to override how the link are routed (how default path geometry is computed) on the canvas by providing `linkRouter` ([`LinkRouter`](/docs/api/workspace/interfaces/LinkRouter.md)) prop to the `<Canvas />`. By default, the [`DefaultLinkRouter`](/docs/api/workspace/classes/DefaultLinkRouter.md) is used which moves apart multiple links between same elements and displays self-links (where target is equal to source) as loops.
29+
30+
### Element decorations
31+
32+
To further customize element rendering the library provides [`<ElementDecoration />`](/docs/api/workspace/functions/ElementDecoration.md) component to display a decoration over a canvas element. These decorations are rendered outside the element template content itself and does not contribute to the measured size of an element.
33+
34+
All decorations for a specific entity are rendered as children of a DOM element with `reactodia-element-decorators` CSS class which immediately follows each target canvas element in the DOM. Such parent DOM elements for the decorations have `transform: translate(...)`, `width` and `height` set to the same values as the target element to be able to layout decoration content via CSS:
35+
36+
```css
37+
/* Position decoration to the left of the target canvas element */
38+
.my-custom-decoration {
39+
position: absolute;
40+
top: 50%;
41+
left: -10px;
42+
transform: translate(-100%,-50%);
43+
}
44+
45+
/* Show decoration on hover over it or target canvas element */
46+
.reactodia-overlaid-element:hover + .reactodia-element-decorations .my-custom-decoration,
47+
.my-custom-decoration:hover {
48+
opacity: 1;
49+
}
50+
```
51+
52+
:::tip
53+
See complete [style customization example](/docs/examples/style-customization) with custom element and link templates, element decorations and more.
54+
:::
55+
956
## Getting the canvas instance
1057

1158
[`useCanvas()`](/docs/api/workspace/functions/useCanvas) hook called from a canvas widget can be used to get the [`CanvasApi`](/docs/api/workspace/interfaces/CanvasApi) instance from a context to read or subscribe to the canvas state or perform viewport-related effects:
@@ -99,6 +146,34 @@ function Example() {
99146
render(<Example />);
100147
```
101148

149+
## Exporting the canvas
150+
151+
It is possible to export a "snapshot" of currently rendered canvas content into an SVG (with HTML parts) or a raster image:
152+
153+
| Canvas API method | Description |
154+
|-------------------|-------------|
155+
| [`exportSvg()`](/docs/api/workspace/interfaces/CanvasApi.md#exportsvg) | Exports the diagram as a serialized into text SVG document with `<foreignObject>` HTML layers inside. (Can be opened by the browser but not with a pure SVG image editor.) |
156+
| [`exportRaster()`](/docs/api/workspace/interfaces/CanvasApi.md#exportraster) | Exports the diagram as a rendered raster image (e.g. PNG, JPEG, etc) serialized into base64-encoded [data URL](https://developer.mozilla.org/en-US/docs/Web/URI/Schemes/data). |
157+
158+
:::note
159+
When exporting into an SVG, the resulting document would include all diagram content as well as every CSS rule which applies to any DOM element inside the diagram content.
160+
161+
Diagram is always exported in the [light theme](/docs/concepts/design-system.mdx).
162+
:::
163+
164+
To prevent being exported a DOM element can be marked with `data-reactodia-no-export` attribute or additional CSS selectors can be provided via `removeByCssSelectors` options to the export methods.
165+
166+
Printing the diagram can be achieved by exporting an SVG, writing it into a newly opened window and printing it:
167+
```ts
168+
const printWindow = window.open('', undefined, 'width=1280,height=720')!;
169+
const svg = await canvas.exportSvg();
170+
printWindow.document.write(svg);
171+
printWindow.document.close();
172+
printWindow.print();
173+
```
174+
175+
The library provides a built-in [`toolbar`](/docs/components/toolbar.md) action component [`<ToolbarActionExport />`](/docs/api/workspace/functions/ToolbarActionExport.md) as a convenient way to export or print the diagram from the UI.
176+
102177
## Styles
103178

104179
The component look can be customized using the following CSS properties (see [design system](/docs/concepts/design-system.mdx) for more information):
@@ -111,3 +186,5 @@ The component look can be customized using the following CSS properties (see [de
111186
| `--reactodia-canvas-underlay-color` | Semi-transparent color to place under components for improved readability when they are placed on the canvas. |
112187
| `--reactodia-element-background-color` | Default background color for the graph elements displayed on the canvas. |
113188
| `--reactodia-link-stroke-color` | Default stroke color for the graph links displayed on the canvas. |
189+
| `--reactodia-monochrome-icon-filter` | [CSS filter](https://developer.mozilla.org/en-US/docs/Web/CSS/filter) for the monochrome [type style](/docs/components/workspace.md#customize-type-styles) icons. |
190+
| `--reactodia-viewport-dock-margin` | Margin from the borders of the canvas for the viewport widgets. |

docs/components/connections-menu.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ title: <ConnectionsMenu />
66

77
[`<ConnectionsMenu />`](/docs/api/workspace/functions/ConnectionsMenu) component is a [canvas widget](/docs/components/canvas.md) to explore and navigate the graph by adding connected entities to the diagram.
88

9+
The component observes [`ConnectionsMenuTopic`](/docs/api/workspace/variables/ConnectionsMenuTopic.md) [command bus topic](/docs/concepts/event-system.md#command-bus).
10+
911
### Example: opening a connections menu on load
1012

1113
```tsx live

docs/components/form-input.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
title: <FormInput* />
3+
---
4+
5+
# Form input components
6+
7+
Reactodia provides basic built-in components to edit entity or relation properties in a form:
8+
9+
| Form input component | Description |
10+
|----------------------|-------------|
11+
| [`<FormInputList />`](/docs/api/workspace/variables/FormInputList.md) | Form input to edit multiple values in a list of specified single value inputs. |
12+
| [`<FormInputText />`](/docs/api/workspace/functions/FormInputText.md) | Form input to edit a single value as a plain string with an optional language. |
13+
14+
:::warning
15+
Currently form input components are considered **unstable** so there might be breaking changes in their API in the future.
16+
:::
17+
18+
### Example: overriding input to a multiline text field
19+
20+
```tsx live noInline
21+
function Example() {
22+
const GRAPH_DATA = 'https://reactodia.github.io/resources/orgOntology.ttl';
23+
24+
const {defaultLayout} = Reactodia.useWorker(Layouts);
25+
26+
const {onMount} = Reactodia.useLoadedWorkspace(async ({context, signal}) => {
27+
const {model, editor, getCommandBus, performLayout} = context;
28+
const response = await fetch(GRAPH_DATA, {signal});
29+
const graphData = new N3.Parser().parse(await response.text());
30+
const dataProvider = new Reactodia.RdfDataProvider({acceptBlankNodes: false});
31+
dataProvider.addGraph(graphData);
32+
await model.createNewDiagram({dataProvider, signal});
33+
const element = model.createElement('http://www.w3.org/ns/org#Organization');
34+
await Promise.all([
35+
model.requestElementData([element.iri]),
36+
model.requestLinks(),
37+
]);
38+
editor.setAuthoringMode(true);
39+
getCommandBus(Reactodia.VisualAuthoringTopic)
40+
.trigger('editEntity', {target: element});
41+
}, []);
42+
43+
const RDF_COMMENT = 'http://www.w3.org/2000/01/rdf-schema#comment';
44+
45+
const [metadataProvider] = React.useState(() => new Reactodia.BaseMetadataProvider({
46+
canModifyEntity: () => ({canEdit: true}),
47+
getEntityShape: types => ({
48+
properties: new Map([
49+
[Reactodia.rdfs.label, {valueShape: {termType: 'Literal'}}],
50+
[RDF_COMMENT, {valueShape: {termType: 'Literal'}}],
51+
])
52+
}),
53+
}));
54+
55+
return (
56+
<div className='reactodia-live-editor'>
57+
<Reactodia.Workspace ref={onMount}
58+
metadataProvider={metadataProvider}
59+
defaultLayout={defaultLayout}>
60+
<Reactodia.DefaultWorkspace
61+
search={null}
62+
visualAuthoring={{
63+
inputResolver: (property, inputProps) =>
64+
property === RDF_COMMENT
65+
? <Reactodia.FormInputList {...inputProps} valueInput={MultilineTextInput} />
66+
: undefined,
67+
}}
68+
/>
69+
</Reactodia.Workspace>
70+
</div>
71+
);
72+
}
73+
74+
function MultilineTextInput(props: Reactodia.FormInputSingleProps) {
75+
return <Reactodia.FormInputText {...props} multiline />;
76+
}
77+
78+
render(<Example />);
79+
```

docs/components/instances-search.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ title: <InstancesSearch />
1010
The same functionality is also available as `<SearchSectionEntities />` [unified search section](/docs/components/unified-search.md).
1111
:::
1212

13+
The component observes [`InstancesSearchTopic`](/docs/api/workspace/variables/InstancesSearchTopic.md) [command bus topic](/docs/concepts/event-system.md#command-bus).
14+
1315
```tsx live
1416
function Example() {
1517
const GRAPH_DATA = 'https://reactodia.github.io/resources/orgOntology.ttl';

docs/components/toolbar.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,75 @@ There are several built-in toolbar actions that can be displayed as menu items o
2121
| [`<ToolbarActionLayout />`](/docs/api/workspace/functions/ToolbarActionLayout.md) | Performs the default [graph layout algorithm](/docs/concepts/graph-layout.md) on the diagram content. |
2222
| [`<ToolbarLanguageSelector />`](/docs/api/workspace/functions/ToolbarLanguageSelector.md) | Displays a [data language](/docs/api/workspace/classes/DiagramModel.md#language) selector for the workspace. |
2323

24+
### Example: additional toolbars
25+
26+
```tsx live
27+
function Example() {
28+
const {defaultLayout} = Reactodia.useWorker(Layouts);
29+
30+
const {onMount, getContext} = Reactodia.useLoadedWorkspace(async ({context, signal}) => {
31+
const {model, view, performLayout} = context;
32+
model.createElement('http://example.com/entity1');
33+
model.createElement('http://example.com/entity2');
34+
model.createLinks({
35+
sourceId: 'http://example.com/entity1',
36+
targetId: 'http://example.com/entity2',
37+
linkTypeId: 'http://example.com/connectedTo',
38+
properties: {},
39+
});
40+
await performLayout({signal});
41+
}, []);
42+
43+
return (
44+
<div className='reactodia-live-editor'>
45+
<Reactodia.Workspace ref={onMount}
46+
defaultLayout={defaultLayout}>
47+
<Reactodia.DefaultWorkspace
48+
actions={null}
49+
navigator={null}
50+
canvasWidgets={[
51+
<Reactodia.Toolbar key='bottom-left'
52+
dock='sw'
53+
menu={
54+
<>
55+
<Reactodia.ToolbarActionClearAll />
56+
<Reactodia.ToolbarActionExport kind='print' />
57+
</>
58+
}>
59+
<Reactodia.ToolbarActionUndo />
60+
<Reactodia.ToolbarActionRedo />
61+
<Reactodia.ToolbarActionLayout />
62+
</Reactodia.Toolbar>,
63+
<Reactodia.Toolbar key='top-right'
64+
dock='ne'>
65+
<Reactodia.ToolbarAction
66+
onSelect={() => {
67+
const {overlay} = getContext();
68+
overlay.showDialog({content: <div>🎉</div>});
69+
}}>
70+
Show a dialog
71+
</Reactodia.ToolbarAction>
72+
</Reactodia.Toolbar>,
73+
<Reactodia.Toolbar key='bottom-right'
74+
dock='se'>
75+
<Reactodia.ToolbarLanguageSelector
76+
languages={[
77+
{code: 'de', label: 'Deutsch'},
78+
{code: 'en', label: 'english'},
79+
{code: 'es', label: 'español'},
80+
{code: 'ru', label: 'русский'},
81+
{code: 'zh', label: '汉语'},
82+
]}
83+
/>
84+
</Reactodia.Toolbar>,
85+
]}
86+
/>
87+
</Reactodia.Workspace>
88+
</div>
89+
);
90+
}
91+
```
92+
2493
## Styles
2594

2695
The component look can be customized using the following CSS properties (see [design system](/docs/concepts/design-system.mdx) for more information):

docs/components/unified-search.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ title: <UnifiedSearch />
66

77
[`<UnifiedSearch />`](/docs/api/workspace/functions/UnifiedSearch.md) is a component to display a search input with a dropdown for results.
88

9+
The component observes [`UnifiedSearchTopic`](/docs/api/workspace/variables/UnifiedSearchTopic.md) [command bus topic](/docs/concepts/event-system.md#command-bus).
10+
911
## Search sections
1012

1113
One or many available search sections (providers) can be specified:
@@ -16,6 +18,8 @@ One or many available search sections (providers) can be specified:
1618
| [`<SearchSectionEntities />`](/docs/api/workspace/functions/SearchSectionEntities.md) | Allows to lookup entities using [data provider](/docs/concepts/data-provider.md). |
1719
| [`<SearchSectionLinkTypes />`](/docs/api/workspace/functions/SearchSectionLinkTypes.md) | Allows to lookup displayed link types and change their [visibility settings](/docs/api/workspace/classes/DiagramModel.md#getlinkvisibility). |
1820

21+
`<SearchSectionEntities />` component observes [`InstancesSearchTopic`](/docs/api/workspace/variables/InstancesSearchTopic.md) [command bus topic](/docs/concepts/event-system.md#command-bus).
22+
1923
## Implement a custom search section
2024

2125
[`useUnifiedSearchSection()`](/docs/api/workspace/functions/useUnifiedSearchSection.md) hook can be used to implement a custom search section:

docs/components/visual-authoring.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ title: <VisualAuthoring />
99
:::important
1010
`<VisualAuthoring />` widget must be provided to the canvas to in order to display visual graph authoring UI.
1111
:::
12+
13+
The component observes [`VisualAuthoringTopic`](/docs/api/workspace/variables/VisualAuthoringTopic.md) [command bus topic](/docs/concepts/event-system.md#command-bus).

docs/components/workspace.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,27 @@ function Example() {
5050
);
5151
}
5252
```
53+
54+
## Customize type styles
55+
56+
Reactodia displays [entities](/docs/concepts/graph-model.md) in different places throughout the workspace components. It is possible to customize overall style based on entity types (accent color and icon) by providing a custom [`TypeStyleResolver`](/docs/api/workspace/type-aliases/TypeStyleResolver.md) to the `<Workspace typeStyleResolver={...} />`:
57+
58+
```tsx
59+
<Reactodia.Workspace
60+
typeStyleResolver={types => {
61+
if (types.includes('http://www.w3.org/2000/01/rdf-schema#Class')) {
62+
return {icon: CERTIFICATE_ICON, iconMonochrome: true};
63+
} else if (types.includes('http://www.w3.org/2002/07/owl#Class')) {
64+
return {icon: CERTIFICATE_ICON, iconMonochrome: true};
65+
} else if (types.includes('http://www.w3.org/2002/07/owl#ObjectProperty')) {
66+
return {icon: COG_ICON, iconMonochrome: true};
67+
} else if (types.includes('http://www.w3.org/2002/07/owl#DatatypeProperty')) {
68+
return {color: '#00b9f2'};
69+
} else {
70+
return undefined;
71+
}
72+
}}
73+
...>
74+
```
75+
76+
By default, the colors are assigned deterministically based on total hash of the types in the [entity data](/docs/api/workspace/interfaces/ElementModel.md).

docs/concepts/data-provider.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ function ExampleRdfProviderProvisionFromJGF() {
8989
} as const;
9090

9191
const factory = Reactodia.Rdf.DefaultDataFactory;
92-
const hasType = factory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
93-
const hasLabel = factory.namedNode('http://www.w3.org/2000/01/rdf-schema#label');
92+
const hasType = factory.namedNode(Reactodia.rdf.type);
93+
const hasLabel = factory.namedNode(Reactodia.rdfs.label);
9494

9595
const triples: Reactodia.Rdf.Quad[] = [];
9696
for (const [id, node] of Object.entries(jsonGraph.graph.nodes)) {

0 commit comments

Comments
 (0)