Commit 1f6bb6b6 by 吴斌

update:缩放,旋转,连接,信息展示。

parent 34606e2c
<!-- <template>
<div id="myDiagramDiv" style="width:800px; height:800px;"></div>
</template>
<script setup lang="ts">
import go from "gojs";
import { onMounted } from "vue";
let $ = go.GraphObject.make; // for conciseness in defining templates
var myDiagram:any = null;
var myAnimation:any = null;
var bucketAnimation:any = null;
function init(){
myDiagram = $(go.Diagram, "myDiagramDiv", // create a Diagram for the DIV HTML element
{
"undoManager.isEnabled": true, // enable undo & redo
// "allowMove": false,
});
// define a simple Node template
myDiagram.nodeTemplateMap.add(
"rect",
$(go.Node, "Auto",
$(go.Shape, "RoundedRectangle", { strokeWidth: 0, fill: "white" },
new go.Binding("fill", "color")),
$(go.TextBlock,
{ margin: 8 ,text: "123"},
new go.Binding("text", "key"))
));
myDiagram.nodeTemplateMap.add(
'bucket',
$(go.Node, "Position",
$(go.Shape, { strokeWidth: 1, fill: "white", width:100, height:100 }, new go.Binding("fill", "color")),
$(go.Shape,{strokeWidth: 1, fill:'white', name:"BUCKET", width: 100, height: 0}, new go.Binding("height", "height").makeTwoWay()),
$(go.TextBlock,
{ margin: 8 ,text: "123"},
new go.Binding("text", "key"))
)
)
myDiagram.linkTemplateMap.add(
'animated',
$(go.Link,{
routing: go.Link.AvoidsNodes,
curve: go.Link.JumpGap,
corner: 5,
toShortLength: 7,
relinkableFrom: true,
relinkableTo: true,
reshapable: true,
resegmentable: true,
},
$(go.Shape, { isPanelMain:true, strokeWidth: 7, stroke: 'black'}),
$(go.Shape, { isPanelMain:true, strokeWidth: 5, stroke: 'red'}),
$(go.Shape, { isPanelMain:true, strokeWidth: 5, stroke: 'green',name:"PIPE", strokeDashArray: [5, 10]}),
$(go.Shape, { toArrow: "Standard", stroke: null })
)
)
myDiagram.model = new go.GraphLinksModel(
[
{ key: "Alpha", color: "lightblue",'category': 'rect'},
{ key: "Beta", color: "orange" },
{ key: "Gamma", color: "lightblue", 'category': 'bucket', height: 0},
{ key: "Delta", color: "pink" },
],
[
{ from: "Alpha", to: "Beta", category: 'animated'},
{ from: "Alpha", to: "Gamma", category: 'animated' },
{ from: "Beta", to: "Beta", category: 'animated' },
{ from: "Gamma", to: "Delta", category: 'animated' },
{ from: "Delta", to: "Alpha"}
]);
}
function animatePIPE(){
if (myAnimation) myAnimation.stop();
// Animate the flow in the pipes
myAnimation = new go.Animation();
myAnimation.easing = go.Animation.EaseLinear;
myDiagram.links.each((link:any) => link.findObject("PIPE")?myAnimation.add(link.findObject("PIPE"), "strokeDashOffset", 15, 0): null);
// Run indefinitely
myAnimation.runCount = Infinity;
myAnimation.start();
}
function animateBucket(){
if (bucketAnimation) bucketAnimation.stop();
// Animate the flow in the pipes
bucketAnimation = new go.Animation();
bucketAnimation.easing = go.Animation.EaseLinear;
myDiagram.nodes.each((node:any) => node.findObject("BUCKET")?
// ()=>{
bucketAnimation.add(node.findObject("BUCKET"), "height", 100, 0)
// bucketAnimation.add(node.findObject("BUCKET"), "position", 0, 100)
// }
: null);
// Run indefinitely
bucketAnimation.runCount = Infinity;
bucketAnimation.duration = 5000;
bucketAnimation.start();
}
onMounted(()=>{
init();
animatePIPE();
animateBucket();
})
</script> -->
<template>
<div class="space-y-4 h-90vh">
<div class="flex h-full space-x-4">
<SourcePanel class="w-[400px] h-full border-solid border-2 border-black rounded"></SourcePanel>
<CenterCanvas class="w-full h-full border-2 border-red-200 border-solid rounded"></CenterCanvas>
<PropPanel class="w-[400px] h-full border-solid border-2 border-black rounded"></PropPanel>
<div class="w-[400px] h-full border-1 border-black rounded border-solid">
<el-collapse>
<el-collapse-item class="m-2" v-for="category in categoryList" :title=category.name>
<SourceCollapse class="w-full h-[240px] m-4" :category="category.key"></SourceCollapse>
</el-collapse-item>
</el-collapse>
</div>
<div id="myDiagram" class="w-full h-full border-1 border-black rounded border-solid"></div>
<div class="w-[400px] h-full border-1 border-black rounded border-solid">
<div id="myInfo"></div>
</div>
</div>
<div class="flex">
<div class="w-full"></div>
......@@ -126,15 +23,141 @@ onMounted(()=>{
<script setup lang="ts">
import CenterCanvas from './components/center-diagram/center-canvas.vue';
import PropPanel from './components/prop-panel/prop-panel.vue';
import SourcePanel from './components/source-panel/source-panel.vue';
import go from "gojs";
import SourceCollapse from "./components/source-panel/source-collapse.vue";
import {onMounted, ref} from "vue";
import {picCategory} from "./kit/ModelData.ts";
import {$, makePort, showSmallPorts} from "./kit/GOJSKit.ts";
import {
makeKitTopRotatingTool,
nodeResizeAdornmentTemplate, nodeRotateAdornmentTemplate,
nodeSelectionAdornmentTemplate
} from "./kit/NodeTemplateKit.ts";
import {linkSelectionAdornmentTemplate} from "./kit/LinkTemplateKit.ts";
import {Inspector} from "./kit/DataInspector.ts";
const categoryList: any = ref(null)
let myDiagram: any = null;
let inspector:any = null
function initPalette(){
categoryList.value = picCategory
}
function initDiagram(){
myDiagram = $(go.Diagram, "myDiagram", {
initialContentAlignment: go.Spot.Center,
//允许撤销
"undoManager.isEnabled": true,
//展示网格
"grid.visible": true,
//滚轮缩放
"allowZoom": true,
//连线是否可以不和节点连接。
"draggingTool.dragsLink": true,
//旋转点相关
"rotatingTool": $(makeKitTopRotatingTool()),
"rotatingTool.handleAngle": 270,
"rotatingTool.handleDistance": 50,
"rotatingTool.snapAngleMultiple": 15,
"rotatingTool.snapAngleEpsilon": 15,
//连接线相关
"draggingTool.dragsLink": true,
"draggingTool.isGridSnapEnabled": true,
"linkingTool.isUnconnectedLinkValid": true,
"linkingTool.portGravity": 20,
"relinkingTool.isUnconnectedLinkValid": true,
"relinkingTool.portGravity": 20,
"relinkingTool.fromHandleArchetype":
$(go.Shape, "Diamond", { segmentIndex: 0, cursor: "pointer", desiredSize: new go.Size(8, 8), fill: "tomato", stroke: "darkred" }),
"relinkingTool.toHandleArchetype":
$(go.Shape, "Diamond", { segmentIndex: -1, cursor: "pointer", desiredSize: new go.Size(8, 8), fill: "darkred", stroke: "tomato" }),
"linkReshapingTool.handleArchetype":
$(go.Shape, "Diamond", { desiredSize: new go.Size(7, 7), fill: "lightblue", stroke: "deepskyblue" }),
//调整大小
"resizingTool.handleArchetype":
$(go.Shape, "Rectangle", { desiredSize: new go.Size(7, 7), fill: "lightblue", stroke: "deepskyblue" }),
"resizingTool.isGridSnapEnabled": true,
})
myDiagram.nodeTemplate = $(go.Node, "Auto",
new go.Binding('location', "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
{selectable: true, selectionAdornmentTemplate: nodeSelectionAdornmentTemplate},
{ resizable: true, resizeObjectName: "view", resizeAdornmentTemplate: nodeResizeAdornmentTemplate },
{ rotatable: true, rotateAdornmentTemplate: nodeRotateAdornmentTemplate, locationSpot:go.Spot.Center },
new go.Binding('angle').makeTwoWay(),
$(go.Picture, {name:"view", cursor: "pointer", width: 100, height: 100, imageStretch: go.GraphObject.Fill},
new go.Binding("source", "img")),
$(go.TextBlock, {margin: 4, text:"", editable:true}, new go.Binding("text", "name").makeTwoWay()),
// four small named ports, one on each side:
makePort("T", go.Spot.Top, true, true),
makePort("L", go.Spot.Left, true, true),
makePort("R", go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, true, true),
{ // handle mouse enter/leave events to show/hide the ports
mouseEnter: function(e, node) { showSmallPorts(node, true); console.log(myDiagram.model.toJson())},
mouseLeave: function(e, node) { showSmallPorts(node, false); },
}
);
myDiagram.linkTemplate = $(go.Link,
{ selectable: true, selectionAdornmentTemplate: linkSelectionAdornmentTemplate },
{ relinkableFrom: true, relinkableTo: true, reshapable: true },
{ routing: go.Link.AvoidsNodes, corner: 5, curve: go.Link.JumpOver, toShortLength: 4 },
new go.Binding("points").makeTwoWay(),
new go.Binding("stroke").makeTwoWay(),
$(go.Shape, // the link path shape
{ isPanelMain: true, strokeWidth: 2 }),
$(go.Shape, // the arrowhead
{ toArrow: "Standard", stroke: null }),
$(go.Panel, "Auto",
// new go.Binding("visible", "isSelected").ofObject(),
$(go.Shape, "RoundedRectangle", // the link shape
{ fill: "transparent", stroke: null }),
$(go.TextBlock,
{
textAlign: "center",
font: "10pt",
stroke: "#000000",
margin: 2,
minSize: new go.Size(10, NaN),
editable: true
}
)
)
);
myDiagram.addDiagramListener("Modified", function(e) {
if (myDiagram.isModified) {
console.log(myDiagram.model.toJson())
}
});
}
function initInfo(){
inspector = new Inspector('myInfo', myDiagram,
{
properties: {
// key would be automatically added for nodes, but we want to declare it read-only also:
"key": { readOnly: true, show: Inspector.showIfPresent },
// fill and stroke would be automatically added for nodes, but we want to declare it a color also:
"fill": { show: Inspector.showIfPresent, type: 'color' },
"stroke": { show: Inspector.showIfPresent, type: 'color' },
}
});
}
function importData(){
console.log("import");
myDiagram.model = go.Model.fromJson({ "class": "GraphLinksModel",
"nodeDataArray": [{"name":"valve2","category":"valve","img":"src/assets/models/valve/阀-2.svg","key":-1,"loc":"-198.477783203125 -137.25607910156253","size":"190 230"}],
"linkDataArray": []});
}
function exportData(){
console.log("export");
}
onMounted(()=>{
initPalette();
initDiagram();
initInfo();
})
</script>
\ No newline at end of file
<template>
<div id="myDiagram"></div>
</template>
<script setup lang="ts">
import {onMounted} from 'vue'
import go from 'gojs'
import {$, makePort, showSmallPorts} from '../../kit/GOJSKit.ts'
import {
nodeSelectionAdornmentTemplate,
nodeResizeAdornmentTemplate,
nodeRotateAdornmentTemplate,
makeTopRotatingTool
} from "../../kit/NodeTemplateKit.ts";
import { linkSelectionAdornmentTemplate } from '../../kit/LinkTemplateKit.ts'
var myDiagram:any = null
function initDiagram() {
myDiagram = $(go.Diagram, "myDiagram", {
initialContentAlignment: go.Spot.Center,
//允许撤销
"undoManager.isEnabled": true,
//展示网格
"grid.visible": true,
//滚轮缩放
"allowZoom": true,
//连线是否可以不和节点连接。
"draggingTool.dragsLink": true,
//旋转点相关
"rotatingTool": $(makeTopRotatingTool()),
"rotatingTool.handleAngle": 270,
"rotatingTool.handleDistance": 50,
"rotatingTool.snapAngleMultiple": 15,
"rotatingTool.snapAngleEpsilon": 15,
//连接线相关
"draggingTool.dragsLink": true,
"draggingTool.isGridSnapEnabled": true,
"linkingTool.isUnconnectedLinkValid": true,
"linkingTool.portGravity": 20,
"relinkingTool.isUnconnectedLinkValid": true,
"relinkingTool.portGravity": 20,
"relinkingTool.fromHandleArchetype":
$(go.Shape, "Diamond", { segmentIndex: 0, cursor: "pointer", desiredSize: new go.Size(8, 8), fill: "tomato", stroke: "darkred" }),
"relinkingTool.toHandleArchetype":
$(go.Shape, "Diamond", { segmentIndex: -1, cursor: "pointer", desiredSize: new go.Size(8, 8), fill: "darkred", stroke: "tomato" }),
"linkReshapingTool.handleArchetype":
$(go.Shape, "Diamond", { desiredSize: new go.Size(7, 7), fill: "lightblue", stroke: "deepskyblue" }),
})
myDiagram.nodeTemplate = $(go.Node, "Spot",
new go.Binding('location', "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
{selectable: true, selectionAdornmentTemplate: nodeSelectionAdornmentTemplate},
{ resizable: true, resizeObjectName: "PANEL", resizeAdornmentTemplate: nodeResizeAdornmentTemplate },
{ rotatable: true, rotateAdornmentTemplate: nodeRotateAdornmentTemplate, locationSpot:go.Spot.Center },
new go.Binding('angle').makeTwoWay(),
$(go.Panel, "Vertical",
// {name:"PANEL", cursor: "pointer", background: "lightblue"},
{name:"PANEL", cursor: "pointer"},
new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
$(go.Picture, new go.Binding("source", "img")),
// $(go.Shape, "Rectangle", {stroke:"red", fill:"yellow", name:"IMAGE"}),
// $(go.TextBlock, {margin: 4, text:"", editable:true, background:"green"}, new go.Binding("text", "name")),
$(go.TextBlock, {margin: 4, text:"", editable:true}, new go.Binding("text", "name")),
),
// four small named ports, one on each side:
makePort("T", go.Spot.Top, true, true),
makePort("L", go.Spot.Left, true, true),
makePort("R", go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, true, true),
{ // handle mouse enter/leave events to show/hide the ports
mouseEnter: function(e, node) { showSmallPorts(node, true); },
mouseLeave: function(e, node) { showSmallPorts(node, false); }
}
)
myDiagram.linkTemplate = $(go.Link,
{ selectable: true, selectionAdornmentTemplate: linkSelectionAdornmentTemplate },
{ relinkableFrom: true, relinkableTo: true, reshapable: true },
{ routing: go.Link.AvoidsNodes, corner: 5, curve: go.Link.JumpOver, toShortLength: 4 },
new go.Binding("points").makeTwoWay(),
$(go.Shape, // the link path shape
{ isPanelMain: true, strokeWidth: 2 }),
$(go.Shape, // the arrowhead
{ toArrow: "Standard", stroke: null }),
$(go.Panel, "Auto",
// new go.Binding("visible", "isSelected").ofObject(),
$(go.Shape, "RoundedRectangle", // the link shape
{ fill: "transparent", stroke: null }),
$(go.TextBlock,
{
textAlign: "center",
font: "10pt",
stroke: "#000000",
margin: 2,
minSize: new go.Size(10, NaN),
editable: true
}
)
)
);
myDiagram.addDiagramListener("Modified", function(e) {
if (myDiagram.isModified) {
console.log(myDiagram.model.toJson())
}
});
}
function init() {
initDiagram()
}
onMounted(() => {
init()
})
</script>
\ No newline at end of file
<template>
<div></div>
</template>
<script setup lang="ts">
</script>
\ No newline at end of file
......@@ -6,7 +6,7 @@ import { onMounted, ref } from 'vue';
import go from 'gojs'
import {$} from '../../kit/GOJSKit'
import { PictureNodeTemplate} from '../../kit/NodeTemplateKit';
import { SourcePictureNodeTemplate} from '../../kit/NodeTemplateKit';
import {picModel} from '../../kit/ModelData.ts'
......@@ -24,7 +24,7 @@ var sourceModel:any = ref(null)
function init(){
sourcePalette = $(go.Palette, props.category, {
layout: $(go.GridLayout, { alignment: go.GridLayout.Location }),
nodeTemplate: PictureNodeTemplate,
nodeTemplate: SourcePictureNodeTemplate,
allowZoom: false
})
sourceModel.value = picModel.filter((item:any) => {
......
<template>
<el-collapse>
<el-collapse-item class="m-2" v-for="category in categoryList" :title=category.name>
<SourceCollapse class="w-full h-[240px] m-4" :category="category.key"></SourceCollapse>
</el-collapse-item>
</el-collapse>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { picCategory } from '../../kit/ModelData.ts'
import SourceCollapse from './source-collapse.vue';
const categoryList: any = ref(null)
function init(){
categoryList.value = picCategory
}
onMounted(() => {
init()
})
</script>
\ No newline at end of file
/*
* Copyright (C) 1998-2021 by Northwoods Software Corporation. All Rights Reserved.
*/
/*
* This is an extension and not part of the main GoJS library.
* Note that the API for this class may change with any version, even point releases.
* If you intend to use an extension in production, you should copy the code to your own source directory.
* Extensions can be found in the GoJS kit under the extensions or extensionsTS folders.
* See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
*/
import go from 'gojs';
/**
* This class implements an inspector for GoJS model data objects.
* The constructor takes three arguments:
* - `divid` ***string*** a string referencing the HTML ID of the to-be inspector's div
* - `diagram` ***Diagram*** a reference to a GoJS Diagram
* - `options` ***Object*** an optional JS Object describing options for the inspector
*
* Options:
* - `inspectSelection` ***boolean*** see {@link #inspectSelection}
* - `includesOwnProperties` ***boolean*** see {@link #includesOwnProperties}
* - `properties` ***Object*** see {@link #properties}
* - `propertyModified` ***function(propertyName, newValue, inspector)*** see {@link #propertyModified}
* - `multipleSelection` ***boolean*** see {@link #multipleSelection}
* - `showUnionProperties` ***boolean*** see {@link #showUnionProperties}
* - `showLimit` ***number*** see {@link #showLimit}
*
* Options for properties:
* - `show` ***boolean | function*** a boolean value to show or hide the property from the inspector, or a predicate function to show conditionally.
* - `readOnly` ***boolean | function*** whether or not the property is read-only
* - `type` ***string*** a string describing the data type. Supported values: "string|number|boolean|color|arrayofnumber|point|rect|size|spot|margin|select"
* - `defaultValue` ***any*** a default value for the property. Defaults to the empty string.
* - `choices` ***Array | function*** when type === "select", the Array of choices to use or a function that returns the Array of choices.
*
* Example usage of Inspector:
* ```js
* var inspector = new Inspector("myInspector", myDiagram,
* {
* includesOwnProperties: false,
* properties: {
* "key": { show: Inspector.showIfPresent, readOnly: true },
* "comments": { show: Inspector.showIfNode },
* "LinkComments": { show: Inspector.showIfLink },
* "chosen": { show: Inspector.showIfNode, type: "checkbox" },
* "state": { show: Inspector.showIfNode, type: "select", choices: ["Stopped", "Parked", "Moving"] }
* }
* });
* ```
*
* This is the basic HTML Structure that the Inspector creates within the given DIV element:
* ```html
* <div id="divid" class="inspector">
* <tr>
* <td>propertyName</td>
* <td><input value=propertyValue /></td>
* </tr>
* ...
* </div>
* ```
*
* If you want to experiment with this extension, try the <a href="../../extensionsTS/DataInspector.html">Data Inspector</a> sample.
* @category Extension
*/
export class Inspector {
private _div: HTMLDivElement;
private _diagram: go.Diagram;
private _inspectedObject: go.ObjectData | null = null;
// Inspector options defaults:
private _inspectSelection: boolean = true;
private _includesOwnProperties: boolean = true;
private _properties: { [index: string]: any } = {};
private _propertyModified: ((a: string, b: string, c: Inspector) => void) | null = null;
private _multipleSelection: boolean = false;
private _showUnionProperties: boolean = false;
private _showLimit: number = 0;
// Private variables used to keep track of internal state
private inspectedProperties: { [index: string]: any } = {};
private multipleProperties: { [index: string]: any } = {};
private tabIndex: number;
// Functions used to keep the Inspector up-to-date
private inspectOnModelChanged: ((e: go.ChangedEvent) => void);
private inspectOnSelectionChanged: ((e: go.DiagramEvent) => void);
/**
* Constructs an Inspector and sets up properties based on the options provided.
* Also sets up change listeners on the Diagram so the Inspector stays up-to-date.
* @param {string} divid a string referencing the HTML ID of the to-be Inspector's div
* @param {Diagram} diagram a reference to a GoJS Diagram
* @param {Object=} options an optional JS Object describing options for the inspector
*/
constructor(divid: string, diagram: go.Diagram, options?: { [index: string]: any }) {
const mainDiv = document.getElementById(divid) as HTMLDivElement;
mainDiv.className = 'inspector';
mainDiv.innerHTML = '';
this._div = mainDiv;
this._diagram = diagram;
this.tabIndex = 0;
// Set properties based on options
if (options !== undefined) {
if (options.inspectSelection !== undefined) this._inspectSelection = options.inspectSelection;
if (options.includesOwnProperties !== undefined) this._includesOwnProperties = options.includesOwnProperties;
if (options.properties !== undefined) this._properties = options.properties;
if (options.propertyModified !== undefined) this._propertyModified = options.propertyModified;
if (options.multipleSelection !== undefined) this._multipleSelection = options.multipleSelection;
if (options.showUnionProperties !== undefined) this._showUnionProperties = options.showUnionProperties;
if (options.showLimit !== undefined) this._showLimit = options.showLimit;
}
// Prepare change listeners
const self = this;
this.inspectOnModelChanged = (e: go.ChangedEvent) => {
if (e.isTransactionFinished) self.inspectObject();
};
this.inspectOnSelectionChanged = (e: go.DiagramEvent) => { self.inspectObject(); };
this._diagram.addModelChangedListener(this.inspectOnModelChanged);
if (this._inspectSelection) {
this._diagram.addDiagramListener('ChangedSelection', this.inspectOnSelectionChanged);
}
}
/**
* This read-only property returns the HTMLElement containing the Inspector.
*/
get div(): HTMLDivElement { return this._div; }
/**
* Gets or sets the {@link Diagram} associated with this Inspector.
*/
get diagram(): go.Diagram { return this._diagram; }
set diagram(val: go.Diagram) {
if (val !== this._diagram) {
// First, unassociate change listeners with current inspected diagram
this._diagram.removeModelChangedListener(this.inspectOnModelChanged);
this._diagram.removeDiagramListener('ChangedSelection', this.inspectOnSelectionChanged);
// Now set the diagram and add the necessary change listeners
this._diagram = val;
this._diagram.addModelChangedListener(this.inspectOnModelChanged);
if (this._inspectSelection) {
this._diagram.addDiagramListener('ChangedSelection', this.inspectOnSelectionChanged);
this.inspectObject();
} else {
this.inspectObject(null);
}
}
}
/**
* This read-only property returns the object currently being inspected.
*
* To set the inspected object, call {@link #inspectObject}.
*/
get inspectedObject(): go.ObjectData | null { return this._inspectedObject; }
/**
* Gets or sets whether the Inspector automatically inspects the associated Diagram's selection.
* When set to false, the Inspector won't show anything until {@link #inspectObject} is called.
*
* The default value is true.
*/
get inspectSelection(): boolean { return this._inspectSelection; }
set inspectSelection(val: boolean) {
if (val !== this._inspectSelection) {
this._inspectSelection = val;
if (this._inspectSelection) {
this._diagram.addDiagramListener('ChangedSelection', this.inspectOnSelectionChanged);
this.inspectObject();
} else {
this._diagram.removeDiagramListener('ChangedSelection', this.inspectOnSelectionChanged);
this.inspectObject(null);
}
}
}
/**
* Gets or sets whether the Inspector includes all properties currently on the inspected object.
*
* The default value is true.
*/
get includesOwnProperties(): boolean { return this._includesOwnProperties; }
set includesOwnProperties(val: boolean) {
if (val !== this._includesOwnProperties) {
this._includesOwnProperties = val;
this.inspectObject();
}
}
/**
* Gets or sets the properties that the Inspector will inspect, maybe setting options for those properties.
* The object should contain string: Object pairs represnting propertyName: propertyOptions.
* Can be used to include or exclude additional properties.
*
* The default value is an empty object.
*/
get properties(): go.ObjectData { return this._properties; }
set properties(val: go.ObjectData) {
if (val !== this._properties) {
this._properties = val;
this.inspectObject();
}
}
/**
* Gets or sets the function to be called when a property is modified by the Inspector.
* The first paremeter will be the property name, the second will be the new value, and the third will be a reference to this Inspector.
*
* The default value is null, meaning nothing will be done.
*/
get propertyModified(): ((a: string, b: string, c: Inspector) => void) | null { return this._propertyModified; }
set propertyModified(val: ((a: string, b: string, c: Inspector) => void) | null) {
if (val !== this._propertyModified) {
this._propertyModified = val;
}
}
/**
* Gets or sets whether the Inspector displays properties for multiple selected objects or just the first.
*
* The default value is false, meaning only the first item in the {@link Diagram#selection} is inspected.
*/
get multipleSelection(): boolean { return this._multipleSelection; }
set multipleSelection(val: boolean) {
if (val !== this._multipleSelection) {
this._multipleSelection = val;
this.inspectObject();
}
}
/**
* Gets or sets whether the Inspector displays the union or intersection of properties for multiple selected objects.
*
* The default value is false, meaning the intersection of properties is inspected.
*/
get showUnionProperties(): boolean { return this._showUnionProperties; }
set showUnionProperties(val: boolean) {
if (val !== this._showUnionProperties) {
this._showUnionProperties = val;
this.inspectObject();
}
}
/**
* Gets or sets how many objects will be displayed when {@link #multipleSelection} is true.
*
* The default value is 0, meaning all selected objects will be displayed for a given property.
*/
get showLimit(): number { return this._showLimit; }
set showLimit(val: number) {
if (val !== this._showLimit) {
this._showLimit = val;
this.inspectObject();
}
}
/**
* This predicate function can be used as a value for the `show` option for properties.
* When used, the property will only be shown when inspecting a {@link Node}.
* @param {Part} part the Part being inspected
* @return {boolean}
*/
public static showIfNode(part: go.Part): boolean { return part instanceof go.Node; }
/**
* This predicate function can be used as a value for the `show` option for properties.
* When used, the property will only be shown when inspecting a {@link Link}.
* @param {Part} part the Part being inspected
* @return {boolean}
*/
public static showIfLink(part: go.Part): boolean { return part instanceof go.Link; }
/**
* This predicate function can be used as a value for the `show` option for properties.
* When used, the property will only be shown when inspecting a {@link Group}.
* @param {Part} part the Part being inspected
* @return {boolean}
*/
public static showIfGroup(part: go.Part): boolean { return part instanceof go.Group; }
/**
* This predicate function can be used as a value for the `show` option for properties.
* When used, the property will only be shown if present.
* Useful for properties such as `key`, which will be shown on Nodes and Groups, but normally not on Links
* @param {Part|null} part the Part being inspected
* @param {string} propname the property to check presence of
* @return {boolean}
*/
public static showIfPresent(data: go.Part | null, propname: string): boolean {
if (data instanceof go.Part) data = data.data;
return typeof data === 'object' && (data as any)[propname] !== undefined;
}
/**
* Update the HTML state of this Inspector with the given object.
*
* If passed an object, the Inspector will inspect that object.
* If passed null, this will do nothing.
* If no parameter is supplied, the {@link #inspectedObject} will be set based on the value of {@link #inspectSelection}.
* @param {Object=} object an optional argument, used when {@link #inspectSelection} is false to
* set {@link #inspectedObject} and show and edit that object's properties.
*/
public inspectObject(object?: go.ObjectData | null): void {
let inspectedObject: go.ObjectData | null = null;
let inspectedObjects: go.Set<go.ObjectData> | null = null;
if (object === null) return;
if (object === undefined) {
if (this._inspectSelection) {
if (this._multipleSelection) { // gets the selection if multiple selection is true
inspectedObjects = this._diagram.selection;
} else { // otherwise grab the first object
inspectedObject = this._diagram.selection.first();
}
} else { // if there is a single inspected object
inspectedObject = this._inspectedObject;
}
} else { // if object was passed in as a parameter
inspectedObject = object;
}
if (!inspectedObjects && inspectedObject) {
inspectedObjects = new go.Set<go.ObjectData>();
inspectedObjects.add(inspectedObject);
}
if (!inspectedObjects || inspectedObjects.count < 1) { // if nothing is selected
this.updateAllHTML();
return;
}
if (inspectedObjects) {
const mainDiv = this._div;
mainDiv.innerHTML = '';
const shared: go.Map<string, any> = new go.Map<string, any>(); // for properties that the nodes have in common
const properties: go.Map<string, any> = new go.Map<string, any>(); // for adding properties
const all: go.Map<string, any> = new go.Map<string, any>(); // used later to prevent changing properties when unneeded
const it = inspectedObjects.iterator;
let nodecount = 2;
// Build table:
const table = document.createElement('table');
const tbody = document.createElement('tbody');
this.inspectedProperties = {};
this.tabIndex = 0;
const declaredProperties = this._properties;
it.next();
inspectedObject = it.value;
this._inspectedObject = inspectedObject;
let data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject;
if (data) { // initial pass to set shared and all
// Go through all the properties passed in to the inspector and add them to the map, if appropriate:
for (const name in declaredProperties) {
const desc = declaredProperties[name];
if (!this.canShowProperty(name, desc, inspectedObject)) continue;
const val = this.findValue(name, desc, data);
if (val === '' && this._properties[name] && this._properties[name].type === 'checkbox') {
shared.add(name, false);
all.add(name, false);
} else {
shared.add(name, val);
all.add(name, val);
}
}
// Go through all the properties on the model data and add them to the map, if appropriate:
if (this._includesOwnProperties) {
for (const k in data) {
if (k === '__gohashid') continue; // skip internal GoJS hash property
if (this.inspectedProperties[k]) continue; // already exists
if (declaredProperties[k] && !this.canShowProperty(k, declaredProperties[k], inspectedObject)) continue;
shared.add(k, data[k]);
all.add(k, data[k]);
}
}
}
while (it.next() && (this._showLimit < 1 || nodecount <= this._showLimit)) { // grabs all the properties from the other selected objects
properties.clear();
inspectedObject = it.value;
if (inspectedObject) {
// use either the Part.data or the object itself (for model.modelData)
data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject;
if (data) {
// Go through all the properties passed in to the inspector and add them to properties to add, if appropriate:
for (const name in declaredProperties) {
const desc = declaredProperties[name];
if (!this.canShowProperty(name, desc, inspectedObject)) continue;
const val = this.findValue(name, desc, data);
if (val === '' && this._properties[name] && this._properties[name].type === 'checkbox') {
properties.add(name, false);
} else {
properties.add(name, val);
}
}
// Go through all the properties on the model data and add them to properties to add, if appropriate:
if (this._includesOwnProperties) {
for (const k in data) {
if (k === '__gohashid') continue; // skip internal GoJS hash property
if (this.inspectedProperties[k]) continue; // already exists
if (declaredProperties[k] && !this.canShowProperty(k, declaredProperties[k], inspectedObject)) continue;
properties.add(k, data[k]);
}
}
}
}
if (!this._showUnionProperties) {
// Cleans up shared map with properties that aren't shared between the selected objects
// Also adds properties to the add and shared maps if applicable
const addIt = shared.iterator;
const toRemove: Array<string> = [];
while (addIt.next()) {
if (properties.has(addIt.key)) {
let newVal = all.get(addIt.key) + '|' + properties.get(addIt.key);
all.set(addIt.key, newVal);
if ((declaredProperties[addIt.key] && declaredProperties[addIt.key].type !== 'color'
&& declaredProperties[addIt.key].type !== 'checkbox' && declaredProperties[addIt.key].type !== 'select')
|| !declaredProperties[addIt.key]) { // for non-string properties i.e color
newVal = shared.get(addIt.key) + '|' + properties.get(addIt.key);
shared.set(addIt.key, newVal);
}
} else { // toRemove array since addIt is still iterating
toRemove.push(addIt.key);
}
}
for (let i = 0; i < toRemove.length; i++) { // removes anything that doesn't showUnionProperties
shared.remove(toRemove[i]);
all.remove(toRemove[i]);
}
} else {
// Adds missing properties to all with the correct amount of seperators
let addIt = properties.iterator;
while (addIt.next()) {
if (all.has(addIt.key)) {
if ((declaredProperties[addIt.key] && declaredProperties[addIt.key].type !== 'color'
&& declaredProperties[addIt.key].type !== 'checkbox' && declaredProperties[addIt.key].type !== 'select')
|| !declaredProperties[addIt.key]) { // for non-string properties i.e color
const newVal = all.get(addIt.key) + '|' + properties.get(addIt.key);
all.set(addIt.key, newVal);
}
} else {
let newVal = '';
for (let i = 0; i < nodecount - 1; i++) newVal += '|';
newVal += properties.get(addIt.key);
all.set(addIt.key, newVal);
}
}
// Adds bars in case properties is not in all
addIt = all.iterator;
while (addIt.next()) {
if (!properties.has(addIt.key)) {
if ((declaredProperties[addIt.key] && declaredProperties[addIt.key].type !== 'color'
&& declaredProperties[addIt.key].type !== 'checkbox' && declaredProperties[addIt.key].type !== 'select')
|| !declaredProperties[addIt.key]) { // for non-string properties i.e color
const newVal = all.get(addIt.key) + '|';
all.set(addIt.key, newVal);
}
}
}
}
nodecount++;
}
// builds the table property rows and sets multipleProperties to help with updateall
let mapIt;
if (!this._showUnionProperties) mapIt = shared.iterator;
else mapIt = all.iterator;
while (mapIt.next()) {
tbody.appendChild(this.buildPropertyRow(mapIt.key, mapIt.value)); // shows the properties that are allowed
}
table.appendChild(tbody);
mainDiv.appendChild(table);
const allIt = all.iterator;
while (allIt.next()) {
this.multipleProperties[allIt.key] = allIt.value; // used for updateall to know which properties to change
}
}
}
/**
* This predicate should be false if the given property should not be shown.
* Normally it only checks the value of "show" on the property descriptor.
*
* The default value is true.
* @param {string} propertyName the property name
* @param {Object} propertyDesc the property descriptor
* @param {Object} inspectedObject the data object
* @return {boolean} whether a particular property should be shown in this Inspector
*/
public canShowProperty(propertyName: string, propertyDesc: go.ObjectData, inspectedObject: go.ObjectData): boolean {
const prop = propertyDesc as any;
if (prop.show === false) return false;
// if "show" is a predicate, make sure it passes or do not show this property
if (typeof prop.show === 'function') return prop.show(inspectedObject, propertyName);
return true;
}
/**
* This predicate should be false if the given property should not be editable by the user.
* Normally it only checks the value of "readOnly" on the property descriptor.
*
* The default value is true.
* @param {string} propertyName the property name
* @param {Object} propertyDesc the property descriptor
* @param {Object} inspectedObject the data object
* @return {boolean} whether a particular property should be shown in this Inspector
*/
public canEditProperty(propertyName: string, propertyDesc: go.ObjectData, inspectedObject: go.ObjectData | null): boolean {
if (this._diagram.isReadOnly || this._diagram.isModelReadOnly) return false;
if (inspectedObject === null) return false;
// assume property values that are functions of Objects cannot be edited
const data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject;
const valtype = typeof data[propertyName];
if (valtype === 'function') return false;
if (propertyDesc) {
const prop = propertyDesc as any;
if (prop.readOnly === true) return false;
// if "readOnly" is a predicate, make sure it passes or do not show this property
if (typeof prop.readOnly === 'function') return !prop.readOnly(inspectedObject, propertyName);
}
return true;
}
/**
* @ignore
* @param propName
* @param propDesc
* @param data
*/
private findValue(propName: string, propDesc: any, data: any): any {
let val = '';
if (propDesc && propDesc.defaultValue !== undefined) val = propDesc.defaultValue;
if (data[propName] !== undefined) val = data[propName];
if (val === undefined) return '';
return val;
}
/**
* This sets `inspectedProperties[propertyName]` and creates the HTML table row for a given property:
* ```html
* <tr>
* <td>propertyName</td>
* <td><input value=propertyValue /></td>
* </tr>
* ```
*
* This method can be customized to change how an Inspector row is rendered.
* @param {string} propertyName the property name
* @param {*} propertyValue the property value
* @return {HTMLTableRowElement} the table row
*/
public buildPropertyRow(propertyName: string, propertyValue: any): HTMLTableRowElement {
const tr = document.createElement('tr');
const td1 = document.createElement('td');
let displayName;
if (this._properties[propertyName] && this._properties[propertyName].name !== undefined) { // name changes the dispaly name shown on inspector
displayName = this._properties[propertyName].name;
} else {
displayName = propertyName;
}
td1.textContent = displayName;
tr.appendChild(td1);
const td2 = document.createElement('td');
const decProp = this._properties[propertyName];
let input: HTMLInputElement | HTMLSelectElement | null = null;
const self = this;
function updateall() {
if (self._diagram.selection.count === 1 || !self.multipleSelection) {
self.updateAllProperties();
} else {
self.updateAllObjectsProperties();
}
}
if (decProp && decProp.type === 'select') {
const inputs = input = document.createElement('select') as HTMLSelectElement;
this.updateSelect(decProp, inputs, propertyName, propertyValue);
inputs.addEventListener('change', updateall);
} else {
const inputi = input = document.createElement('input') as HTMLInputElement;
if (inputi && inputi.setPointerCapture) {
inputi.addEventListener("pointerdown", e => inputi.setPointerCapture(e.pointerId));
}
inputi.value = this.convertToString(propertyValue);
if (decProp) {
const t = decProp.type;
if (t !== 'string' && t !== 'number' && t !== 'boolean' &&
t !== 'arrayofnumber' && t !== 'point' && t !== 'size' &&
t !== 'rect' && t !== 'spot' && t !== 'margin') {
inputi.setAttribute('type', decProp.type);
}
if (decProp.type === 'color') {
if (inputi.type === 'color') {
inputi.value = this.convertToColor(propertyValue);
// input.addEventListener('input', updateall); // removed with multi select
inputi.addEventListener('change', updateall);
}
} if (decProp.type === 'checkbox') {
inputi.checked = !!propertyValue;
inputi.addEventListener('change', updateall);
}
}
if (inputi.type !== 'color') inputi.addEventListener('blur', updateall);
}
if (input) {
input.tabIndex = this.tabIndex++;
input.disabled = !this.canEditProperty(propertyName, decProp, this._inspectedObject);
td2.appendChild(input);
}
tr.appendChild(td2);
this.inspectedProperties[propertyName] = input;
return tr;
}
/**
* @hidden @ignore
* HTML5 color input will only take hex,
* so let HTML5 canvas convert the color into hex format.
* This converts "rgb(255, 0, 0)" into "#FF0000", etc.
*/
public convertToColor(propertyValue: string): string {
const ctx: CanvasRenderingContext2D | null = document.createElement('canvas').getContext('2d');
if (ctx === null) return '#000000';
ctx.fillStyle = propertyValue;
return ctx.fillStyle;
}
/**
* @hidden @ignore
*/
public convertToArrayOfNumber(propertyValue: string): Array<number> | null {
if (propertyValue === 'null') return null;
const split = propertyValue.split(' ');
const arr = [];
for (let i = 0; i < split.length; i++) {
const str = split[i];
if (!str) continue;
arr.push(parseFloat(str));
}
return arr;
}
/**
* @hidden @ignore
*/
public convertToString(x: any): string {
if (x === undefined) return 'undefined';
if (x === null) return 'null';
if (x instanceof go.Point) return go.Point.stringify(x);
if (x instanceof go.Size) return go.Size.stringify(x);
if (x instanceof go.Rect) return go.Rect.stringify(x);
if (x instanceof go.Spot) return go.Spot.stringify(x);
if (x instanceof go.Margin) return go.Margin.stringify(x);
if (x instanceof go.List) return this.convertToString(x.toArray());
if (Array.isArray(x)) {
let str = '';
for (let i = 0; i < x.length; i++) {
if (i > 0) str += ' ';
const v = x[i];
str += this.convertToString(v);
}
return str;
}
return x.toString();
}
/**
* @hidden @ignore
* Update all of the HTML in this Inspector.
*/
public updateAllHTML(): void {
const inspectedProps = this.inspectedProperties;
const isPart = this._inspectedObject instanceof go.Part;
const data = isPart ? (this._inspectedObject as any).data : this._inspectedObject;
if (!data) { // clear out all of the fields
for (const name in inspectedProps) {
const input = inspectedProps[name];
if (input instanceof HTMLSelectElement) {
input.innerHTML = '';
} else if (input.type === 'color') {
input.value = '#000000';
} else if (input.type === 'checkbox') {
input.checked = false;
} else {
input.value = '';
}
}
} else {
for (const name in inspectedProps) {
const input = inspectedProps[name];
const propertyValue = data[name];
if (input instanceof HTMLSelectElement) {
const decProp = this._properties[name];
this.updateSelect(decProp, input, name, propertyValue);
} else if (input.type === 'color') {
input.value = this.convertToColor(propertyValue);
} else if (input.type === 'checkbox') {
input.checked = !!propertyValue;
} else {
input.value = this.convertToString(propertyValue);
}
}
}
}
/**
* @hidden @ignore
* Update an HTMLSelectElement with an appropriate list of choices, given the propertyName
*/
public updateSelect(decProp: any, select: HTMLSelectElement, propertyName: string, propertyValue: any): void {
select.innerHTML = ''; // clear out anything that was there
let choices = decProp.choices;
if (typeof choices === 'function') choices = choices(this._inspectedObject, propertyName);
if (!Array.isArray(choices)) choices = [];
decProp.choicesArray = choices; // remember list of actual choice values (not strings)
for (let i = 0; i < choices.length; i++) {
const choice = choices[i];
const opt = document.createElement('option');
opt.text = this.convertToString(choice);
select.add(opt);
}
select.value = this.convertToString(propertyValue);
}
private parseValue(decProp: any, value: any, input: any, oldval: any) {
// If it's a boolean, or if its previous value was boolean,
// parse the value to be a boolean and then update the input.value to match
let type = '';
if (decProp !== undefined && decProp.type !== undefined) {
type = decProp.type;
}
if (type === '') {
if (typeof oldval === 'boolean') type = 'boolean'; // infer boolean
else if (typeof oldval === 'number') type = 'number';
else if (oldval instanceof go.Point) type = 'point';
else if (oldval instanceof go.Size) type = 'size';
else if (oldval instanceof go.Rect) type = 'rect';
else if (oldval instanceof go.Spot) type = 'spot';
else if (oldval instanceof go.Margin) type = 'margin';
}
// convert to specific type, if needed
switch (type) {
case 'boolean': value = !(value === false || value === 'false' || value === '0'); break;
case 'number': value = parseFloat(value); break;
case 'arrayofnumber': value = this.convertToArrayOfNumber(value); break;
case 'point': value = go.Point.parse(value); break;
case 'size': value = go.Size.parse(value); break;
case 'rect': value = go.Rect.parse(value); break;
case 'spot': value = go.Spot.parse(value); break;
case 'margin': value = go.Margin.parse(value); break;
case 'checkbox': value = input.checked; break;
case 'select': value = decProp.choicesArray[input.selectedIndex]; break;
}
return value;
}
/**
* @hidden @ignore
* Update all of the data properties of all the objects in {@link #inspectedObjects} according to the
* current values held in the HTML input elements.
*/
private updateAllObjectsProperties() {
const inspectedProps = this.inspectedProperties;
const diagram = this._diagram;
diagram.startTransaction('set all properties');
for (const name in inspectedProps) {
const input = inspectedProps[name];
let value = input.value;
const arr1: Array<string> = value.split('|');
let arr2: Array<string> = [];
if (this.multipleProperties[name]) {
// don't split if it is union and its checkbox type
if (this._properties[name] && this._properties[name].type === 'checkbox' && this._showUnionProperties) {
arr2.push(this.multipleProperties[name]);
} else if (this._properties[name]) {
arr2 = this.multipleProperties[name].toString().split('|');
}
}
const it = diagram.selection.iterator;
let change = false;
if (this._properties[name] && this._properties[name].type === 'checkbox') change = true; // always change checkbox
if (arr1.length < arr2.length // i.e Alpha|Beta -> Alpha procs the change
&& (!this._properties[name] // from and to links
|| !(this._properties[name] // do not change color checkbox and choices due to them always having less
&& (this._properties[name].type === 'color' || this._properties[name].type === 'checkbox' || this._properties[name].type === 'choices')))) {
change = true;
} else { // standard detection in change in properties
for (let j = 0; j < arr1.length && j < arr2.length; j++) {
if (!(arr1[j] === arr2[j])
&& !(this._properties[name] && this._properties[name].type === 'color' && arr1[j].toLowerCase() === arr2[j].toLowerCase())) {
change = true;
}
}
}
if (change) { // only change properties it needs to change instead all of them
for (let i = 0; i < diagram.selection.count; i++) {
it.next();
const isPart = it.value instanceof go.Part;
const data = isPart ? it.value.data : it.value;
if (data) { // ignores the selected node if there is no data
if (i < arr1.length) value = arr1[i];
else value = arr1[0];
// don't update "readOnly" data properties
const decProp = this._properties[name];
if (!this.canEditProperty(name, decProp, it.value)) continue;
const oldval = data[name];
value = this.parseValue(decProp, value, input, oldval);
// in case parsed to be different, such as in the case of boolean values,
// the value shown should match the actual value
input.value = value;
// modify the data object in an undo-able fashion
diagram.model.setDataProperty(data, name, value);
// notify any listener
if (this.propertyModified !== null) this.propertyModified(name, value, this);
}
}
}
}
diagram.commitTransaction('set all properties');
}
/**
* @hidden @ignore
* Update all of the data properties of {@link #inspectedObject} according to the
* current values held in the HTML input elements.
*/
private updateAllProperties() {
const inspectedProps = this.inspectedProperties;
const diagram = this._diagram;
const isPart = this.inspectedObject instanceof go.Part;
const data = isPart ? (this.inspectedObject as any).data : this.inspectedObject;
if (!data) return; // must not try to update data when there's no data!
diagram.startTransaction('set all properties');
for (const name in inspectedProps) {
const input = inspectedProps[name];
let value = input.value;
// don't update "readOnly" data properties
const decProp = this._properties[name];
if (!this.canEditProperty(name, decProp, this.inspectedObject)) continue;
const oldval = data[name];
value = this.parseValue(decProp, value, input, oldval);
// in case parsed to be different, such as in the case of boolean values,
// the value shown should match the actual value
input.value = value;
// modify the data object in an undo-able fashion
diagram.model.setDataProperty(data, name, value);
// notify any listener
if (this.propertyModified !== null) this.propertyModified(name, value, this);
}
diagram.commitTransaction('set all properties');
}
}
......@@ -5,5 +5,7 @@ export var linkSelectionAdornmentTemplate =
$(go.Adornment, "Link",
$(go.Shape,
// isPanelMain declares that this Shape shares the Link.geometry
{ isPanelMain: true, fill: null, stroke: "deepskyblue", strokeWidth: 0 }) // use selection object's strokeWidth
{ isPanelMain: true, fill: null, stroke: "deepskyblue", strokeWidth: 1 },
new go.Binding("stroke").makeTwoWay()
) // use selection object's strokeWidth
);
\ No newline at end of file
......@@ -2,14 +2,15 @@
export const picCategory = [
{key:"valve",name:"阀门"},
{key:"pump",name:"泵"},
{key:"computer",name:"计算机"},
]
export const picModel = [
{ name: "computer1", category: "comnputer", img: "src/assets/models/computer/电脑.svg"},
{ name: "computer1", category: "computer", img: "src/assets/models/computer/电脑.svg"},
{ name: "valve2", category: "valve", img: "src/assets/models/valve/阀-2.svg"},
{ name: "vavle3", category: "valve", img: "src/assets/models/valve/阀.svg"},
{ name: "vavle4", category: "valve", img: "src/assets/models/valve/阀门-01.svg"},
{ name: "vavle5", category: "valve", img: "src/assets/models/valve/阀门2-01.svg"},
{ name: "valve3", category: "valve", img: "src/assets/models/valve/阀.svg"},
{ name: "valve4", category: "valve", img: "src/assets/models/valve/阀门-01.svg"},
{ name: "valve5", category: "valve", img: "src/assets/models/valve/阀门2-01.svg"},
{name: "pump1", category: "pump", img: "src/assets/models/pump/立式泵.svg"},
{name: "pump2", category: "pump", img: "src/assets/models/pump/卧式泵.svg"},
{name: "pump3", category: "pump", img: "src/assets/models/pump/旋转泵.svg"},
......
import {$} from './GOJSKit.js';
import {$, makePort, showSmallPorts} from './GOJSKit.js';
import go from 'gojs';
// 节点选中时的边框效果
......@@ -9,8 +9,8 @@ $(go.Adornment, "Auto",
);
// 表示节点旋转的锚点效果
export const makeTopRotatingTool = () => (
class TopRotatingTool extends go.RotatingTool {
export const makeKitTopRotatingTool = () => (
class KitTopRotatingTool extends go.RotatingTool {
updateAdornments(part) {
go.RotatingTool.prototype.updateAdornments.call(this, part)
const adornment = part.findAdornment('Rotating');
......@@ -46,7 +46,7 @@ $(go.Adornment, "Spot",
$(go.Shape, { alignment: go.Spot.BottomRight, cursor: "sw-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" })
);
export var PictureNodeTemplate =
export var SourcePictureNodeTemplate =
$(go.Node, "Vertical",
$(go.Picture,
{ width:80,height:80},
......@@ -57,3 +57,29 @@ $(go.Node, "Vertical",
new go.Binding("text", "name"))
)
export var DiagramPictureNodeTemplate = $(go.Node, "Spot",
new go.Binding('location', "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
{selectable: true, selectionAdornmentTemplate: nodeSelectionAdornmentTemplate},
{ resizable: true, resizeObjectName: "PANEL", resizeAdornmentTemplate: nodeResizeAdornmentTemplate },
{ rotatable: true, rotateAdornmentTemplate: nodeRotateAdornmentTemplate, locationSpot:go.Spot.Center },
{resizable: true, resizeObjectName: "view"},
new go.Binding('angle').makeTwoWay(),
$(go.Panel, "Vertical",
{name:"PANEL", cursor: "pointer", background: "lightblue"},
$(go.Panel, "Viewbox",{name:"view", viewboxStretch: go.GraphObject.Uniform},
new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
$(go.Picture, new go.Binding("source", "img")),
),
$(go.TextBlock, {margin: 4, text:"", editable:true, background:"green", alignment:go.Spot.Bottom, alignmentFocus:go.Spot.Top}, new go.Binding("text", "name").makeTwoWay()),
),
// four small named ports, one on each side:
makePort("T", go.Spot.Top, true, true),
makePort("L", go.Spot.Left, true, true),
makePort("R", go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, true, true),
{ // handle mouse enter/leave events to show/hide the ports
mouseEnter: function(e, node) { showSmallPorts(node, true); console.log(myDiagram.model.toJson())},
mouseLeave: function(e, node) { showSmallPorts(node, false); }
}
);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment