1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>组织结构图</title>
  7. <meta name="description" content="An organization chart editor -- edit details and change relationships." />
  8. <meta name="viewport" content="width=device-width, initial-scale=1">
  9. <!-- Copyright - by Northwoods Software Corporation. -->
  10.  
  11. <style>
  12. .inspector {
  13. display: inline-block;
  14. font: bold 14px helvetica, sans-serif;
  15. background-color: #;
  16. /* Grey 900 */
  17. color: #F5F5F5;
  18. /* Grey 100 */
  19. cursor: default;
  20. }
  21.  
  22. .inspector table {
  23. border-collapse: separate;
  24. border-spacing: 2px;
  25. }
  26.  
  27. .inspector td,
  28. th {
  29. padding: 2px;
  30. }
  31.  
  32. .inspector input {
  33. background-color: #;
  34. /* Grey 800 */
  35. color: #F5F5F5;
  36. /* Grey 100 */
  37. font: bold 12px helvetica, sans-serif;
  38. border: 0px;
  39. padding: 2px;
  40. }
  41.  
  42. .inspector input:disabled {
  43. background-color: #BDBDBD;
  44. /* Grey 400 */
  45. color: #;
  46. /* Grey 700 */
  47. }
  48.  
  49. .inspector select {
  50. background-color: #;
  51. }
  52. </style>
  53.  
  54. <script src="https://cdnjs.cloudflare.com/ajax/libs/gojs/1.8.13/go-debug.js"></script>
  55. <!-- this is only for the GoJS Samples framework -->
  56.  
  57. </head>
  58.  
  59. <body onload="init()">
  60. <div id="sample">
  61. <div id="myDiagramDiv" style="background-color: #34343C; border: solid 1px black; height: 570px;"></div>
  62. <p>
  63. <button id="zoomToFit">Zoom to Fit</button>
  64. <button id="centerRoot">Center on root</button>
  65. </p>
  66.  
  67. <div>
  68. <div id="myInspector">
  69. </div>
  70. </div>
  71. <p>
  72. This editable organizational chart sample color-codes the Nodes according to the tree level in the hierarchy.
  73. </p>
  74. <p>
  75. Double click on a node in order to add a person or the diagram background to add a new boss. Double clicking the diagram
  76. uses the
  77. <a>ClickCreatingTool</a>
  78. with a custom
  79. <a>ClickCreatingTool.insertPart</a> to scroll to the new node and start editing the
  80. <a>TextBlock</a> for its name .
  81. </p>
  82. <p>
  83. Drag a node onto another in order to change relationships. You can also draw a link from a node's background to other nodes
  84. that have no "boss". Links can also be relinked to change relationships. Right-click or tap-hold a Node to bring up
  85. a context menu which allows you to:
  86. <ul>
  87. <li>Vacate Position - remove the information specfic to the current person in that role</li>
  88. <li>Remove Role - removes the role entirely and reparents any children</li>
  89. <li>Remove Department - removes the role and the whole subtree</li>
  90. </ul>
  91. Deleting a Node or Link will orphan the child Nodes and generate a new tree. A custom SelectionDeleting
  92. <a>DiagramEvent</a> listener will clear out the boss info when the parent is removed.
  93. </p>
  94. <p>
  95. Select a node to edit/update node data values. This sample uses the
  96. <a href="../extensions/dataInspector.html">Data Inspector</a> extension to display and modify Part data.
  97. </p>
  98. <p>
  99. To learn how to build an org chart from scratch with GoJS, see the
  100. <a href="../learn/index.html">Getting Started tutorial</a>.
  101. </p>
  102. <p>
  103. If you want to have some "assistant" nodes on the side, above the regular reports, see the
  104. <a href="orgChartAssistants.html">Org Chart Assistants</a> sample, which is a copy of this sample that uses a custom
  105. <a>TreeLayout</a> to position "assistants" that way.
  106. </p>
  107. <div>
  108. <div>
  109. <button id="SaveButton" onclick="save()">Save</button>
  110. <button onclick="load()">Load</button>
  111. Diagram Model saved in JSON format:
  112. </div>
  113. <textarea id="mySavedModel" style="width:100%; height:270px;">
  114. { "class": "go.TreeModel",
  115. "nodeDataArray": [
  116. {"key":, "name":"中心主题"}
  117. ]
  118. }
  119. </textarea>
  120. </div>
  121. </div>
  122. </body>
  123.  
  124. <script id="code">
  125.  
  126. function init() {
  127. if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this
  128. var $ = go.GraphObject.make; //GraphObject是所有图形基类,这里简洁定义模板,$太敏感,为避免与jQuery冲突,此处使用ds
  129.  
  130. //图表由节点、文字、线、箭头组成。
  131. myDiagram =
  132. $(go.Diagram, "myDiagramDiv", // must be the ID or reference to div
  133. {
  134. "initialContentAlignment": go.Spot.Center, // 将图表在画布中居中显示
  135. maxSelectionCount: , // 一次允许选择一个部件,
  136. //"isReadOnly": true, // 只读
  137. "allowZoom": true, //画布缩放
  138. //"InitialLayoutCompleted":loadDiagramProperties这是函数名, //一个DiagramEvent侦听器
  139. //鼠标滚轮事件放大和缩小,而不是向上和向下滚动
  140. "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,
  141. "undoManager.isEnabled": true, // 操作支持Ctrl-Z撤销、Ctrl-Y重做
  142. validCycle: go.Diagram.CycleDestinationTree, // make sure users can only create trees
  143. //"clickCreatingTool.archetypeNodeData": { // 默认单根节点,这段代码允许多根节点,双击背景创建新的根节点
  144. // name: "(自由节点)"
  145. //},
  146. "clickCreatingTool.insertPart": function (loc) { // scroll to the new node
  147. var node = go.ClickCreatingTool.prototype.insertPart.call(this, loc);
  148. if (node !== null) {
  149. this.diagram.select(node);
  150. this.diagram.commandHandler.scrollToPart(node);
  151. this.diagram.commandHandler.editTextBlock(node.findObject("NAMETB"));
  152. }
  153. return node;
  154. },
  155. layout:
  156. $(go.TreeLayout,
  157. {
  158. treeStyle: go.TreeLayout.StyleLastParents,
  159. arrangement: go.TreeLayout.ArrangementHorizontal,
  160. // properties for most of the tree:
  161. angle: ,
  162. layerSpacing: ,
  163. // properties for the "last parents":
  164. alternateAngle: ,
  165. alternateLayerSpacing: ,
  166. alternateAlignment: go.TreeLayout.AlignmentBus,
  167. alternateNodeSpacing:
  168. })
  169. });
  170.  
  171. // 当文档被修改时,在标题中添加“*”并启用“Save”按钮
  172. myDiagram.addDiagramListener("Modified", function (e) {
  173. var button = document.getElementById("SaveButton");
  174. if (button) button.disabled = !myDiagram.isModified;
  175. var idx = document.title.indexOf("*");
  176. if (myDiagram.isModified) {
  177. if (idx < ) document.title += "*";
  178. } else {
  179. if (idx >= ) document.title = document.title.substr(, idx);
  180. }
  181. });
  182.  
  183. // manage boss info manually when a node or link is deleted from the diagram
  184. myDiagram.addDiagramListener("SelectionDeleting", function (e) {
  185. var part = e.subject.first(); // e.subject is the myDiagram.selection collection,
  186. // so we'll get the first since we know we only have one selection
  187. myDiagram.startTransaction("clear boss");
  188. if (part instanceof go.Node) {
  189. var it = part.findTreeChildrenNodes(); // find all child nodes
  190. while (it.next()) { // now iterate through them and clear out the boss information
  191. var child = it.value;
  192. var bossText = child.findObject("boss"); // since the boss TextBlock is named, we can access it by name
  193. if (bossText === null) return;
  194. bossText.text = "";
  195. }
  196. } else if (part instanceof go.Link) {
  197. var child = part.toNode;
  198. var bossText = child.findObject("boss"); // since the boss TextBlock is named, we can access it by name
  199. if (bossText === null) return;
  200. bossText.text = "";
  201. }
  202. myDiagram.commitTransaction("clear boss");
  203. });
  204.  
  205. var levelColors = ["#AC193D", "#2672EC", "#8C0095", "#5133AB",
  206. "#008299", "#D24726", "#008A00", "#094AB2"];
  207.  
  208. // override TreeLayout.commitNodes to also modify the background brush based on the tree depth level
  209. myDiagram.layout.commitNodes = function () {
  210. go.TreeLayout.prototype.commitNodes.call(myDiagram.layout); // do the standard behavior
  211. // then go through all of the vertexes and set their corresponding node's Shape.fill
  212. // to a brush dependent on the TreeVertex.level value
  213. myDiagram.layout.network.vertexes.each(function (v) {
  214. if (v.node) {
  215. var level = v.level % (levelColors.length);
  216. var color = levelColors[level];
  217. var shape = v.node.findObject("SHAPE");
  218. if (shape) shape.stroke = $(go.Brush, "Linear", { : color, : go.Brush.lightenBy(color, 0.05), start: go.Spot.Left, end: go.Spot.Right });
  219. }
  220. });
  221. };
  222.  
  223. // when a node is double-clicked, add a child to it
  224. function createNode(e, obj) {
  225. //拿到节点的对象,后面要拿什么值就直接拿
  226. var clicked = obj.part;
  227. if (clicked !== null) {
  228. var thisemp = clicked.data;
  229. myDiagram.startTransaction("createNode");
  230. var newemp = {
  231. name: "(新节点)",
  232. parent: thisemp.key
  233. };
  234. //console.log(thisemp.key);
  235. console.log(myDiagram.model.toJson());
  236. myDiagram.model.addNodeData(newemp);
  237. myDiagram.commitTransaction("createNode");
  238. }
  239. }
  240.  
  241. // this is used to determine feedback during drags
  242. function mayWorkFor(node1, node2) {
  243. if (!(node1 instanceof go.Node)) return false; // must be a Node
  244. if (node1 === node2) return false; // cannot work for yourself
  245. if (node2.isInTreeOf(node1)) return false; // cannot work for someone who works for you
  246. return true;
  247. }
  248.  
  249. // 为大多数文本块提供通用样式
  250. // Some of these values may be overridden in a particular TextBlock.某些值可能在特定的文本块中被覆盖
  251. function textStyle() {
  252. //strokez颜色,添加textAlign: "center"好像效果可能是被覆盖了
  253. return { font: "9pt Segoe UI,sans-serif", stroke: "white" };
  254. }
  255.  
  256. // This converter is used by the Picture.
  257. function findHeadShot(key) {
  258. if (key < || key > ) return "images/HSnopic.jpg"; // There are only 16 images on the server
  259. return "images/HS" + key + ".jpg"
  260. }
  261.  
  262. // define the Node template 定义节点模板 描述如何构建每个节点
  263. myDiagram.nodeTemplate =
  264. $(go.Node, "Auto",//形状自动填充适合 与css设置width:auto同样效果
  265. //{ doubleClick: createNode },
  266. { // handle dragging a Node onto a Node to (maybe) change the reporting relationship
  267. mouseDragEnter: function (e, node, prev) {
  268. var diagram = node.diagram;
  269. var selnode = diagram.selection.first();
  270. if (!mayWorkFor(selnode, node)) return;
  271. var shape = node.findObject("SHAPE");
  272. if (shape) {
  273. shape._prevFill = shape.fill; // remember the original brush
  274. shape.fill = "darkred";
  275. }
  276. },
  277. mouseDragLeave: function (e, node, next) {
  278. var shape = node.findObject("SHAPE");
  279. if (shape && shape._prevFill) {
  280. shape.fill = shape._prevFill; // restore the original brush
  281. }
  282. },
  283. mouseDrop: function (e, node) {
  284. var diagram = node.diagram;
  285. var selnode = diagram.selection.first(); // assume just one Node in selection
  286. if (mayWorkFor(selnode, node)) {
  287. // find any existing link into the selected node
  288. var link = selnode.findTreeParentLink();
  289. if (link !== null) { // 重新连接所有已有连接
  290. link.fromNode = node;
  291. } else { // 新建连接
  292. diagram.toolManager.linkingTool.insertLink(node, node.port, selnode, selnode.port);
  293. }
  294. }
  295. }
  296. },
  297. // for sorting, have the Node.text be the data.name
  298. new go.Binding("text", "name"),
  299. // bind the Part.layerName to control the Node's layer depending on whether it isSelected
  300. new go.Binding("layerName", "isSelected", function (sel) { return sel ? "Foreground" : ""; }).ofObject(),
  301. //设置节点形状:长方形
  302. $(go.Shape, "Rectangle",
  303. {
  304. name: "SHAPE", fill: "#333333", stroke: 'white', strokeWidth: 3.5,
  305. // set the port properties: 是否可连接fromLinkable、toLinkable
  306. portId: "", fromLinkable: false, toLinkable: false, cursor: "pointer"
  307. }),
  308. // Panel 有不同的类型,每个类型表示一种布局,通过不同的坐标系统排列
  309. $(go.Panel, "Horizontal",
  310. // 定义文本显示框
  311. $(go.Panel, "Table",
  312. {
  313. minSize: new go.Size(, NaN),
  314. maxSize: new go.Size(, NaN),
  315. margin: new go.Margin(),//设置文本和边框距离
  316. defaultAlignment: go.Spot.Center
  317. },
  318. $(go.RowColumnDefinition, { column: , width: }),
  319. // 设置文本节点
  320. $(go.TextBlock, textStyle(), // the name
  321. {
  322. row: , column: , columnSpan: ,
  323. font: "12pt Segoe UI,sans-serif",
  324. editable: true, isMultiline: false,// editable文本是否可编辑
  325. minSize: new go.Size(, )
  326. },
  327. //将节点数据nodeDataArray.name与text建立联系
  328. new go.Binding("text", "name").makeTwoWay())
  329. ) // end Table Panel
  330. ) // end Horizontal Panel
  331. ); // end Node
  332.  
  333. // 选中的节点显示用于添加子节点的按钮
  334. myDiagram.nodeTemplate.selectionAdornmentTemplate =
  335. $(go.Adornment, "Spot",
  336. $(go.Panel, "Auto",
  337. $(go.Placeholder, {
  338. margin: new go.Margin(, -, , )
  339. })
  340. ),
  341. // 所选节点的删除按钮
  342. $("Button", {
  343. alignment: go.Spot.Right,
  344. alignmentFocus: go.Spot.Left,
  345. click: function (e, obj) {
  346. var node = obj.part.adornedPart;
  347. //console.log(node.data.key);
  348. if (node !== null) {
  349. myDiagram.startTransaction("remove dept");
  350. // 删除单个节点myDiagram.model.removeNodeData(node.data)只要能拿到node.data对象就能删除了;
  351. //删除整个子树,包括节点本身
  352. myDiagram.removeParts(node.findTreeParts());
  353. myDiagram.commitTransaction("remove dept");
  354. }
  355. }
  356. // 定义装饰中此按钮的单击行为
  357. },
  358. $(go.TextBlock, "-", // 按钮的内容
  359. {
  360. font: "bold 8pt sans-serif"
  361. })
  362. ),
  363. // 所选节点的新增按钮
  364. $("Button", {
  365. alignment: go.Spot.Right,
  366. alignmentFocus: go.Spot.Right,
  367. click: createNode
  368. },
  369. $(go.TextBlock, "+", // 按钮的内容
  370. {
  371. font: "bold 8pt sans-serif"
  372. })
  373. )
  374. );
  375.  
  376. //监听键盘事件
  377. myDiagram.commandHandler.doKeyDown = function () {
  378. var e = myDiagram.lastInput;
  379. var control = e.control || e.meta;
  380. var key = e.key;
  381.  
  382. console.log('key' + key);//Tab和Enter键好像这里取到的名字是空
  383.  
  384. if (control && (key === 'Z' || key === 'Y')) {
  385. console.log('Ctrl+Z/Y');
  386. };
  387.  
  388. // 取消Del/Backspace删除键的命令关联:
  389. //if (key === 'Del' || key === 'Backspace') return;
  390.  
  391. go.CommandHandler.prototype.doKeyDown.call(this);
  392. };
  393.  
  394. // 设置线条和箭头,是否允许拖动连接relinkableFrom,relinkableTo
  395. myDiagram.linkTemplate =
  396. $(go.Link, go.Link.Orthogonal,
  397. { corner: , relinkableFrom: false, relinkableTo: false },
  398. $(go.Shape, { strokeWidth: 1.5, stroke: "#F5F5F5" })); // the link shape
  399.  
  400. // 拖拽框选功能
  401. myDiagram.toolManager.dragSelectingTool.box =
  402. $(go.Part,
  403. { layerName: "Tool", selectable: true },
  404. $(go.Shape,
  405. { name: "SHAPE", fill: null, stroke: "chartreuse", strokeWidth: }));
  406.  
  407. // read in the JSON-format data from the "mySavedModel" element
  408. load();
  409.  
  410. // support editing the properties of the selected person in HTML
  411. if (window.Inspector) myInspector = new Inspector("myInspector", myDiagram,
  412. {
  413. properties: {
  414. "key": { readOnly: true },
  415. "comments": {}
  416. }
  417. });
  418.  
  419. // Setup zoom to fit button
  420. document.getElementById('zoomToFit').addEventListener('click', function () {
  421. myDiagram.commandHandler.zoomToFit();
  422. });
  423.  
  424. document.getElementById('centerRoot').addEventListener('click', function () {
  425. myDiagram.scale = ;
  426. myDiagram.commandHandler.scrollToPart(myDiagram.findNodeForKey());
  427. });
  428.  
  429. } // end init
  430.  
  431. // Show the diagram's model in JSON format
  432. function save() {
  433. document.getElementById("mySavedModel").value = myDiagram.model.toJson();
  434. myDiagram.isModified = false;
  435. }
  436. function load() {
  437. // model中的数据每一个js对象都代表着一个相应的模型图中的元素
  438. myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value);
  439. // make sure new data keys are unique positive integers
  440. var lastkey = ;
  441. myDiagram.model.makeUniqueKeyFunction = function (model, data) {
  442. var k = data.key || lastkey;
  443. while (model.findNodeDataForKey(k)) k++;
  444. data.key = lastkey = k;
  445. return k;
  446. };
  447. }
  448.  
  449. "use strict";//严格模式,在开发中使用严格模式能帮助我们早发现错误
  450.  
  451. function Inspector(divid, diagram, options) {
  452. var mainDiv = document.getElementById(divid);
  453. mainDiv.className = "inspector";
  454. mainDiv.innerHTML = "";
  455. this._div = mainDiv;
  456. this._diagram = diagram;
  457. this._inspectedProperties = {};
  458. this._multipleProperties = {};
  459.  
  460. // Either a GoJS Part or a simple data object, such as Model.modelData
  461. this.inspectedObject = null;
  462.  
  463. // Inspector options defaults:
  464. this.includesOwnProperties = true;
  465. this.declaredProperties = {};
  466. this.inspectsSelection = true;
  467. this.propertyModified = null;
  468. this.multipleSelection = false;
  469. this.showAllProperties = false;
  470. this.showSize = ;
  471.  
  472. if (options !== undefined) {
  473. if (options["includesOwnProperties"] !== undefined) this.includesOwnProperties = options["includesOwnProperties"];
  474. if (options["properties"] !== undefined) this.declaredProperties = options["properties"];
  475. if (options["inspectSelection"] !== undefined) this.inspectsSelection = options["inspectSelection"];
  476. if (options["propertyModified"] !== undefined) this.propertyModified = options["propertyModified"];
  477. if (options['multipleSelection'] !== undefined) this.multipleSelection = options['multipleSelection'];
  478. if (options['showAllProperties'] !== undefined) this.showAllProperties = options['showAllProperties'];
  479. if (options['showSize'] !== undefined) this.showSize = options['showSize'];
  480. }
  481.  
  482. var self = this;
  483. diagram.addModelChangedListener(function (e) {
  484. if (e.isTransactionFinished) self.inspectObject();
  485. });
  486. if (this.inspectsSelection) {
  487. diagram.addDiagramListener("ChangedSelection", function (e) { self.inspectObject(); });
  488. }
  489. }
  490.  
  491. // Some static predicates to use with the "show" property.
  492. Inspector.showIfNode = function (part) { return part instanceof go.Node };
  493. Inspector.showIfLink = function (part) { return part instanceof go.Link };
  494. Inspector.showIfGroup = function (part) { return part instanceof go.Group };
  495.  
  496. // Only show the property if its present. Useful for "key" which will be shown on Nodes and Groups, but normally not on Links
  497. Inspector.showIfPresent = function (data, propname) {
  498. if (data instanceof go.Part) data = data.data;
  499. return typeof data === "object" && data[propname] !== undefined;
  500. };
  501.  
  502. /**
  503. * Update the HTML state of this Inspector given the properties of the {@link #inspectedObject}.
  504. * @param {Object} object is an optional argument, used when {@link #inspectSelection} is false to
  505. * set {@link #inspectedObject} and show and edit that object's properties.
  506. */
  507. Inspector.prototype.inspectObject = function (object) {
  508. var inspectedObject = null;
  509. var inspectedObjects = null;
  510. if (object === null) return;
  511. if (object === undefined) {
  512. if (this.inspectsSelection) {
  513. if (this.multipleSelection) { // gets the selection if multiple selection is true
  514. inspectedObjects = this._diagram.selection;
  515. } else { // otherwise grab the first object
  516. inspectedObject = this._diagram.selection.first();
  517. }
  518. } else { // if there is a single inspected object
  519. inspectedObject = this.inspectedObject;
  520. }
  521. } else { // if object was passed in as a parameter
  522. inspectedObject = object;
  523. }
  524. if (inspectedObjects && inspectedObjects.count === ) {
  525. inspectedObject = inspectedObjects.first();
  526. }
  527. if (inspectedObjects && inspectedObjects.count <= ) {
  528. inspectedObjects = null;
  529. }
  530.  
  531. // single object or no objects
  532. if (!inspectedObjects || !this.multipleSelection) {
  533. if (inspectedObject === null) {
  534. this.inspectedObject = inspectedObject;
  535. this.updateAllHTML();
  536. return;
  537. }
  538.  
  539. this.inspectedObject = inspectedObject;
  540. if (this.inspectObject === null) return;
  541. var mainDiv = this._div;
  542. mainDiv.innerHTML = '';
  543.  
  544. // use either the Part.data or the object itself (for model.modelData)
  545. var data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject;
  546. if (!data) return;
  547. // Build table:
  548. var table = document.createElement('table');
  549. var tbody = document.createElement('tbody');
  550. this._inspectedProperties = {};
  551. this.tabIndex = ;
  552. var declaredProperties = this.declaredProperties;
  553.  
  554. // Go through all the properties passed in to the inspector and show them, if appropriate:
  555. for (var name in declaredProperties) {
  556. var desc = declaredProperties[name];
  557. if (!this.canShowProperty(name, desc, inspectedObject)) continue;
  558. var val = this.findValue(name, desc, data);
  559. tbody.appendChild(this.buildPropertyRow(name, val));
  560. }
  561. // Go through all the properties on the model data and show them, if appropriate:
  562. if (this.includesOwnProperties) {
  563. for (var k in data) {
  564. if (k === '__gohashid') continue; // skip internal GoJS hash property
  565. if (this._inspectedProperties[k]) continue; // already exists
  566. if (declaredProperties[k] && !this.canShowProperty(k, declaredProperties[k], inspectedObject)) continue;
  567. tbody.appendChild(this.buildPropertyRow(k, data[k]));
  568. }
  569. }
  570.  
  571. table.appendChild(tbody);
  572. mainDiv.appendChild(table);
  573. } else { // multiple objects selected
  574. var mainDiv = this._div;
  575. mainDiv.innerHTML = '';
  576. var shared = new go.Map(); // for properties that the nodes have in common
  577. var properties = new go.Map(); // for adding properties
  578. var all = new go.Map(); // used later to prevent changing properties when unneeded
  579. var it = inspectedObjects.iterator;
  580. // Build table:
  581. var table = document.createElement('table');
  582. var tbody = document.createElement('tbody');
  583. this._inspectedProperties = {};
  584. this.tabIndex = ;
  585. var declaredProperties = this.declaredProperties;
  586. it.next();
  587. inspectedObject = it.value;
  588. this.inspectedObject = inspectedObject;
  589. var data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject;
  590. if (data) { // initial pass to set shared and all
  591. // Go through all the properties passed in to the inspector and add them to the map, if appropriate:
  592. for (var name in declaredProperties) {
  593. var desc = declaredProperties[name];
  594. if (!this.canShowProperty(name, desc, inspectedObject)) continue;
  595. var val = this.findValue(name, desc, data);
  596. if (val === '' && desc && desc.type === 'checkbox') {
  597. shared.add(name, false);
  598. all.add(name, false);
  599. } else {
  600. shared.add(name, val);
  601. all.add(name, val);
  602. }
  603. }
  604. // Go through all the properties on the model data and add them to the map, if appropriate:
  605. if (this.includesOwnProperties) {
  606. for (var k in data) {
  607. if (k === '__gohashid') continue; // skip internal GoJS hash property
  608. if (this._inspectedProperties[k]) continue; // already exists
  609. if (declaredProperties[k] && !this.canShowProperty(k, declaredProperties[k], inspectedObject)) continue;
  610. shared.add(k, data[k]);
  611. all.add(k, data[k]);
  612. }
  613. }
  614. }
  615. var nodecount = ;
  616. while (it.next() && (this.showSize < || nodecount <= this.showSize)) { // grabs all the properties from the other selected objects
  617. properties.clear();
  618. inspectedObject = it.value;
  619. if (inspectedObject) {
  620. // use either the Part.data or the object itself (for model.modelData)
  621. data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject;
  622. if (data) {
  623. // Go through all the properties passed in to the inspector and add them to properties to add, if appropriate:
  624. for (var name in declaredProperties) {
  625. var desc = declaredProperties[name];
  626. if (!this.canShowProperty(name, desc, inspectedObject)) continue;
  627. var val = this.findValue(name, desc, data);
  628. if (val === '' && desc && desc.type === 'checkbox') {
  629. properties.add(name, false);
  630. } else {
  631. properties.add(name, val);
  632. }
  633. }
  634. // Go through all the properties on the model data and add them to properties to add, if appropriate:
  635. if (this.includesOwnProperties) {
  636. for (var k in data) {
  637. if (k === '__gohashid') continue; // skip internal GoJS hash property
  638. if (this._inspectedProperties[k]) continue; // already exists
  639. if (declaredProperties[k] && !this.canShowProperty(k, declaredProperties[k], inspectedObject)) continue;
  640. properties.add(k, data[k]);
  641. }
  642. }
  643. }
  644. }
  645. if (!this.showAllProperties) {
  646. // Cleans up shared map with properties that aren't shared between the selected objects
  647. // Also adds properties to the add and shared maps if applicable
  648. var addIt = shared.iterator;
  649. var toRemove = [];
  650. while (addIt.next()) {
  651. if (properties.has(addIt.key)) {
  652. var newVal = all.get(addIt.key) + '|' + properties.get(addIt.key);
  653. all.set(addIt.key, newVal);
  654. if ((declaredProperties[addIt.key] && declaredProperties[addIt.key].type !== 'color'
  655. && declaredProperties[addIt.key].type !== 'checkbox' && declaredProperties[addIt.key].type !== 'select')
  656. || !declaredProperties[addIt.key]) { // for non-string properties i.e color
  657. newVal = shared.get(addIt.key) + '|' + properties.get(addIt.key);
  658. shared.set(addIt.key, newVal);
  659. }
  660. } else { // toRemove array since addIt is still iterating
  661. toRemove.push(addIt.key);
  662. }
  663. }
  664. for (var i = ; i < toRemove.length; i++) { // removes anything that doesn't showAllPropertiess
  665. shared.remove(toRemove[i]);
  666. all.remove(toRemove[i]);
  667. }
  668. } else {
  669. // Adds missing properties to all with the correct amount of seperators
  670. var addIt = properties.iterator;
  671. while (addIt.next()) {
  672. if (all.has(addIt.key)) {
  673. if ((declaredProperties[addIt.key] && declaredProperties[addIt.key].type !== 'color'
  674. && declaredProperties[addIt.key].type !== 'checkbox' && declaredProperties[addIt.key].type !== 'select')
  675. || !declaredProperties[addIt.key]) { // for non-string properties i.e color
  676. var newVal = all.get(addIt.key) + '|' + properties.get(addIt.key);
  677. all.set(addIt.key, newVal);
  678. }
  679. } else {
  680. var newVal = '';
  681. for (var i = ; i < nodecount - ; i++) newVal += '|';
  682. newVal += properties.get(addIt.key);
  683. all.set(addIt.key, newVal);
  684. }
  685. }
  686. // Adds bars in case properties is not in all
  687. addIt = all.iterator;
  688. while (addIt.next()) {
  689. if (!properties.has(addIt.key)) {
  690. if ((declaredProperties[addIt.key] && declaredProperties[addIt.key].type !== 'color'
  691. && declaredProperties[addIt.key].type !== 'checkbox' && declaredProperties[addIt.key].type !== 'select')
  692. || !declaredProperties[addIt.key]) { // for non-string properties i.e color
  693. var newVal = all.get(addIt.key) + '|';
  694. all.set(addIt.key, newVal);
  695. }
  696. }
  697. }
  698. }
  699. nodecount++;
  700. }
  701. // builds the table property rows and sets multipleProperties to help with updateall
  702. var mapIt;
  703. if (!this.showAllProperties) mapIt = shared.iterator;
  704. else mapIt = all.iterator;
  705. while (mapIt.next()) {
  706. tbody.appendChild(this.buildPropertyRow(mapIt.key, mapIt.value)); // shows the properties that are allowed
  707. }
  708. table.appendChild(tbody);
  709. mainDiv.appendChild(table);
  710. var allIt = all.iterator;
  711. while (allIt.next()) {
  712. this._multipleProperties[allIt.key] = allIt.value; // used for updateall to know which properties to change
  713. }
  714. }
  715. };
  716.  
  717. /**
  718. * @ignore
  719. * This predicate should be false if the given property should not be shown.
  720. * Normally it only checks the value of "show" on the property descriptor.
  721. * The default value is true.
  722. * @param {string} propertyName the property name
  723. * @param {Object} propertyDesc the property descriptor
  724. * @param {Object} inspectedObject the data object
  725. * @return {boolean} whether a particular property should be shown in this Inspector
  726. */
  727. Inspector.prototype.canShowProperty = function (propertyName, propertyDesc, inspectedObject) {
  728. if (propertyDesc.show === false) return false;
  729. // if "show" is a predicate, make sure it passes or do not show this property
  730. if (typeof propertyDesc.show === "function") return propertyDesc.show(inspectedObject, propertyName);
  731. return true;
  732. }
  733.  
  734. /**
  735. * @ignore
  736. * This predicate should be false if the given property should not be editable by the user.
  737. * Normally it only checks the value of "readOnly" on the property descriptor.
  738. * The default value is true.
  739. * @param {string} propertyName the property name
  740. * @param {Object} propertyDesc the property descriptor
  741. * @param {Object} inspectedObject the data object
  742. * @return {boolean} whether a particular property should be shown in this Inspector
  743. */
  744. Inspector.prototype.canEditProperty = function (propertyName, propertyDesc, inspectedObject) {
  745. if (this._diagram.isReadOnly || this._diagram.isModelReadOnly) return false;
  746. // assume property values that are functions of Objects cannot be edited
  747. var data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject;
  748. var valtype = typeof data[propertyName];
  749. if (valtype === "function") return false;
  750. if (propertyDesc) {
  751. if (propertyDesc.readOnly === true) return false;
  752. // if "readOnly" is a predicate, make sure it passes or do not show this property
  753. if (typeof propertyDesc.readOnly === "function") return !propertyDesc.readOnly(inspectedObject, propertyName);
  754. }
  755. return true;
  756. }
  757.  
  758. /**
  759. * @ignore
  760. * @param {any} propName
  761. * @param {any} propDesc
  762. * @param {any} data
  763. * @return {any}
  764. */
  765. Inspector.prototype.findValue = function (propName, propDesc, data) {
  766. var val = '';
  767. if (propDesc && propDesc.defaultValue !== undefined) val = propDesc.defaultValue;
  768. if (data[propName] !== undefined) val = data[propName];
  769. if (val === undefined) return '';
  770. return val;
  771. }
  772.  
  773. /**
  774. * @ignore
  775. * This sets this._inspectedProperties[propertyName] and creates the HTML table row:
  776. * <tr>
  777. * <td>propertyName</td>
  778. * <td><input value=propertyValue /></td>
  779. * </tr>
  780. * @param {string} propertyName the property name
  781. * @param {*} propertyValue the property value
  782. * @return the table row
  783. */
  784. Inspector.prototype.buildPropertyRow = function (propertyName, propertyValue) {
  785. var mainDiv = this._div;
  786. var tr = document.createElement("tr");
  787.  
  788. var td1 = document.createElement("td");
  789. td1.textContent = propertyName;
  790. tr.appendChild(td1);
  791.  
  792. var td2 = document.createElement("td");
  793. var decProp = this.declaredProperties[propertyName];
  794. var input = null;
  795. var self = this;
  796. function updateall() { self.updateAllProperties(); }
  797.  
  798. if (decProp && decProp.type === "select") {
  799. input = document.createElement("select");
  800. this.updateSelect(decProp, input, propertyName, propertyValue);
  801. input.addEventListener("change", updateall);
  802. } else {
  803. input = document.createElement("input");
  804.  
  805. input.value = this.convertToString(propertyValue);
  806. if (decProp) {
  807. var t = decProp.type;
  808. if (t !== 'string' && t !== 'number' && t !== 'boolean' &&
  809. t !== 'arrayofnumber' && t !== 'point' && t !== 'size' &&
  810. t !== 'rect' && t !== 'spot' && t !== 'margin') {
  811. input.setAttribute("type", decProp.type);
  812. }
  813. if (decProp.type === "color") {
  814. if (input.type === "color") {
  815. input.value = this.convertToColor(propertyValue);
  816. // input.addEventListener("input", updateall);
  817. input.addEventListener("change", updateall);
  818. }
  819. } if (decProp.type === "checkbox") {
  820. input.checked = !!propertyValue;
  821. input.addEventListener("change", updateall);
  822. }
  823. }
  824. if (input.type !== "color") input.addEventListener("blur", updateall);
  825. }
  826.  
  827. if (input) {
  828. input.tabIndex = this.tabIndex++;
  829. input.disabled = !this.canEditProperty(propertyName, decProp, this.inspectedObject);
  830. td2.appendChild(input);
  831. }
  832. tr.appendChild(td2);
  833.  
  834. this._inspectedProperties[propertyName] = input;
  835. return tr;
  836. };
  837.  
  838. /**
  839. * @ignore
  840. * HTML5 color input will only take hex,
  841. * so var HTML5 canvas convert the color into hex format.
  842. * This converts "rgb(255, 0, 0)" into "#FF0000", etc.
  843. * @param {string} propertyValue
  844. * @return {string}
  845. */
  846. Inspector.prototype.convertToColor = function (propertyValue) {
  847. var ctx = document.createElement("canvas").getContext("2d");
  848. ctx.fillStyle = propertyValue;
  849. return ctx.fillStyle;
  850. };
  851.  
  852. /**
  853. * @ignore
  854. * @param {string}
  855. * @return {Array.<number>}
  856. */
  857. Inspector.prototype.convertToArrayOfNumber = function (propertyValue) {
  858. if (propertyValue === "null") return null;
  859. var split = propertyValue.split(' ');
  860. var arr = [];
  861. for (var i = ; i < split.length; i++) {
  862. var str = split[i];
  863. if (!str) continue;
  864. arr.push(parseFloat(str));
  865. }
  866. return arr;
  867. };
  868.  
  869. /**
  870. * @ignore
  871. * @param {*}
  872. * @return {string}
  873. */
  874. Inspector.prototype.convertToString = function (x) {
  875. if (x === undefined) return "undefined";
  876. if (x === null) return "null";
  877. if (x instanceof go.Point) return go.Point.stringify(x);
  878. if (x instanceof go.Size) return go.Size.stringify(x);
  879. if (x instanceof go.Rect) return go.Rect.stringify(x);
  880. if (x instanceof go.Spot) return go.Spot.stringify(x);
  881. if (x instanceof go.Margin) return go.Margin.stringify(x);
  882. if (x instanceof go.List) return this.convertToString(x.toArray());
  883. if (Array.isArray(x)) {
  884. var str = "";
  885. for (var i = ; i < x.length; i++) {
  886. if (i > ) str += " ";
  887. var v = x[i];
  888. str += this.convertToString(v);
  889. }
  890. return str;
  891. }
  892. return x.toString();
  893. };
  894.  
  895. /**
  896. * @ignore
  897. * Update all of the HTML in this Inspector.
  898. */
  899. Inspector.prototype.updateAllHTML = function () {
  900. var inspectedProps = this._inspectedProperties;
  901. var diagram = this._diagram;
  902. var isPart = this.inspectedObject instanceof go.Part;
  903. var data = isPart ? this.inspectedObject.data : this.inspectedObject;
  904. if (!data) { // clear out all of the fields
  905. for (var name in inspectedProps) {
  906. var input = inspectedProps[name];
  907. if (input instanceof HTMLSelectElement) {
  908. input.innerHTML = "";
  909. } else if (input.type === "color") {
  910. input.value = "#000000";
  911. } else if (input.type === "checkbox") {
  912. input.checked = false;
  913. } else {
  914. input.value = "";
  915. }
  916.  
  917. }
  918. } else {
  919. for (var name in inspectedProps) {
  920. var input = inspectedProps[name];
  921. var propertyValue = data[name];
  922. if (input instanceof HTMLSelectElement) {
  923. var decProp = this.declaredProperties[name];
  924. this.updateSelect(decProp, input, name, propertyValue);
  925. } else if (input.type === "color") {
  926. input.value = this.convertToColor(propertyValue);
  927. } else if (input.type === "checkbox") {
  928. input.checked = !!propertyValue;
  929. } else {
  930. input.value = this.convertToString(propertyValue);
  931. }
  932. }
  933. }
  934. }
  935.  
  936. /**
  937. * @ignore
  938. * Update an HTMLSelectElement with an appropriate list of choices, given the propertyName
  939. */
  940. Inspector.prototype.updateSelect = function (decProp, select, propertyName, propertyValue) {
  941. select.innerHTML = ""; // clear out anything that was there
  942. var choices = decProp.choices;
  943. if (typeof choices === "function") choices = choices(this.inspectedObject, propertyName);
  944. if (!Array.isArray(choices)) choices = [];
  945. decProp.choicesArray = choices; // remember list of actual choice values (not strings)
  946. for (var i = ; i < choices.length; i++) {
  947. var choice = choices[i];
  948. var opt = document.createElement("option");
  949. opt.text = this.convertToString(choice);
  950. select.add(opt, null);
  951. }
  952. select.value = this.convertToString(propertyValue);
  953. }
  954.  
  955. /**
  956. * @ignore
  957. * Update all of the data properties of {@link #inspectedObject} according to the
  958. * current values held in the HTML input elements.
  959. */
  960. Inspector.prototype.updateAllProperties = function () {
  961. var inspectedProps = this._inspectedProperties;
  962. var diagram = this._diagram;
  963. if (diagram.selection.count === || !this.multipleSelection) { // single object update
  964. var isPart = this.inspectedObject instanceof go.Part;
  965. var data = isPart ? this.inspectedObject.data : this.inspectedObject;
  966. if (!data) return; // must not try to update data when there's no data!
  967.  
  968. diagram.startTransaction('set all properties');
  969. for (var name in inspectedProps) {
  970. var input = inspectedProps[name];
  971. var value = input.value;
  972.  
  973. // don't update "readOnly" data properties
  974. var decProp = this.declaredProperties[name];
  975. if (!this.canEditProperty(name, decProp, this.inspectedObject)) continue;
  976.  
  977. // If it's a boolean, or if its previous value was boolean,
  978. // parse the value to be a boolean and then update the input.value to match
  979. var type = '';
  980. if (decProp !== undefined && decProp.type !== undefined) {
  981. type = decProp.type;
  982. }
  983. if (type === '') {
  984. var oldval = data[name];
  985. if (typeof oldval === 'boolean') type = 'boolean'; // infer boolean
  986. else if (typeof oldval === 'number') type = 'number';
  987. else if (oldval instanceof go.Point) type = 'point';
  988. else if (oldval instanceof go.Size) type = 'size';
  989. else if (oldval instanceof go.Rect) type = 'rect';
  990. else if (oldval instanceof go.Spot) type = 'spot';
  991. else if (oldval instanceof go.Margin) type = 'margin';
  992. }
  993.  
  994. // convert to specific type, if needed
  995. switch (type) {
  996. case 'boolean': value = !(value === false || value === 'false' || value === ''); break;
  997. case 'number': value = parseFloat(value); break;
  998. case 'arrayofnumber': value = this.convertToArrayOfNumber(value); break;
  999. case 'point': value = go.Point.parse(value); break;
  1000. case 'size': value = go.Size.parse(value); break;
  1001. case 'rect': value = go.Rect.parse(value); break;
  1002. case 'spot': value = go.Spot.parse(value); break;
  1003. case 'margin': value = go.Margin.parse(value); break;
  1004. case 'checkbox': value = input.checked; break;
  1005. case 'select': value = decProp.choicesArray[input.selectedIndex]; break;
  1006. }
  1007.  
  1008. // in case parsed to be different, such as in the case of boolean values,
  1009. // the value shown should match the actual value
  1010. input.value = value;
  1011.  
  1012. // modify the data object in an undo-able fashion
  1013. diagram.model.setDataProperty(data, name, value);
  1014.  
  1015. // notify any listener
  1016. if (this.propertyModified !== null) this.propertyModified(name, value, this);
  1017. }
  1018. diagram.commitTransaction('set all properties');
  1019. } else { // selection object update
  1020. diagram.startTransaction('set all properties');
  1021. for (var name in inspectedProps) {
  1022. var input = inspectedProps[name];
  1023. var value = input.value;
  1024. var arr1 = value.split('|');
  1025. var arr2 = [];
  1026. if (this._multipleProperties[name]) {
  1027. // don't split if it is union and its checkbox type
  1028. if (this.declaredProperties[name] && this.declaredProperties[name].type === 'checkbox' && this.showAllProperties) {
  1029. arr2.push(this._multipleProperties[name]);
  1030. } else {
  1031. arr2 = this._multipleProperties[name].toString().split('|');
  1032. }
  1033. }
  1034. var it = diagram.selection.iterator;
  1035. var change = false;
  1036. if (this.declaredProperties[name] && this.declaredProperties[name].type === 'checkbox') change = true; // always change checkbox
  1037. if (arr1.length < arr2.length // i.e Alpha|Beta -> Alpha procs the change
  1038. && (!this.declaredProperties[name] // from and to links
  1039. || !(this.declaredProperties[name] // do not change color checkbox and choices due to them always having less
  1040. && (this.declaredProperties[name].type === 'color' || this.declaredProperties[name].type === 'checkbox' || this.declaredProperties[name].type === 'choices')))) {
  1041. change = true;
  1042. } else { // standard detection in change in properties
  1043. for (var j = ; j < arr1.length && j < arr2.length; j++) {
  1044. if (!(arr1[j] === arr2[j])
  1045. && !(this.declaredProperties[name] && this.declaredProperties[name].type === 'color' && arr1[j].toLowerCase() === arr2[j].toLowerCase())) {
  1046. change = true;
  1047. }
  1048. }
  1049. }
  1050. if (change) { // only change properties it needs to change instead all of them
  1051. for (var i = ; i < diagram.selection.count; i++) {
  1052. it.next();
  1053. var isPart = it.value instanceof go.Part;
  1054. var data = isPart ? it.value.data : it.value;
  1055.  
  1056. if (data) { // ignores the selected node if there is no data
  1057. if (i < arr1.length) value = arr1[i];
  1058. else value = arr1[];
  1059.  
  1060. // don't update "readOnly" data properties
  1061. var decProp = this.declaredProperties[name];
  1062. if (!this.canEditProperty(name, decProp, it.value)) continue;
  1063.  
  1064. // If it's a boolean, or if its previous value was boolean,
  1065. // parse the value to be a boolean and then update the input.value to match
  1066. var type = '';
  1067. if (decProp !== undefined && decProp.type !== undefined) {
  1068. type = decProp.type;
  1069. }
  1070. if (type === '') {
  1071. var oldval = data[name];
  1072. if (typeof oldval === 'boolean') type = 'boolean'; // infer boolean
  1073. else if (typeof oldval === 'number') type = 'number';
  1074. else if (oldval instanceof go.Point) type = 'point';
  1075. else if (oldval instanceof go.Size) type = 'size';
  1076. else if (oldval instanceof go.Rect) type = 'rect';
  1077. else if (oldval instanceof go.Spot) type = 'spot';
  1078. else if (oldval instanceof go.Margin) type = 'margin';
  1079. }
  1080.  
  1081. // convert to specific type, if needed
  1082. switch (type) {
  1083. case 'boolean': value = !(value === false || value === 'false' || value === ''); break;
  1084. case 'number': value = parseFloat(value); break;
  1085. case 'arrayofnumber': value = this.convertToArrayOfNumber(value); break;
  1086. case 'point': value = go.Point.parse(value); break;
  1087. case 'size': value = go.Size.parse(value); break;
  1088. case 'rect': value = go.Rect.parse(value); break;
  1089. case 'spot': value = go.Spot.parse(value); break;
  1090. case 'margin': value = go.Margin.parse(value); break;
  1091. case 'checkbox': value = input.checked; break;
  1092. case 'select': value = decProp.choicesArray[input.selectedIndex]; break;
  1093. }
  1094.  
  1095. // in case parsed to be different, such as in the case of boolean values,
  1096. // the value shown should match the actual value
  1097. input.value = value;
  1098.  
  1099. // modify the data object in an undo-able fashion
  1100. diagram.model.setDataProperty(data, name, value);
  1101.  
  1102. // notify any listener
  1103. if (this.propertyModified !== null) this.propertyModified(name, value, this);
  1104. }
  1105. }
  1106. }
  1107. }
  1108. diagram.commitTransaction('set all properties');
  1109. }
  1110. };
  1111.  
  1112. </script>
  1113.  
  1114. </html>

