Restrict objects in dynamically created rectangle

Hi Team,

I am working with floor planner app.
Problem Statement

Requied Output

I am able to achieve for only single wall
when in “FloorPalnner-Templates-Furniture.js”
following function

function stayInViewport(part, pt, gridpt) {

** var diagram = part.diagram;**
** if (diagram === null) return pt;**
** // compute the area inside the viewport**
** var v = diagram.fixedBounds.copy();**
** v.subtractMargin(diagram.padding);**
** var b = part.actualBounds;**
** var loc = part.location;**
** // get the bounds of the part being dragged**
** var x = pt.x - (loc.x - b.x);**
** var y = pt.y - (loc.y - b.y);**
** var r = new go.Rect(x, y, b.width, b.height);**
** // now limit the location appropriately**
** var xa = Math.max(v.x + 1, Math.min(pt.x, v.right - b.width - 1)) + (loc.x - b.x);**
** var ya = Math.max(v.y + 1, Math.min(pt.y, v.bottom - b.height - 1)) + (loc.y - b.y);**

** return new go.Point(xa, ya);**

}

at dragComputation: stayInViewport, of makeDefaultNode Function

fixedBounds is set when showrectangle function is called on right click.

I am not able to achieve(object should not move outside the rectangle) for all wall dynamically can you please help me out how can i achieve for every wall.

You might want to consider how you would handle the cases of a room that is not rectangular or does not have well-defined walls. Since Floorplanner does not have any concept of “Rooms” by default, this implementation is entirely up to you.

I think I understand your question, but could you please post all your code / changes you have made to the Floorplanner application so I can tinker with what you’ve done so far? You could post it here or email it to GoJS at our nwoods.com domain.

Below is the code

FloorplanFilesystem.js

Added below function for right click action

FloorplanFilesystem.prototype.loadFloorplanOfLine=function(obj,e){
    var floorplan = myFloorplan;
    c_height=450; //90" dynamic data later on will be fetch from database
    l_height=30; //6" Dynamic data later on will be fetch from database
    l_height=25;
    if(obj.part.data.startpoint.x==obj.part.data.endpoint.x){
        wallLength=Math.abs(obj.part.data.startpoint.y-obj.part.data.endpoint.y);
          startPointY=(obj.part.data.startpoint.y>obj.part.data.endpoint.y) ? obj.part.data.startpoint.y:obj.part.data.endpoint.y;
          startPointX=obj.part.data.startpoint.x;
    }else if(obj.part.data.startpoint.y==obj.part.data.endpoint.y){
        wallLength=Math.abs(obj.part.data.startpoint.x-obj.part.data.endpoint.x);
          startPointX=(obj.part.data.startpoint.x<obj.part.data.endpoint.x) ? obj.part.data.startpoint.x:obj.part.data.endpoint.x;
          startPointY=obj.part.data.startpoint.y;
    }
    line1 = {
        "key": "wall1",
        "category": "WallGroup",
        "caption": "Wall",
        "type": "Wall",
        "startpoint": {"class": "go.Point", "x": startPointX+length, "y": startPointY},
        "endpoint": {"class": "go.Point", "x": startPointX+wallLength-length, "y": startPointY},
        "thickness": 3,
        "isGroup": true,
        "notes": ""
    };
    line2 = {
        "key": "wall2",
        "category": "WallGroup",
        "caption": "Wall",
        "type": "Wall",
        "startpoint": {"class": "go.Point", "x": startPointX+wallLength-length, "y": startPointY},
        "endpoint": {
            "class": "go.Point",
            "x": startPointX+wallLength-length,
            "y": startPointY + c_height
        },
        "thickness": 3,
        "isGroup": true,
        "notes": ""
    };
    line3 = {
        "key": "wall3",
        "category": "WallGroup",
        "caption": "Wall",
        "type": "Wall",
        "startpoint": {
            "class": "go.Point",
            "x": startPointX+wallLength-length,
            "y": startPointY + c_height
        },
        "endpoint": {
            "class": "go.Point",
            "x": startPointX+length,
            "y": startPointY + c_height
        },
        "thickness": 3,
        "isGroup": true,
        "notes": ""
    };
    line4 = {
        "key": "wall2",
        "category": "WallGroup",
        "caption": "Wall",
        "type": "Wall",
        "startpoint": {
            "class": "go.Point",
            "x": startPointX+length,
            "y": startPointY + c_height
        },
        "endpoint": {
            "class": "go.Point",
            "x": startPointX+length,
            "y": startPointY
        },
        "thickness": 3,
        "isGroup": true,
        "notes": ""
    };

        line5= {
            "key": "wall2",
            "category": "WallGroup",
            "caption": "Wall",
            "type": "Wall",
            "startpoint": {
                "class": "go.Point",
                "x": startPointX+length,
                "y": startPointY
            },
            "endpoint": {
                "class": "go.Point",
                "x": startPointX+length,
                "y": startPointY - l_height
            },
            "thickness": 3,
            "isGroup": true,
            "notes": ""
        };
        line6 = {
            "key": "wall2",
            "category": "WallGroup",
            "caption": "Wall",
            "type": "Wall",
            "startpoint": {
                "class": "go.Point",
                "x": startPointX + length,
                "y": startPointY - l_height
            },
            "endpoint": {
                "class": "go.Point",
                "x": startPointX+wallLength - length,
                "y": startPointY - l_height
            },
            "thickness": 3,
            "isGroup": true,
            "notes": ""
        };
        line7= {
            "key": "wall2",
            "category": "WallGroup",
            "caption": "Wall",
            "type": "Wall",
            "startpoint": {
                "class": "go.Point",
                "x": startPointX+wallLength-length,
                "y": startPointY - l_height
            },
            "endpoint": {
                "class": "go.Point",
                "x": startPointX+wallLength-length,
                "y": startPointY
            },
            "thickness": 3,
            "isGroup": true,
            "notes": ""
        };

        elevation_view = {
            "class": "go.GraphLinksModel",
            "modelData": { "units": "centimeters", "unitsAbbreviation": "cm", "gridSize": 10, "wallThickness": 5, "preferences": { "showWallGuidelines": true, "showWallLengths": true, "showWallAngles": true, "showOnlySmallWallAngles": true, "showGrid": true, "gridSnap": true } },
            "nodeDataArray": [line1, line2, line3, line4,line6, line5,line7],
            "linkDataArray": []
        };


    floorplan.model = go.Model.fromJson(elevation_view);

    floorplan.skipsUndoManager = true;
    floorplan.startTransaction("generate walls");
    floorplan.nodes.each(function (node) {
        if (node.category === "WallGroup") floorplan.updateWall(node);
    });
    if (floorplan.floorplanUI) {
        floorplan.floorplanUI.updateUI();
        floorplan.floorplanUI.updateStatistics();
    }
    floorplan.fixedBounds=floorplan.computeBounds();
    floorplan.commitTransaction("generate walls");
    floorplan.undoManager.isEnabled = true;

    if( isNaN(floorplan.fixedBounds.x) && isNaN(floorplan.fixedBounds.y)) {
        floorplan.documentBounds.bottom+=l_height;
        floorplan.documentBounds.height-=l_height;
        floorplan.fixedBounds = floorplan.documentBounds;
    }

}

In Floorplan-Templates-Furniture.js
added below property
dragComputation:stayInViewport
in makeDefaultNode function.

stayInViewport Function is below

function stayInViewport(part, pt, gridpt) {

    var diagram = part.diagram;
    if (diagram === null) return pt;
    // compute the area inside the viewport
    var v = diagram.fixedBounds.copy();
    v.subtractMargin(diagram.padding);
    var b = part.actualBounds;
    var loc = part.location;
    // get the bounds of the part being dragged
    var x = pt.x - (loc.x - b.x);
    var y = pt.y - (loc.y - b.y);
    var r = new go.Rect(x, y, b.width, b.height);
    // now limit the location appropriately
    var xa = Math.max(v.x + 1, Math.min(pt.x, v.right - b.width - 1)) + (loc.x - b.x);
    var ya = Math.max(v.y + 1, Math.min(pt.y, v.bottom - b.height - 1)) + (loc.y - b.y);

    return new go.Point(xa, ya);


}

then in Floorplan-Templates-General.js

Added Context menu code

 $("ContextMenuButton",
            $(go.TextBlock, "ShowRectangle"),
            {
                click: function (e, obj) {
                    FloorplanFilesystem.prototype.loadFloorplanOfLine(obj,e);
                }
            }
        ),

in makeContextMenu function

and i am saving the Problem statement mention above in initial post in db so that i can access it.

Why is your stayInViewport function (which really ought to be renamed) working with the Diagram.fixedBounds instead of the rectangular area that you have computed for the room?

Hi walter ,

When FloorplanFilesystem.prototype.loadFloorplanOfLine function is called i am updating the Diagram.fixedBounds according to the rectangle. But it did not work.

That sounds like an undesirable policy. Nevertheless, when I try your stayInViewport function unmodified as the Part.dragComputation for my Nodes in my test app, after setting Diagram.fixedBounds to some plausible rectangular area, it worked as I believe you are expecting, both for in-diagram drag-and-drops as well as drag-and-drops from a Palette.

Your code is also making invalid changes to Diagram.documentBounds. Please make sure that you are using the debug version of the GoJS library, go-debug.js, during your development, and check the console window output for warnings and errors.

Hi walter,

I tried the same but that did not work for me.
Please note : when i am reloading the entire page then i am able to get desired result for each wall (Selecting unique wall on every reload).
But without reloading/ refreshing the page when i try open one by one every line’s rectangle view then it does not work.
Please See below step
1.Draw a problem statement as mentioned above in initial query
2.Save it
3.Open rectangle view of any one of the line & check object are restricted or not within that area
4.without saving again open saved file(in step 2)
5.Try opening rectangle view of other wall and check object are restricted within area or not.(That’s then time when i am facing the issue).

Have you fixed those errors that I pointed out? The easiest way to do so is to use go-debug.js and make sure there are no console warnings or errors during the running of your app.

Until you fix those errors, I won’t know that the problem that you are asking about isn’t caused by those errors.

There is no warning and errors when i use go-debug.js

What code did you change and how?

I have changes the diagram.fixedBounds according to the rectangle (in above mention FloorplanFilesystem.prototype.loadFloorplanOfLine).
I am getting below error in console.

Error: The Rect is frozen, so its properties cannot be set: Rect(1020.0720000000001,1428.5,3849.8559999999998,3109) to value: 1908.6440000000002

Ah, good, so you are now seeing the errors that I expected that you should get when executing your code.

OK, fix those and see if your code works better the second time around.