通过单击 GOJS 中的形状在形状上制作斑点
Make spots on shapes by clicking on the shape in GOJS
我正在使用 GOJS,每当我点击形状时我都想做一个点。这个点应该正好出现在我点击 shape.Can 的位置上,我这样做了吗?
这是我的代码,我添加了硬编码的点或端口
function makePort(name, spot, output, input) {
return GO(go.Shape, "Circle",
{
fill: "grey",
stroke: null,
desiredSize: new go.Size(10, 10),
alignment: spot,
alignmentFocus: spot,
portId: name,
fromSpot: spot, toSpot: spot,
fromLinkable: output, toLinkable: input,
cursor: "pointer"
});
}
myDiagram.nodeTemplate =
GO(go.Node, "Spot",
{
selectionAdorned: false, // don't show the standard selection handle
resizable: true, resizeObjectName: "SHAPE", // user can resize the Shape
rotatable: true, rotateObjectName: "SHAPE", // user can rotate the Shape
// without rotating the label
layoutConditions: go.Part.LayoutStandard & ~go.Part.LayoutNodeSized
},
new go.Binding("location", "loc").makeTwoWay(), // TwoWay Binding // Binds diagram and model location with eachother
a = GO(go.Shape,
{
click:click1,
name: "SHAPE",
width: 70, height: 70,
stroke: "#000000",
fill: "transparent",
//angle: 45,
strokeWidth: 1
},
new go.Binding("figure","fig"),
new go.Binding("name_shape", "key"),
new go.Binding("angle", "ang").makeTwoWay(), // Binds diagram and model angle with eachother
// new go.Binding("desiredSize", "size").makeTwoWay(), // Binds diagram and model size with eachother
new go.Binding("geometryString", "geometry").makeTwoWay()),// Binds diagram and model geometry string with eachother
// GO(go.Shape,"Circle", // the "A" port
// { width: 20, height: 20, portId: "A",stroke:null,toSpot: go.Spot.Left}),
/*GO(go.Panel, "Vertical",
GO(go.TextBlock,
new go.Binding("text", "fig")),
GO(go.TextBlock, { stroke: "blue" },
new go.Binding("text", "parameter1", function(p1) { return p1; }).ofObject("SHAPE"))
)*/
// GO(go.Shape, // the "A" port
// { width: 6, height: 6, portId: "A" }),
// four small named ports, one on each side:
makePort("T", go.Spot.Top, false, true),
makePort("L", go.Spot.Left, true, true),
makePort("TL", go.Spot.TopLeft, true, true),
makePort("BL", go.Spot.BottomLeft, true, true),
makePort("R", go.Spot.Right, true, true),
makePort("TR", go.Spot.TopRight, true, true),
makePort("BR", go.Spot.BottomRight, true, true),
makePort("B", go.Spot.Bottom, true, true),
makePort("C",go.Spot.Center,true,true),
{ // handle mouse enter/leave events to show/hide the ports
mouseEnter: function(e, node) { showSmallPorts(node, true); },
mouseLeave: function(e, node) { showSmallPorts(node, false); }
}
);
function showSmallPorts(node, show) {
node.ports.each(function(port) {
if (port.portId !== "") { // don't change the default port, which is the big shape
port.fill = show ? "rgba(0,0,0,.3)" : null;
}
});
我认为这应该符合您的要求:
function init() {
var $ = go.GraphObject.make;
myDiagram =
$(go.Diagram, "myDiagramDiv",
{ initialContentAlignment: go.Spot.Center, "undoManager.isEnabled": true });
myDiagram.nodeTemplate =
$(go.Node, "Spot",
{ selectionObjectName: "BODY" },
new go.Binding("itemArray", "spots"),
{ // each spot is represented by a Panel holding a circular Shape
// at a particular alignment relative to the "BODY"
itemTemplate:
$(go.Panel,
$(go.Shape, "Circle",
{
fill: $(go.Brush, go.Brush.Radial, { 0.0: "gray", 1.0: "transparent" }),
strokeWidth: 0, width: 16, height: 16
}),
new go.Binding("alignment", "spot", go.Spot.parse).makeTwoWay(go.Spot.stringify)
),
// when the user clicks on the node, add a "spot"
click: function(e, obj) {
e.diagram.startTransaction();
// convert click point into Spot in node's bounds
var pt = e.documentPoint; // in document coordinates
var node = obj.part;
var b = node.actualBounds; // will be in document coordinates
var spot = new go.Spot(Math.max(0, Math.min((pt.x - b.x) / b.width, 1)),
Math.max(0, Math.min((pt.y - b.y) / b.height, 1)));
// add an Object describing the spot's location (as a Spot value)
var spotsArray = node.data.spots;
if (!Array.isArray(spotsArray)) spotsArray = node.data.spots = [];
e.diagram.model.addArrayItem(spotsArray, { spot: go.Spot.stringify(spot) });
e.diagram.commitTransaction("added spot");
}
},
$(go.Panel, "Auto",
{ name: "BODY", width: 100, height: 100 },
$(go.Shape, { fill: "whitesmoke" }),
$(go.TextBlock, { editable: true },
new go.Binding("text").makeTwoWay())
)
);
myDiagram.model = $(go.GraphLinksModel,
{
copiesArrays: true, // make sure the data.spots Array is copied
copiesArrayObjects: true, // make sure the Objects in those Arrays are also copied
nodeDataArray: [
{ key: 1, text: "Alpha", spots: [] },
{ key: 2, text: "Beta", spots: [{ spot: "0.3, 0.2" }] }
],
linkDataArray: [
{ from: 1, to: 2 }
]
});
}
执行此操作并单击几个位置的节点会导致:
请注意,"Beta" 节点以一个点开始,如模型数据中所定义。
顺便说一下,我不清楚用户想要添加的 "spots" 真的必须是 "ports"。您可以通过给每个 "spot" 一个 "port" 一个唯一的 GraphObject.portId.
您可能想阅读 GoJS 简介的所有页面,位于 http://gojs.net/latest/intro。
我正在使用 GOJS,每当我点击形状时我都想做一个点。这个点应该正好出现在我点击 shape.Can 的位置上,我这样做了吗? 这是我的代码,我添加了硬编码的点或端口
function makePort(name, spot, output, input) {
return GO(go.Shape, "Circle",
{
fill: "grey",
stroke: null,
desiredSize: new go.Size(10, 10),
alignment: spot,
alignmentFocus: spot,
portId: name,
fromSpot: spot, toSpot: spot,
fromLinkable: output, toLinkable: input,
cursor: "pointer"
});
}
myDiagram.nodeTemplate =
GO(go.Node, "Spot",
{
selectionAdorned: false, // don't show the standard selection handle
resizable: true, resizeObjectName: "SHAPE", // user can resize the Shape
rotatable: true, rotateObjectName: "SHAPE", // user can rotate the Shape
// without rotating the label
layoutConditions: go.Part.LayoutStandard & ~go.Part.LayoutNodeSized
},
new go.Binding("location", "loc").makeTwoWay(), // TwoWay Binding // Binds diagram and model location with eachother
a = GO(go.Shape,
{
click:click1,
name: "SHAPE",
width: 70, height: 70,
stroke: "#000000",
fill: "transparent",
//angle: 45,
strokeWidth: 1
},
new go.Binding("figure","fig"),
new go.Binding("name_shape", "key"),
new go.Binding("angle", "ang").makeTwoWay(), // Binds diagram and model angle with eachother
// new go.Binding("desiredSize", "size").makeTwoWay(), // Binds diagram and model size with eachother
new go.Binding("geometryString", "geometry").makeTwoWay()),// Binds diagram and model geometry string with eachother
// GO(go.Shape,"Circle", // the "A" port
// { width: 20, height: 20, portId: "A",stroke:null,toSpot: go.Spot.Left}),
/*GO(go.Panel, "Vertical",
GO(go.TextBlock,
new go.Binding("text", "fig")),
GO(go.TextBlock, { stroke: "blue" },
new go.Binding("text", "parameter1", function(p1) { return p1; }).ofObject("SHAPE"))
)*/
// GO(go.Shape, // the "A" port
// { width: 6, height: 6, portId: "A" }),
// four small named ports, one on each side:
makePort("T", go.Spot.Top, false, true),
makePort("L", go.Spot.Left, true, true),
makePort("TL", go.Spot.TopLeft, true, true),
makePort("BL", go.Spot.BottomLeft, true, true),
makePort("R", go.Spot.Right, true, true),
makePort("TR", go.Spot.TopRight, true, true),
makePort("BR", go.Spot.BottomRight, true, true),
makePort("B", go.Spot.Bottom, true, true),
makePort("C",go.Spot.Center,true,true),
{ // handle mouse enter/leave events to show/hide the ports
mouseEnter: function(e, node) { showSmallPorts(node, true); },
mouseLeave: function(e, node) { showSmallPorts(node, false); }
}
);
function showSmallPorts(node, show) {
node.ports.each(function(port) {
if (port.portId !== "") { // don't change the default port, which is the big shape
port.fill = show ? "rgba(0,0,0,.3)" : null;
}
});
我认为这应该符合您的要求:
function init() {
var $ = go.GraphObject.make;
myDiagram =
$(go.Diagram, "myDiagramDiv",
{ initialContentAlignment: go.Spot.Center, "undoManager.isEnabled": true });
myDiagram.nodeTemplate =
$(go.Node, "Spot",
{ selectionObjectName: "BODY" },
new go.Binding("itemArray", "spots"),
{ // each spot is represented by a Panel holding a circular Shape
// at a particular alignment relative to the "BODY"
itemTemplate:
$(go.Panel,
$(go.Shape, "Circle",
{
fill: $(go.Brush, go.Brush.Radial, { 0.0: "gray", 1.0: "transparent" }),
strokeWidth: 0, width: 16, height: 16
}),
new go.Binding("alignment", "spot", go.Spot.parse).makeTwoWay(go.Spot.stringify)
),
// when the user clicks on the node, add a "spot"
click: function(e, obj) {
e.diagram.startTransaction();
// convert click point into Spot in node's bounds
var pt = e.documentPoint; // in document coordinates
var node = obj.part;
var b = node.actualBounds; // will be in document coordinates
var spot = new go.Spot(Math.max(0, Math.min((pt.x - b.x) / b.width, 1)),
Math.max(0, Math.min((pt.y - b.y) / b.height, 1)));
// add an Object describing the spot's location (as a Spot value)
var spotsArray = node.data.spots;
if (!Array.isArray(spotsArray)) spotsArray = node.data.spots = [];
e.diagram.model.addArrayItem(spotsArray, { spot: go.Spot.stringify(spot) });
e.diagram.commitTransaction("added spot");
}
},
$(go.Panel, "Auto",
{ name: "BODY", width: 100, height: 100 },
$(go.Shape, { fill: "whitesmoke" }),
$(go.TextBlock, { editable: true },
new go.Binding("text").makeTwoWay())
)
);
myDiagram.model = $(go.GraphLinksModel,
{
copiesArrays: true, // make sure the data.spots Array is copied
copiesArrayObjects: true, // make sure the Objects in those Arrays are also copied
nodeDataArray: [
{ key: 1, text: "Alpha", spots: [] },
{ key: 2, text: "Beta", spots: [{ spot: "0.3, 0.2" }] }
],
linkDataArray: [
{ from: 1, to: 2 }
]
});
}
执行此操作并单击几个位置的节点会导致:
请注意,"Beta" 节点以一个点开始,如模型数据中所定义。
顺便说一下,我不清楚用户想要添加的 "spots" 真的必须是 "ports"。您可以通过给每个 "spot" 一个 "port" 一个唯一的 GraphObject.portId.
您可能想阅读 GoJS 简介的所有页面,位于 http://gojs.net/latest/intro。