The MindFusion Forums
Flow Diagramming Components >> Html Canvas & JavaScript >> To highlight a composite node/link/label when selected !
https://mindfusion.eu/Forum/YaBB.pl?num=1552647996

Message started by Kannan Thirumal on Mar 15th, 2019 at 11:06am

Title: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Mar 15th, 2019 at 11:06am
Hi,

I've defined a composite node like this.

OrgChartNode = CompositeNode.classFromTemplate("OrgChartNode",
    {
      component: "GridPanel",
      id: "id",
      rowDefinitions: ["*"],
      columnDefinitions: ["22"],
      children:
        [
          {
            component: "GridPanel",
            rowDefinitions: ["18", "5"],
            columnDefinitions: ["18", "5"],
            children:
              [
                {
                  gridColumn: 0,
                  component: "Image",
                  name: "MainImage",
                  autoProperty: true,
                  location: "MainImage.png",
                  margin: "3",
                  imageAlign: "TopLeft"
                },
                {
                  gridColumn: 0,
                  component: "Image",
                  name: "FirstImage",
                  autoProperty: true,
                  location: "FirstImage.png",
                  margin: "3, 3, 0, 0",
                  imageAlign: "TopLeft"
                },
                {
                  gridColumn: 0,
                  component: "Text",
                  name: "NoOfElementsText",
                  autoProperty: true,
                  text: "title",
                  margin: "3, 40, 0, 0",
                  font: "Verdana 12px",
                  textAlign: "BottomLeft"
                },
              ]
          },
    });

I want to highlight the node when selected. I tried setting stroke like this, but didn't work. Any idea?

    var node = new this.OrgChartNode();

    var compNode = node as CompositeNode;
    compNode.setStroke("#FFFFFF");
    compNode.setStrokeThickness(5);

Regards,
Kannan

Title: Re: To highlight a composite node when selected !
Post by Lyubo on Mar 15th, 2019 at 12:48pm
Hi,

You can add a Rect component to the template, and set its pen and strokeThickness properties:


Code (javascript):
//...
{   
    component: "Rect",
    name: "Background",
    pen: "#FFF",
    strokeThickness: 5
},
//...


If you have more than 1 row/column in the template, you can set its rowSpan/columnSpan properties respectively.

Regards,
Lyubo

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Mar 15th, 2019 at 1:25pm
Hi,

I've defined like this but didn't work. Any idea?

OrgChartNode = CompositeNode.classFromTemplate("OrgChartNode",
    {
      component: "GridPanel",
      id: "id",
      rowDefinitions: ["*"],
      columnDefinitions: ["22"],
      children:
        [
          {
            component: "GridPanel",
            rowDefinitions: ["18", "5"],
            columnDefinitions: ["18", "5"],
            children:
              [
                {
                  gridColumn: 0,
                  component: "Rect",
                  name: "Background",
                  pen: "black",
                  //stroke: "black",
                  strokeThickness: 5,
                },
                {
                  gridColumn: 0,
                  component: "Image",
                  name: "MainImage",
                  autoProperty: true,
                  location: "MainImage.png",
                  margin: "3",
                  imageAlign: "TopLeft"
                },
                {
                  gridColumn: 0,
                  component: "Image",
                  name: "FirstImage",
                  autoProperty: true,
                  location: "FirstImage.png",
                  margin: "3, 3, 0, 0",
                  imageAlign: "TopLeft"
                },
                {
                  gridColumn: 0,
                  component: "Text",
                  name: "NoOfElementsText",
                  autoProperty: true,
                  text: "title",
                  margin: "3, 40, 0, 0",
                  font: "Verdana 12px",
                  textAlign: "BottomLeft"
                },
              ]
          },
    });

Regards,
Kannan

Title: Re: To highlight a composite node when selected !
Post by Lyubo on Mar 19th, 2019 at 11:40am
Hi,

We've adjusted the Tutorial3 sample from the JsDiagram package to show one way you can implement highlighting for CompositeNode. You can download it here.

Regards,
Lyubo

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 11th, 2019 at 12:13pm
Hi,

I'm highlighting the node on selection by the following code,

this.diagram.addEventListener(Event.nodeSelected, (sender, args) => {
      var node = args.getNode();
      this.selectNode(node);
    });

    this.diagram.addEventListener(Event.nodeDeselected, (sender, args) => {
      var node = args.getNode();
      this.deselectNode(node);
    });
  }

  private selectedNode: any;

  private selectNode(node): void {

    var background = node.getComponent("Background");
    background.pen = "Orange";
    background.strokeThickness = 5;
    background.margin.right = -node.bounds.width + 18;
    background.margin.bottom = -node.bounds.height + 12;
    node.invalidate();
  }

  private deselectNode(node): void {
    var background = node.getComponent("Background");
    background.pen = "white";
    background.strokeThickness = 0;
    node.invalidate();
  }

This is working fine. But when selecting another node, the previous node selection is not clearing properly. Please check the attached screen shot Node Selection Background Issue.png.

Also when doing multiple select using mouse drag, the mouse drag is still continuing and it is not releasing. That is the selection rectangle is moving along with the mouse. Please check the attached screen shot Mouse Multi Select Issue.png.

I've uploaded the sample in the below path,

https://drive.google.com/open?id=1yu5xlJn3aqoBzXnKvcrUZ177vETo3M1i

Regards,
Kannan
Node_Selection_Background_Issue.png (Attachment deleted)
Mouse_Multi_Select_Issue.png (Attachment deleted)

Title: Re: To highlight a composite node when selected !
Post by Slavcho on Jun 11th, 2019 at 6:11pm
The "Background" rect from your node template does not fit inside node's Bounds due to the fixed row/column sizes, and latest version repaints only the area of node.Bounds, so the rect's part that sticks out doesn't get refreshed. Try using * instead of fixed sizes in row/col definitions to make the rows and columns resize with the node.

Actually I'm not seeing any reason for the nested grids in the template.txt and using two rows and columns if you only need to display a rectangle with image inside; try a single SimplePanel having the Rect and Image components as its children.

Alternatively if you really need the frame rectangle to be drawn outside of node.Bounds, you will have to override the DiagramNode.getRepaintBounds method and return a larger rectangle.

The selection will keep getting drawn if some error happens during processing of mouse-up events. Try enabling stop-on-error in your browser's debugger and check the top of the call stack to see what's wrong.

Regards,
Slavcho
Mindfusion

Title: Re: To highlight a composite node when selected !
Post by Lyubo on Jun 12th, 2019 at 8:00am

Kannan Thirumal wrote on Jun 11th, 2019 at 12:13pm:
Also when doing multiple select using mouse drag, the mouse drag is still continuing and it is not releasing. That is the selection rectangle is moving along with the mouse. Please check the attached screen shot Mouse Multi Select Issue.png.


Hi,

The selection stops, because the interaction goes out of the bounds of the diagram canvas. To prevent that, set a bigger bounds rectangle for the diagram.

Regards,
Lyubo

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 13th, 2019 at 11:49am
Hi,

     I increased the width/height of canvas and tried. Still same is happening.

     Please check the sample to reproduce the issue: https://drive.google.com/open?id=1yu5xlJn3aqoBzXnKvcrUZ177vETo3M1i

Regards,
Kannan

Title: Re: To highlight a composite node when selected !
Post by Slavcho on Jun 14th, 2019 at 9:37am
Hi,

You can make the diagram's area larger by calling diagram.setBounds(new Rect(...)); Assigning canvas element's width and height will have no effect since the Bounds value overwrites them.

Regards,
Slavcho

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 17th, 2019 at 6:37am
Hi,

This is happening because of the node highlight-logic below,

this.diagram.addEventListener(Event.nodeSelected, (sender, args) => {
      var node = args.getNode();
      this.selectNode(node);
    });

    this.diagram.addEventListener(Event.nodeDeselected, (sender, args) => {
      var node = args.getNode();
      this.deselectNode(node);
    });
  }

  private selectNode(node): void {

    var background = node.getComponent("Background");
    background.pen = "Orange";
    background.strokeThickness = 5;
    background.margin.right = -node.bounds.width + 18;
    background.margin.bottom = -node.bounds.height + 12;
    node.invalidate();
  }

  private deselectNode(node): void {
    var background = node.getComponent("Background");
    background.pen = "white";
    background.strokeThickness = 0;
    node.invalidate();
  }

