Looking for drag to draw a line similar to DragCreating tool

how can I draw a line similar to how i draw a rectangle with DragCreating tool, i intend to turn on and off this tool just like how drag creating work, achieve data binding of desired size, angle and position.

The DragCreatingTool will create an instance of a Part as determined by the DragCreatingTool.archetypeNodeData and whatever template you have set up for that data.

You could customize the DragCreatingTool.box value to change the appearance and behavior of the temporary Part used by the tool.

I came across this similar example Line Drawing and Reshaping Sample, with arrowheads but the UpdateLineGeometry is making things complicated.

Uncaught TypeError: Cannot read properties of undefined (reading ‘x’)

  • at Function.updateLineGeometry*

var drawLine = function () {

var drawLineToolEnabled = document.getElementById("dragLine").checked;

var tool = _DIAGRAM.toolManager.findTool("LineDrawing");

tool.archetypeNodeData = {

  fill: "transparent",

  stroke: "black",

  strokeWidth: 2,

  opacity: 0.5,

  category: "Line",

};

// // Drect

tool.isEnabled = drawLineToolEnabled;

};


diagram.nodeTemplateMap.add(

  "Line",

  $(

    go.Part,

    {

      reshapable: true, // allow LineReshapingTool to work

      selectionAdorned: false, // binding on Shape.stroke changes color from blue to orange

      locationObjectName: "SHAPE",

      locationSpot: new go.Spot(0, 0, selectionMargin, selectionMargin), // account for strokeWidth

    },

    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(

      go.Point.stringify

    ),

    $(

      go.Shape,

      {

        // this is to make it easier for users to click on this line

        fill: null,

        stroke: "transparent",

        strokeWidth: selectionMargin * 2,

      },

      new go.Binding("geometry").ofObject("SHAPE")

    ), // shares Geometry with "SHAPE"

    $(

      go.Shape,

      {

        // this shows the actual line, thinner than the transparent shape for selection

        name: "SHAPE",

        fill: null,

        stroke: "black",

        strokeWidth: 2,

        position: new go.Point(

          selectionMargin - 1 / 2,

          selectionMargin - 1 / 2

        ),

      },

      new go.Binding("geometry", "pts", _makeGeo).makeTwoWay(_saveGeo),

      new go.Binding("stroke", "isSelected", (s) =>

        s ? "#00D1FF" : "black"

      ).ofObject()

    )

  )

);

var _makeGeo = function (pts) {

// shares a lot of code with LineDrawingTool.updateLineGeometry

var startx = pts[0]; // already in geometry coordinates, not in document coordinates

var starty = pts[1];

var endx = pts[2];

var endy = pts[3];

// determine the offset between document coordinates and geometry coordinates with the origin at the top-left

var lx = Math.min(startx, endx);

var ly = Math.min(starty, endy);

var sx = startx - lx;

var sy = starty - ly;

var ex = endx - lx;

var ey = endy - ly;

// compute the points of the arrowhead at the end

var ang = go.Point.direction(startx, starty, endx, endy);

var p = new go.Point(0, 0).rotate(ang);

var q = new go.Point(0, 0).rotate(ang);

var pe0x = ex + p.x;

var pe0y = ey + p.y;

var pe1x = ex + q.x;

var pe1y = ey + q.y;

// assume the backwards arrowhead at the start is a mirror image of the one at the end

var ps0x = sx - p.x;

var ps0y = sy - p.y;

var ps1x = sx - q.x;

var ps1y = sy - q.y;

var geo = new go.Geometry()

  .add(

    new go.PathFigure(sx, sy, false).add(

      new go.PathSegment(go.PathSegment.Line, ex, ey)

    )

  )

  .add(

    new go.PathFigure(pe0x, pe0y, false)

      .add(new go.PathSegment(go.PathSegment.Line, ex, ey))

      .add(new go.PathSegment(go.PathSegment.Line, pe1x, pe1y))

  )

  .add(

    new go.PathFigure(ps0x, ps0y, false)

      .add(new go.PathSegment(go.PathSegment.Line, sx, sy))

      .add(new go.PathSegment(go.PathSegment.Line, ps1x, ps1y))

  );

geo.normalize();

return geo;

};


var _saveGeo = function (geo) {

var fig = geo.figures.elt(0);

var seg = fig.segments.elt(0);

return [fig.startX, fig.startY, seg.endX, seg.endY];

};

The original sample seems to work well, so you’ll need to debug whatever changes you have made to it.