Skip to content

Commit

Permalink
0.5.0 (#62)
Browse files Browse the repository at this point in the history
* feat: add partial handling for touches

* fix: fix edge creation with touches

* refactor: refactor root pointer api

* fix: add sharing of observables and todos

* fix: do not show old curve when touch is started

* refactor: move elementFromPoint to root-pointer

* refactor: move handling touch over and out to separate function

* feat: add schedulers

* feat: add changes filtering api

* fix: fix types

* docs: add handling changes page
  • Loading branch information
artem-mangilev authored Jun 16, 2024
1 parent 19ef16d commit 7504af6
Show file tree
Hide file tree
Showing 22 changed files with 685 additions and 43 deletions.
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"@ng-doc/builder": "~16.17.0",
"@ng-doc/core": "~16.17.0",
"@ng-doc/ui-kit": "~16.17.0",
"@ngneat/hot-toast": "^6.1.0",
"@ngneat/overview": "^5.1.1",
"d3-drag": "^3.0.0",
"d3-path": "^3.1.0",
"d3-selection": "^3.0.0",
Expand Down Expand Up @@ -51,4 +53,4 @@
"ng-packagr": "^16.2.0",
"typescript": "~5.1.3"
}
}
}
7 changes: 6 additions & 1 deletion projects/ngx-vflow-demo/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { AppComponent } from './app.component';
import { VflowModule } from '../../../ngx-vflow-lib/src/public-api';
import { provideHttpClient } from "@angular/common/http";
import { NgDocButtonIconComponent, NgDocIconComponent, NgDocTooltipDirective } from "@ng-doc/ui-kit";
import { HotToastModule } from "@ngneat/hot-toast";

@NgModule({
declarations: [
Expand All @@ -25,7 +26,10 @@ import { NgDocButtonIconComponent, NgDocIconComponent, NgDocTooltipDirective } f
NgDocThemeToggleComponent,
NgDocIconComponent,
NgDocButtonIconComponent,
NgDocTooltipDirective
NgDocTooltipDirective,
HotToastModule.forRoot({
position: 'top-right'
})
],
providers: [
provideNgDocApp({
Expand Down Expand Up @@ -56,6 +60,7 @@ import { NgDocButtonIconComponent, NgDocIconComponent, NgDocTooltipDirective } f
anchorScrolling: 'enabled',
}),
),

],
bootstrap: [AppComponent],
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vflow
[nodes]="nodes"
[edges]="edges"
(onConnect)="createEdge($event)"
(onNodesChange)="handleNodeChanges($event)"
(onEdgesChange)="handleEdgeChanges($event)"
/>

<ng-template #toast let-ctx>
<h3>{{ ctx.data.title }}</h3>

<pre>{{ ctx.data.json }}</pre>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ChangeDetectionStrategy, Component, TemplateRef, ViewChild, inject } from '@angular/core';
import { HotToastService } from '@ngneat/hot-toast';
import { Connection, Edge, EdgeChange, Node, NodeChange, VflowModule } from 'projects/ngx-vflow-lib/src/public-api';

