ng-plan
Version:
This module will draw a 2D plan drawing from a geoJSON object. It was built to visualize 2D space boundaries from the Building Information Modeling (BIM) authring tool, Revit. It is quite generic, but does have some features that are mainly related to the
2 lines • 11.2 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("@angular/material/icon"),require("@angular/platform-browser"),require("d3-decompose"),require("d3-polygon"),require("@angular/common"),require("@angular/platform-browser/animations"),require("@angular/material")):"function"==typeof define&&define.amd?define("ng-plan",["exports","@angular/core","@angular/material/icon","@angular/platform-browser","d3-decompose","d3-polygon","@angular/common","@angular/platform-browser/animations","@angular/material"],t):t(e["ng-plan"]={},e.ng.core,e.ng.material.icon,e.ng.platformBrowser,null,null,e.ng.common,e.ng.platformBrowser.animations,e.ng.material)}(this,function(e,o,t,n,r,h,s,i,a){"use strict";var c=function(){function e(e,t){this.matIconRegistry=e,this.domSanitizer=t,this.clickedRoom=new o.EventEmitter,this.clickedCanvas=new o.EventEmitter,this.selectedColor="#ebefe4",this.defaultColor="#f2flec",this.baseScale=.9,this.baseOffsetX=0,this.baseOffsetY=0,this.transform="translate("+this.baseOffsetX+","+this.baseOffsetY+") scale("+this.baseScale+","+this.baseScale+")",this.movedX=0,this.movedY=0,this.scaled=1,this.panMode=!1,this.addNodeMode=!1}return e.prototype.ngAfterViewInit=function(){this.getCanvasSize()},e.prototype.ngOnChanges=function(e){e.data&&e.data.currentValue&&(this.data=e.data.currentValue,this.extractRooms(),this.getScaleOffset(),this.zoomExtents()),e.colors&&e.colors.currentValue&&this.defineColors(),e.selected&&this.updateSelection()},e.prototype.updateSelection=function(){var t=this;this.rooms&&(this.rooms=this.rooms.map(function(e){return-1!=t.selected.indexOf(e.uri)?e.selected=!0:e.selected=!1,e}))},e.prototype.defineColors=function(){var o=this;this.rooms.map(function(t){var e=o.colors.filter(function(e){return e.uri==t.uri});return 0<e.length&&(t.color=e[0].color,t.description=e[0].value),t})},e.prototype.getCanvasSize=function(){var e=this.planContainer.nativeElement.getBoundingClientRect();this.canvasWidth=e.width,this.canvasHeight=e.height,this.canvasCentroid=[this.canvasWidth/2,this.canvasHeight/2]},e.prototype.extractRooms=function(){var l,d,m,p,u=this;if(!this.data.features)return this.rooms=null;this.rooms=this.data.features.map(function(e){var t,o=[],n="";if(e.geometry&&"Polygon"==e.geometry.type){var r=[];e.geometry.coordinates.forEach(function(e){var s="",i="";e.map(function(e,t){var o=e[0],n=-e[1];return s+=o+","+n+" ",i+=0==t?"M"+o+","+n+" ":"L"+o+","+n+" ",e[1]=n,(!l||o<l)&&(l=o),(!m||m<o)&&(m=o),(!d||n<d)&&(d=n),(!p||p<n)&&(p=n),e}),s=s.trim(),i=i.trim(),r.length<1&&(t=h.polygonCentroid(e)),r.push(s),n+=i}),o.push(r)}var s=e.properties.name,i=e.properties.uri,a=e.properties.color?e.properties.color:u.defaultColor,c=e.properties.description?e.properties.description:"";return u.boundingBox=[l,d,m,p],{name:s,uri:i,description:c,color:a,polygons:o,path:n,centroid:t}})},e.prototype.getScaleOffset=function(){var e=this.boundingBox,t=e[2]-e[0],o=e[3]-e[1],n=this.canvasWidth/t,s=this.canvasHeight/o,i=Math.min(s,n),r=[i*(e[0]+t/2),i*(e[1]+o/2)],a=this.canvasCentroid[0]-r[0],c=this.canvasCentroid[1]-r[1];return this.baseOffsetX=a,this.baseOffsetY=c,[this.baseScale=i,a,c]},e.prototype.move=function(e){e&&this.zoomHandler(undefined,e)},e.prototype.moveEnd=function(e){this.movedX=this.movedX+e[0],this.movedY=this.movedY+e[1]},e.prototype.onWindowResize=function(){this.getCanvasSize(),this.getScaleOffset(),this.zoomExtents()},e.prototype.zoomExtents=function(){this.scaled=.95*this.baseScale,this.movedX=0,this.movedY=0,this.zoomHandler()},e.prototype.zoomOut=function(e){var t=this.baseScale/5;this.scaled=this.scaled-t,this.zoomHandler(e)},e.prototype.zoomIn=function(e){var t=this.baseScale/5;this.scaled=this.scaled+t,this.zoomHandler(e)},e.prototype.zoomHandler=function(e,t){if(t)var o=this.baseOffsetX+this.movedX+t[0],n=this.baseOffsetY+this.movedY+t[1];else o=this.baseOffsetX+this.movedX,n=this.baseOffsetY+this.movedY;r.decompose(this.transform).scale,r.decompose(this.transform).translate;var s="scale("+this.scaled+","+this.scaled+")",i="translate("+o+","+n+")";this.transform=i+""+s},e.prototype.selectRoom=function(e,t){var o=this.scaled,n=this.baseOffsetX+this.movedX,s=this.baseOffsetY+this.movedY,i=[(e.offsetX-n)/o,-((e.offsetX-s)/o)];this.clickedRoom.emit({uri:t.uri,coordinates:i})},e.prototype.onCanvasClick=function(e){"canvas"==e.target.id&&this.clickedCanvas.emit()},e.decorators=[{type:o.Component,args:[{selector:"ng-plan",template:'\x3c!-- Toolbar --\x3e\n<div class="toolbar" *ngIf="toolbar">\n <div class="icon-div" (click)="zoomIn(null)" matTooltip="Zoom in">\n <mat-icon>zoom_in</mat-icon>\n </div>\n <div class="icon-div" (click)="zoomOut(null)" matTooltip="Zoom out">\n <mat-icon>zoom_out</mat-icon>\n </div>\n <div class="icon-div" (click)="zoomExtents()" matTooltip="Zoom extents">\n <mat-icon svgIcon="zoom_extents"></mat-icon>\n </div>\n</div>\n\n<div class="footer">\n <p>Press and hold "Alt" to pan</p>\n</div>\n\n<svg canvasEvents\n [style.cursor]="panMode ? \'move\' : \'default\'"\n #canvas\n class=canvas\n (click)="onCanvasClick($event)"\n (zoomOut)="zoomOut($event)"\n (zoomIn)="zoomIn($event)"\n (panMode)="panMode = $event"\n (move)="move($event)"\n (moveEnd)="moveEnd($event)"\n (window:resize)="onWindowResize()"\n (addNodeMode)="addNodeMode = $event"\n id="canvas">\n\n \x3c!--Draw rooms--\x3e\n <g *ngFor="let room of rooms"\n [attr.transform]="transform"\n [id]="room.uri"\n (click)="selectRoom($event, room)"\n [attr.fill]="room.selected ? selectedColor : room.color"\n class="room">\n\n \x3c!-- Draw polygons --\x3e\n \x3c!-- <polygon *ngFor="let polygon of room.polygons" \n [attr.points]="polygon" \n class="polygon">\n </polygon> --\x3e\n\n \x3c!-- Draw paths --\x3e\n <path\n [class.selected-space]="room.selected"\n [attr.d]="room.path"\n class="polygon">\n </path> \n\n \x3c!-- Draw centroids --\x3e\n <circle \n *ngIf="centroids" \n [attr.cx]="room.centroid[0]" \n fill="black" \n [attr.cy]="room.centroid[1]" \n [attr.r]="scaled*500">\n </circle>\n\n \x3c!-- Add labels --\x3e\n <text \n [style.font-size.em]="\'12\'"\n style = "font-family:roboto; fill: black;"\n text-anchor="middle" \n alignment-baseline="central"\n [attr.x]="room.centroid[0]"\n [attr.dy]="room.description ? -150 : 0"\n [attr.y]="room.centroid[1]">\n {{room.name}}\n </text>\n\n \x3c!-- Add description --\x3e\n <text \n *ngIf = "room.description"\n [style.font-size.em]="\'10\'"\n style = "font-family:roboto; fill: black;"\n text-anchor="middle" \n alignment-baseline="central"\n [attr.x]="room.centroid[0]"\n [attr.y]="room.centroid[1]"\n dy="150">\n {{room.description}}\n </text>\n </g>\n\n</svg>',styles:[".canvas{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:100%;height:100%;position:fixed;top:0;left:0;bottom:0;right:0;z-index:-1}.polygon{stroke:#000;stroke-width:1;vector-effect:non-scaling-stroke;fill-rule:evenodd}.room:hover{opacity:.5;cursor:pointer}.selected-space{stroke-width:2}.toolbar{position:absolute;color:red;right:20px;width:100%}.icon-div>.mat-icon{float:right;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:rgba(220,220,220,.3);border-width:1px;border-radius:5px;margin-left:5px;padding:5px;z-index:1}.mat-icon{color:rgba(0,0,0,.6);font-size:30px;height:30px;width:30px;z-index:10}.mat-icon:hover{cursor:pointer;color:rgba(0,0,0,1)}.footer{background-color:rgba(220,220,220,.3);position:absolute;font-family:consolas;font-size:12px;padding:0 10px;border-radius:5px;bottom:10px}"]}]}],e.ctorParameters=function(){return[{type:t.MatIconRegistry},{type:n.DomSanitizer}]},e.propDecorators={clickedRoom:[{type:o.Output}],clickedCanvas:[{type:o.Output}],data:[{type:o.Input}],colors:[{type:o.Input}],centroids:[{type:o.Input}],toolbar:[{type:o.Input}],selected:[{type:o.Input}],selectedColor:[{type:o.Input}],defaultColor:[{type:o.Input}],planContainer:[{type:o.ViewChild,args:["canvas"]}]},e}(),l=function(){function e(){this.zoomOut=new o.EventEmitter,this.zoomIn=new o.EventEmitter,this.moveInit=new o.EventEmitter,this.move=new o.EventEmitter,this.moveEnd=new o.EventEmitter,this.panMode=new o.EventEmitter,this.addNodeMode=new o.EventEmitter,this.mouseDown=!1,this.dragMode=!1}return e.prototype.onMouseWheelChrome=function(e){this.mouseWheelFunc(e)},e.prototype.onMouseWheelFirefox=function(e){this.mouseWheelFunc(e)},e.prototype.onMouseWheelIE=function(e){this.mouseWheelFunc(e)},e.prototype.onKeyDown=function(e){"ArrowDown"==e.key&&this.zoomIn.emit(e),"ArrowUp"==e.key&&this.zoomOut.emit(e),"Alt"==e.key&&(this.dragMode=!0,this.panMode.emit(!0)),"Control"==e.key&&this.addNodeMode.emit(!0)},e.prototype.onKeyUp=function(e){"Alt"==e.key&&(this.dragMode=!1,this.panMode.emit(!1)),"Control"==e.key&&this.addNodeMode.emit(!1)},e.prototype.onMouseClick=function(e){this.mouseDown=!0,1==e.button&&(this.dragMode=!0),this.dragMode&&(this.clickX=e.offsetX,this.clickY=e.offsetY,this.panMode.emit(!0),this.moveInit.emit([e.offsetX,e.offsetY]))},e.prototype.onMouseMove=function(e){this.dragMode&&this.mouseDown&&this.move.emit([e.offsetX-this.clickX,e.offsetY-this.clickY])},e.prototype.onMouseUp=function(e){this.mouseDown=!1,this.dragMode&&(this.dragMode=!1,this.panMode.emit(!1),this.moveEnd.emit([e.offsetX-this.clickX,e.offsetY-this.clickY]))},e.prototype.mouseWheelFunc=function(e){e=window.event||e;var t=Math.max(-1,Math.min(1,e.wheelDelta||-e.detail));0<t?this.zoomIn.emit(e):t<0&&this.zoomOut.emit(e),e.returnValue=!1,e.preventDefault&&e.preventDefault()},e.decorators=[{type:o.Directive,args:[{selector:"[canvasEvents]"}]}],e.propDecorators={zoomOut:[{type:o.Output}],zoomIn:[{type:o.Output}],moveInit:[{type:o.Output}],move:[{type:o.Output}],moveEnd:[{type:o.Output}],panMode:[{type:o.Output}],addNodeMode:[{type:o.Output}],onMouseWheelChrome:[{type:o.HostListener,args:["mousewheel",["$event"]]}],onMouseWheelFirefox:[{type:o.HostListener,args:["DOMMouseScroll",["$event"]]}],onMouseWheelIE:[{type:o.HostListener,args:["onmousewheel",["$event"]]}],onKeyDown:[{type:o.HostListener,args:["document:keydown",["$event"]]}],onKeyUp:[{type:o.HostListener,args:["document:keyup",["$event"]]}],onMouseClick:[{type:o.HostListener,args:["mousedown",["$event"]]}],onMouseMove:[{type:o.HostListener,args:["mousemove",["$event"]]}],onMouseUp:[{type:o.HostListener,args:["mouseup",["$event"]]}]},e}(),d=function(){function e(){}return e.decorators=[{type:o.NgModule,args:[{imports:[s.CommonModule,i.BrowserAnimationsModule,a.MatIconModule,a.MatTooltipModule],declarations:[c,l],exports:[c]}]}],e}();e.PlanModule=d,e.ɵb=l,e.ɵa=c,Object.defineProperty(e,"__esModule",{value:!0})});
//# sourceMappingURL=ng-plan.umd.min.js.map