How to store node offset position in ngrx store using Angular Diagram?
In Angular Diagram , NgRx is a state management library that utilizes reactive programming principles to manage application state in a predictable and efficient manner. It helps organize, manage, and synchronize the state of an Angular application across components, making it easier to develop and maintain complex applications.
How NgRx works:
The NgRx state management process is a combination of five key elements:
- Store: The application state is maintained in the store. It is immutable.
- Selectors: Angular components can subscribe to the store and get updates through selectors.
- Reducers: Reducers are responsible for handling the transition from one state to another.
- Actions: Actions modify the state of the store by using reducers.
- Effects: Effects are the results of actions. Also, they can be used to listen for particular action types and run when the action happens.
Installation and creation if NgRx store:
NgRx can be installed using NPM, Yarn, or Angular CLI as follows:
// NPM
npm install @ngrx/store --save
// Yarn
yarn add @ngrx/store
// Angular CLI
ng add @ngrx/store@latest
After installation, you need to create a separate directory named /store under the src/app directory. This folder will contain all the files related to the NgRx store.
As a first step, we need to create an interface for nodeData , and define the required properties inside the interface. Here, we are storing node’s id , offsetX and offsetY. Let’s name the model nodeData.model.ts.
export interface NodeData {
id: string;
offsetX: number;
offsetY: number;
}
Then, we need to create an action file to define NgRx actions. Here, we have created a file named nodeData.actions.ts under the actions folder and imported Actions from the NgRx store.
import { Action } from '@ngrx/store';
import { NodeData } from '../models/nodeData.model';
export enum DiagramActionType {
ADD_ITEM = '[ARTICLE] Add ARTICLE',
}
export class AddDiagramAction implements Action {
readonly type = DiagramActionType.ADD_ITEM;
constructor(public payload: NodeData ) {}
}
export type DiagramAction = AddDiagramAction;
In the above action file, we defined an action as a constant using enum. Then, we implemented the AddDiagramAction class from the NgRx Action class, which accepts two parameters: a type and an optional payload.
Now, we need to create a reducer to help us in state transitions. So, inside the reducers directory, create a nodeData.reducer.ts file with the following content:
// import the interface
import { DiagramAction, DiagramActionType } from '../actions/nodeData.actions';
import { NodeData } from '../models/nodeData.model';
//create a dummy initial state
const initialState: Array<NodeData > = [
{
id: "",
offsetX: 300 ,
offsetY: 200 ,
},
];
export function NodeDataReducer(
state: Array<NodeData> = initialState,
action: DiagramAction
) {
switch (action.type) {
case DiagramActionType.ADD_ITEM:
console.log("State", ...state);
console.log("action",action.payload);
return [...state, action.payload];
default:
return state;
}
}
In the above reducer, we have created an initial state for the NodeData interface and a reducer function named nodeDataReducer Which accepts a state and an action as input parameters. If the action type is ADD_ITEM, it will return the state and the payload. Otherwise, it will only return the state.
For the final step of store creation, we need to create another model to keep all application states in a single place. Here, we have named it state.model.ts and it will look like this:
import { NodeData } from '../models/nodeData.model';
export interface State {
readonly nodeData: Array<NodeData >;
}
Now, you need to register the NgRx store in the Angular application. To do this, import the reducer created in the previous step to the app.module.ts file and include it in the imports array.
Usage of ngrx store with Angular diagram:
After registering the store in AppModule, we can start using it in our diagram component by importing the dependent store files in app.component.ts file.
export class AppComponent implements OnInit {
nodeData$: Observable<Array<NodeData>>;
constructor(private store: Store<State>) {}
ngOnInit(): void {
this.nodeData$ = this.store.select((store) => {
return store.article
});
}
}
The above code shows the app.component.ts file of our example. There, we have set a property nodeData$ to a type of observable and subscribed to the store to get the nodeData.
Storing node offset and id:
For storing the node’s position during dragging, we employed the positionChange event of the diagram. This event triggers whenever objects are moved on the diagram, allowing us to obtain the updated offset values of the dragged node. We proceed by storing both the position and the node’s identity within the nodeCollection object. Subsequently, this data is dispatched to the store.
public positionChange(args: IDraggingEventArgs): void {
console.log("position change");
if (args.state === 'Completed') {
var nodeCollection = { id:(args.source instanceof Node ? (args.source as any).id : args.source.nodes[0].id),offsetX: args.newValue.offsetX, offsetY:args.newValue.offsetY};
this.store.dispatch(new AddDiagramAction(nodeCollection));
}
}
The sample with the implementation mentioned above is attached below
Sample:
Conclusion
I hope you enjoyed learning about how to store node offset position in ngrx store using Angular Diagram.
You can refer to our Angular Diagram feature tour page to know about its other groundbreaking feature representations and documentation, and how to quickly get started for configuration specifications. You can also explore our Angular Diagram example to understand how to create and manipulate data.
For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our other controls.
If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!