Cannot bind alignment

Hi Walter. I try to align my adornment in node. I use go.Binding to set alignment from dataModel

new go.Binding('alignment','alignment',go.Spot.parse).makeTwoWay( go.Spot.stringify)

model example

{
   id: 'unique id',
   alignment: '1 0 0 0',
   fill: 'red',
}

To set adornment on node I use

const node = myDiagram.selection.first();
const adornment = MyAdornment();
adornment.adornedObject = node;
node.addAdornment('new_adornment', adornment)

after run code, alignment get value not from dataModel. It equals go.Spot.Center.

But if I set alignment in template without dataModel, it works correctly.

How to correctly connect dataModel and adornment alignment?

Also I use isActionable: true and actionMove: handleActionMove to drag adornment on node

Could you please show the definition of MyAdornment? I don’t know which GraphObject that Binding is on.

In previouse message I lost {category: ‘text’} in dataModel example. In my code it exists.

const adornmentTemplateMap = new go.Map();
adornmentTemplateMap.add('text', TextAdornmentPanel);

const MyAdornment = () => $(
  go.Adornment,
  'Spot',
  {
    zOrder: 2,
  },
  $(
    go.Panel,
    'Auto',
    $(go.Shape, {
      fill: null,
      strokeWidth: 0,
      stroke: 'black',
    }),
    $(go.Placeholder, { margin: 75 }),
  ),
  new go.Binding('itemArray', 'adornmentList'),
  {
    itemTemplateMap: adornmentTemplateMap,
  },
);

const TextAdornmentPanel = $(
go.Panel,
‘Auto’,
{
isActionable: true,
actionMove: handleMoveAdornmentPanel,
},
$(
go.Shape,
new go.Binding(‘stroke’, ‘strokeColor’),
new go.Binding(‘strokeWidth’, ‘strokeWidth’),
new go.Binding(‘fill’, ‘fillColor’),
new go.Binding(‘figure’, ‘figure’),
new go.Binding(‘alignment’,‘alignment’,go.Spot.parse).makeTwoWay( go.Spot.stringify)
),
$(
go.Panel,
‘Spot’,
{
padding: new go.Margin(3, 3, 3, 3),
},
$(
go.TextBlock,
{
textAlign: ‘center’,
verticalAlignment: go.Spot.Center,
overflow: go.TextBlock.OverflowEllipsis,
isMultiline: false,
editable: false,
},
new go.Binding(‘text’, ‘text’),
),
),
);


const handleMoveAdornmentPanel = (evt, obj) => {
  const { position } = obj.part;
  const { documentPoint } = evt;
  let dx = Math.abs(position.x - documentPoint.x);
  let dy = Math.abs(position.y - documentPoint.y);
  if (documentPoint.x - position.x < 0) {
    dx = (-1) * dx;
  }
  if (documentPoint.y - position.y < 0) {
    dy = (-1) * dy;
  }
  const newSpot = new go.Spot(0, 0, dx, dy);
  obj.alignment = newSpot;
};

I don’t see how setting or binding the alignment on the Shape that is the main element of an “Auto” Panel will have any effect.

Didn’t you really want to bind the alignment on the panel that is the whole item template, so that alignment would affect the position of the item panel within the “Spot” panel that is the Adornment?

TextAdornmentPanel has alignment binding. Yes, I wanna add adornment panel to node that contain any panel (adornment templates), and drag its inside node

You mentioned dragging before, but I don’t see how any issues with dragging have anything to do with binding the alignment property.

I change alignment in handleMoveAdornmentPanel and after change alignment by dragging datamodel not updated too. and initial alignment also not correctly work.

Saving property values in the model is usually accomplished via a TwoWay data Binding.

Are you sure your code is setting the alignment property on the same GraphObject where you have the TwoWay Binding declared? That doesn’t seem to be the case, but it’s hard for me to guess.

Saving alignment values in model is the second problem. The first - get alignment from model end set it on adornment.

I my code correctly work only if i use next code

const TextAdornmentPanel = $(
go.Panel,
‘Auto’,
  {
    alignment: new go.Spot(0, 0, 0, 0)
    isActionable: true,
    actionMove: handleMoveAdornmentPanel,
  },
)

if I use

new go.Binding(‘alignment’,‘alignment’,() => new go.Spot(1, 1, 0, 0)).makeTwoWay( go.Spot.stringify)

it does not work correctly. In the last case adornment alignment is equal go.Spot.Center

I’ll repeat:

OOh, I set binding on shape but should on Panel. Thank you

I change my code, and initial alignment correctly work.

const TextAdornmentPanel = $(
go.Panel,
‘Auto’,
{
    isActionable: true,
    actionMove: handleMoveAdornmentPanel,
},
   new go.Binding(‘alignment’,‘alignment’,go.Spot.parse).makeTwoWay( go.Spot.stringify)
$(
go.Shape,
    new go.Binding(‘stroke’, ‘strokeColor’),
    new go.Binding(‘strokeWidth’, ‘strokeWidth’),
    new go.Binding(‘fill’, ‘fillColor’),
    new go.Binding(‘figure’, ‘figure’),
),
$(
go.Panel,
‘Spot’,
{
padding: new go.Margin(3, 3, 3, 3),
},
$(
go.TextBlock,
{
textAlign: ‘center’,
verticalAlignment: go.Spot.Center,
overflow: go.TextBlock.OverflowEllipsis,
isMultiline: false,
editable: false,
},
new go.Binding(‘text’, ‘text’),
),
),
);

but makeTwoWay not work. I think the problem in handleMoveAdornmentPanel

in next code

  const newSpot = new go.Spot(0, 0, dx, dy);
  obj.alignment = newSpot;

Does resolve exist?

Your posts are too short for me to understand the context and intent of your questions.

Which data you need?

I have no idea of what your question was. There was no mention of “resolve” anywhere earlier in this forum topic. Please think about what someone might be thinking who is reading your words but is unfamiliar with your thoughts

Here I asked you.

Why does makeTwoWay not update dataModel?

Yes, if your code sets the GraphObject.alignment property on such a Panel, it will update the “alignment” property of the corresponding data Object in the Array that is the “adornmentList” property value on the node data object.

Thank you, walter