This was suggested on this post on Mar 19th, 2019 at 12:40pm.

Is there any other way to highlight a selected node?

I'm not sure the below code also not working for node selection?

    var compNode = node as CompositeNode;

    compNode.setStroke("#FFFFFF");
    compNode.setStrokeThickness(5);

Regards,
Kannan

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 17th, 2019 at 12:42pm
Hi,

After setting diagram bounds also I'm having the same issue. I've attached the sample to reproduce the issue. Please check it,

     https://drive.google.com/open?id=1LL3Ev1_gEdohu3kJGqW8UXNmWLJ2OnCw

Regards,
Kannan


Slavcho wrote on Jun 14th, 2019 at 9:37am:
Hi,

You can make the diagram's area larger by calling diagram.setBounds(new Rect(...)); Assigning canvas element's width and height will have no effect since the Bounds value overwrites them.

Regards,
Slavcho


Title: Re: To highlight a composite node when selected !
Post by Lyubo on Jun 17th, 2019 at 1:06pm
Hi,

You can make the highlight utilizing the custom drawing adjustment handles technique:


Code (javascript):
// Subscribe to the drawAdjustmentHandles and hitTestAdjustmentHandles events.
diagram.addEventListener(MindFusion.Diagramming.Events.drawAdjustmentHandles, onDrawHandles);
diagram.addEventListener(MindFusion.Diagramming.Events.hitTestAdjustmentHandles, onHitTestHandles);

// ...

// drawAdjustmentHandles handler
function onDrawHandles(sender, args)
{
     var bounds = args.node.getBounds();
     var context = args.context;
     var size = args.node.parent.getAdjustmentHandlesSize();
     var halfsize = size / 2;

     // draw the highlight
     context.save();
     context.fillStyle = "#ce0000"; //highlight brush
     context.fillRect(bounds.x - halfsize, bounds.y - halfsize, bounds.width + size, size);
     context.fillRect(bounds.x - halfsize, bounds.y - halfsize, size, bounds.height + size);
     context.fillRect(bounds.x - halfsize, bounds.y + bounds.height - halfsize, bounds.width + size, size);
     context.fillRect(bounds.x + bounds.width - halfsize, bounds.y - halfsize, size, bounds.height + size);
     context.restore();

     // Draw the regular handles
     args.node.handlesStyle = MindFusion.Diagramming.HandlesStyle.SquareHandles;
     MindFusion.Diagramming.HandleUtils.drawSquareHandles(context, args.node);
     args.node.handlesStyle = MindFusion.Diagramming.HandlesStyle.Custom;
}

// hitTestAdjustmentHandles handler
function onHitTestHandles(sender, args)
{
     var node = args.node;
     var mousePosition = args.mousePosition;

     // Temporarily set the handles style to default to perform hit-testing
     args.node.handlesStyle = MindFusion.Diagramming.HandlesStyle.SquareHandles;
     var result = MindFusion.Diagramming.HandleUtils.pointInHandle(mousePosition, node);
     args.node.handlesStyle = MindFusion.Diagramming.HandlesStyle.Custom;

     if (result)
           return args.setAdjustmentHandle(result.index);
}

// ...

// set the item's handles style
node.setHandlesStyle(MindFusion.Diagramming.HandlesStyle.Custom);


The HandleUtils class is currently not available in the TypeScript definitions file, so you'll need to add it via declaration merging.

Regards,
Lyubo

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 17th, 2019 at 1:33pm
Hi,

I'm getting this compile error,

ERROR in src/app/diagram/diagram.component.ts(85,28): error TS2339: Property 'HandleUtils' does not exist on type 'typeof Diagramming'.
src/app/diagram/diagram.component.ts(96,41): error TS2339: Property 'HandleUtils' does not exist on type 'typeof Diagramming'.

Please help me to fix this.

Regards,
Kannan

Title: Re: To highlight a composite node when selected !
Post by Lyubo on Jun 17th, 2019 at 2:16pm

Kannan Thirumal wrote on Jun 17th, 2019 at 12:42pm:
Hi,

After setting diagram bounds also I'm having the same issue. I've attached the sample to reproduce the issue. Please check it,

     https://drive.google.com/open?id=1LL3Ev1_gEdohu3kJGqW8UXNmWLJ2OnCw

Regards,
Kannan


Your application gives error, because you're calling getComponent method on DiagramNode and ShapeNode. This method is available only on CompositeNode. That's why the selection can't complete.

Title: Re: To highlight a composite node when selected !
Post by Lyubo on Jun 17th, 2019 at 4:13pm

Kannan Thirumal wrote on Jun 17th, 2019 at 1:33pm:
Hi,

I'm getting this compile error,

ERROR in src/app/diagram/diagram.component.ts(85,28): error TS2339: Property 'HandleUtils' does not exist on type 'typeof Diagramming'.
src/app/diagram/diagram.component.ts(96,41): error TS2339: Property 'HandleUtils' does not exist on type 'typeof Diagramming'.

Please help me to fix this.

Regards,
Kannan


Hi,

You can use standard TypeScript declaration merging like this:

Code (javascript):
declare module "diagram-library"
{
     namespace Diagramming
     {
           class HandleUtils
           {
                 drawSquareHandles(context: CanvasRenderingContext2D, item: MindFusion.Diagramming.DiagramItem): void;
                 pointInHandle(point: MindFusion.Drawing.Point, item: MindFusion.Diagramming.DiagramItem) : number;
           }
     }
}


If that doesn't work in your setup, you can always cast to any to avoid the compile-time errors, i.e. replace the HandleUtils calls in the example in the previous post with:

Code (javascript):
//...

(MindFusion.Diagramming["HandleUtils"] as any).drawSquareHandles(context, args.node);

//...
var result = (MindFusion.Diagramming["HandleUtils"] as any).pointInHandle(mousePosition, node);
//...


Regards,
Lyubo


Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 18th, 2019 at 4:34am
Oh. That is the root cause :-( Thank you LyuBO :-)


Lyubo wrote on Jun 17th, 2019 at 2:16pm:

Kannan Thirumal wrote on Jun 17th, 2019 at 12:42pm:
Hi,

After setting diagram bounds also I'm having the same issue. I've attached the sample to reproduce the issue. Please check it,

     https://drive.google.com/open?id=1LL3Ev1_gEdohu3kJGqW8UXNmWLJ2OnCw

Regards,
Kannan


Your application gives error, because you're calling getComponent method on DiagramNode and ShapeNode. This method is available only on CompositeNode. That's why the selection can't complete.


Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 19th, 2019 at 7:19am
Hi,

May I know how to override the DiagramNode.getRepaintBounds method? I tried but didn't work. Please let me know.

this.DiagramNode = MyCompositeNode.classFromTemplate("DiagramNode", template);

class MyCompositeNode extends CompositeNode {

  constructor() {

    super();
  }

  getRepaintBounds(): MindFusion.Drawing.Rect {

    var bounds = super.getRepaintBounds();

    var newBounds = new Rect(bounds.x - 5, bounds.y - 5, bounds.width + 5, bounds.height + 5);

    return newBounds;
  }

  static classFromTemplate(className: string, jsonTemplate: any): any {

    var class1 = super.classFromTemplate(className, jsonTemplate);

    return class1;
  }
}

Also I'm not sure why the below code is not working?

    var node = new this.DiagramNode();

    var compNode = node as CompositeNode;
    compNode.setStroke("Blue");
    compNode.setStrokeThickness(5);

Regards,
Kannan


Slavcho wrote on Jun 11th, 2019 at 6:11pm:
The "Background" rect from your node template does not fit inside node's Bounds due to the fixed row/column sizes, and latest version repaints only the area of node.Bounds, so the rect's part that sticks out doesn't get refreshed. Try using * instead of fixed sizes in row/col definitions to make the rows and columns resize with the node.

Actually I'm not seeing any reason for the nested grids in the template.txt and using two rows and columns if you only need to display a rectangle with image inside; try a single SimplePanel having the Rect and Image components as its children.

Alternatively if you really need the frame rectangle to be drawn outside of node.Bounds, you will have to override the DiagramNode.getRepaintBounds method and return a larger rectangle.

The selection will keep getting drawn if some error happens during processing of mouse-up events. Try enabling stop-on-error in your browser's debugger and check the top of the call stack to see what's wrong.

Regards,
Slavcho
Mindfusion


