haojianlong 4 سال پیش
والد
کامیت
1cf739ae6a
35فایلهای تغییر یافته به همراه528 افزوده شده و 304 حذف شده
  1. 48 2
      docs/.vuepress/components/example/web/graph/scene/ImageItem.vue
  2. 253 0
      docs/.vuepress/components/example/web/graph/scene/SEditLine.vue
  3. 55 184
      docs/.vuepress/components/example/web/graph/scene/TextItem.vue
  4. 1 1
      docs/dev/data-center/index.js
  5. 11 11
      docs/dev/data-center/relations/belongs/Bd2Sp.md
  6. 5 5
      docs/dev/data-center/relations/belongs/Eq2Bd.md
  7. 16 9
      docs/dev/data-center/relations/belongs/Eq2Fl.md
  8. 7 6
      docs/dev/data-center/relations/belongs/Eq2Sh.md
  9. 26 18
      docs/dev/data-center/relations/belongs/Eq2Sp.md
  10. 6 7
      docs/dev/data-center/relations/belongs/Fl2Fl.md
  11. 3 3
      docs/dev/data-center/relations/belongs/Pe2Bd.md
  12. 2 2
      docs/dev/data-center/relations/belongs/Pe2Fl.md
  13. 1 1
      docs/dev/data-center/relations/belongs/Pe2Sh.md
  14. 1 1
      docs/dev/data-center/relations/belongs/Pe2Sp.md
  15. 3 3
      docs/dev/data-center/relations/belongs/Sh2Bd.md
  16. 3 2
      docs/dev/data-center/relations/belongs/Sh2Sh.md
  17. 11 5
      docs/dev/data-center/relations/belongs/Sp2Fl.md
  18. 5 5
      docs/dev/data-center/relations/belongs/Sp2Sp.md
  19. 12 5
      docs/dev/data-center/relations/belongs/Sp2Sp2.md
  20. 1 1
      docs/dev/data-center/relations/belongs/Sy2Bd.md
  21. 1 1
      docs/dev/data-center/relations/belongs/Sy2Fl.md
  22. 1 1
      docs/dev/data-center/relations/belongs/Sy2Sh.md
  23. 1 1
      docs/dev/data-center/relations/belongs/Sy2Sp.md
  24. 3 3
      docs/dev/data-center/relations/belongs/f_rel_calc.md
  25. BIN
      docs/dev/data-center/relations/belongs/img/sp2sp2-1.PNG
  26. 1 1
      docs/dev/data-center/relations/other/calc_area_v3.md
  27. 5 5
      docs/dev/data-center/relations/other/calc_vertically_overlap.md
  28. 1 1
      docs/dev/data-center/relations/other/other_ispace_floor_overlap.md
  29. 1 1
      docs/dev/data-center/relations/other/rel_affected_space.md
  30. 1 1
      docs/dev/data-center/relations/other/rel_str_similar.md
  31. 1 1
      docs/dev/data-center/relations/topology/sys_block.md
  32. 1 1
      docs/dev/data-center/relations/topology/sys_direction.md
  33. 1 0
      docs/dev/saga-graphy/index.js
  34. 17 0
      docs/dev/saga-graphy/scene-manage/items/editLine.md
  35. 23 16
      docs/dev/saga-graphy/system-diagram/json-file.md

+ 48 - 2
docs/.vuepress/components/example/web/graph/scene/ImageItem.vue

@@ -1,12 +1,58 @@
 <template>
-    <canvas id="imageItem1" width="400" height="400" />
+    <div>
+        <el-row>
+            <el-button @click="Full">铺满</el-button>
+            <el-button @click="Equivalency">等比缩放</el-button>
+            <el-button @click="AutoFit">自适应</el-button>
+        </el-row>
+        <canvas id="ImageItem1" width="740" height="400"/>
+    </div>
 </template>
 
 <script lang="ts">
+    import { SGraphScene, SGraphView } from "@saga-web/graph";
+    import { SImageItem } from "@saga-web/big/lib";
+    import { SImageShowType } from "@saga-web/big/lib/enums/SImageShowType";
+
+    class SScene extends SGraphScene {
+        imageItem: SImageItem = new SImageItem(null);
+        constructor() {
+            super();
+            this.imageItem.moveable = true;
+            this.imageItem.width = 400;
+            this.imageItem.height = 300;
+            this.imageItem.url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1591685374103&di=cd5a56b2e3f5e12d7145b967afbcfb7a&imgtype=0&src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201408%2F05%2F20140805191039_cuTPn.jpeg";
+            this.addItem(this.imageItem);
+        }
+    }
+
+    class ImageView extends SGraphView {
+        constructor() {
+            super("ImageItem1");
+        }
+    }
 
     export default {
         mounted(): void {
-            // new TestView();
+            let view = new ImageView();
+            view.scene = this.scene;
+            view.fitSceneToView();
+        },
+        data() {
+            return {
+                scene: new SScene(),
+            }
+        },
+        methods: {
+            Full() {
+                this.scene.imageItem.showType = SImageShowType.Full;
+            },
+            Equivalency() {
+                this.scene.imageItem.showType = SImageShowType.Equivalency;
+            },
+            AutoFit() {
+                this.scene.imageItem.showType = SImageShowType.AutoFit;
+            },
         }
     }
 </script>

+ 253 - 0
docs/.vuepress/components/example/web/graph/scene/SEditLine.vue

