| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480 |
- import {Diagram, Template, EquipmentNode, Line, Comp, Container, MainPipe, Legend, Anchor, Point4Anchor} from './DiagramModel';
- import {Point, BackgroundPaniter, ViewTool} from './UIUtils';
- import {Editor, Selection} from './Editor';
- /**
- * 系统图编辑器,演示版本
- * @author zhaoyk
- */
- export class DiagramEditor extends Editor {
- private util: EditUtil;
-
- diagram: Diagram;
- templateData: Template;
- libertyCons: Array<Container>; //自由定位的容器
-
- tmpMainPipe:Array<Array<Point>>;
- currentTmpMainPipe:Array<Point>;
-
- showData(data?: any): void {
- this.diagram = (<Diagram>data);
- this.templateData = this.diagram.template;
- this.selection = new Selection();
-
- this.setState(this.getState());
- this.util = new EditUtil(this);
-
- this.redraw();
- }
- protected initCanvasSize(): Point {
- return new Point(3500, 3500);
- }
-
- addListeners():void {
- this.canvas.addEventListener('click', event=>{this.onClick(event)});
- this.container.addEventListener("mousemove", event=>{this.onMouseMove(event)});
- }
-
- setState(state: number): void{
- this.state = state;
-
- if(this.state == 9)
- this.tmpMainPipe = new Array<Array<Point>>();
- else
- this.tmpMainPipe = null;
-
- this.currentTmpMainPipe = null;
- }
-
- redraw(): void {
- this.beforeRedraw();
-
- if(!this.diagram.template)
- return;
-
- this.libertyCons = new Array<Container>();
- const root = this.templateData.frame;
- this.util.prepareParent(root);
- //绘制排列定位容器
- this.drawContainer(root);
-
- //绘制自由定位容器
- const p = new Point(root.location.x, root.location.y);
- p.y += root.size.y;
- this.libertyCons.forEach(con => {
- p.y += 20;
- con.location = new Point(p.x, p.y);
- this.drawContainer(con, true);
- p.y += con.size.y;
- });
-
- //绘制干管
- if(this.templateData.mainPipes) {
- this.templateData.mainPipes.forEach(item => {
- this.ctx.strokeStyle = "#000000";
- this.ctx.setLineDash([]);
- this.ctx.lineWidth = 2;
- if(this.getSelComp() == item)
- this.ctx.strokeStyle = "#5783FA";
-
- this.ctx.beginPath();
- for(const arr of item.locationPath){
- var iter = 0;
- for(var p of arr) {
- p = this.util.toCanvas(p);
- if(iter == 0)
- this.ctx.moveTo(p.x, p.y);
- else
- this.ctx.lineTo(p.x, p.y);
- iter++;
- }
- }
- this.ctx.stroke();
- });
- }
-
- //绘制连线
- if(this.diagram.lines) {
- this.diagram.lines.forEach(line => {
- if(line.locationPath) {
- this.ctx.strokeStyle = "#000000";
- this.ctx.setLineDash([]);
- this.ctx.lineWidth = 1;
-
- this.ctx.beginPath();
- var iter = 0;
- for(var p of line.locationPath){
- p = this.util.toCanvas(p);
- if(iter == 0)
- this.ctx.moveTo(p.x, p.y);
- else
- this.ctx.lineTo(p.x, p.y);
- iter++;
- }
- this.ctx.stroke();
- }
- });
- }
- }
-
- private drawContainer(con:Container, drawLiberty?:boolean) {
- if(!drawLiberty && con.position.absolute)
- return;
- if(con.size.x == 0 && con.size.y == 0)
- return;
-
- const liberty = con.position.absolute;
- const location = !liberty ? this.util.locationOnCanvas(con) : this.util.toCanvas(con.location);
-
- const equip = con.equipmentTypes && con.equipmentTypes.length > 0;
- var color = !liberty ? "#9b9ea3": "#42B983";
- var dash = [3, 2];
-
- if(equip) {
- this.ctx.lineWidth = 1;
- this.ctx.setLineDash(dash);
- this.ctx.strokeStyle = color;
-
- this.ctx.beginPath();
- this.ctx.rect(location.x, location.y, con.size.x, con.size.y);
- this.ctx.closePath();
-
- if(this.getSelComp() == con) {
- this.ctx.fillStyle = "rgba(0, 127, 255, 0.1)";
- this.ctx.fill();
- }
- this.ctx.stroke();
- }
- if(con.children)
- con.children.forEach(item => {
- if(item.compType == 'container')
- this.drawContainer(<Container>item);
- else if(item.compType == 'equipmentNode')
- this.drawEquipNode(<EquipmentNode>item);
- else if(item.compType == 'packNode')
- this.drawEquipNode(<EquipmentNode>item);
- });
- }
-
- private drawEquipNode(node: EquipmentNode): void {
- const location = this.util.locationOnCanvas(node);
-
- this.ctx.lineWidth = 1;
- this.ctx.setLineDash([]);
- this.ctx.strokeStyle = "#000000";
-
- this.ctx.beginPath();
- this.ctx.rect(location.x, location.y, node.size.x, node.size.y);
- if(this.getSelComp() == node) {
- this.ctx.fillStyle = "rgba(0, 127, 255, 0.1)";
- this.ctx.fill();
- }
- this.ctx.stroke();
- if(node.anchorLocations) {
- for(const code in node.anchorLocations) {
- this.ctx.beginPath();
- var p: Point = node.anchorLocations[code];
- p = new Point(p.x + location.x, p.y + location.y);
- ViewTool.paintPoint(this.ctx, p, '#000000', true);
- }
- }
- if(node.label) {
- const lbl = node.label;
- ViewTool.drawText(this.ctx, lbl.content, new Point(location.x + lbl.location.x, location.y + lbl.location.y), node.size);
- }
- }
-
- // private redrawOnScroll(_this) {
- // const top = _this.container.scrollTop;
- // const left = _this.container.scrollLeft;
- // _this.canvas.style.top = top + 'px';
- // _this.canvas.style.left = left + 'px';
-
- // _this.draw(_this.mapData);
- // }
-
- private onClick(event): void {
- if(this.state != 9) { //selection
- var sel:any = this.util.findMainPipe(event.layerX, event.layerY);
- if(sel == null)
- sel = this.util.findComp(event.layerX, event.layerY);
-
- if(sel != this.getSelComp)
- this.setSelComp(sel);
- } else { //paint main pipe
- if(this.currentTmpMainPipe == null) {
- this.currentTmpMainPipe = new Array<Point>();
- this.tmpMainPipe.push(this.currentTmpMainPipe);
- }
-
- const point = new Point(event.layerX, event.layerY);
- this.adjustPointForMp(point);
- this.currentTmpMainPipe.push(point);
-
- this.redraw();
- }
- }
-
- setSelComp(comp: any): void{
- this.selection.setSel(comp);
- this.redraw();
-
- this.editorPart.onSelectionChange();
- }
-
- getSelComp(): any {
- if(!this.selection)
- return null;
- return this.selection.getSel();
- }
-
- buildSelInfo(){
- var info = null;
- const sel = this.getSelComp();
- if(sel != null) {
- if(sel.compType == "equipmentNode") {
- info = '设备id: ' + sel.dataObject.id;
- info += ' | 设备类型: ' + sel.dataObject.classCode;
- info += ' | 设备名称: ' + sel.dataObject.name;
- } else {
- info = 'id: ' + sel.id;
- if(sel.name)
- info += ' | 名称: ' + sel.name;
- if(sel.layout) {
- if(sel.layout.layout == 1)
- info += ' | 布局方式: 行式';
- else if(sel.layout.layout == 2)
- info += ' | 布局方式: 列式';
- }
- if(sel.equipmentTypes && sel.equipmentTypes.length > 0){
- info += ' | 设备类型: ' + sel.equipmentTypes;
- }
- if(sel.locationPath){
- var str = '';
- const arr:Array<Array<Point>> = new Array<Array<Point>>();
- for(const line of sel.locationPath) {
- const ps:Array<Point> = new Array<Point>();
- arr.push(ps);
-
- line.forEach(item => {
- ps.push(this.util.toCanvas(item));
- });
-
- if(str.length > 0)
- str += ", ";
- str += ViewTool.pointsToStr(ps);
- }
- info += ' | ' + str;
- }
- }
- }
-
- if(info == null)
- info = '~';
- return info;
- }
-
- getState(): number {
- const sel = this.getSelComp();
- if(!sel)
- return 0;
- if(sel.locationPath)
- return 2;
- return 1;
- }
-
- getCompById(id: string): any {
- if(!id)
- return null;
-
- if(this.templateData.mainPipes) {
- for(const mp of this.templateData.mainPipes) {
- if(mp.id == id)
- return mp;
- }
- }
-
- return this.getConById(id);
- }
-
- getConById(id:string): Container {
- return this.findCon(id, this.templateData.frame);
- }
- private findCon(id:string, con: Container): Container {
- if(con.id == id)
- return con;
- for(const sub of con.children) {
- if(sub.compType == 'container') {
- const rtn = this.findCon(id, <Container>sub);
- if(rtn != null)
- return rtn;
- }
- }
- return null;
- }
- //干管绘制时,自动调整横平竖直
- private adjustPointForMp(point: Point) {
- if(this.currentTmpMainPipe && this.currentTmpMainPipe.length > 0) {
- const pre = this.currentTmpMainPipe[this.currentTmpMainPipe.length - 1];
- if(Math.abs(pre.x - point.x) < Math.abs(pre.y - point.y))
- point.x = pre.x;
- else
- point.y = pre.y;
- }
- }
-
- private onMouseMove(event): void {
- if(this.state == 9) {
- const point = new Point(event.layerX, event.layerY);
- this.adjustPointForMp(point);
-
- //显示当前坐标位置
- this.editorPart.dynInfo = ViewTool.pointToStr(point);
-
- this.redraw();
- }
- }
- }
- class EditUtil {
-
- private editor:DiagramEditor;
-
- private template:Template;
- constructor(editor:DiagramEditor) {
- this.editor = editor;
- this.template = editor.templateData;
- }
-
- prepareParent(con:Container) {
- if(con.children) {
- con.children.forEach(item => {
- item.parent = con;
-
- if(item.compType == 'container') {
- this.prepareParent(<Container>item);
-
- if(item.position.absolute)
- this.editor.libertyCons.push(<Container>item);
- }
- });
- }
- }
-
- clearParent(con:Container){
- con.parent = null;
- con.children.forEach(item => {
- item.parent = null;
-
- if(item.compType == 'container')
- this.clearParent(<Container>item);
- });
- }
-
- locationOnDiagram(con:Comp): Point {
- const p:Point = new Point(0, 0);
- var c = con;
- while (c != null){
- p.x += c.location.x;
- p.y += c.location.y;
-
- c = c.parent;
- }
- return p;
- }
-
- locationOnCanvas(con:Comp): Point {
- return this.toCanvas(this.locationOnDiagram(con));
- }
-
- toCanvas(point:Point): Point {
- return new Point(point.x + this.editor.margin, point.y + this.editor.margin);
- }
-
- findComp(x:number, y:number): Comp {
- var rtn = this.tryFindComp(x, y, this.template.frame);
- if(!rtn) {
- for(const con of this.editor.libertyCons){
- rtn = this.tryFindComp(x, y, con);
- if(rtn)
- break;
- }
- }
- return rtn;
- }
-
- private tryFindComp(x:number, y:number, target:Comp): Comp {
- if(this.containsPoint(target, x, y)){
- if(target.compType == 'container') {
- for(const item of (<Container>target).children) {
- const c = this.tryFindComp(x, y, item);
- if(c != null)
- return c;
- }
- }
- return target;
- }
- return null;
- }
-
- containsPoint(con:Comp, x:number, y:number):boolean{
- if(con.location){
- var point;
- if(con.position && con.position.absolute)
- point = this.toCanvas(con.location)
- else
- point = this.locationOnCanvas(con);
- return x >= point.x && y >= point.y && x <= point.x + con.size.x && y <= point.y + con.size.y;
- }
- return false;
- }
-
- findMainPipe(x:number, y:number): any {
- if(this.template.mainPipes) {
- for(const mp of this.template.mainPipes){
- for(const line of mp.locationPath) {
- var pre: Point = null;
- for(var point of line) {
- point = this.toCanvas(point);
- if(pre != null) {
- var x1:number;
- var y1:number;
- var x2:number;
- var y2:number;
- const scope = 3;
- if(pre.y == point.y) { //水平
- y1 = pre.y - scope;
- y2 = pre.y + scope;
- x1 = Math.min(pre.x, point.x);
- x2 = Math.max(pre.x, point.x);
- } else { //垂直
- x1 = pre.x - scope;
- x2 = pre.x + scope;
- y1 = Math.min(pre.y, point.y);
- y2 = Math.max(pre.y, point.y);
- }
- if(x >= x1 && y >= y1 && x <= x2 && y <= y2)
- return mp;
- }
- pre = point;
- }
- }
- }
- }
- return null;
- }
-
- }
|