参考 学习文档  https://liuxiaofan.com/2018/03/16/3521.html

GoJS组织结构图2的更多相关文章

  1. GoJS组织结构图

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. GoJS 友情链接

    目前GoJS官网是学习gojs的最佳选择 GOJS简单示例 GoJS API学习 GoJS组织结构图2 mind map思维导图 组织结构图 GoJS实例1 GoJS实例2 GoJS实例3 GoJS实 ...

  3. GoJS超详细入门(插件使用无非:引包、初始化、配参数(json)、引数据(json)四步)

    GoJS超详细入门(插件使用无非:引包.初始化.配参数(json).引数据(json)四步) 一.总结 一句话总结:插件使用无非:引包.初始化.配参数(json).引数据(json)四步. 1.goj ...

  4. gojs绘流程图

    引用:http://www.tuicool.com/articles/eEruaqu http://www.open-open.com/lib/view/open1435023502544.html ...

  5. GoJS使用

    1. 先学习官网的这篇Get Started with GoJS教程入门,了解GoJS基础知识: 2. 浏览GoJS各个示例(Samples.Intro),找到契合自己业务需要的某个或者某几个例子,然 ...

  6. Web功能之组织结构图

    前提:由于项目需要显示组织结构图的形式 工具:VS2010 项目:ASP.NET 自带的web项目 (带模板页) 插件:OrgChart(依赖:OrgChart.dll).JOrgChart 不多说 ...

  7. 模仿Word中组织结构图的特点生成流程图

    //基本原理: // 1. 从下往上计算位置 // 2. 模仿Word中组织结构图的特点 //调用代码: Tree<string> tree = new Tree<string> ...

  8. asp.net 组织结构图控件

    记得之前做项目的时候客户需要看一个组织结构图,从而了解一下公司的概况,本来自己之前没有做过这方面的控件,只好找度娘,出于对项目的完美,网上很多控件画面感比较渣,后来只能在这些个中挑个比较好的来做,先看 ...

  9. GoJS研究,简单图表制作。

    话不多说,先上图 我在这个中加入了缩略图.鼠标放大缩小等功能. <!doctype html> <html> <head> <title>Flowcha ...