@@ -0,0 +1,253 @@
+<template>
+    <div>
+        <el-button @click="show">展示</el-button>
+        <el-button @click="create">创建</el-button>
+        <el-button @click="edit">编辑</el-button>
+        <canvas id="editLine" width="740" height="400"  tabindex="0" />
+    </div>
+</template>
+<script lang='ts'>
+    import {SGraphItem, SGraphScene, SGraphView} from "@saga-web/graph/";
+    import {SMouseEvent} from "@saga-web/base/";
+    import {SColor, SLine, SPainter, SPoint, SRect} from "@saga-web/draw";
+    import {SRelationState} from "@saga-web/big/lib/enums/SRelationState";
+    import {SMathUtil} from "@saga-web/big/lib/utils/SMathUtil";
+
+    /**
+     * 直线item
+     *
+     * */
+
+    class SLineItem extends SGraphItem {
+        /** 线段   */
+        line: SPoint[] = [];
+        /** 是否完成绘制  */
+        _status: SRelationState = SRelationState.Create;
+        get status(): SRelationState {
+            return this._status;
+        }
+        set status(v: SRelationState) {
+            this._status = v;
+            this.update();
+        }
+        /** 线条颜色    */
+        _strokeColor: string = "#000000";
+        get strokeColor(): string {
+            return this._strokeColor;
+        }
+        set strokeColor(v: string) {
+            this._strokeColor = v;
+            this.update();
+        }
+        /** 填充色 */
+        _fillColor: string = "#2196f3";
+        get fillColor(): string {
+            return this._fillColor;
+        }
+        set fillColor(v: string) {
+            this._fillColor = v;
+            this.update();
+        }
+        /** 线条宽度    */
+        _lineWidth: number = 1;
+        get lineWidth(): number {
+            return this._lineWidth;
+        }
+        set lineWidth(v: number) {
+            this._lineWidth = v;
+            this.update();
+        }
+        /** 拖动灵敏度   */
+        dis: number = 10;
+        /** 拖动灵敏度   */
+        sceneDis: number = 10;
+
+        /**
+         * 构造函数
+         *
+         * @param   parent  父级
+         * @param   line    坐标集合
+         * */
+        constructor(parent: SGraphItem | null, line: SPoint[]);
+
+        /**
+         * 构造函数
+         *
+         * @param   parent  父级
+         * @param   point   第一个点坐标
+         * */
+        constructor(parent: SGraphItem | null, point: SPoint);
+
+        /**
+         * 构造函数
+         *
+         * @param   parent  父级
+         * @param   l       坐标集合|第一个点坐标
+         * */
+        constructor(parent: SGraphItem | null, l: SPoint | SPoint[]) {
+            super(parent);
+            if (l instanceof SPoint) {
+                this.line.push(l);
+            } else {
+                this.line = l;
+            }
+        }
+
+        /**
+         * 鼠标按下事件
+         *
+         * @param   event   鼠标事件
+         * @return  是否处理事件
+         * */
+        onMouseDown(event: SMouseEvent): boolean {
+            console.log(this);
+            if (this.status == SRelationState.Normal) {
+                return super.onMouseDown(event);
+            } else if (this.status == SRelationState.Edit) {
+            } else if (this.status == SRelationState.Create) {
+
+            }
+            this.$emit("mousedown");
+            return true;
+        } // Function onMouseDown()
+
+        /**
+         * 鼠标移动事件
+         *
+         * @param   event   鼠标事件
+         * @return  是否处理事件
+         * */
+        onMouseMove(event: SMouseEvent): boolean {
+            if (this.status == SRelationState.Create) {
+
+                return true;
+            } else {
+                return super.onMouseMove(event);
+            }
+        } // Function onMouseMove()
+
+        /**
+         * 鼠标移动事件
+         *
+         * @param   event   鼠标事件
+         * @return  是否处理事件
+         * */
+        onMouseUp(event: SMouseEvent): boolean {
+            // if (this.status == SRelationState.Create) {
+            //     this.status = SRelationState.Edit;
+            //     return true;
+            // } else {
+                return super.onMouseUp(event);
+            // }
+        } // Function onMouseUp()
+
+        /**
+         * 判断点是否在区域内
+         *
+         * @param   x
+         * @param   y
+         * @return  true-是
+         */
+        contains(x: number, y: number): boolean {
+            if (this.line.length == 2) {
+                let p = new SPoint(x, y);
+                if (
+                    SMathUtil.pointToLine(p, new SLine(this.line[0], this.line[1])).MinDis <
+                    this.dis
+                ) {
+                    return true;
+                }
+            }
+            return false;
+        } // Function contains()
+
+        /**
+         * Item对象边界区域
+         *
+         * @return	SRect
+         */
+        boundingRect(): SRect {
+            if (this.line.length == 2) {
+                let x: number = this.line[0].x > this.line[1].x ? this.line[1].x : this.line[0].x;
+                let y: number = this.line[0].x > this.line[1].x ? this.line[1].y : this.line[0].y;
+                let width: number = Math.abs(this.line[0].x - this.line[1].x);
+                let height: number = Math.abs(this.line[0].y - this.line[1].y);
+                return new SRect(
+                    x,
+                    y,
+                    width,
+                    height
+                );
+            } else {
+                return new SRect();
+            }
+        } // Function boundingRect()
+
+        /**
+         * Item绘制操作
+         *
+         * @param   painter painter对象
+         */
+        onDraw(painter: SPainter): void {
+            this.sceneDis = painter.toPx(this.dis);
+            painter.pen.lineWidth = painter.toPx(this.lineWidth);
+            painter.pen.color = new SColor(this.strokeColor);
+            if (this.p1 instanceof SPoint && this.p2 instanceof SPoint) {
+                // 绘制外轮廓
+                painter.brush.color = SColor.Transparent;
+                painter.pen.color = new SColor("#128eee");
+                painter.drawRect(this.boundingRect());
+
+                // 绘制基本图形
+                painter.pen.color = new SColor(this.strokeColor);// 需注释
+                painter.drawLine(this.p1, this.p2);
+
+                // 编辑态
+                if (this.status == SRelationState.Edit) {
+                    painter.brush.color = SColor.White;
+
+                    // painter.brush.color = new SColor(this.fillColor);
+
+                    painter.drawCircle(this.p1.x, this.p1.y, painter.toPx(5));
+
+                    painter.drawCircle(this.p2.x, this.p2.y, painter.toPx(5));
+                }
+            }
+        } // Function onDraw()
+    } // Class SLineItem
+
+    export default {
+        data() {
+            return {
+                scene: null,
+                view: null
+            };
+        },
+        mounted(): void {
+            this.view = new SGraphView("editLine");
+        },
+        methods: {
+            show() {
+                const scene = new SGraphScene();
+                this.view.scene = scene;
+                const line: SPoint[] = [new SPoint(100, 100), new SPoint(300, 300)];
+                const lineItem = new SLineItem(null, line);
+                lineItem.status = SRelationState.Normal;
+                scene.addItem(lineItem);
+                this.view.fitSceneToView();
+            },
+            create() {
+                const scene = new SGraphScene();
+                this.view.scene = scene;
+                const lineItem = new SLineItem(null, [] );
+                lineItem.status = SRelationState.Create;
+                scene.addItem(lineItem);
+                scene.grabItem = lineItem;
+                this.view.fitSceneToView();
+            },
+            edit() {
+
+            }
+        }
+    };
+</script>

+ 55 - 184
docs/.vuepress/components/example/web/graph/scene/TextItem.vue

@@ -1,131 +1,63 @@
 <template>
 	<div>
 		<el-row>
-			<el-input v-model="input" @keyup.native="handleKeyup" style="width:200px;" placeholder="请输入内容"></el-input>
-
+			<el-input v-model="text" @change="handleChangeText" type="textarea" :autosize="{ minRows: 1, maxRows: 1}" placeholder="请输入内容" style="width:200px;"></el-input>
+			<el-input-number v-model="size" @change="handleChangeSize" :min="1" label="字号"></el-input-number>
+			<el-color-picker v-model="color" @change="handleChangeColor" style="top: 15px;"></el-color-picker>
 			<el-button @click="undo">Undo</el-button>
 			<el-button @click="redo">Redo</el-button>
+			<el-button @click="reset">Reset</el-button>
 		</el-row>
-		<canvas id="TextItem1" width="400" height="400" />
+		<canvas id="TextItem1" width="740" height="400" tabindex="0"/>
 	</div>
 </template>
 
 <script lang="ts">
-	import { SMouseEvent, SUndoStack } from "@saga-web/base";
-    import { SColor, SPainter, SRect, SFont, SSize, STextBaseLine } from "@saga-web/draw";
-	import { SObjectItem } from "@saga-web/big/lib/items/SObjectItem";
-	import { SGraphItem, SGraphScene, SGraphView } from "@saga-web/graph";
-	import { SGraphCommand } from "@saga-web/graph/lib";
-	import { SUndoCommand } from "@saga-web/base/lib";
+	import { SUndoStack } from "@saga-web/base";
+    import { SFont } from "@saga-web/draw";
+	import { SGraphItem, SGraphScene, SGraphView, SGraphPropertyCommand, SGraphMoveCommand } from "@saga-web/graph";
 	import { SPoint } from "@saga-web/draw/lib";
-
-	class TextItem extends SObjectItem {
-		/** 文本内容 */
-		private _text: string = "";
-		get text(): string {
-			return this._text;
-		}
-		set text(v: string) {
-			this._text = v;
-			this.update();
-		}
-
-		/** 文本颜色 */
-		private _color: string ="#333333";
-		get color():string {
-			return this._color;
-		}
-		set color(v: string) {
-			this._color = v;
-			this.update();
-		}
-
-		/** 字体 */
-		private _font: SFont;
-		get font():SFont {
-			return this._font;
-		}
-		set font(v: SFont) {
-			this._font = v;
-			this.update();
-		}
-
-		/** 文本绘制最大宽 */
-    	maxWidth: number | undefined = undefined;
-
-		/**
-         * 构造函数
-         *
-         * @param   parent      指向父Item
-         * @param   str         文本内容
-         */
-        constructor(parent: SGraphItem | null = null, str: string = "") {
-			super(parent);
-			this._text = str;
-			this._font = new SFont();
-			this.moveable = true;
-			this.selectable = true;
-			this.selected = true;
-		}
-
-		/**
-         * 对象边界区域
-         *
-         * @return  边界区域
-         */
-        boundingRect(): SRect {
-            return new SRect(this.x, this.y, this.width, this.height);
-        }
-
-		protected onResize(oldSize: SSize, newSize: SSize) {
-			console.log("resize",oldSize,newSize)
-		}
-
-		/**
-         * Item绘制操作
-         *
-         * @param   canvas      画布
-         */
-        onDraw(canvas: SPainter): void {
-			// this.width = canvas.toPx(canvas.textWidth(this.text));
-			// this.height = canvas.toPx(this.font.size);
-
-			// canvas.font.textBaseLine = this.font.textBaseLine;
-			// canvas.font.textDirection = this.font.textDirection;
-			// canvas.font.textAlign = this.font.textAlign;
-			// canvas.font.name = this.font.name;
-			// canvas.font.size = canvas.toPx(this.font.size);
-			// canvas.brush.color = new SColor(this.color);
-			// canvas.drawText(this.text, 0, 0, this.maxWidth);
-
-
-			canvas.brush.color = SColor.White;
-			canvas.drawRect(this.x, this.y, this.width, this.height);
-			//绘制文本
-			canvas.brush.color = new SColor(this.color);
-			canvas.font = this.font;
-			canvas.drawText(this.text, this.x, this.y , this.maxWidth);
-        }
-	}
+	import {STextItem} from "@saga-web/big/lib";
 
 	class SScene extends SGraphScene {
 		undoStack = new SUndoStack();
-		textItem: SGraphItem = new TextItem(null);
+		textItem: STextItem = new STextItem(null);
 
 		constructor() {
 			super();
+			this.textItem.moveable = true;
+			this.textItem.x = 100;
+			this.textItem.y = 100;
 			this.addItem(this.textItem);
 			this.textItem.connect("onMove", this, this.onItemMove.bind(this));
 		}
 
 		updateText(str: string): void {
-			if(this.textItem.text !== str) {
+			if (this.textItem.text !== str) {
 				let old = this.textItem.text;
 				this.textItem.text = str;
 				this.undoStack.push(new SGraphPropertyCommand(this, this.textItem, "text", old, str));
 			}
 		}
 
+		updateColor(color: string): void {
+			if (this.textItem.color !== color) {
+				let old = this.textItem.color;
+				this.textItem.color = color;
+				this.undoStack.push(new SGraphPropertyCommand(this, this.textItem, "color", old, color));
+			}
+		}
+
+		updateSize(size: number): void {
+			if (this.textItem.font.size !== size) {
+				let old = new SFont(this.textItem.font);
+				let font = new SFont(this.textItem.font);
+				font.size = size;
+				this.textItem.font = font;
+				this.undoStack.push(new SGraphPropertyCommand(this, this.textItem, "font", old, font));
+			}
+		}
+
 		onItemMove(item: SGraphItem, ...arg: any): void {
             this.undoStack.push(new SGraphMoveCommand(this, item, arg[0][0] as SPoint, arg[0][1] as SPoint));
         }
@@ -138,106 +70,45 @@
         }
 	}
 
