Setting the position of new shape being created

for newly created shape there is transform:matrix (matrix(1 0 0 1 -270 -2790)) property that is set on the shape element. In my case if I add new component it is getting render over the sibling element, I want to change its position;

how can i change this?

@Niklas_Kiefer any help on this?

Update

this is how it looks on ui

ezgif-5-6a787a5b8c

this is how i am rendering

drawConnection = function (parent, shape) {
  var conn = this.bpmnRenderer.drawShape(parent, shape);
  attr(conn, {
    stroke: 'red'
  });
  return conn;
}

drawShape = function (parent, shape) {
  return this.drawCustomeShape(parent, shape);
}

drawCustomeShape(parent, shape) {
  const elementShape = drawRect(270, 60, 30, '#FFFF');

  attr(elementShape, {
    stroke: "green",
    "stroke-width": "1px",
  });

  append(parent, elementShape);

  if (shape.businessObject.name) {
    const headerRect = drawRect(150, 40, 0, '#ffffff')
    attr(headerRect, {
      x: 60,
      y: -25,
      strokeWidth: 2,
      stroke: 'white',
      transform: 'translate(10, 30)'
    });
    append(parent, headerRect);

    let headingText = drawText('#4f7c9e', "bold", 'translate(15, 45)', 12, 170)
    classes(headingText).add('djs-label');
    attr(headingText, { x: 70, y: -10 });
    append(headingText, document.createTextNode(shape.businessObject.name));
    append(parent, headingText);

  }

  var textEle = drawText('#7291a8', "bold", 'translate(15, 45)', 12, 20)
  classes(textEle).add('djs-label');
  attr(textEle, { x: 50, y: 5 });
  
  var text = "from_some_function";
  append(textEle, document.createTextNode(text));
  append(parent, textEle);

  const rectHit = drawRect(180, 100, 0, 'white');

  attr(rectHit, {
    x: 0,
    y: 0,
    stroke: 'white',
    strokeOpacity: '0',
    strokeWidth: 15,
    fill: 'none'
  });
  classes(rectHit).add('djs-hit');
  classes(rectHit).add('djs-hit-all');
  classes(rectHit).add('rectEle');
  append(parent.parentNode, rectHit);

  const rectOutline = drawRect(0, 0, 0, 'none');// update height width in css class accordingly
  attr(rectOutline, {
    x: -6,
    y: -6
  });
  classes(rectOutline).add('djs-outline');
  classes(rectOutline).add('rectEle');
  append(parent.parentNode, rectOutline);
  return elementShape;

}

function drawRect(width, height, borderRadius, color) {
  const rect = create('rect');

  attr(rect, {
    width: width,
    height: height,
    rx: borderRadius,
    ry: borderRadius,
    fill: color
  });
  return rect;
}

function drawText(color, fontWeight, transform, fontSize, width) {
  var textEle = create('text');
  attr(textEle, {
    fill: color,
    fontWeight: fontWeight,
    transform: transform,
    fontSize: fontSize,
    inlineSize: width
  });
  return textEle;
}

How do you add the new element?

@nikku have edited the post with code and screen shot

@nikku @Niklas_Kiefer any clue will help too

The way you append new shapes is by interacting with our Modeling API.

It allows you to interface with the modeler, create new shapes, and also assign the position in the process:

const shape = elementFactory.createShape(...);

modeling.createShape(shape, { x: 100, y: 500 });

this i need to write in drawShape of CustomRenderer as i am getting shape object there.

thanks for the reply!!!

In the CustomeContextPad where I am creating the element I added

modeling.createShape(shape, { x: 100, y: 500 });

and now this is throwing error

TypeError: Cannot read properties of undefined (reading 'children')
    at BpmnOrderingProvider.getOrdering (BpmnOrderingProvider.js:146:1)
    at OrderingProvider.js:48:1
    at invokeFunction (EventBus.js:514:1)
    at push../node_modules/diagram-js/lib/core/EventBus.js.EventBus._invokeListener (EventBus.js:365:1)
    at push../node_modules/diagram-js/lib/core/EventBus.js.EventBus._invokeListeners (EventBus.js:350:1)
    at push../node_modules/diagram-js/lib/core/EventBus.js.EventBus.fire (EventBus.js:311:1)
    at push../node_modules/diagram-js/lib/command/CommandStack.js.CommandStack._fire (CommandStack.js:346:1)
    at push../node_modules/diagram-js/lib/command/CommandStack.js.CommandStack._internalExecute (CommandStack.js:388:1)
    at push../node_modules/diagram-js/lib/command/CommandStack.js.CommandStack.execute (CommandStack.js:147:1)
    at push../node_modules/diagram-js/lib/features/modeling/Modeling.js.Modeling.createShape (Modeling.js:291:1)
    at Object.click (CustomContextPad.js:134:1)
    at push../node_modules/diagram-js/lib/features/context-pad/ContextPad.js.ContextPad.trigger (ContextPad.js:203:1)
    at HTMLDivElement.<anonymous> (ContextPad.js:301:1)
    at HTMLDivElement.<anonymous> (index.esm.js:359:1)