Title: Re: To highlight a composite node when selected !
Post by Lyubo on Jun 19th, 2019 at 12:39pm
Hi,

You can override the getRepaintBounds method like this:

Code (javascript):
// ...

// Call inside your ngAfterViewInit for example
var originalGetRotatedBounds = CompositeNode.prototype.getRepaintBounds;
CompositeNode.prototype.getRepaintBounds = function()
{
     var bounds = originalGetRotatedBounds.apply(this, []);
     var newBounds = new Rect(bounds.x - 5, bounds.y - 5, bounds.width + 10, bounds.height + 10);
     return newBounds;
};

//...
this.DiagramNode = CompositeNode.classFromTemplate("DiagramNode", template);
//...


Regards,
Lyubo

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 20th, 2019 at 9:46am
Hi,

     Thank you. It works ! Like highlighting node, I need to highlight selected link too. ie when selected the link, need to change the size and color of the control points. May I know how to do that? Thank you !

Regards,
Kannan

Title: Re: To highlight a composite node when selected !
Post by Lyubo on Jun 20th, 2019 at 12:58pm
Hi,

Custom drawing of links' adjustment handles is not supported out of the box, but you can achieve it by overriding the DiagramLink.drawHandles method and customize the fill, stroke, thickness, size, etc. of the handles:

Code (java):
MindFusion.Diagramming.DiagramLink.prototype["drawHandles"] = function (context)
{
    context.fillStyle = "yellow"; // handle background
    context.strokeStyle = "red"; // handle stroke
    if (context.setLineDash)
        context.setLineDash([]);
    context.lineWidth = 2 / context._mf_scale; // handle stroke thickness

    var size = this.getEffectiveHandlesSize() * 1.5; // handle size
    var hsize = size / 2;

    // the side and corner handles
    for (var i = 0; i < this.points.length; i++)
    {
        var point = this.points[i];

        if (i % 3 > 0 || this.shape != MindFusion.Diagramming.LinkShape.Bezier)
        {
            context.fillRect(point.x - hsize, point.y - hsize, size, size);
            context.strokeRect(point.x - hsize, point.y - hsize, size, size);
        }
        else
        {
            MindFusion.Diagramming.HandleUtils.drawCircle(context, point, hsize);
        }
    }
};


Regards,
Lyubo

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 24th, 2019 at 7:36am
Hi,

I'm getting a weird behavior. ie selection is not happening for the FIRST created node.

Please see the attached screen shot.

Also please download the sample code from this path,

https://drive.google.com/open?id=1yu5xlJn3aqoBzXnKvcrUZ177vETo3M1i

Regards,
Kannan


Lyubo wrote on Jun 19th, 2019 at 12:39pm:
Hi,

You can override the getRepaintBounds method like this:

Code (javascript):
// ...

// Call inside your ngAfterViewInit for example
var originalGetRotatedBounds = CompositeNode.prototype.getRepaintBounds;
CompositeNode.prototype.getRepaintBounds = function()
{
     var bounds = originalGetRotatedBounds.apply(this, []);
     var newBounds = new Rect(bounds.x - 5, bounds.y - 5, bounds.width + 10, bounds.height + 10);
     return newBounds;
};

//...
this.DiagramNode = CompositeNode.classFromTemplate("DiagramNode", template);
//...


Regards,
Lyubo


First_Node_Not_Selected.png (Attachment deleted)

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 24th, 2019 at 7:43am

Kannan Thirumal wrote on Jun 24th, 2019 at 7:36am:
Hi,

I'm facing an odd behavior. ie selection is not happening for the FIRST created node.

Sample-1 :

    this.createCompositeNode(diagramElement1);
    this.createCompositeNode(diagramElement2);
    this.createCompositeNode(diagramElement3);
    this.createCompositeNode(diagramElement21);
    this.createCompositeNode(diagramElement22);
    this.createShapeNode(shapeElement1);
    this.createShapeNode(shapeElement2);

Sample-2:

    this.createCompositeNode(diagramElement2);
    this.createCompositeNode(diagramElement1);
    this.createCompositeNode(diagramElement3);
    this.createCompositeNode(diagramElement21);
    this.createCompositeNode(diagramElement22);
    this.createShapeNode(shapeElement1);
    this.createShapeNode(shapeElement2);

Please see the attached screen shot for Sample-1 and Sample-2.

Also please download the sample code from this path,

https://drive.google.com/open?id=1yu5xlJn3aqoBzXnKvcrUZ177vETo3M1i

Regards,
Kannan


Lyubo wrote on Jun 19th, 2019 at 12:39pm:
Hi,

You can override the getRepaintBounds method like this:

Code (javascript):
// ...

// Call inside your ngAfterViewInit for example
var originalGetRotatedBounds = CompositeNode.prototype.getRepaintBounds;
CompositeNode.prototype.getRepaintBounds = function()
{
     var bounds = originalGetRotatedBounds.apply(this, []);
     var newBounds = new Rect(bounds.x - 5, bounds.y - 5, bounds.width + 10, bounds.height + 10);
     return newBounds;
};

//...
this.DiagramNode = CompositeNode.classFromTemplate("DiagramNode", template);
//...


Regards,
Lyubo



Sample1-First_Node_Not_Selected.png (Attachment deleted)
Sample2-First_Node_Not_Selected.png (Attachment deleted)

Title: Re: To highlight a composite node when selected !
Post by Lyubo on Jun 24th, 2019 at 8:40am
Hi,

Are you sure you've linked the correct sample code above? I've downloaded it and it appears it's the first version of the application we already had and I can't find or reproduce the issue you've described.

