|
@@ -0,0 +1,348 @@
|
|
|
|
+/*
|
|
|
|
+ * ********************************************************************************************************************
|
|
|
|
+ *
|
|
|
|
+ * :*$@@%$*: ;: ;; ;;
|
|
|
|
+ * :@@%! :!@@%: %! ;%%@@%$ =@@@@@@@%; @%@@@%%%%@@@@@
|
|
|
|
+ * :@%; :$= %%$$$%$$ ;$$ ;$@= !@$
|
|
|
|
+ * =@! %! @ $=;% !@@@%: !$$$$$$$$$$$$$$=
|
|
|
|
+ * =@* %! @ $= % %@= =%@! %=
|
|
|
|
+ * *$%%! @@= ;=$%%%$*: %! @ $= % =%%%%%%@$ *%: =%
|
|
|
|
+ * %@@!: !@@@%=$@@@@%! :*@@$: %! @ $= % $* ;@ @* :%*
|
|
|
|
+ * ;@@! ;!!!;: ;@%: =======@%========* @ $$ % $%*****$@ :@$=*********=@$
|
|
|
|
+ * $@* ;@@@%=!: *@*
|
|
|
|
+ * =@$ ;;;!=%@@@@=! =@!
|
|
|
|
+ * %@$: =@%: :*@@@* %@= Copyright (c) 2016-2020. 北京上格云技术有限公司
|
|
|
|
+ * ;%@@$=$@@%* *@@@$=%@@%;
|
|
|
|
+ * ::;:: ::;:: All rights reserved.
|
|
|
|
+ *
|
|
|
|
+ * ********************************************************************************************************************
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+import { SGraphyItem } from "@saga-web/graphy/lib";
|
|
|
|
+import { SColor, SLine, SPainter, SPoint, SRect } from "@saga-web/draw/lib";
|
|
|
|
+import { Relation } from "../types/Relation";
|
|
|
|
+import { SMouseEvent } from "@saga-web/base/lib";
|
|
|
|
+import { BaseRelationItem } from "./BaseRelationItem";
|
|
|
|
+import { AnchorItem } from "./AnchorItem";
|
|
|
|
+import { ItemOrder } from "../types/ItemOrder";
|
|
|
|
+import { SMathUtil } from "../util/SMathUtil";
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 关系item-折线画法-横平竖直
|
|
|
|
+ *
|
|
|
|
+ * @author 郝建龙
|
|
|
|
+ */
|
|
|
|
+export class DirectRelationItem extends BaseRelationItem {
|
|
|
|
+ /** 关系数据 */
|
|
|
|
+ data: Relation | null = null;
|
|
|
|
+ /** 折点信息 */
|
|
|
|
+ pointList: SPoint[] = [];
|
|
|
|
+ /** 尾端折点3 */
|
|
|
|
+ lastPointList: SPoint[] = [];
|
|
|
|
+ /** 是否结束 */
|
|
|
|
+ closeFlag = false;
|
|
|
|
+ /** 两端锚点-锚点1 */
|
|
|
|
+ Anchor1: AnchorItem | null = null;
|
|
|
|
+ /** 两端锚点-锚点2 */
|
|
|
|
+ Anchor2: AnchorItem | null = null;
|
|
|
|
+ /** 动画设置参数-偏移量 */
|
|
|
|
+ private _dashOffset: number = 20;
|
|
|
|
+ get dashOffset(): number {
|
|
|
|
+ return this._dashOffset;
|
|
|
|
+ }
|
|
|
|
+ set dashOffset(value: number) {
|
|
|
|
+ this._dashOffset = value;
|
|
|
|
+ this.update();
|
|
|
|
+ }
|
|
|
|
+ /** 当前选中点index */
|
|
|
|
+ curIndex: number = 0;
|
|
|
|
+ /** 计算时最小距离设置 */
|
|
|
|
+ len: number = 15;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 构造函数
|
|
|
|
+ *
|
|
|
|
+ * @param parent 指向父对象
|
|
|
|
+ * @param data Relation数据
|
|
|
|
+ */
|
|
|
|
+ constructor(parent: SGraphyItem | null, data: Relation) {
|
|
|
|
+ super(parent);
|
|
|
|
+ this.data = data;
|
|
|
|
+ this.selectable = true;
|
|
|
|
+ this.Anchor1 = data.Anchor1 || null;
|
|
|
|
+ this.Anchor2 = data.Anchor2 || null;
|
|
|
|
+ this.zOrder = ItemOrder.RelateOrder;
|
|
|
|
+ if (data.PointList) {
|
|
|
|
+ this.pointList = data.PointList.map(it => {
|
|
|
|
+ let x = it.X,
|
|
|
|
+ y = it.Y;
|
|
|
|
+ if (x < this.minX) {
|
|
|
|
+ this.minX = x;
|
|
|
|
+ }
|
|
|
|
+ if (y < this.minY) {
|
|
|
|
+ this.minY = y;
|
|
|
|
+ }
|
|
|
|
+ if (x > this.maxX) {
|
|
|
|
+ this.maxX = x;
|
|
|
|
+ }
|
|
|
|
+ if (y > this.maxY) {
|
|
|
|
+ this.maxY = y;
|
|
|
|
+ }
|
|
|
|
+ return new SPoint(x, y);
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ if (this.Anchor1) {
|
|
|
|
+ this.pointList.push(
|
|
|
|
+ this.Anchor1.mapToScene(this.Anchor1.X, this.Anchor1.Y)
|
|
|
|
+ );
|
|
|
|
+ this.lastPointList = [
|
|
|
|
+ this.Anchor1.mapToScene(this.Anchor1.X, this.Anchor1.Y)
|
|
|
|
+ ];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } // Constructor
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 鼠标按下事件
|
|
|
|
+ *
|
|
|
|
+ * @param event 事件参数
|
|
|
|
+ * @return boolean
|
|
|
|
+ */
|
|
|
|
+ onMouseDown(event: SMouseEvent): boolean {
|
|
|
|
+ if (event.buttons == 1) {
|
|
|
|
+ if (this.closeFlag) {
|
|
|
|
+ let len = 15;
|
|
|
|
+ for (let i = 0; i < this.pointList.length; i++) {
|
|
|
|
+ let dis = SMathUtil.pointDistance(
|
|
|
|
+ event.x,
|
|
|
|
+ event.y,
|
|
|
|
+ this.pointList[i].x,
|
|
|
|
+ this.pointList[i].y
|
|
|
|
+ );
|
|
|
|
+ if (dis < len) {
|
|
|
|
+ len = dis;
|
|
|
|
+ this.curIndex = i;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (event.altKey && this.canMove()) {
|
|
|
|
+ this.pointList.splice(this.curIndex, 1);
|
|
|
|
+ this.curIndex = -1;
|
|
|
|
+ this.update();
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ if (this.scene) {
|
|
|
|
+ this.scene.grabItem = this;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (this.lastPointList.length > 0) {
|
|
|
|
+ for (let i = 1; i < this.lastPointList.length; i++) {
|
|
|
|
+ this.pointList.push(this.lastPointList[i]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (this.Anchor2) {
|
|
|
|
+ this.closeFlag = true;
|
|
|
|
+ }
|
|
|
|
+ this.update();
|
|
|
|
+ return true;
|
|
|
|
+ } // Function onMouseDown()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 鼠标移动事件
|
|
|
|
+ *
|
|
|
|
+ * @param event 事件参数
|
|
|
|
+ * @return boolean
|
|
|
|
+ */
|
|
|
|
+ onMouseMove(event: SMouseEvent): boolean {
|
|
|
|
+ if (this.closeFlag) {
|
|
|
|
+ //连线完成,拖动其中的点
|
|
|
|
+ if (this.canMove()) {
|
|
|
|
+ this.pointList[this.curIndex].x = event.x;
|
|
|
|
+ this.pointList[this.curIndex].y = event.y;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ //连线未完成
|
|
|
|
+ if (this.pointList.length) {
|
|
|
|
+ this.lastPointList = [
|
|
|
|
+ this.pointList[this.pointList.length - 1],
|
|
|
|
+ new SPoint(event.x, event.y)
|
|
|
|
+ ];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ this.update();
|
|
|
|
+ return true;
|
|
|
|
+ } // Function onMouseMove()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 鼠标抬起事件
|
|
|
|
+ *
|
|
|
|
+ * @param event 事件参数
|
|
|
|
+ * @return boolean
|
|
|
|
+ */
|
|
|
|
+ onMouseUp(event: SMouseEvent): boolean {
|
|
|
|
+ this.curIndex = -1;
|
|
|
|
+ if (this.scene) {
|
|
|
|
+ this.scene.grabItem = null;
|
|
|
|
+ }
|
|
|
|
+ this.update();
|
|
|
|
+ return true;
|
|
|
|
+ } // Function onMouseUp()
|
|
|
|
+
|
|
|
|
+ /***
|
|
|
|
+ * 键盘按键弹起事件
|
|
|
|
+ *
|
|
|
|
+ * @param event 事件参数
|
|
|
|
+ */
|
|
|
|
+ onKeyUp(event: KeyboardEvent): void {
|
|
|
|
+ if (event.keyCode == 13) {
|
|
|
|
+ this.closeFlag = true;
|
|
|
|
+ }
|
|
|
|
+ if (event.keyCode == 46 || event.keyCode == 8) {
|
|
|
|
+ console.log("删除");
|
|
|
|
+ if (this.canMove) {
|
|
|
|
+ this.pointList.splice(this.curIndex + 1, 1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } // Function onKeyUp()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 当前点是否可删除或移动
|
|
|
|
+ *
|
|
|
|
+ * */
|
|
|
|
+ private canMove(): boolean {
|
|
|
|
+ return this.curIndex > 0 && this.curIndex < this.pointList.length - 1;
|
|
|
|
+ } // canMove()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 鼠标右键事件
|
|
|
|
+ *
|
|
|
|
+ * @param event 事件参数
|
|
|
|
+ * @return boolean
|
|
|
|
+ */
|
|
|
|
+ onContextMenu(event: SMouseEvent): boolean {
|
|
|
|
+ this.$emit("ContextMenu", event);
|
|
|
|
+ return true;
|
|
|
|
+ } // Function onContextMenu()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 鼠标双击事件
|
|
|
|
+ *
|
|
|
|
+ * @param event 事件参数
|
|
|
|
+ * @return boolean
|
|
|
|
+ */
|
|
|
|
+ onDoubleClick(event: SMouseEvent): boolean {
|
|
|
|
+ let len = SMathUtil.pointToLine(
|
|
|
|
+ new SPoint(event.x, event.y),
|
|
|
|
+ new SLine(this.pointList[0], this.pointList[1])
|
|
|
|
+ ),
|
|
|
|
+ index = 0;
|
|
|
|
+ if (this.pointList.length > 2) {
|
|
|
|
+ for (let i = 1; i < this.pointList.length - 1; i++) {
|
|
|
|
+ let dis = SMathUtil.pointToLine(
|
|
|
|
+ new SPoint(event.x, event.y),
|
|
|
|
+ new SLine(this.pointList[i], this.pointList[i + 1])
|
|
|
|
+ );
|
|
|
|
+ if (dis.MinDis < len.MinDis) {
|
|
|
|
+ len = dis;
|
|
|
|
+ index = i;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (len.Point) {
|
|
|
|
+ this.pointList.splice(index + 1, 0, len.Point);
|
|
|
|
+ this.update();
|
|
|
|
+ }
|
|
|
|
+ this.$emit("onDoubleClick", event);
|
|
|
|
+ return true;
|
|
|
|
+ } // Function onDoubleClick()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 点击点是否在item范围内
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+ contains(x: number, y: number): boolean {
|
|
|
|
+ if (this.closeFlag) {
|
|
|
|
+ let p = new SPoint(x, y);
|
|
|
|
+ // todo差缩放
|
|
|
|
+ for (let i = 1; i < this.pointList.length; i++) {
|
|
|
|
+ let PTL = SMathUtil.pointToLine(
|
|
|
|
+ p,
|
|
|
|
+ new SLine(
|
|
|
|
+ this.pointList[i - 1].x,
|
|
|
|
+ this.pointList[i - 1].y,
|
|
|
|
+ this.pointList[i].x,
|
|
|
|
+ this.pointList[i].y
|
|
|
|
+ )
|
|
|
|
+ );
|
|
|
|
+ if (PTL.MinDis < this.len) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /***/
|
|
|
|
+ change(): void {
|
|
|
|
+ if (this.pointList.length) {
|
|
|
|
+ if (this.Anchor1) {
|
|
|
|
+ // 判断删除equip后,不移动
|
|
|
|
+ if (this.Anchor1.parent && this.Anchor1.parent.parent) {
|
|
|
|
+ this.pointList[0] = this.Anchor1.mapToScene(
|
|
|
|
+ this.Anchor1.X,
|
|
|
|
+ this.Anchor1.Y
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (this.Anchor2) {
|
|
|
|
+ // 删除equip后
|
|
|
|
+ if (this.Anchor2.parent && this.Anchor2.parent.parent) {
|
|
|
|
+ this.pointList[
|
|
|
|
+ this.pointList.length - 1
|
|
|
|
+ ] = this.Anchor2.mapToScene(this.Anchor2.X, this.Anchor2.Y);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ this.update();
|
|
|
|
+ } // Function change()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Item绘制操作
|
|
|
|
+ *
|
|
|
|
+ * @param painter painter对象
|
|
|
|
+ */
|
|
|
|
+ onDraw(painter: SPainter): void {
|
|
|
|
+ painter.pen.lineWidth = 3;
|
|
|
|
+ painter.pen.color = new SColor("#409EFF");
|
|
|
|
+ painter.brush.color = new SColor("#409EFF");
|
|
|
|
+ painter.drawPolyline(this.pointList);
|
|
|
|
+
|
|
|
|
+ painter.pen.lineWidth = 1;
|
|
|
|
+ painter.pen.lineDash = [10, 10];
|
|
|
|
+ painter.pen.dashOffset = this.dashOffset;
|
|
|
|
+ painter.pen.color = SColor.White;
|
|
|
|
+ painter.drawPolyline(this.pointList);
|
|
|
|
+
|
|
|
|
+ if (this.name) {
|
|
|
|
+ painter.brush.color = SColor.Black;
|
|
|
|
+ painter.font.size = 12;
|
|
|
|
+ painter.drawText(
|
|
|
|
+ this.name,
|
|
|
|
+ this.pointList[0].x + 20,
|
|
|
|
+ this.pointList[0].y
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.dashOffset -= 3;
|
|
|
|
+ if (!this.closeFlag) {
|
|
|
|
+ painter.pen.color = new SColor("#409EFF");
|
|
|
|
+ painter.drawPolyline(this.lastPointList);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (let i = 1; i < this.pointList.length - 1; i++) {
|
|
|
|
+ painter.drawCircle(this.pointList[i].x, this.pointList[i].y, 5);
|
|
|
|
+ }
|
|
|
|
+ } // Function onDraw()
|
|
|
|
+} // Class RelationItem
|