console.<computed> @ index.js:1
push../node_modules/diagram-js/lib/core/EventBus.js.EventBus._invokeListener @ EventBus.js:380
push../node_modules/diagram-js/lib/core/EventBus.js.EventBus._invokeListeners @ EventBus.js:350
push../node_modules/diagram-js/lib/core/EventBus.js.EventBus.fire @ EventBus.js:311
push../node_modules/diagram-js/lib/command/CommandStack.js.CommandStack._fire @ CommandStack.js:346
push../node_modules/diagram-js/lib/command/CommandStack.js.CommandStack._internalExecute @ CommandStack.js:388
push../node_modules/diagram-js/lib/command/CommandStack.js.CommandStack.execute @ CommandStack.js:147
push../node_modules/diagram-js/lib/features/modeling/Modeling.js.Modeling.createShape @ Modeling.js:291
(anonymous) @ CustomContextPad.js:134
push../node_modules/diagram-js/lib/features/context-pad/ContextPad.js.ContextPad.trigger @ ContextPad.js:203
(anonymous) @ ContextPad.js:301
(anonymous) @ index.esm.js:359
BpmnOrderingProvider.js:146 Uncaught TypeError: Cannot read properties of undefined (reading 'children')
    at BpmnOrderingProvider.getOrdering (BpmnOrderingProvider.js:146:1)
    at OrderingProvider.js:48:1
    at invokeFunction (EventBus.js:514:1)
    at push../node_modules/diagram-js/lib/core/EventBus.js.EventBus._invokeListener (EventBus.js:365:1)
    at push../node_modules/diagram-js/lib/core/EventBus.js.EventBus._invokeListeners (EventBus.js:350:1)
    at push../node_modules/diagram-js/lib/core/EventBus.js.EventBus.fire (EventBus.js:311:1)
    at push../node_modules/diagram-js/lib/command/CommandStack.js.CommandStack._fire (CommandStack.js:346:1)
    at push../node_modules/diagram-js/lib/command/CommandStack.js.CommandStack._internalExecute (CommandStack.js:388:1)
    at push../node_modules/diagram-js/lib/command/CommandStack.js.CommandStack.execute (CommandStack.js:147:1)
    at push../node_modules/diagram-js/lib/features/modeling/Modeling.js.Modeling.createShape (Modeling.js:291:1)
    at Object.click (CustomContextPad.js:134:1)
    at push../node_modules/diagram-js/lib/features/context-pad/ContextPad.js.ContextPad.trigger (ContextPad.js:203:1)
    at HTMLDivElement.<anonymous> (ContextPad.js:301:1)
    at HTMLDivElement.<anonymous> (index.esm.js:359:1)

And instead of setting x,y on shape, I tried setting

element.x += 200;

it worked but now starting point of the connection is not from the sibling component. Like this

image

even I tried creating manual connection using

static reConnectElement(el) {
    const sourceConnection = el.incoming[0];
    const source = el.incoming[0]?.source;
    // for starting node there can be no source
    if (source) {
      deleteConnection(sourceConnection);
      const connection = connectElement(source, el);
    }

  }

deleteConnection(connection) {
    const modeling = getModeler().get('modeling');
    modeling.removeConnection(connection);
 }

connectElement(source, target) {
    const modeling = getModeler().get('modeling');
    return modeling.connect(source, target);
  }

but it creates the same line not connected to its sibling source component. I checked the source id it is same element that it should be connected to

This is not the way to do it. Why would you only figure out where an element is supposed to be during rendering? Rendering is supposed to look at an element and to render it at the specified position. Think of separation between model and view.

Even i tried just after creating the shape, still same issue. With

const shapeX = element.x + SHAPE_WIDTH + DISTANCE;
moveElement(shape, { x: shapeX, y: shape.y });


moveElement(el, coords) {
    const modeling = getModeler().get('modeling');
    // get the delta from current and previous coordinates
    const delta = {
      x: coords.x - el.x,
      y: coords.y - el.y
    };

    // move the shape
    modeling.moveShape(el, delta);
  }

it worked.

but is there any other way?