-	/**
-	 * 属性修改命令类
-	 *
-	 * @author  张宇(taohuzy@163.com)
-	 */
-	class SGraphPropertyCommand<T> extends SGraphCommand {
-		/**	指向item对象	*/
-		item: SGraphItem;
-		/** 属性名称 */
-		propName: string;
-		/** 属性旧值 */
-		oldProp: T;
-		/** 属性新值 */
-    	newProp: T;
-
-		/**
-		 * 构造函数
-		 *
-		 * @param   scene       命令所属的场景类
-		 * @param   item        命令所属的item类
-		 * @param   propName    修改的属性名称
-		 * @param   oldProp     修改前的属性值
-		 * @param   newProp     修改后的属性值
-		 */
-        constructor(scene: SGraphScene, item: SGraphItem, propName: string, oldProp: T, newProp: T) {
-            super(scene);
-			this.item = item;
-			this.propName = propName;
-            this.oldProp = oldProp;
-            this.newProp = newProp;
-        } // Constructor
-
-		/**
-		 * redo操作
-		 */
-        redo(): void {
-            this.item[this.propName] = this.newProp;
-            this.item.update();
-        } // Function redo()
-
-		/**
-		 * undo操作
-		 */
-        undo(): void {
-            this.item[this.propName] = this.oldProp;
-            this.item.update();
-        } // Function undo()
-	}
-
-	class SGraphMoveCommand extends SGraphCommand {
-        item: SGraphItem;
-        old: SPoint;
-        pos: SPoint;
-
-        constructor(scene: SGraphScene, item: SGraphItem, old: SPoint, pos: SPoint) {
-            super(scene);
-            this.item = item;
-            this.old = old;
-            this.pos = pos;
-        }
-        mergeWith(command: SUndoCommand): boolean {
-            if (command instanceof  SGraphMoveCommand && command.item == this.item) {
-                command.pos = this.pos;
-                return true;
-            }
-            return false;
-        }
-
-        redo(): void {
-            this.item.pos = new SPoint(this.pos.x, this.pos.y);
-            this.item.update();
-        }
-
-        undo(): void {
-            this.item.pos = new SPoint(this.old.x, this.old.y);
-            this.item.update();
-        }
-    }
-
     export default {
         mounted(): void {
 			let view = new TestView();
-			this.scene.updateText(this.input);
+			this.scene.updateText(this.text);
+			this.scene.updateColor(this.color);
+			this.scene.updateSize(this.size);
 			view.scene = this.scene;
 		},
 		data() {
 			return {
 				scene: new SScene(),
-				input: '测试文本',
+				text: '测试文本',
+				size: 20,
+				color: "#333333",
 			}
 		},
 		methods: {
-			handleKeyup(value): void {
-				this.scene.updateText(this.input);
+			handleChangeText(text): void {
+				this.scene.updateText(this.text);
+			},
+			handleChangeColor(color): void {
+				this.scene.updateColor(color);
+			},
+			handleChangeSize(size): void {
+				this.scene.updateSize(size);
 			},
 			undo(): void {
 				this.scene.undoStack.undo();
 			},
 			redo(): void {
 				this.scene.undoStack.redo();
+			},
+			reset(): void {
+				this.text = "测试文本";
+				this.size = 20;
+				this.color = "#333333";
+				this.scene.updateText(this.text);
+				this.scene.updateColor(this.color);
+				this.scene.updateSize(this.size);
 			}
 		},
     }
@@ -245,4 +116,4 @@
 
 <style scoped>
 
-</style>
+</style>

+ 1 - 1
docs/dev/data-center/index.js

@@ -32,7 +32,7 @@ const content = [
             ["/dev/data-center/relations/belongs/Sh2Sh", "竖井贯通关系"],
             ["/dev/data-center/relations/belongs/Sp2Fl", "业务空间所属楼层"],
             ["/dev/data-center/relations/belongs/Sp2Sp", "业务空间邻接关系"],
-            ["/dev/data-center/relations/belongs/Sp2Sp_new", "业务空间邻接关系(新)"],
+            ["/dev/data-center/relations/belongs/Sp2Sp2", "业务空间邻接关系(新)"],
             ["/dev/data-center/relations/belongs/Sy2Bd", "系统所在建筑"],
             ["/dev/data-center/relations/belongs/Sy2Fl", "系统所在楼层"],
             ["/dev/data-center/relations/belongs/Sy2Sh", "系统所在竖井"],

+ 11 - 11
docs/dev/data-center/relations/belongs/Bd2Sp.md

@@ -1,25 +1,24 @@
-建筑下的业务空间
+# 建筑下的业务空间
 ## 前置条件
-有所属楼层的业务空间(所有业务空间表都需要处理)
+    1. 业务空间必须要有所属的楼层
 ```
 FROM zone_* WHERE project_id='Pj4201050001' AND floor_id is not null
 ```
-## 处理方式
+## 处理逻辑
 
-从绑定的楼层里取建筑ID,
-将建筑ID填入设备ID(建筑ID为空,则设备的建筑ID也为空)。
+    1. 从业务空间绑定的楼层信息里取到楼层所属的建筑ID,
+    2. 取到的建筑ID即是业务空间的所属建筑 (建筑ID为空,则的建筑ID也为空).
 
 ## 实现方式
 SQL
 ```
-update zone_air_conditioning zone set zone.building_id = floor.building_id from floor where zone.floor_id = floor.id and zone.project_id = 'Pj4201050001' and zone.floor_id is not null
+update zone_space_base zone set zone.building_id = floor.building_id from floor where zone.floor_id = floor.id and zone.project_id = 'Pj4201050001' and zone.floor_id is not null
 ```
 
 # 函数
 ```
-create or replace function public.rel_bd2sp(tables text, project_id character varying) returns boolean
-as
-$$
+CREATE OR REPLACE FUNCTION "public"."rel_bd2sp"("tables" text, "project_id" varchar)
+  RETURNS "pg_catalog"."bool" AS $BODY$
 try:
     list = tables.split(',')
     # 将下面对数据库的操作作为一个事务, 出异常则自动rollback
@@ -33,8 +32,9 @@ except Exception as e:
     return False
 else:
     return True
-$$
-LANGUAGE 'plpython3u' VOLATILE;
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
 ```
 
 ## 输入

+ 5 - 5
docs/dev/data-center/relations/belongs/Eq2Bd.md

@@ -1,16 +1,16 @@
-设备所在建筑
+# 设备所在建筑
 ## 前置条件
-设备已经绑定楼层
+    1. 设备已经绑定楼层
 ```
 FROM equipment WHERE project_id='Pj4201050001' AND floor_id is not null
 ```
 
 ## 依赖函数
     Eq2Fl
-## 处理方式
+## 处理逻辑
 
-从绑定的楼层里取建筑ID,
-将建筑ID填入设备ID(建筑ID为空,则设备的建筑ID也为空)。
+    1. 设备绑定的楼层里取楼层所属的建筑ID,
+    2. 将取到的建筑ID填入设备的所属建筑中(建筑ID为空,则设备的所属建筑ID也为空)。
 
 ## 实现方式
 SQL

+ 16 - 9
docs/dev/data-center/relations/belongs/Eq2Fl.md

@@ -1,20 +1,26 @@
 设备所在楼层
 ## 前置条件
-    1. 设备有ModelId信息点
-    2. 楼层有ModelId信息点
-    3. 楼层的ModelId信息点等于设备的ModelId所属模型楼层的信息点
-    4. 设备没有所在楼层关系
-    5. 设备有Location(非必要)
-    6. 楼层有Outline(非必要)
+    1. 设备有ModelId信息点  (模型web服务的模型id)
+    2. 楼层有ModelId信息点  (模型web服务的楼层id)
+    3. 设备没有所在楼层关系
+    4. 设备有Location(非必要)
+    5. 楼层有Outline(非必要)
     
 
-## 处理方式
-    1. 如果楼层有Outline, 设备有Location, 做点(Location)在多边形(Outline)内的判断, 在多边形内则认为有关系
-    2. 如果不满足条件1, 则判断ModelId信息点的值, 相等则认为有关系
+## 处理逻辑
+    1. 如果楼层有Outline, 设备有Location, 做点(Location)在多边形(Outline)内的判断, 点在多边形内则认为有关系
+    2. 如果不满足条件1, 即楼层没有Outline, 设备没有Location, 则判断它们ModelId信息点的值, 相等则认为有关系   
+        (此处的相等表示设备上的ModelId信息点在关系上从属于楼层上的ModelId信息点, 即模型web服务中的模型id属于楼层id)
+
+## 技术细节
+    1. 做点在多边形内的判断, 使用到了python的 shapely 库 中的 Path 类的contains_points 方法
 
 # 函数
 
 ## 代码
+<details>
+<summary>源码</summary>
+
 ```
 -- 设备所在楼层
 CREATE OR REPLACE FUNCTION "public"."rel_eq2fl"("project_id" varchar)
@@ -101,6 +107,7 @@ $BODY$
 
 select public.rel_eq2fl('Pj1101010015');
 ```
+</details>
 
 ## 输入
     1. 项目id

+ 7 - 6
docs/dev/data-center/relations/belongs/Eq2Sh.md

@@ -1,13 +1,14 @@
-设备所在竖井关系计算
+# 设备所在竖井关系计算
 ## 前置条件
-    1. 首先需要有设备所在业务空间关系
-    2. 需要有竖井包含业务空间关系
+    1. 设备需要有所在业务空间关系
+    2. 竖井需要有包含业务空间关系
     
 ## 依赖函数
     Eq2Sp
-## 计算过程
-    1. 通过 竖井--> 业务空间 --> 设备的间接关系, 堆出竖井和设备的关系
-    2. 结果保存到r_eq_in_sh表中
+    
+## 处理逻辑
+    1. 通过 竖井 --> 业务空间 --> 设备 的间接所属关系, 推出竖井和设备的关系
+    
 ## 函数
 ```
 -- 设备所在竖井

+ 26 - 18
docs/dev/data-center/relations/belongs/Eq2Sp.md

@@ -1,21 +1,23 @@
-设备所在业务空间
+# 设备所在业务空间
 ## 前置条件
-    1. 业务空间有所属楼层
-    2. 设备有所属楼层
-    3. 业务空间有轮廓数据(outline)
-    4. 设备有坐标信息(bimLocation)
+    1. 业务空间有所属楼层关系
+    2. 设备有所属楼层关系
+    3. 业务空间有轮廓数据(outline信息点)
+    4. 设备有坐标信息(bimLocation信息点)
 ## 依赖函数
-    Eq2Fl
-## 处理方式
-    将在同一楼层内的设备和业务空间取出, 判断设备的bim_location是否在业务空间的outline内, 
-    如果在, 则添加进对应的关系表内, 控制sign = 2
+    Eq2Fl, Sp2Fl
+## 处理逻辑
+    1. 取出项目内的所有业务空间和设备, 将在同一楼层内的设备和业务空间分成一组
+    2. 在一组内, 判断设备的bim_location是否在业务空间的outline内, 即做点在多边形内的判断, 点在多边形内则认为有关系
 
 # 函数
 ## 代码
+<details>
+<summary>源码</summary>
+
 ```
-create or replace function public.rel_eq2sp(tables text, out_tables text, project_id character varying, sign1 integer, sign2 integer) returns boolean
-as
-$$
+CREATE OR REPLACE FUNCTION "public"."rel_eq2sp"("tables" text, "out_tables" text, "project_id" varchar, "sign1" int4, "sign2" int4)
+  RETURNS "pg_catalog"."bool" AS $BODY$
 from matplotlib.path import Path
 import json
 
@@ -80,8 +82,9 @@ with plpy.subtransaction():
             if len(equips) == 0:
                 continue
             # 获取楼层下的业务空间
-            space_plan = plpy.prepare("select id, outline from {0} as sp where project_id = $1 and outline is not null and floor_id = $2".format(in_table_name), ["text", "text"])
-            spaces = space_plan.execute([project_id, floor_id])
+
+            space_plan = plpy.prepare("select sp.id, sp.outline, sp.object_type from public.r_sp_in_fl rel inner join {0} sp on rel.space_id = sp.id where outline is not null and rel.floor_id = $1".format(in_table_name), ["text"])
+            spaces = space_plan.execute([floor_id])
             if len(spaces) == 0:
                 continue
             # 判断设备的bim_location是否在业务空间的outline内
@@ -91,18 +94,23 @@ with plpy.subtransaction():
                         location = equip['bim_location'].split(',')
                         if is_point_in_polygon(location[0], location[1], space['outline']):
                             # 设备在业务空间内, 添加关系
-                            insert_plan = plpy.prepare("insert into {0}(equip_id, space_id, project_id, sign) values($1, $2, $3, 2) ".format(out_table_name.strip()), ["text", "text", 'text'])
-                            insert_plan.execute([equip['id'], space['id'], project_id])
+                            insert_plan = plpy.prepare("insert into {0}(eq_id, sp_id, project_id, sign, type, zone_type) values($1, $2, $3, 2, 'eq2sp_in', $4)".format(out_table_name.strip()), ["text", "text", "text", "text"])
+                            insert_plan.execute([equip['id'], space['id'], project_id, space['object_type']])
                     except Exception as ex:
+                        plpy.warning(ex)
                         continue
 return True
-$$
-LANGUAGE 'plpython3u' VOLATILE;
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
 
 
 例子:
 select public.rel_eq2sp('zone_general,zone_lighting', 'r_eq_in_sp_zone_general,r_eq_in_sp_zone_lighting', 'Pj1101010015', 2, 2);
 ```
+</details>
+
+
 ## 输入
     1. 参与计算的业务空间表的全名称, 带schema名, 以英文逗号隔开
     2. 关系计算结果存储的表, 跟第一个参数一一对应, 带schema名, 以英文逗号隔开

+ 6 - 7
docs/dev/data-center/relations/belongs/Fl2Fl.md

@@ -1,14 +1,13 @@
-楼层贯通关系
+# 楼层贯通关系
 ## 前置条件
-两个楼层的model_id信息点需要一致并不能为空, 则认为两个楼层是贯通关系
+
+    1. 两个楼层的model_id信息点需要一致且不能为空, 则认为两个楼层是贯通关系
 ```
 FROM floor WHERE project_id='Pj4201050001' AND model_id is not null
 ```
-## 处理方式
-    1. 先删除项目下所有的贯通关系(只删除sign为2的关系)
-    2. 多表连接更新:
-        1. 根据model_id信息点多表连接
-        2. 将结果插入到r_fl_through_fl表中, sign置为2
+## 处理逻辑
+    1. 拿到所有楼层
+    2. 如果两个楼层的ModelId信息点相同, 则认为两楼层有贯通关系
 
 # 函数
 

+ 3 - 3
docs/dev/data-center/relations/belongs/Pe2Bd.md

@@ -1,11 +1,11 @@
-资产所在建筑
+# 资产所在建筑
 ## 前置条件
     1. 资产有绑定的设备或部件
     2. 绑定的设备或部件有所在建筑
 ## 依赖函数
     Eq2Bd
-## 计算流程
-    根据 资产 --> 设备/部件 --> 建筑 的间接关系, 来获取资产和建筑的所在关系
+## 处理逻辑
+    根据 资产 --> 设备/部件 --> 建筑 的间接从属关系, 来获取资产和建筑的所在关系
     
 ## 函数
 ```

+ 2 - 2
docs/dev/data-center/relations/belongs/Pe2Fl.md

@@ -1,10 +1,10 @@
-资产所在楼层
+# 资产所在楼层
 ## 前置条件
     1. 资产有绑定的设备或部件
     2. 绑定的设备或部件有所在楼层
 ## 依赖函数
     Eq2Fl
-## 计算流程
+## 处理逻辑
     根据 资产 --> 设备/部件 --> 楼层 的间接关系, 来获取资产所在建筑的关系
     
 ## 函数

+ 1 - 1
docs/dev/data-center/relations/belongs/Pe2Sh.md

@@ -1,4 +1,4 @@
-资产所在竖井
+# 资产所在竖井
 ## 前置条件
     1. 资产有绑定的设备或部件
     2. 绑定的设备或部件有所在竖井关系

+ 1 - 1
docs/dev/data-center/relations/belongs/Pe2Sp.md

@@ -1,4 +1,4 @@
-资产所在业务空间
+# 资产所在业务空间
 ## 前置条件
     1. 资产有绑定的设备或部件
     2. 绑定的设备或部件有所在业务空间关系

+ 3 - 3
docs/dev/data-center/relations/belongs/Sh2Bd.md

@@ -1,11 +1,11 @@
-竖井关联的建筑
+# 竖井关联的建筑
 
 # 计算流程
     
     根据竖井关联的空间关系来推导
     
-# 处理流程
-    1. 竖井包含有业务空间, 并且业务空间有所属建筑
+## 处理逻辑
+    1. 根据 竖井 --> 业务空间 --> 建筑 的间接关系, 来获取资产所在业务空间的关系
     
 # 函数
 

+ 3 - 2
docs/dev/data-center/relations/belongs/Sh2Sh.md

@@ -1,8 +1,9 @@
-竖井贯通关系
+# 竖井贯通关系
 ## 前置条件
     1. 竖井包含的有元空间(竖井在r_sh_contain_si表中有数据)
-## 处理流程
+## 处理逻辑
     1. 竖井包含有相同的元空间, 则认为两竖井贯通
+    (竖井包含元空间的数据是前端做划分)
 ## 函数
 ```
 -- 竖井贯通关系

+ 11 - 5
docs/dev/data-center/relations/belongs/Sp2Fl.md

@@ -1,16 +1,21 @@
-在多个楼层划分一个模型时, 根据已有的业务空间所属楼层数据重新计算业务空间所属楼层
+# 业务空间所属楼层 (关系由前端生成, 此算法是在多个楼层划分一个模型时, 根据已有的业务空间所属楼层数据重新计算业务空间所属楼层)
 ## 前置条件
     1. 楼层有外轮廓
     2. 业务空间有外轮廓
     3. 有2个或2个以上的楼层的ModelId相同(意思是一个模型划分成了多个楼层)
     4. 这些ModelId相同的楼层下有所属的业务空间关系
     5. 业务空间所属楼层表内维护的关系是正确的
-## 处理流程
-    1. 查出项目内所有ModelId相同的楼层(如果没有则返回)
-    2. 按照ModelId将楼层分组, 相同ModelId的楼层为一组, 每组内按照以下规则计算
-    3. 获取组内所有楼层下的业务空间, 将查出的业务空间的轮廓与楼层的轮廓比对是否有重叠部分(所有业务空间 X 所有楼层次对比), 如果有重叠则认为该业务空间和该楼层有关系
+    
+## 处理逻辑
+    1. 查出项目内所有ModelId相同的楼层(如果没有则结束)
+    2. 按照ModelId信息点将楼层分组, 相同ModelId的楼层为一组, 每组内按照以下规则计算
+    3. 获取组内所有楼层下的业务空间, 将查出的业务空间的轮廓与组内楼层的轮廓比对是否有重叠部分(所有业务空间 X 组内楼层个数次对比), 如果有重叠则认为该业务空间和该楼层有关系
     4. 在业务空间所属楼层表内删除该组楼层下的所有业务空间关系, 并插入新计算出的业务空间所属楼层的关系
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 
 CREATE OR REPLACE FUNCTION "public"."rel_sp2fl"("project_id" varchar)
@@ -171,6 +176,7 @@ $BODY$
 
 select public.rel_sp2fl('Pj1101050001')
 ```
+</details>
 
 ## 入参
     1. 项目id

+ 5 - 5
docs/dev/data-center/relations/belongs/Sp2Sp.md

@@ -2,15 +2,15 @@
 ## 前置条件
     1. 业务空间有所在楼层
     2. 业务空间有外轮廓
-## 处理流程
+## 处理逻辑
     1. 查出所有有所在楼层, 并且外轮廓不是null的业务空间
-    2. 根据所在楼层, 业务空间分区来将业务空间分组
-    3. 计算每个分组内的业务空间的相邻关系
+    2. 根据所在楼层, 业务空间分区类型来将业务空间分组
+    3. 分别计算每个分组内的业务空间的相邻关系
     计算相邻算法:
-    1. 首先判断围成业务空间的线段, 两两空间之间是否有近似平行的线段(线段偏转误差小于1度)
+    1. 首先判断围成业务空间轮廓的线段, 两两业务空间之间是否有近似平行的线段(线段平行偏转误差小于1度算作近似平行)
         1). 近似平行判断: 首先获取两个线段的斜率, 再计算斜率的反正切(即与x轴的角度, 不过是以pi为单位), 再判断两个角度差的绝对值是否小于1度
     2. 如果有近似平行的线段, 判断是否相互有投影在线段上, 有投影在线段上, 则认为是两平行线段有重合部分, 业务空间有相邻的可能性
-    3. 判断互相有投影点在对方线段上之后, 判断投影线的长度, 是否小于250mm(墙的最大厚度), 如果小于250mm则认为两空间相邻
+    3. 判断互相有投影点在对方线段上之后, 判断投影线的长度, 是否小于250mm(墙的最大厚度), 如果小于250mm则认为两空间相邻
 ## 函数
 ```
 create or replace function public.rel_sp2sp1(project_id character varying) returns boolean

+ 12 - 5
docs/dev/data-center/relations/belongs/Sp2Sp2.md

@@ -2,9 +2,9 @@
 ## 前置条件
     1. 业务空间有所在楼层
     2. 业务空间有外轮廓
-## 处理流程
-    1. 查出所有有所在楼层, 并且外轮廓不是null的业务空间
-    2. 根据所在楼层, 业务空间分区类型来将业务空间分组
+## 处理逻辑
+    1. 查出所有有所在楼层关系, 并且外轮廓不是null的业务空间
+    2. 根据所在楼层, 业务空间分区类型来将业务空间分为不同的 (例如 : A 楼层下的默认业务空间是一组, A楼层下的空调分区是另外一组)
     3. 计算每个分组内的业务空间的相邻关系
     计算相邻算法 (如下图):
     1. 在一个分组内, 遍历每个业务空间上组成外轮廓的每条线段, 根据线段的长度, 是否超过delta_distance来区分成两种情况判断
@@ -12,12 +12,17 @@
         在P5点处作AB线段的垂线线段, 上下两边长度均为door_length长, 找到点P4和P6. 同理可以找到点P7和P9. 
         2). 如果线段长度小于或等于delta_distance, 假设线段AE长度小于delta_distance, 则在线段中间点P2处作垂直于AE的垂线线段, 
         上下两边长度均为door_length长, 找到点P1和P3.
-    2. 将上面找到的点, 依次与其他业务空间外轮廓做一次点是否在多边形内的判断, 如果在, 则认为该多边形与图中多边形相邻
+    2. 将上面找到的点, 依次与组内其他业务空间外轮廓做一次点是否在多边形内的判断, 如果在, 则认为该多边形与图中多边形相邻
     
    
-  ![Image text](img/sp2sp2-1.PNG)
+![Image text](./img/sp2sp2-1.PNG)
 
 ## 函数
+
+
+<details>
+<summary>源码</summary>
+
 ```
 create function rel_sp2sp_v2(project_id character varying) returns boolean
     language plpython3u
@@ -300,6 +305,8 @@ alter function rel_sp2sp_v2(varchar) owner to postgres;
 select public.rel_sp2sp_v2('Pj1101050001')
 ```
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 1 - 1
docs/dev/data-center/relations/belongs/Sy2Bd.md

@@ -4,7 +4,7 @@
     2. 系统下的设备有所属建筑的关系
 ## 依赖函数
     Eq2Bd
-## 计算流程
+## 处理逻辑
     1. 通过 系统 --> 设备 --> 建筑 的间接关系, 获取系统所在建筑的关系
     2. 结果存储在 r_sy_in_bd 表中
     

+ 1 - 1
docs/dev/data-center/relations/belongs/Sy2Fl.md

@@ -4,7 +4,7 @@
     2. 系统下的设备有所属楼层关系
 ## 依赖函数
     Eq2Fl
-## 计算流程
+## 处理逻辑
     1. 通过 系统 --> 设备 --> 楼层 的间接关系, 获取系统所在楼层的关系
     2. 计算关系存储在表 r_sy_in_fl 中
 ## 函数

+ 1 - 1
docs/dev/data-center/relations/belongs/Sy2Sh.md

@@ -4,7 +4,7 @@
     2. 系统下的设备有所在竖井关系
 ## 依赖函数
     Eq2Sh
-## 计算流程
+## 处理逻辑
     1. 根据 系统 --> 设备 --> 竖井 来间接获取系统所属竖井关系
     2. 计算后的关系存储在表 r_sy_in_sh
 ## 函数

+ 1 - 1
docs/dev/data-center/relations/belongs/Sy2Sp.md

@@ -4,7 +4,7 @@
     2. 系统下的设备有所在业务空间关系
 ## 依赖函数
     Eq2Sp
-## 计算流程
+## 处理逻辑
     1. 根据 系统 --> 设备 --> 业务空间 的间接关系, 获取系统和业务空间的关系
     2. 计算结果存储在r_sy_in_sp_*中
 ## 函数

+ 3 - 3
docs/dev/data-center/relations/belongs/f_rel_calc.md

@@ -1,4 +1,4 @@
-管理关系计算函数依赖和函数输入类型
+# 管理关系计算函数依赖和函数输入类型
 
 # 说明
     classify 该变量是根据函数的输入将函数分类
@@ -6,12 +6,13 @@
 
 # 函数
 ## 代码
+
 ```
 CREATE OR REPLACE FUNCTION "public"."f_rel_calc"("func" text, "project_id" varchar, "tables" text, "out_tables" text, "sign1" int4, "sign2" int4)
   RETURNS "pg_catalog"."int4" AS $BODY$
 # 根据函数输入类型分类
 classify = {"eq2bd":1, "eq2fl":1, "sp2fl":1, "eq2sh":1, "pe2bd":1, "pe2fl":1, "pe2sh":1, "pe2sp":1, "sh2sh":1, "sy2bd":1,
-    "sy2fl":1, "sy2sh":1, "sy2sp":1, "bd2sp":2, "eq2sp":3, "fl2fl":4}
+    "sy2fl":1, "sy2sh":1, "sy2sp":1, "sh2bd":1, "bd2sp":2, "eq2sp":3, "fl2fl":4}
 dependency = {"eq2bd":["eq2fl"], "eq2sh":["eq2sp"], "eq2sp":["eq2fl", "sp2fl"], "pe2bd":["eq2bd"], "pe2fl":["eq2fl"], "pe2sh":["eq2sh"],
     "pe2sp":["eq2sp"], "sy2bd":["eq2bd"], "sy2fl":["eq2fl"], "sy2sh":["eq2sh"], "sy2sp":["eq2sp"]}
 def get_type_by_func_name(func_name):
