Hey walter,
below is a template of a GOJS PArt which should more or less look and work like a sticky note.
however, as u can see in the screenshot ,
- the textblock is overflowing outside of the Rectangle Shape as i type in it. My expectation is the Rectangle shud dynamically changes it width and height to ensure the textblock is is always inside it.
- the Textblock is always centered. i want it to occupy fill the entire rectangle always, with some padding, and i want the ability to center, left and right align the text.
- i have added adornments, to change the background color of the node, and font color of the node, but they dont seem to work.
i am having trouble debugging the issue. could you please help.
export const stickyNoteTemplate = $(
go.Node,
"Spot",
{
layerName: STICKY_NOTES_LAYER,
resizable: true,
resizeObjectName: "PANEL",
selectionObjectName: "PANEL",
selectionAdorned: true,
locationSpot: go.Spot.Center,
// Add shadow effect
shadowVisible: true,
shadowOffset: new go.Point(3, 3),
shadowBlur: 5,
// Add double-click behavior to edit text
doubleClick: function (e, obj) {
const textblock = obj.findObject("TEXTBLOCK");
if (textblock) textblock.isEditing = true;
},
},
// Main panel that will be resized
$(
go.Panel,
"Auto",
{
name: "PANEL",
minSize: new go.Size(100, 50),
},
// The shape that represents the sticky note
$(
go.Shape,
"RoundedRectangle",
{
name: "SHAPE",
fill: "lightyellow",
stroke: "darkgray",
strokeWidth: 1,
// Make sure the shape fills the panel
stretch: go.GraphObject.Fill,
},
new go.Binding("fill", "backgroundColor")
),
// The text block that contains the editable text
$(
go.TextBlock,
{
name: "TEXTBLOCK",
margin: 10,
textAlign: "left",
verticalAlignment: go.Spot.Top,
editable: true,
font: "12pt sans-serif",
stroke: "black", // Default font color
wrap: go.TextBlock.WrapFit,
isMultiline: true,
overflow: go.TextBlock.WrapFit,
width: 150, // Default width
// Listen for text changes to resize the node
textEdited: function (textBlock, oldText, newText) {
textBlock.diagram.startTransaction("resize after text edit");
textBlock.diagram.commitTransaction("resize after text edit");
},
},
new go.Binding("text").makeTwoWay(),
new go.Binding("stroke", "fontColor"),
new go.Binding("textAlign", "textAlign")
)
),
// Add a context menu
{
contextMenu: $(
go.Adornment,
"Vertical",
// Background color section
$(go.TextBlock, "Background Color", { margin: 5 }),
$(
go.Panel,
"Horizontal",
{ defaultStretch: go.GraphObject.Horizontal },
...backgroundColors.map((color) =>
$(
go.Panel,
"Auto",
{
margin: 3,
// Use mouseDrop instead of click for better reliability
mouseDrop: function (e, obj) {
console.log("Background color clicked:", color);
const node = obj.part.adornedPart;
if (node && node.diagram) {
const diagram = node.diagram;
diagram.startTransaction("change background color");
diagram.model.setDataProperty(
node.data,
"backgroundColor",
color
);
diagram.commitTransaction("change background color");
}
},
cursor: "pointer",
},
$(go.Shape, "Rectangle", {
fill: color,
stroke: "black",
width: 20,
height: 20,
})
)
)
),
// Font color section
$(go.TextBlock, "Font Color", { margin: 5 }),
$(
go.Panel,
"Horizontal",
{ defaultStretch: go.GraphObject.Horizontal },
...fontColors.map((color) =>
$(
go.Panel,
"Auto",
{
margin: 3,
// Use mouseDrop instead of click for better reliability
mouseDrop: function (e, obj) {
console.log("Font color clicked:", color);
const node = obj.part.adornedPart;
if (node && node.diagram) {
const diagram = node.diagram;
diagram.startTransaction("change font color");
diagram.model.setDataProperty(node.data, "fontColor", color);
diagram.commitTransaction("change font color");
}
},
cursor: "pointer",
},
$(go.Shape, "Rectangle", {
fill: color,
stroke: "black",
width: 20,
height: 20,
})
)
)
),
// Text alignment section
$(go.TextBlock, "Text Alignment", { margin: 5 }),
$(
go.Panel,
"Horizontal",
{ defaultStretch: go.GraphObject.Horizontal },
$(
go.Panel,
"Auto",
{
margin: 3,
// Use mouseDrop instead of click for better reliability
mouseDrop: function (e, obj) {
console.log("Text align left clicked");
const node = obj.part.adornedPart;
if (node && node.diagram) {
const diagram = node.diagram;
diagram.startTransaction("change text align");
diagram.model.setDataProperty(node.data, "textAlign", "left");
diagram.commitTransaction("change text align");
}
},
cursor: "pointer",
},
$(go.TextBlock, "Left", { margin: 2 })
),
$(
go.Panel,
"Auto",
{
margin: 3,
// Use mouseDrop instead of click for better reliability
mouseDrop: function (e, obj) {
console.log("Text align center clicked");
const node = obj.part.adornedPart;
if (node && node.diagram) {
const diagram = node.diagram;
diagram.startTransaction("change text align");
diagram.model.setDataProperty(node.data, "textAlign", "center");
diagram.commitTransaction("change text align");
}
},
cursor: "pointer",
},
$(go.TextBlock, "Center", { margin: 2 })
),
$(
go.Panel,
"Auto",
{
margin: 3,
// Use mouseDrop instead of click for better reliability
mouseDrop: function (e, obj) {
console.log("Text align right clicked");
const node = obj.part.adornedPart;
if (node && node.diagram) {
const diagram = node.diagram;
diagram.startTransaction("change text align");
diagram.model.setDataProperty(node.data, "textAlign", "right");
diagram.commitTransaction("change text align");
}
},
cursor: "pointer",
},
$(go.TextBlock, "Right", { margin: 2 })
)
),
// Center in viewport
$(
go.Panel,
"Auto",
{
margin: 5,
// Use mouseDrop instead of click for better reliability
mouseDrop: function (e, obj) {
console.log("Center in viewport clicked");
const node = obj.part.adornedPart;
if (node && node.diagram) {
const diagram = node.diagram;
diagram.startTransaction("center shape");
const viewportBounds = diagram.viewportBounds;
const centerX = viewportBounds.width / 2;
const centerY = viewportBounds.height / 2;
node.location = new go.Point(centerX, centerY);
diagram.commitTransaction("center shape");
}
},
cursor: "pointer",
},
$(go.TextBlock, "Center in Viewport", { margin: 2 })
)
),
},
new go.Binding("location", "location", go.Point.parse).makeTwoWay(
go.Point.stringify
)
);