Regards,
Lyubo

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 24th, 2019 at 8:54am
Sorry Lyubo, could you please check this?

https://drive.google.com/open?id=11O8F1N3c7ekyIUk5FX1-OrDDTd8jVU77


Lyubo wrote on Jun 24th, 2019 at 8:40am:
Hi,

Are you sure you've linked the correct sample code above? I've downloaded it and it appears it's the first version of the application we already had and I can't find or reproduce the issue you've described.

Regards,
Lyubo


Title: Re: To highlight a composite node when selected !
Post by Lyubo on Jun 24th, 2019 at 11:38am
Hi,

The first node gets deselected in your getCurrentSelectedDiagramElement method. You need to either refactor it to handle the multiple selection, or just rely on the NodeSelected and NodeDeselected event handling, that you already use.

Regards,
Lyubo

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 24th, 2019 at 1:42pm
Hi Lyubo,

     Thank you for helping me to find the root cause. Will fix that!

Regards,
Kannan


Lyubo wrote on Jun 24th, 2019 at 11:38am:
Hi,

The first node gets deselected in your getCurrentSelectedDiagramElement method. You need to either refactor it to handle the multiple selection, or just rely on the NodeSelected and NodeDeselected event handling, that you already use.

Regards,
Lyubo


Title: Re: To highlight a composite node/link when selected !
Post by Kannan Thirumal on Jun 26th, 2019 at 7:40am
Hi Lyubo,

This works! Thank you!

When I click the link, the points are shown and I'm able to customize the points now. That is fine. But when I mouse hover the link, the points are not shown. May I know how to show link points on mouse over and how to customize those points?

Regards,
Kannan


Lyubo wrote on Jun 20th, 2019 at 12:58pm:
Hi,

Custom drawing of links' adjustment handles is not supported out of the box, but you can achieve it by overriding the DiagramLink.drawHandles method and customize the fill, stroke, thickness, size, etc. of the handles:

Code (java):
MindFusion.Diagramming.DiagramLink.prototype["drawHandles"] = function (context)
{
    context.fillStyle = "yellow"; // handle background
    context.strokeStyle = "red"; // handle stroke
    if (context.setLineDash)
        context.setLineDash([]);
    context.lineWidth = 2 / context._mf_scale; // handle stroke thickness

    var size = this.getEffectiveHandlesSize() * 1.5; // handle size
    var hsize = size / 2;

    // the side and corner handles
    for (var i = 0; i < this.points.length; i++)
    {
        var point = this.points[i];

        if (i % 3 > 0 || this.shape != MindFusion.Diagramming.LinkShape.Bezier)
        {
            context.fillRect(point.x - hsize, point.y - hsize, size, size);
            context.strokeRect(point.x - hsize, point.y - hsize, size, size);
        }
        else
        {
            MindFusion.Diagramming.HandleUtils.drawCircle(context, point, hsize);
        }
    }
};


Regards,
Lyubo


Title: Re: To highlight a composite node when selected !
Post by Lyubo on Jun 26th, 2019 at 12:23pm
Hi,

You can set the ModificationStart property to AutoHandles. That will show the handles on mouse hover:

Code (javascript):
diagram.setModificationStart(MindFusion.Diagramming.ModificationStart.AutoHandles);


Regards,
Lyubo

Title: Re: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Jun 26th, 2019 at 12:44pm
Hi Lyubo,

Thank you! It works.

May I know how to customize the node label which I've attached to the node like this. Points are displayed on mouse over and selection. But, for points, I need to fill color on mouse over and need to change border color on selection of the label (similar to link selection).

  private createCompositeNode(diagramElement: DiagramElement): CompositeNode {

    var node = new this.DiagramNode();

    node.setBounds(new Rect(diagramElement.x, diagramElement.y, diagramElement.width, diagramElement.height));
    node.setMainImage(diagramElement.imageSource);
    node.setHandlesStyle(common.Diagramming.HandlesStyle.EasyMove);

    var compNode = node as CompositeNode;
    var mainImageComponent = compNode.getComponent("MainImage") as any;
    mainImageComponent.image.width = diagramElement.width;
    mainImageComponent.image.height = diagramElement.height;

    node.setHandlesStyle(MindFusion.Diagramming.HandlesStyle.Custom);

    this.diagram.addItem(node);

    var nodeName = this.addNodeName(this.diagram, diagramElement);

    this.diagram.addItem(nodeName);
    node.attach(nodeName);

    return compNode;
  }

  private addNodeName(diagram: Diagram, diagramElement: DiagramElement): ShapeNode {

    var nameNode = diagram.getFactory().createShapeNode(diagramElement.x, diagramElement.y + 60, 50, 20);

    nameNode.setEnableStyledText(true);
    nameNode.setText(diagramElement.name);
    nameNode.setFont(new Font("Verdana", 10));
    nameNode.setAllowOutgoingLinks(false);
    nameNode.setAllowIncomingLinks(false);
    nameNode.setTransparent(true);
    nameNode.setHandlesStyle(common.Diagramming.HandlesStyle.EasyMove);
    nameNode.setStroke("Orange");
    nameNode.setStrokeThickness(5);

    return nameNode;
  }

Regards,
Kannan


Lyubo wrote on Jun 26th, 2019 at 12:23pm:
Hi,

You can set the ModificationStart property to AutoHandles. That will show the handles on mouse hover:

Code (javascript):
diagram.setModificationStart(MindFusion.Diagramming.ModificationStart.AutoHandles);


Regards,
Lyubo


Node_Label_Selection.png (Attachment deleted)

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jun 26th, 2019 at 1:08pm
Hi,