@Component({
templateUrl: './handling-changes-demo.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [VflowModule],
})
export class HandlingChangesDemoComponent {
private toast = inject(HotToastService);

@ViewChild('toast')
public toastTemplate!: TemplateRef<unknown>;

public nodes: Node[] = [
{
id: '1',
point: { x: 100, y: 100 },
type: 'default',
text: `1`,
},
{
id: '2',
point: { x: 200, y: 200 },
type: 'default',
text: `2`
},
]

public edges: Edge[] = []

public createEdge({ source, target }: Connection) {
this.edges = [...this.edges, {
id: `${source} -> ${target}`,
source,
target
}]
}

public handleNodeChanges(changes: NodeChange[]) {
this.toast.info(this.toastTemplate, {
data: {
title: '(onNodesChange)',
json: JSON.stringify(changes, null, 2)
},
})
}

public handleEdgeChanges(changes: EdgeChange[]) {
this.toast.info(this.toastTemplate, {
data: {
title: '(onEdgesChange)',
json: JSON.stringify(changes, null, 2)
},
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<button (click)="addNodes()">Add nodes</button>

<vflow
[nodes]="nodes"
[edges]="edges"
(onConnect)="createEdge($event)"
(onNodesChange.position.single)="handleNodePositionChange($event)"
(onNodesChange.select.single)="handleNodeSelectChange($event)"
(onNodesChange.add.many)="handleNodesAddChange($event)"
(onEdgesChange.add)="handleEdgesAddChange($event)"
/>

<ng-template #toast let-ctx>
<h3>{{ ctx.data.title }}</h3>

<pre>{{ ctx.data.json }}</pre>
</ng-template>

Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { ChangeDetectionStrategy, Component, TemplateRef, ViewChild, inject } from '@angular/core';
import { HotToastModule, HotToastService, provideHotToastConfig } from '@ngneat/hot-toast';
import { Connection, Edge, EdgeChange, Node, NodeAddChange, NodeChange, NodePositionChange, NodeSelectedChange, VflowModule } from 'projects/ngx-vflow-lib/src/public-api';

@Component({
templateUrl: './handling-changes-filtered-demo.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [VflowModule],
})
export class HandlingChangesFilteredDemoComponent {
private toast = inject(HotToastService);

@ViewChild('toast')
public toastTemplate!: TemplateRef<unknown>;

public nodes: Node[] = [
{
id: '1',
point: { x: 100, y: 100 },
type: 'default',
text: `1`,
},
{
id: '2',
point: { x: 200, y: 200 },
type: 'default',
text: `2`
},
]

public edges: Edge[] = []

public createEdge({ source, target }: Connection) {
this.edges = [...this.edges, {
id: `${source} -> ${target}`,
source,
target
}]
}

public handleNodePositionChange(change: NodePositionChange) {
this.toast.info(this.toastTemplate, {
data: {
title: '(onNodesChange.position.single)',
json: JSON.stringify(change, null, 2)
},
})
}

public handleNodeSelectChange(change: NodeSelectedChange) {
this.toast.info(this.toastTemplate, {
data: {
title: '(onNodesChange.select.single)',
json: JSON.stringify(change, null, 2)
},
})
}

public handleNodesAddChange(changes: NodeAddChange[]) {
this.toast.info(this.toastTemplate, {
data: {
title: '(onNodesChange.add.many)',
json: JSON.stringify(changes, null, 2)
},
})
}

public handleEdgesAddChange(changes: EdgeChange[]) {
this.toast.info(this.toastTemplate, {
data: {
title: '(onEdgesChange.add)',
json: JSON.stringify(changes, null, 2)
},
})
}

public addNodes() {
this.nodes = [...this.nodes,
{
id: crypto.randomUUID(),
point: { x: 0, y: 0 },
type: 'default',
text: `random`,
},
{
id: crypto.randomUUID(),
point: { x: 300, y: 300 },
type: 'default',
text: `random`
},
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# {{ NgDocPage.title }}

> **Info**
> You can observe changes in the toasts. It's also better to see this page in desktop
You can observe a lot of changes of nodes and edges.

Types of `NodeChange`s:
- `position` - new node position (after drag and drop)
- `add` - when node was created
- `remove` - when node was removed
- `select` - when node was selected (also triggers for unselected nodes)

Types of `EdgeChange`s:
- `add` - when edge was created
- `remove` - when edge was removed
- `select` - when edge was selected (also triggers for unselected edges)
- `detached` - when edge became invisible due to unexistance of source or target node. It will help you
to delete such edges from edges list

There are a couple ways to receive these changes:

## From (onNodesChange) and (onEdgesChange) outputs

This is a way to get every possible change. Changes came as non empty arrays:
- `(onNodesChange)` emits `NodeChange[]`
- `(onEdgesChange)` emits `EdgeChange[]`

{{ NgDocActions.demo("HandlingChangesDemoComponent", { expanded: false }) }}

## From filtered outputs

For your convenience there is a filtering scheme for changes based on `(onNodesChange)` and `(onEdgesChange)` events:

- `(onNodesChange.[NodeChangeType])` - a list of node changes of certain type
- `(onNodesChange.[EdgeChangeType])` - a list of edge changes of certain type
- `(onNodesChange.[NodeChangeType].[Count])` - a list (`many`) of or single (`single`) node change of certain type
- `(onEdgesChange.[EdgeChangeType].[Count])` - a list (`many`) of or single (`single`) edge change of certain type

Where:

```ts
type NodeChangeType = 'position' | 'add' | 'remove' | 'select'

type EdgeChangeType = 'detached' | 'add' | 'remove' | 'select'

// single - when there is only one change of this type (for example if you drag and drop some node, it's consireder as single change)
// many - when there is more than one change of this type (for example if you deleted several nodes at the same time)
type Count = 'single' | 'many'
```
{{ NgDocActions.demo("HandlingChangesFilteredDemoComponent", { expanded: false }) }}
List of all possible filter outputs:
```
'onNodesChange.position',
'onNodesChange.position.single',
'onNodesChange.position.many',
'onNodesChange.add',
'onNodesChange.add.single',
'onNodesChange.add.many',
'onNodesChange.remove',
'onNodesChange.remove.single',
'onNodesChange.remove.many',
'onNodesChange.select',
'onNodesChange.select.single',
'onNodesChange.select.many',

'onEdgesChange.detached',
'onEdgesChange.detached.single',
'onEdgesChange.detached.many',
'onEdgesChange.add',
'onEdgesChange.add.single',
'onEdgesChange.add.many',
'onEdgesChange.remove',
'onEdgesChange.remove.single',
'onEdgesChange.remove.many',
'onEdgesChange.select',
'onEdgesChange.select.single',
'onEdgesChange.select.many',
```

## From componenet itself

```ts
{
...
@ViewChild(VflowComponent)
vflow: VflowComponent

ngAfterViewInit() {
this.vflow.nodesChange$.subscribe((changes) => {
// handle node changes
})

this.vflow.edgesChange$.subscribe((changes) => {
// handle edges changes
})
}
...
}
```


Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { NgDocPage } from '@ng-doc/core';
import ExamplesCategory from '../../ng-doc.category';
import { HandlingChangesDemoComponent } from './demo/handling-changes-demo/handling-changes-demo.component';
import { HandlingChangesFilteredDemoComponent } from './demo/handling-changes-filtered-demo/handling-changes-filtered-demo.component';

const TestPage: NgDocPage = {
title: `Handling changes`,
mdFile: './index.md',
category: ExamplesCategory,
demos: { HandlingChangesDemoComponent, HandlingChangesFilteredDemoComponent },
order: 3
};

export default TestPage;
1 change: 0 additions & 1 deletion projects/ngx-vflow-demo/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';


platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
Loading

0 comments on commit 7504af6

Please sign in to comment.