That depends on what Geometry you are making.
I don’t understand or maybe I am confused now.
I went according to your above comment, is there something still missing ? I just want to be able to draw a simple staright line on layout.
How are you initializing the new Geometry?
Here, makeGeo() and makeNewGeo() are the two methods I am using to intialize and modify the geometry respectively.
drawLine() {
const $ = go.GraphObject.make;
const cxt = this;
const fp: Floorplan = this.floorPlan;
fp.nodeTemplateMap.add("ScaleLineNode", this.makeScaleLineNode());
fp.toolManager.mouseMoveTools.insertAt(
2,
$(DragCreatingTool, {
isEnabled: true, // disabled by the checkbox
delay: 0, // always canStart(), so PanningTool never gets the chance to run
archetypeNodeData: {
stroke: "green",
strokeWidth: 3,
category: "ScaleLineNode",
loc: new go.Point(0, 0),
geo: this.makeGeo(),
},
insertPart(bounds) {
const part = DragCreatingTool.prototype.insertPart.call(this, bounds);
part.data.geo = cxt.makeNewGeo(this.diagram);
const shape: go.Shape = part.findObject('SHAPE') as go.Shape;
const pos = part.data.geo.copy();
part.position.x = - pos.startX - shape.strokeWidth / 2;
part.position.y = - pos.startY - shape.strokeWidth / 2;
//part.position = pos;
return part;
}
}));
}
makeGeo() {
const data = new go.Geometry(go.Geometry.Line);
data.startX = 0;
data.startY = 0;
data.endX = 1;
data.endY = 1;
return data;
}
makeNewGeo(diag) {
const data = new go.Geometry(go.Geometry.Line);
data.startX = diag.firstInput.documentPoint.x;
data.startY = diag.firstInput.documentPoint.y;
data.endX = diag.lastInput.documentPoint.x;
data.endY = diag.lastInput.documentPoint.y;
data.normalize();
return data;
}
So your makeGeo
function always creates a line that goes from top-left to bottom right. Is that what you want?
You are not using the return value from Geometry.normalize to position the Node.
The value of Part.position is immutable. GraphObject | GoJS API
Tried to incorporate everything that you just said, still going nowhere. Can you help me with a sample or some code, I think I may not be understanding you correctly.
archetypeNodeData: {
stroke: "green",
strokeWidth: 3,
category: "ScaleLineNode",
loc: new go.Point(0, 0),
geo: this.makeGeo(fp)
},
insertPart(bounds) {
const part = DragCreatingTool.prototype.insertPart.call(this, bounds);
const shape: go.Shape = part.findObject('SHAPE') as go.Shape;
const obj = part.data.geo.copy();
const pos = new go.Point(obj.startX - shape.strokeWidth / 2, obj.startY - shape.strokeWidth / 2);
part.position = pos;
return part;
}
}));
}
makeGeo(diag) {
const data = new go.Geometry(go.Geometry.Line);
data.startX = diag.firstInput.documentPoint.x;
data.startY = diag.firstInput.documentPoint.y;
data.endX = diag.lastInput.documentPoint.x;
data.endY = diag.lastInput.documentPoint.y;
data.normalize();
return data;
}
I don’t know what all of your requirements are, but here’s my attempt at implementing what I think you are asking for:
<!DOCTYPE html>
<html>
<head>
<title>Minimal GoJS Sample</title>
<!-- Copyright 1998-2020 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="go.js"></script>
<script src="../extensions/DragCreatingTool.js"></script>
<script id="code">
// Customize the DragCreatingTool extension to always draw a simple line.
function DragCreatingLineTool() {
DragCreatingTool.call(this);
this.delay = 0; // always canStart(), so PanningTool never gets the chance to run
this.box =
go.GraphObject.make(go.Part,
{ layerName: "Tool" },
go.GraphObject.make(go.Shape,
{ name: "SHAPE", fill: null, stroke: "cyan", strokeWidth: 2 })
);
this.archetypeNodeData = { category: "Line" };
// reuse two simple Line Geometrys
var slash = new go.Geometry(go.Geometry.Line);
slash.startX = 1;
slash.startY = 0;
slash.endX = 0;
slash.endY = 1;
DragCreatingLineTool.SlashGeometry = slash;
var backslash = new go.Geometry(go.Geometry.Line);
backslash.startX = 0;
backslash.startY = 0;
backslash.endX = 1;
backslash.endY = 1;
DragCreatingLineTool.BackslashGeometry = backslash;
}
go.Diagram.inherit(DragCreatingLineTool, DragCreatingTool);
DragCreatingLineTool.prototype.insertPart = function(bounds) {
var arch = this.archetypeNodeData;
if (arch === null) return null;
// decide whether to use Slash or Backslash
arch.slash = (this.diagram.lastInput.documentPoint.x < this.diagram.firstInput.documentPoint.x);
return DragCreatingTool.prototype.insertPart.call(this, bounds);
}
function init() {
var $ = go.GraphObject.make;
myDiagram =
$(go.Diagram, "myDiagramDiv",
{
"resizingTool.minSize": new go.Size(0, 0), // allow horizontal or vertical lines
"undoManager.isEnabled": true,
"ModelChanged": function(e) { // just for demonstration purposes,
if (e.isTransactionFinished) { // show the model data in the page's TextArea
document.getElementById("mySavedModel").textContent = e.model.toJson();
}
}
});
// install the custom DragCreatingTool
myDiagram.toolManager.mouseMoveTools.insertAt(2, new DragCreatingLineTool());
// The regular node and link templates don't really matter for this demo
myDiagram.nodeTemplateMap.add("Line",
$(go.Node,
{ resizable: true, resizeObjectName: "SHAPE" },
new go.Binding("position", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Shape,
{
name: "SHAPE",
isGeometryPositioned: true,
desiredSize: new go.Size(100, 100),
geometry: DragCreatingLineTool.BackslashGeometry
},
new go.Binding("geometry", "slash", function(slash) {
return slash ? DragCreatingLineTool.SlashGeometry : DragCreatingLineTool.BackslashGeometry;
}),
new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
new go.Binding("stroke", "color"),
new go.Binding("strokeWidth", "thickness"))
));
myDiagram.model = new go.GraphLinksModel(
[
{ key: 1, text: "Alpha", color: "lightblue" },
{ key: 2, text: "Beta", color: "orange" },
{ key: 3, category: "Line", color: "green", thickness: 2 },
{ key: 3, category: "Line", color: "blue", thickness: 4, slash: true }
],
[
{ from: 1, to: 2 }
]);
}
</script>
</head>
<body onload="init()">
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
<textarea id="mySavedModel" style="width:100%;height:250px"></textarea>
</body>
</html>
Hi @walter, apologies for not having to be able to explain my requirement to you clear enough.
Here is what I am looking for -
I want to be able to draw a simple straight line exactly like this on my layout while dragging, I don’t need the measurement it shows though.
This GIF is an example from the wallbuildingtool.ts in Floor Planner .
Although it is an overkill for my requirement to be able to reuse it and it is a gojs Group, A simple gojs Node would suffice in my case, if it is at all possible.
// Customize the DragCreatingTool extension to always draw a simple line.
function DragCreatingLineTool() {
DragCreatingTool.call(this);
// reuse two simple Line Geometrys
var slash = new go.Geometry(go.Geometry.Line);
slash.startX = 1;
slash.startY = 0;
slash.endX = 0;
slash.endY = 1;
DragCreatingLineTool.SlashGeometry = slash;
var backslash = new go.Geometry(go.Geometry.Line);
backslash.startX = 0;
backslash.startY = 0;
backslash.endX = 1;
backslash.endY = 1;
DragCreatingLineTool.BackslashGeometry = backslash;
this.delay = 0; // always canStart(), so PanningTool never gets the chance to run
this.box =
go.GraphObject.make(go.Part,
{ layerName: "Tool" },
go.GraphObject.make(go.Shape,
{
name: "SHAPE",
geometry: DragCreatingLineTool.BackslashGeometry,
fill: null,
stroke: "magenta",
strokeWidth: 2
})
);
this.archetypeNodeData = { category: "Line" };
}
go.Diagram.inherit(DragCreatingLineTool, DragCreatingTool);
DragCreatingLineTool.prototype.isSlash = function() {
var s = this.diagram.firstInput.documentPoint;
var e = this.diagram.lastInput.documentPoint;
return (e.x < s.x && e.y > s.y) || (e.x > s.x && e.y < s.y);
}
DragCreatingLineTool.prototype.doMouseMove = function() {
this.box.elt(0).geometry = this.isSlash() ? DragCreatingLineTool.SlashGeometry : DragCreatingLineTool.BackslashGeometry;
DragCreatingTool.prototype.doMouseMove.call(this);
}
DragCreatingLineTool.prototype.insertPart = function(bounds) {
var arch = this.archetypeNodeData;
if (arch === null) return null;
// decide whether to use Slash or Backslash
arch.slash = this.isSlash();
return DragCreatingTool.prototype.insertPart.call(this, bounds);
}
Thanks, it works.
I have two more questions, how do we make the line selection adornment to be shape of line itself, rather than a rectangle.
And, how do I calculate the actual length of the line drawn ? I have node.actualBounds.width and node.actualBounds.height , but what if the line is not straight ?
https://gojs.net/latest/intro/selection.html
Sorry, but getting the length of a path is not in the Geometry API.
Can calculating the hypotenuse of the rectangle be a potential solution to this ?
If you only care about a Geometry of type Line, yes.
In this case yes, I do only care about it.
Very well then. Thanks.