@@ -76,7 +77,6 @@ $BODY$
   LANGUAGE plpython3u VOLATILE
   COST 100
 
-
 例子:
 select public.f_rel_calc('rel_eq2sh', 'Pj*******', 'zone_space_base','relationship.r_eq2sp', 2, 2)
 ```

BIN
docs/dev/data-center/relations/belongs/img/sp2sp2-1.PNG


+ 1 - 1
docs/dev/data-center/relations/other/calc_area_v3.md

@@ -3,7 +3,7 @@
 
 
-## 处理方式
+## 处理逻辑
 
 根据业务空间轮廓的格式, 以此计算内部每个小轮廓的面积, 加和在一起为最终结果
 小轮廓面积计算: 计算首个子轮廓面积, 并减去随后所有子轮廓的面积. 结果为小轮廓面积

+ 5 - 5
docs/dev/data-center/relations/other/calc_vertically_overlap.md

@@ -4,12 +4,12 @@
 ```
 
 ```
-## 处理方式
+## 处理逻辑
 
-获取所有建筑, for循环获取每个建筑下所有的业务空间, 按楼层分类
-每个楼层的每个业务空间分别和别的楼层的每个业务空间判断is_vertically_overlap
-将结果是true的两个业务空间保存起来
-删除旧业务空间的垂直交通关系(自动计算的), 添加新关系
+    1. 获取所有建筑, for循环获取每个建筑下所有的业务空间, 按楼层分类
+    2. 每个楼层的每个业务空间分别和别的楼层的每个业务空间判断is_vertically_overlap
+    3. 将结果是true的两个业务空间保存起来
+    4. 删除旧业务空间的垂直交通关系(自动计算的), 添加新关系
 
 ## 实现方式
 

+ 1 - 1
docs/dev/data-center/relations/other/other_ispace_floor_overlap.md

@@ -3,7 +3,7 @@
     1. 元空间和楼层必须都有轮廓
     2. 轮廓必须符合规则
     
-# 处理方式
+# 处理逻辑
 
     将楼层的外轮廓与元空间的最外层轮廓做是否重叠检查操作
 

+ 1 - 1
docs/dev/data-center/relations/other/rel_affected_space.md

@@ -9,7 +9,7 @@
 
 ## 依赖函数
-## 处理方式
+## 处理逻辑
 
     1. 查询出所有绑定该revit模型楼层的数据中心楼层
         SELECT id FROM public.floor where model_id = 'revit模型楼层'

+ 1 - 1
docs/dev/data-center/relations/other/rel_str_similar.md

@@ -6,7 +6,7 @@
 
 ## 依赖函数
-## 处理方式
+## 处理逻辑
 
     根据编辑距离来计算相似度
 

+ 1 - 1
docs/dev/data-center/relations/topology/sys_block.md

@@ -5,7 +5,7 @@
 3. 相邻层立管开放端口坐标位置相等(距离差值不能超过0.01)
 4. (非强制)通过模型检查:连接件检查、系统类型名称检查、管网及相关设备检查、管段检查
 
-## 处理方式
+## 处理逻辑
 
 1. 获取所有当前项目project_id下的的有模型文件models; 表:revit.model_folder、revit.model_floor、revit.model_file
 2. 遍历models,获取model层的系统图systemGraphs;

+ 1 - 1
docs/dev/data-center/relations/topology/sys_direction.md

@@ -4,7 +4,7 @@
 1. 通过管网系统分块计算;
 2. 指定源。
 
-## 处理方式
+## 处理逻辑
 
 1. 从connected_block表中取出所有关系,构建无向图
 2. 从connected_block_source表中取出所有的源

+ 1 - 0
docs/dev/saga-graphy/index.js

@@ -25,6 +25,7 @@ const content = [
                     ["/dev/saga-graphy/scene-manage/items/clock", "时钟"],
                     ["/dev/saga-graphy/scene-manage/items/text", "文本"],
                     ["/dev/saga-graphy/scene-manage/items/image", "图片"],
+                    ["/dev/saga-graphy/scene-manage/items/editLine", "可编辑直线"],
                     ["/dev/saga-graphy/scene-manage/items/edit-polygon", "可编辑多边形示例"],
                     ["/dev/saga-graphy/scene-manage/items/imgText", "图例item(图片文本组合)"]
                 ]

+ 17 - 0
docs/dev/saga-graphy/scene-manage/items/editLine.md

@@ -0,0 +1,17 @@
+# 可编辑直线示例
+::: details 目录
+[[toc]]
+:::
+
+<example-web-graph-scene-SEditLine/>
+
+::: tip 注
+1、可以通过双击table在编辑状态和展示状态来回切换,<br/>
+2、创建状态时;enter + 左键闭合多边形 <br/>
+3、编辑状态时:鼠标点击在边上可加点,可拖动点;<br/>
+4、编辑状态时:通过ALT键 + 鼠标左键 删除顶点
+:::
+
+::: details 查看代码
+<<< @/docs/.vuepress/components/example/web/graph/scene/SEditLine.vue
+:::

+ 23 - 16
docs/dev/saga-graphy/system-diagram/json-file.md

@@ -6,8 +6,10 @@
 ## 整体数据格式
 
 ```