随机推荐

  1. acm数论之旅---扩展欧几里得算法

    度娘百科说: 首先, ax+by = gcd(a, b) 这个公式肯定有解 (( •̀∀•́ )她说根据数论中的相关定理可以证明,反正我信了) 所以 ax+by = gcd(a, b) * k 也肯定 ...

  2. numpy.eye() 生成对角矩阵

    numpy.eye(N,M=None, k=0, dtype=<type 'float'>) 关注第一个第三个参数就行了 第一个参数:输出方阵(行数=列数)的规模,即行数或列数 第三个参数 ...

  3. es 搜索功能简介

    DSL 语法介绍 语法 范围 /_search 集群上搜索所有的索引 /index1/_search index1 /index1,index2/_search index1和index2 /inde ...

  4. 【转】获取Jenkins构建时Git Change Log

    原文:https://www.jianshu.com/p/513ab6915dbd 在基于Jenkins进行CI持续集成的工作,在构建后上传蒲公英时想将本次版本的git commit信息同步到蒲公英的 ...

  5. LeetCode中等题(三)

    题目一: 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明:1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NULL, m ...

  6. HDU 1372 Knight Moves(bfs)

    嗯... 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1372 这是一道很典型的bfs,跟马走日字一个道理,然后用dir数组确定骑士可以走的几个方向, ...

  7. HD Tune检查硬盘各参数的含义

    01 =Read Error Rate / (底层)数据读取错误率指从磁盘表面读取数据时发生的硬件读取错误的比率,Raw值对于不同的厂商有着不同的体系,单纯看做1个十进制数字是没有任何意义的.以上为W ...

  8. 扒网站工具 HTTrack Website Copier

    下载地址:http://www.pc6.com/softview/SoftView_30936.html 作者:匿名用户 链接:https://www.zhihu.com/question/34188 ...

  9. java课后问题解答

    1.当有多个嵌套的try…catch…finally时,要特别注意finally的执行时机 答:当有多层嵌套的finally时,异常在不同的层次抛出 ,在不同的位 置抛出,可能会导致不同的finall ...

  10. el-dialog 如何自定义大小样式

    使用属性:custom-class 然后在css中根据这个类型编写指定的样式即可(比如宽高) 举例: