How can I position ports on the right side of a graph element in JointJS?

I'm in the process of developing an Angular application that allows users to dynamically create graphs. Currently, I am working on a function that adds ports to vertices and I want the user to be able to select the position of the port (right, left, top, bottom). While following an example from JointJS documentation, I encountered an issue where I can only adjust the position of the port label, not the port itself:

View ports created using the code below

This is the function I have created to return the port body based on the specified position ('top', 'right' etc.) and name:

getPort(portName: string, position: string): object {
    return {
      position: {
        name: position
      },
      attrs: {
        label: {
          text: portName
        },
        portBody: {
          magnet: true,
          r: 10,
          fill: '#023047',
          stroke: '#023047'
        }
      },
      label: {
        position: {
          name: position
        },
        markup: [{
          tagName: 'text',
          selector: 'label',
          className: 'label-text'
        }]
      },
      markup: [{
        tagName: 'circle',
        selector: 'portBody'
      }]
    };
  }

Here is how I add the port to my graph (using the unique vertex name as an argument):

this.graph.getElements().forEach(element => {
      if (element.attributes.attrs['label'].text == agentName) {
        element.addPort(port)
      }
})

Although I followed this tutorial, I am still facing issues where even after copying some port bodies intended for the right side, they appear on the left side instead. What could I possibly be doing wrong?

Answer №1

It turns out that you have the ability to specify the position of ports within port groups. I updated my shapes by adding the following section:

ports: {
    groups: {
      'left': this.PORT_GROUP('left'),
      'right': this.PORT_GROUP('right'),
      'top': this.PORT_GROUP('top'),
      'bottom': this.PORT_GROUP('bottom'),
    }
  }

Additionally, I created a function for this purpose:

PORT_GROUP(position: string): object {
    return {
      position: {
        name: position
      },
      attrs: {
        portBody: {
          magnet: true,
          r: 10,
          fill: '#023047',
          stroke: '#023047'
        }
      },
      label: {
        position: {
          name: position,
        },
        markup: [{
          tagName: 'text',
          selector: 'label',
          className: 'label-text'
        }]
      },
      markup: [{
        tagName: 'circle',
        selector: 'portBody'
      }]
    };
  }

With these changes, the ports are now correctly positioned with their respective bodies:

{
  group: 'left',
  attrs: {label: {text: 'portName'}}
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Calling a function within another function

In my code, I have a function that formats the price and retrieves the value needed for refactoring after upgrading our dependencies. I'm struggling with passing the form value to the amountOnBlur function because the blur function in the dependencie ...

Building an Event Scheduler in Outlook Calendar with Angular 5

Currently, I am utilizing Angular version 5.2 for a room booking portal project. One of the requirements entails adding an event to the Outlook calendar on the day a room is booked. The system includes a table listing all bookings, with a button in each ro ...

What prevents me from employing my nestjs unique decorator within a constructor?

I am looking to develop a personalized decorator that fetches tenant information. This is the current code snippet I have: export type TenantInfo = { token: string id: string } export const TenantInfo = createParamDecorator( (data: unknown, cont ...

Compel a customer to invoke a particular function

Is there a way to ensure that the build method is always called by the client at the end of the command chain? const foo = new Foo(); foo.bar().a() // I need to guarantee that the `build` method is invoked. Check out the following code snippet: interface ...

Utilizing the adapter design pattern in Angular with TypeScript for enhancing a reactive form implementation

I've been struggling to understand how to implement the adapter pattern in Angular6. Despite reading numerous articles and tutorials, I still can't quite grasp the concept. Could someone provide some insights on this topic? Essentially, I have a ...

Pay attention to the input field once the hidden attribute is toggled off

In attempting to shift my attention to the input element following a click on the edit button, I designed the code below. The purpose of the edit is to change the hidden attribute to false. Here's what I attempted: editMyLink(i, currentState) { ...

Exploring Angular: Embracing the Power of Query String Parameters

I've been struggling with subscribing to query string parameters in Angular 2+. Despite looking at various examples, I can't seem to make it work. For instance, on this Stack Overflow thread, the question is about obtaining query parameters from ...

What is the reason behind typescript making it necessary for me to find a way to set a value of type

function f1() { const v : string = String(); if(v) {alert("IF");} // OK const b : boolean = v; // Type 'string' is not assignable to type 'boolean'. if(b) {alert("BOOLEAN");} } f1(); My approach to this issue involv ...

What is the most effective approach for annotating TypeScript abstract classes that are dynamically loaded?

I am in the process of developing a library that allows for the integration of external implementations, and I am exploring the optimal approach to defining types for these implementations. Illustration abstract class Creature { public abstract makeN ...

Delivering secure route information to paths in Angular 2

When defining my routes in the routing module, I have structured the data passing like this: const routes: Routes = [ { path: '', redirectTo: 'login', pathMatch: 'full' }, { path: 'login', component: LoginCompon ...

Tips for utilizing Variant on an overridden component using as props in ChakraUI

I created a custom Component that can be re-rendered as another component using the BoxProps: export function Label ({ children, ...boxProps }: BoxProps) { return ( <Box {...boxProps}> {children} </Box> ); } It functio ...

Attempting to compile TypeScript by referencing ng2-bootstrap using Gulp within Visual Studio

I've been struggling with this issue for a few days now, and I'm really hoping someone can help me out. Currently, I am experimenting with Angular2 in an aspnet core project. The setup involves using a gulpfile.js to build .ts files and transfer ...

Using a targeted div as a child component in React

How can I specifically pass a div with the class name 'message-content' as props.children, without including all the divs above it? <div className="message"> <div className="message-title-info">A ...

Can dynamic values be sent to a custom form validator in Angular 6?

Essentially, I am facing a challenge with validating form inputs that are interdependent (for example, ensuring that the "from" time is earlier than the "to" time). However, I'm unsure of the best approach to tackle this issue. Below is my form group ...

What is the best approach to transpiling TypeScript aliased paths to JavaScript?

I am currently facing an issue with my TypeScript project where I need to transpile it into executable JavaScript while using path aliases for my NPM package development. One specific scenario involves importing a method from the lib directory without spe ...

Creating a custom Map type in TypeScript

I am exploring the concept of defining a Map type in Typescript using generics. Essentially, I want to create something similar to: EntityMap<U, V>, where U can only be either a string or a number This is what I have managed to come up with so far: ...

After pushing to history in React, the rendered component fails to display on the screen

I am in the process of developing a React application. Here are the dependencies I am currently using: "react": "^17.0.2", "react-dom": "^17.0.2", "react-helmet": "^6.1.0", "react-router" ...

Having trouble uploading a PNG image (logo) with Cypress

I have been attempting to upload a png file using Cypress and here is what I have tried so far: Cypress.Commands.add('upload_image', (fileName, selector) => { return cy.get(selector).then(subject => { return cy.fixture(fileName, &apo ...

Building basic objects in TypeScript

My current project involves utilizing an interface for vehicles. export interface Vehicle { IdNumber: number; isNew: boolean; contact: { firstName: string; lastName: string; cellPhoneNumber: number; ...

Exploring Angular 2's nested navigation using the latest router technology

Is there a way to implement nested navigation in Angular? I had this functionality with the previous router setup. { path: '/admin/...', component: AdminLayoutComponent } It seems that since rc1 of angular2, this feature is no longer supported. ...