This works but the mouse over and selection are same. But I need different colors as attached sample image.

Mouse Over : Gray Filled
Selection : Orange Border

Regards,
Kannan


Lyubo wrote on Jun 26th, 2019 at 12:23pm:
Hi,

You can set the ModificationStart property to AutoHandles. That will show the handles on mouse hover:

Code (javascript):
diagram.setModificationStart(MindFusion.Diagramming.ModificationStart.AutoHandles);


Regards,
Lyubo


Node_Label-Mouse_Over.png (Attachment deleted)
Node_Label-Selection.png (Attachment deleted)

Title: Re: To highlight a composite node when selected !
Post by Lyubo on Jun 27th, 2019 at 5:56am

Kannan Thirumal wrote on Jun 26th, 2019 at 1:08pm:
Hi,

This works but the mouse over and selection are same. But I need different colors as attached sample image.

Mouse Over : Gray Filled
Selection : Orange Border

Regards,
Kannan


Hi,

Just check if the link is selected in your drawHandles override and apply the needed fill/stroke brushes:

Code (java):
if (this.getSelected())
{
    context.fillStyle = "yellow"; // handle background
    context.strokeStyle = "orange"; // handle stroke
}
else
{
    context.fillStyle = "gray"; // handle background
    context.strokeStyle = "black"; // handle stroke
}


The above code will work only if the ModificationStart property is set to AutoHandles - or the handles will show only for selection - so the else condition will never be fulfilled if not set.

Regards,
Lyubo

Title: Re: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Jun 27th, 2019 at 2:17pm
Hi Lyubo,

Thanks ! It works ! I tried the same for node label like this. But I couldn't find similar to "this.points". May I know how to fix this? I need the similar behavior which is attached with this.

    ShapeNode.prototype["drawHandles"] = function (context) {

      if (this.getSelected()) {
        context.fillStyle = "Transparent"; // handle background
        context.strokeStyle = "Orange"; // handle stroke
      }
      else {
        context.fillStyle = "LightGray"; // handle background
        context.strokeStyle = "LightGray"; // handle stroke
      }

      if (context.setLineDash)
        context.setLineDash([]);
      context.lineWidth = 1.5; // 2 / context._mf_scale; // handle stroke thickness

      var size = this.getEffectiveHandlesSize() * 2; // handle size
      var hsize = size / 2;

      // the side and corner handles
      for (var i = 0; i < this.points.length; i++) {
        var point = this.points[i];

        if (i % 3 > 0 || this.shape != MindFusion.Diagramming.LinkShape.Bezier) {
          context.fillRect(point.x - hsize, point.y - hsize, size, size);
          context.strokeRect(point.x - hsize, point.y - hsize, size, size);
        }
        else {
          (MindFusion.Diagramming["HandleUtils"] as any).drawCircle(context, point, hsize);
        }
      }
    };

I've attached a label (another ShapeNode) for the node like this,

  private createCompositeNode(diagramElement: DiagramElement): CompositeNode {

    var node = new this.DiagramNode();

    node.setBounds(new Rect(diagramElement.x, diagramElement.y, diagramElement.width, diagramElement.height));
    node.setMainImage(diagramElement.imageSource);
    node.setHandlesStyle(common.Diagramming.HandlesStyle.Invisible);

    var compNode = node as CompositeNode;
    var mainImageComponent = compNode.getComponent("MainImage") as any;
    mainImageComponent.image.width = diagramElement.width;
    mainImageComponent.image.height = diagramElement.height;

    this.diagram.addItem(node);

    var nodeName = this.addNodeName(this.diagram, diagramElement);

    this.diagram.addItem(nodeName);
    node.attach(nodeName);

    return compNode;
  }

  private addNodeName(diagram: Diagram, diagramElement: DiagramElement): ShapeNode {

    var nameNode = diagram.getFactory().createShapeNode(diagramElement.x, diagramElement.y + 60, 50, 20);

    nameNode.setEnableStyledText(true);
    nameNode.setText(diagramElement.name);
    nameNode.setFont(new Font("Verdana", 10));
    nameNode.setAllowOutgoingLinks(false);
    nameNode.setAllowIncomingLinks(false);
    nameNode.setTransparent(true);
    nameNode.setHandlesStyle(common.Diagramming.HandlesStyle.SquareHandles);
    nameNode.setStroke("Blue");
    nameNode.setStrokeThickness(5);

    return nameNode;
  }

Regards,
Kannan
Node_Label-Mouse_Over_001.png (Attachment deleted)
Node_Label-Selection_001.png (Attachment deleted)

Title: Re: To highlight a composite node/link/label when selected !
Post by Lyubo on Jul 1st, 2019 at 5:37am
Hi,

A ShapeNode instance doesn't have a points member, as it doesn't have control points like links do. It uses entirely different method to draw the adjustment handles, and that's the method you need to override.

Try this:

Code (javascript):
var originalDrawSH = MindFusion.Diagramming.HandleUtils["drawSquareHandles"];
MindFusion.Diagramming.HandleUtils["drawSquareHandles"] = function (context, item)
{
     if (!MindFusion.AbstractionLayer.isInstanceOfType(MindFusion.Diagramming.ShapeNode, item))
     {
           originalDrawSH.apply(this, [context, item]);
           return;
     }

     var AdjustmentHandles = MindFusion.Diagramming.AdjustmentHandles;
     var HandlesStyle = MindFusion.Diagramming.HandlesStyle;

     var bounds = item.getBounds();
     var diagram = item.getParent();
     var showDisabled = diagram.getShowDisabledHandles();
     var center = bounds.center();
     var size = item.getEffectiveHandlesSize();
     var hsize = size / 2;
     var style = item.getHandlesStyle();
     var mask = item.getEnabledHandles();

     // Calculate selection handles coordinates
     var mm = MindFusion.Drawing.GraphicsUnit.getMillimeter(diagram.measureUnit);
     var handlePoints = MindFusion.Diagramming.HandleUtils.getHandlePositions(bounds, mm);

     if (item.getSelected())
     {
           context.fillStyle = "Transparent"; // handle background
           context.strokeStyle = "Orange"; // handle stroke
     }
     else
     {
           context.fillStyle = "LightGray"; // handle background
           context.strokeStyle = "LightGray"; // handle stroke
     }
     context.lineWidth = 1 / context._mf_scale;

     // the rotation handle first, so the line connecting top center and rotation is below
     if ((mask & AdjustmentHandles.Rotate) != 0)
           MindFusion.Diagramming.HandleUtils["drawRotationHandle"](context, item);

     // The side and corner handles
     for (var h = 0; h < 9; h++)
     {
           var disabled = (mask & (1 << h)) == 0;
           if (disabled && !showDisabled)
                 continue;

           var point = handlePoints[h];

           if (h == 8)
           {
                 if (style == HandlesStyle.EasyMove)
                 {
                       MindFusion.Diagramming.HandleUtils["drawCircle"](context, point, size);
                       continue;
                 }
                 if (style != HandlesStyle.SquareHandles)
                       continue;
           }

           context.fillRect(point.x - hsize, point.y - hsize, size, size);
           context.strokeRect(point.x - hsize, point.y - hsize, size, size);
     }
};


Regards,
Lyubo

Title: Re: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Jul 1st, 2019 at 6:09am
Thank you Lyubo ! It works !

Title: Re: To highlight a composite node when selected !
Post by Kannan Thirumal on Jul 1st, 2019 at 6:16am

Lyubo wrote on Jun 26th, 2019 at 12:23pm:
Hi,

You can set the ModificationStart property to AutoHandles. That will show the handles on mouse hover:

Code (javascript):
diagram.setModificationStart(MindFusion.Diagramming.ModificationStart.AutoHandles);


Regards,
Lyubo


Hi,

I did this and it works. But after that, when mouse over on the NODE, the mouse pointer changes to "Move" style. May I know why?

Regards,
Kannan

Title: Re: To highlight a composite node/link/label when selected !
Post by Lyubo on Jul 1st, 2019 at 7:25am
Hi,

You've probably set the nodes' handles style to EasyMove. The purpose of the adjustment handles is to allow users to interact with items. The move cursor shows, because when EasyMove is in effect, any point of the interior of a node enables moving the node, except a small area in the center that allows creating links.

Regards,
Lyubo

Title: Re: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Jul 1st, 2019 at 7:37am
Hi,

No, I've set the handle style as Invisible like this,

node.setHandlesStyle(common.Diagramming.HandlesStyle.Invisible);

I've uploaded sample code,

https://drive.google.com/open?id=1_9cJaNeL-tezTR4IQmUFb3siWaIlEvgC

Regards,
Kannan

Title: Re: To highlight a composite node/link/label when selected !
Post by Lyubo on Jul 1st, 2019 at 10:35am
Hi,

Invisible handles behave in the same way - they are not shown, but users can still interact with the nodes - hence you see the move cursor. If you want to not show the handles and preserve the interactions, you can use Custom handles and custom drawing we showed you several posts back. Just don't call the original square handles drawing code that our example showed.

Regards,
Lyubo

Title: Re: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Jul 29th, 2019 at 12:21pm
Hi,

     In some cases, I don't want to do multiple selection of nodes on mouse drag. ie don't need to show the selection rectangle which moves along with mouse pointer.

But multi selection should happen on Ctrl + Click on nodes.

Regards,
Kannan

Title: Re: To highlight a composite node/link/label when selected !
Post by Lyubo on Jul 29th, 2019 at 1:34pm
Hi,

Are you using Behavior.Modify? It shows the selection rectangle on mouse down+move. You can override the createController method, check if a selection controller will be returned and return it only when you want to show the selection:

Code (javascript):
var originalCreate = MindFusion.Diagramming.ModifyBehavior.prototype.createController;
MindFusion.Diagramming.ModifyBehavior.prototype.createController = function (state)
{
     var controller = originalCreate.apply(this, [state]);

     if (MindFusion.AbstractionLayer.isInstanceOfType(MindFusion.Diagramming.CreateSelectionController, controller))
     {
           // determine if the selection rectangle needs to be shown and return the controller
           if (makeSelectRect)
                 return controller;
           else
                 return null;
     }

        return controller;
};


Regards,
Lyubo

Title: Re: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Jul 30th, 2021 at 6:38pm
Hi,

I've two components FlowDiagramComponent and TreeDiagramComponent displayed in two tabs.

In the first tab component FlowDiagramComponent, I've defined the drawSquareHandles.

When I do something on the TreeDiagramComponent (second tab) like mouse over on the text "Node # 1" or drag the child node "P1" or the whole node itself, I'm getting the below error in drawSquareHandles of first component FlowDiagramComponent .

core.js:4002 ERROR TypeError: Cannot read property 'handleStroke' of undefined
    at Object.drawSquareHandles (MindFusion.Diagramming.js:6)
    at Object.MindFusion.Diagramming.HandleUtils.drawSquareHandles (diagram.component.ts:454)
    at Object.drawAdjustmentHandles (MindFusion.Diagramming.js:6)
    at InputParametersNode.drawHandles (MindFusion.Diagramming.js:6)
    at adH.<computed>.drawForeground (MindFusion.Diagramming.js:6)
    at adH.<computed>.repaint (MindFusion.Common.js:6)
    at cQ (MindFusion.Common.js:6)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:26247)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)

May I know how to fix this?

I've uploaded the sample app to reproduce this issue:

https://drive.google.com/file/d/17q1JNEzEi2tqHA2c1PhtD1aGUomBlDyB/view?usp=sharing

Regards,
Kannan
Error_handleStroke.png (Attachment deleted)

Title: Re: To highlight a composite node/link/label when selected !
Post by Lyubo on Aug 2nd, 2021 at 6:11am
Hi,

The HandleUtils.drawSquareHandles method expects a third parameter, which is omitted from the declaration override.

Adding the missing parameter and passing it to the original function would look like this in your code:

Code (javascript):
declare module "diagram-library"
{
  namespace Diagramming {
    class HandleUtils {
      static drawSquareHandles(context: CanvasRenderingContext2D, item: MindFusion.Diagramming.DiagramItem, handlesVisualStyle: any): void;

//...

var originalDrawSquareHandles = MindFusion.Diagramming.HandleUtils.drawSquareHandles;
    MindFusion.Diagramming.HandleUtils.drawSquareHandles = function (context: any, item: any, handlesVisualStyle: any) {
      if (!MindFusion.AbstractionLayer.isInstanceOfType(MindFusion.Diagramming.ShapeNode, item)) {
        originalDrawSquareHandles.apply(this, [context, item, handlesVisualStyle]);
        return;
      }

// ...


Regards,
Lyubo
MindFusion

Title: Re: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Aug 2nd, 2021 at 10:36am
Hi,

This looks fine. No 'undefined handleStroke' error now. But still the event is raised in first component when ui operation happens in second component. Is there a way to avoid this?

Regards,
Kannan

Title: Re: To highlight a composite node/link/label when selected !
Post by Lyubo on Aug 2nd, 2021 at 10:59am
Hi,

Which event is raised? Or do you mean the drawSquareHandles method? If you mean the latter, your override in the FlowDiagramComponent will be called in each instance, since you override the library function itself.

If you need it to execute only for your FlowDiagramComponent and not for your TreeDiagramComponent, you can check the context argument (this is the canvas element 2d context), or the item's parent - this will be the diagram instance in your case.

Regards,
Lyubo
MindFusion

Title: Re: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Aug 2nd, 2021 at 11:10am
Hi,

Yes, I mean the drawSquareHandles method. This is overridden inside the FlowDiagramComponent (ngAfterViewInit method). But this method is called when ui node changes happens in the TreeDiagramComponent. Is this method override is common for all the code in the app? Is there any way to restrict to one component? For example, in the future, if I want to do drawSquareHandles in a different way for different component.

Regards,
Kannan

Title: Re: To highlight a composite node/link/label when selected !
Post by Lyubo on Aug 2nd, 2021 at 11:27am
Hi,

When you override a prototype method or as it is the case with drawSquareHandles - a static function - it effectively replaces that method in the library itself and is called in each instance.

In most cases it's easy enough to distinguish which component called the particular method. I wrote as an edit to my previous post (you might have missed it), in the case with drawSquareHandles you can check the context.canvas element (for example if you use different IDs for the canvases), or check for the item's parent - it's the diagram instance where the operation that called the method occurred.

Regards,
Lyubo
MindFusion

Title: Re: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Mar 31st, 2022 at 4:58am
Hi Lyubo,

We have created diagrams using silverlight application. Now I'm loading those diagrams in html/js. The nodes and links are created correctly. But for SOME links, the selection handles are not shown. I've overridden drawHandles like below. When mouse is moved over the links, control is not coming inside this method

DiagramLink.prototype["drawHandles"] = function (context) {
           .......
});

I've commented this method and tried. Still selection handles are not showing for those links.

I've added link click event like this,

this.diagram.addEventListener(Event.linkClicked, this.handleLinkClicked);

this.handleLinkClicked = function (sender: any, args: LinkEventArgs) {
          ............
}

When I click the link, the control is coming to this event.

May I know why for some links, the selection handles are not shown? Any clue?

Regards,
Kannan

Title: Re: To highlight a composite node/link/label when selected !
Post by Lyubo on Mar 31st, 2022 at 6:37am
Hi,

Are you showing the handles through a custom method/behavior or are you using the built-in ModificationStart property set to AutoHandles?

Also, does the below override get called for the links that do show handles?


Kannan Thirumal wrote on Mar 31st, 2022 at 4:58am:


DiagramLink.prototype["drawHandles"] = function (context) {
           .......
});


Regards,
Lyubo

Title: Re: To highlight a composite node/link/label when selected !
Post by Kannan Thirumal on Mar 31st, 2022 at 6:42am
Hi,

1. Yes, I've set like this,

this.diagram.setModificationStart(MindFusion.Diagramming.ModificationStart.AutoHandles);

But I'm using drawHandles to customize the selection handle's fill etc as suggested by before like this,

https://mindfusion.eu/Forum/YaBB.pl?num=1552647996/19#19

2. Yes, for links showing selection handles, drawHandles override is called when I move the mouse over the link.

Regards,
Kannan

Title: Re: To highlight a composite node/link/label when selected !
Post by Lyubo on Mar 31st, 2022 at 7:16am
Are there any relevant errors shown in the console? You can send us a project with instructions to reproduce the issue, so we can investigate.

Regards,
Lyubo

The MindFusion Forums » Powered by YaBB 2.6.11!
YaBB Forum Software © 2000-2025. All Rights Reserved.