For text elements inside shapes (labels):
text_width = (text.length × fontSize × 0.6) + 20
Round to nearest 10 for grid alignment.
CRITICAL: When creating shapes with labels:
Generate unique IDs:
shape-id for the shapetext-id for the textgroup-id for the groupShape element must have:
groupIds: [group-id]boundElements: [{type: "text", id: text-id}]Text element must have:
containerId: shape-idgroupIds: [group-id] (SAME as shape)textAlign: "center"verticalAlign: "middle"width: calculated_widthx, y coordinates to 20px gridMath.round(value / 20) * 20Use for forward flow (left-to-right, top-to-bottom):
{
"type": "arrow",
"startBinding": {
"elementId": "source-shape-id",
"focus": 0,
"gap": 10
},
"endBinding": {
"elementId": "target-shape-id",
"focus": 0,
"gap": 10
},
"points": [[0, 0], [distance_x, distance_y]]
}
Use for upward flow, backward flow, or complex routing:
{
"type": "arrow",
"startBinding": {...},
"endBinding": {...},
"points": [
[0, 0],
[intermediate_x, 0],
[intermediate_x, intermediate_y],
[final_x, final_y]
],
"elbowed": true
}
After creating arrow, update boundElements on both connected shapes:
{
"id": "shape-id",
"boundElements": [
{ "type": "text", "id": "text-id" },
{ "type": "arrow", "id": "arrow-id" }
]
}
Theme colors should be applied consistently:
backgroundColor from theme primary fillstrokeColor from theme accentstrokeColor = "#1e1e1e" (dark text)strokeColor from theme accentBefore saving, verify:
groupIdscontainerId pointing to parent shapetextAlign + verticalAlign)startBinding and endBindingboundElements array updated on connected shapesRemove from final output:
appState objectfiles object (unless images used)isDeleted: true