<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
margin: 0;
}
.vessel {
position: absolute;
top: 0;
right: 0;
z-index: 3;
}
.vessel .row1 {
display: flex;
justify-content: flex-end;
}
</style>
</head>
<body>
<div class="sampleWrapper">
<div style="width: 100%; height: fit-content; display: flex; flex: 2">
<div id="myPaletteDiv" style="width: 100px; margin-right: 2px"></div>
<div id="myDiagramDiv" style="flex-grow: 1; height: 100vh"></div>
</div>
<div class="vessel" id="right_buttons">
<div class="row1">
<select id="theme" οnchange="changeTheme()">
<option value="light">Light</option>
<option value="dark" selected>Dark</option>
</select>
<!-- <button οnclick="printDiagram()">打印</button> -->
<div>
<button οnclick="empty()">清空</button>
<button id="SaveButton" οnclick="save()">保存</button>
<button οnclick="load()">重新加载</button>
</div>
</div>
<textarea id="mySavedModel" style="width: 400px; height: 400px;display: none;"></textarea>
</div>
</div>
<script>
window.addEventListener("DOMContentLoaded", function() {
// 查找所有的水印元素并移除
// var watermarks = document.getElementsByClassName('watermark');
// for (var i = 0; i < watermarks.length; i++) {
// watermarks[i].parentNode.removeChild(watermarks[i]);
// }
// topnav
var topButton = document.getElementById("topnavButton");
var topnavList = document.getElementById("topnavList");
if (topButton && topnavList) {
topButton.addEventListener("click", function(e) {
console.log('点击1')
topnavList
.classList
.toggle("hidden");
e.stopPropagation();
});
document.addEventListener("click", function(e) {
console.log('点击2')
// 如果单击的元素不是列表,则关闭列表
if (!topnavList.classList.contains("hidden") && !e.target.closest("#topnavList")) {
topButton.click();
}
});
// 设置活动active a 元素
var url = window
.location
.href
.toLowerCase();
var aTags = topnavList.getElementsByTagName('a');
for (var i = 0; i < aTags.length; i++) {
var lowerhref = aTags[i]
.href
.toLowerCase();
if (url.startsWith(lowerhref)) {
aTags[i]
.classList
.add('active');
break;
}
}
}
});
</script>
<!-- 引入GoJS JavaScript库 -->
<script src="js/go.js"></script>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script id="code">
/**
* 样式白底黑字,黑线;
* 点击跳转
* 只查看时不能操作
*/
var data = {
"class": "GraphLinksModel",
"nodeDataArray": [{
"category": "开始",
"text": "开始",
"key": 1,
"loc": "-730 -40"
},
{
"text": "子1",
"key": 2,
"loc": "-500 -155"
},
{
"text": "子2",
"key": 3,
"loc": "-500 -5"
}
],
"linkDataArray": [{
"from": 1,
"to": 2
},{
"from": 1,
"to": 3
}]
}
function getUrlParams(paramName) {
const urlParams = new URLSearchParams(window.location.search);
const paramValue = urlParams.get(paramName); // 'paramName'是要获取的参数名
return paramValue;
}
var flag = getUrlParams('setting') ? true : false
function init() {
if (!flag) {
/* 只查看,不能修改 */
document.getElementById('right_buttons').setAttribute('style', 'display:none')
document.getElementById('myPaletteDiv').setAttribute('style', 'display:none')
}
if (window.goSamples) goSamples(); // 初始化实例,不需要回调 -- you don't need to call this
myDiagram = new go.Diagram(
'myDiagramDiv', // 必须命名或引用DIV HTML元素
{
'themeManager.changesDivBackground': true,
'themeManager.currentTheme': "dark",
'isReadOnly': !flag,
// 禁止拖动
// "allowMove":false,
// 禁止鼠标拖动区域选中
// "dragSelectingTool.isEnabled" : false,
// "allowDelete": true,//禁止删除节点
'undoManager.isEnabled': true, //启用撤销和重做
// "allowMove":false,
// "draggingTool.dragsLink": false,//拖动线
// "ismodelfied":true, //禁止拖拽
// 禁止鼠标拖动区域选中
// "dragSelectingTool.isEnabled" : false,
// "allowDelete": true,//禁止删除节点
// "allowCopy": true,//禁止复制
}
);
/* 点击事件跳转 */
myDiagram.addDiagramListener('ObjectSingleClicked', (e) => {
console.log('click点击跳转', e.subject.part.data, e.subject.part.data.key)
// window.open("baidu.com")
});
// 当文档被修改时,在标题后面加上"*",并启用"保存"按钮
myDiagram.addDiagramListener('Modified', (e) => {
console.log('modified修改')
const button = document.getElementById('SaveButton');
if (button) button.disabled = !myDiagram.isModified;
const idx = document.title.indexOf('*');
if (myDiagram.isModified) {
if (idx < 0) document.title += '*';
} else {
if (idx >= 0) document.title = document.title.slice(0, idx);
}
});
// 设置一些颜色/字体默认("浅色")和深色主题
myDiagram.themeManager.set('light', {
colors: {
text: '#fff',
start: '#468dd3',
step: '#55aaff',
conditional: '#6a9a8a',
end: '#7f1d1d',
comment: '#ffaaff',
bgText: '#000',
link: '#dcb263',
linkOver: '#cbd5e1',
div: '#ede9e0',
},
});
myDiagram.themeManager.set('dark', {
colors: {
text: '#fff',
step: '#414a8d',
conditional: '#88afa2',
comment: '#bfb674',
bgText: '#fff',
link: '#000000',
linkOver: '#475569',
div: '#fff',
},
});
defineFigures();
// 节点模板的帮助器定义
function nodeStyle(node) {
node
// the Node.位置位于每个节点的中心
.set({
locationSpot: go.Spot.Center
})
// The Node.location comes from the "loc" property of the node data,
// converted by the Point.parse static method.
// If the Node.location is changed, it updates the "loc" property of the node data,
// converting back using the Point.stringify static method.
.bindTwoWay('location', 'loc', go.Point.parse, go.Point.stringify);
}
function shapeStyle(shape) {
// 使整个节点形成一个端口
shape.set({
strokeWidth: 0,
portId: '',
cursor: 'pointer'
});
}
function textStyle(textblock) {
textblock.set({
font: 'bold 11pt Figtree, sans-serif'
}).theme('stroke', 'text');
}
// 为常规节点定义Node模板
myDiagram.nodeTemplateMap.add(
'', // the default category默认类别
new go.Node('Auto').apply(nodeStyle).add(
new go.Shape('Rectangle', {
fromLinkable: true,
toLinkable: true,
fromSpot: go.Spot.AllSides,
toSpot: go.Spot.AllSides,
})
.apply(shapeStyle)
.theme('fill', 'step'),
new go.TextBlock({
margin: 12,
maxSize: new go.Size(160, NaN),
wrap: go.Wrap.Fit,
editable: true,
})
.apply(textStyle)
.bindTwoWay('text')
)
);
myDiagram.nodeTemplateMap.add(
'Conditional',
new go.Node('Auto').apply(nodeStyle).add(
new go.Shape('Conditional', {
fromLinkable: true,
toLinkable: true
}).apply(shapeStyle).theme('fill', 'conditional'),
new go.TextBlock({
margin: 8,
maxSize: new go.Size(160, NaN),
wrap: go.Wrap.Fit,
textAlign: 'center',
editable: true,
})
.apply(textStyle)
.bindTwoWay('text')
)
);
myDiagram.nodeTemplateMap.add(
'Start',
new go.Node('Auto')
.apply(nodeStyle)
.add(
new go.Shape('Capsule', {
fromLinkable: true
}).apply(shapeStyle).theme('fill', 'start'),
new go.TextBlock('Start', {
margin: new go.Margin(5, 6)
}).apply(textStyle).bind('text')
)
);
myDiagram.nodeTemplateMap.add(
'End',
new go.Node('Auto')
.apply(nodeStyle)
.add(
new go.Shape('Capsule', {
toLinkable: true
}).apply(shapeStyle).theme('fill', 'end'),
new go.TextBlock('End', {
margin: new go.Margin(5, 6)
}).apply(textStyle).bind('text')
)
);
myDiagram.nodeTemplateMap.add(
'Comment',
new go.Node('Auto').apply(nodeStyle).add(
new go.Shape('File', {
strokeWidth: 3
}).theme('fill', 'div').theme('stroke', 'comment'),
new go.TextBlock({
font: '9pt Figtree, sans-serif',
margin: 8,
maxSize: new go.Size(200, NaN),
wrap: go.Wrap.Fit,
textAlign: 'center',
editable: true,
})
.theme('stroke', 'bgText')
.bindTwoWay('text')
// 没有端口,因为不允许链接与注释连接
)
);
// 替换"linkTemplateMap"中的默认Link模板
myDiagram.linkTemplate = new go.Link({
routing: go.Routing.AvoidsNodes,
curve: go.Curve.JumpOver,
corner: 5,
toShortLength: 4,
relinkableFrom: true,
relinkableTo: true,
reshapable: true,
resegmentable: true,
// 鼠标悬停线上地突出显示链接:
mouseEnter: (e, link) => {
link.findObject('HIGHLIGHT').stroke = link.diagram.themeManager.findValue('linkOver',
'colors');
// console.log('mouseEnter')
},
// 鼠标移开线
// mouseLeave: (e, link) => (link.findObject('HIGHLIGHT').stroke = 'transparent'),
mouseLeave: (e, link) => {
link.findObject('HIGHLIGHT').stroke = 'transparent';
// console.log('leave')
},
// Context-click创建一个可编辑的链接标签
contextClick: (e, link) => {
console.log('创建')
e.diagram.model.commit((m) => {
m.set(link.data, 'text', 'Label');
});
},
})
.bindTwoWay('points')
.add(
// the highlight shape, normally transparent高光形状,通常是透明的
new go.Shape({
isPanelMain: true,
strokeWidth: 8,
stroke: 'transparent',
name: 'HIGHLIGHT',
}),
// the link path shape
new go.Shape({
isPanelMain: true,
strokeWidth: 2
}).theme('stroke', 'link'),
// the arrowhead
new go.Shape({
toArrow: 'standard',
strokeWidth: 0,
scale: 1.5
}).theme('fill', 'link'),
// the link label
new go.Panel('Auto', {
visible: false
})
.bind('visible', 'text', (t) => typeof t === 'string' && t.length > 0) // 只有在有文本时才显示
.add(
// a gradient that fades into the background渐入背景的渐变
new go.Shape('Ellipse', {
strokeWidth: 0
}).theme('fill', 'div', null, null, (c) => {
// console.log('创建')
return new go.Brush(go.BrushType.Radial, {
colorStops: new go.Map([{
key: 0,
value: c
},
{
key: 0.5,
value: `${c}00`
},
]),
});
}),
new go.TextBlock({
name: 'LABEL',
font: '9pt Figtree, sans-serif',
margin: 3,
editable: true,
})
.theme('stroke', 'bgText')
.bindTwoWay('text')
)
);
// linktool和RelinkingTool使用的临时链接也是正交的:
myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Routing.Orthogonal;
myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Routing.Orthogonal;
load(); // 从一些JSON文本加载一个初始图
// 初始化页面左侧的Palette
myPalette = new go.Palette(
'myPaletteDiv', // 必须命名或引用DIV HTML元素
{
nodeTemplateMap: myDiagram.nodeTemplateMap, // share the templates used by myDiagram
themeManager: myDiagram.themeManager, // share the ThemeManager used by myDiagram
model: new go.GraphLinksModel([
// 指定调色板的内容
{
category: 'Start',
text: 'Start'
},
{
text: 'Step'
},
{
category: 'Conditional',
text: '???'
},
{
category: 'End',
text: 'End'
},
{
category: 'Comment',
text: 'Comment'
},
]),
}
);
} // end init
// 为节点模板定义一些自定义形状
function defineFigures() {
go.Shape.defineFigureGenerator('Conditional', (shape, w, h) => {
const geo = new go.Geometry();
const fig = new go.PathFigure(w * 0.15, 0, true);
geo.add(fig);
fig.add(new go.PathSegment(go.SegmentType.Line, w * 0.85, 0));
fig.add(new go.PathSegment(go.SegmentType.Line, w, 0.5 * h));
fig.add(new go.PathSegment(go.SegmentType.Line, w * 0.85, h));
fig.add(new go.PathSegment(go.SegmentType.Line, w * 0.15, h));
fig.add(new go.PathSegment(go.SegmentType.Line, 0, 0.5 * h).close());
geo.spot1 = new go.Spot(0.15, 0);
geo.spot2 = new go.Spot(0.85, 1);
return geo;
});
// taken from ../extensions/Figures.js:
go.Shape.defineFigureGenerator('File', (shape, w, h) => {
const geo = new go.Geometry();
const fig = new go.PathFigure(0, 0, true); // starting point
geo.add(fig);
fig.add(new go.PathSegment(go.SegmentType.Line, 0.75 * w, 0));
fig.add(new go.PathSegment(go.SegmentType.Line, w, 0.25 * h));
fig.add(new go.PathSegment(go.SegmentType.Line, w, h));
fig.add(new go.PathSegment(go.SegmentType.Line, 0, h).close());
const fig2 = new go.PathFigure(0.75 * w, 0, false);
geo.add(fig2);
// The Fold
fig2.add(new go.PathSegment(go.SegmentType.Line, 0.75 * w, 0.25 * h));
fig2.add(new go.PathSegment(go.SegmentType.Line, w, 0.25 * h));
geo.spot1 = new go.Spot(0, 0.25);
geo.spot2 = go.Spot.BottomRight;
return geo;
});
}
// 以用户可以编辑的JSON格式显示图的模型
function save() {
console.log(data, JSON.parse(myDiagram.model.toJson()))
return;
document.getElementById('mySavedModel').value = myDiagram.model.toJson();
myDiagram.isModified = false;
}
function load() {
myDiagram.model = go.Model.fromJson(data);
document.getElementById('mySavedModel').value = myDiagram.model.toJson()
}
function empty() {
myDiagram.model.nodeDataArray = [];
myDiagram.model.linkDataArray = [];
document.getElementById('mySavedModel').value = ''
}
// 通过打开一个包含每个页面的图表内容的SVG图像的新窗口来打印图表
function printDiagram() {
console.log('printDiagram')
const svgWindow = window.open();
if (!svgWindow) return; // failure to open a new Window
svgWindow.document.title = "GoJS Flowchart";
svgWindow.document.body.style.margin = "0px";
const printSize = new go.Size(700, 960);
const bnds = myDiagram.documentBounds;
let x = bnds.x;
let y = bnds.y;
while (y < bnds.bottom) {
while (x < bnds.right) {
const svg = myDiagram.makeSvg({
scale: 1.0,
position: new go.Point(x, y),
size: printSize,
background: myDiagram.themeManager.findValue('div', 'colors'),
});
svgWindow.document.body.appendChild(svg);
x += printSize.width;
}
x = bnds.x;
y += printSize.height;
}
setTimeout(() => {
svgWindow.print();
svgWindow.close();
}, 1);
}
function changeTheme() {
console.log('changeTheme')
const myDiagram = go.Diagram.fromDiv('myDiagramDiv');
if (myDiagram) {
myDiagram.themeManager.currentTheme = document.getElementById('theme').value;
}
}
window.addEventListener('DOMContentLoaded', () => {
// setTimeout仅用于确保在加载图表之前加载字体
// you may want to use an asset loading library for this
// to keep this sample simple, it does not
setTimeout(() => {
init();
}, 300);
});
/**
* o+=String.fromCharCode(t.charCodeAt(r)^i[(i[e]+i[s])%256]);
if(o.indexOf('GoJS 2.1 evaluation')>-1 || o.indexOf('(i) 1998-2021 Northwoods Software')>-1||
o.indexOf('Not for distribution or production use')>-1
||o.indexOf('gojs.net')>-1){return '';}else{
return o}
*/
</script>
</body>
</html>
go.js流程图思维导图,根据setting地址栏参数判断是否能拖动修改,点击跳转,双击修改文字,
Stacey-TL2024-08-08 16:52
相关推荐
和你一起去月球几秒前
TypeScript - 函数(下)_Legend_King6 分钟前
vue3 + elementPlus 日期时间选择器禁用未来及过去时间余生H8 分钟前
transformer.js(三):底层架构及性能优化指南凡人的AI工具箱11 分钟前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)景天科技苑21 分钟前
【vue3+vite】新一代vue脚手架工具vite,助力前端开发更快捷更高效chnming198727 分钟前
STL关联式容器之map进击的六角龙28 分钟前
深入浅出:使用Python调用API实现智能天气预报檀越剑指大厂29 分钟前
【Python系列】浅析 Python 中的字典更新与应用场景石小石Orz30 分钟前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~小行星12532 分钟前
前端预览pdf文件流