-    {
-        EntityList:[
+{
+    Data:[
+        {
+            EntityList:[],
             Elements:{                          // 系统图展示所需数据
                 Nodes:[],                       // 图例节点,所有与工程信息化相关的图例(图标类型与区域)
                 Markers:[],                     // 与工程信息无关的标识对象(增加文本注释,图上的图片说明)
@@ -19,24 +21,29 @@
             ProjectID: '',                      // 项目ID
             BuildingID: '',                     // 建筑ID
             FloorID: '',                        // 楼层id
-            Note: '',                           // 图说明
-        ]
-    }
+            Note: ''                           // 图说明
+            
+        }
+    ],
+    Message: '',
+    Result: ''
+}
 ```
 
 ## 图例节点
 
 ```
     Nodes:[
-        {
+        {   
             ID: '',                             // ID
             Name: '',                           // 名称
             AttachObjectIds:[],                 // 返回工程信息化对象 ID 列表
-            GraphElementType: '',               // 图标,区域类型
+            GraphElementType: '',               // 图例类型 None/Line/Zone/Image:非图例/线条/区域类型/图标
             GraphElementId: '',                 // 对应的图元ID
-            Pos: {X: 0, y: 0},                  // 位置
-            Scale: {X: 1, y: 1, Z: 1},          // 缩放
-            Rolate: {X: 0, y: 0, Z: 0},         // 旋转
+            Num: 1                              //图例数量
+            Pos: {X: 0, Y: 0},                  // 位置
+            Scale: {X: 1, Y: 1, Z: 1},          // 缩放
+            Rolate: {X: 0, Y: 0, Z: 0},         // 旋转
             Size: {Width:0, Height: 0},         // 大小
             AnchorList:[
                     {
@@ -62,10 +69,10 @@
         {
             ID: '',                             // ID
             Name: '',                           // 名称
-            Type: '',                           // 图标(Image),线类型(Line)
+            Type: '',                           // 图标(Image),线类型(Line),文本(Text)
             Pos: {X: 0, y: 0},                  // 位置
-            Scale: {X: 1, y: 1, Z: 1},          // 缩放
-            Rolate: {X: 0, y: 0, Z: 0},         // 旋转
+            Scale: {X: 1, Y: 1, Z: 1},          // 缩放
+            Rolate: {X: 0, Y: 0, Z: 0},         // 旋转
             Size: {Width:0, Height: 0},         // 大小
             Properties: {}                      // 由应用自己定义
         },
@@ -81,12 +88,12 @@
             ID: '',                             // ID
             Name: '',                           // 名称
             GraphElementId: '',                 // 对应的图例ID
-            NodeID1: '',                        // 关联节点1_id
-            NodeID2: '',                        // 关联节点2_id
+            Node1ID: '',                        // 关联节点1_id
+            Node2ID: '',                        // 关联节点2_id
             Anchor1ID: '',                      // 关联锚点1_id
             Anchor2ID: '',                      // 关联锚点2_id
             Dir: 0,                             // 方向(0:无向,1:节点1到节点2,2:节点2到节点1)
-            LineType: '',                       // 直线,水平垂直
+            LineType: '',                       // 直线(Line),水平垂直
             PointList: [],                      // 线的顶点坐标
             Style: ''                           // 线的绘图样式
         },