То, что вы пытаетесь сделать, не очень эффективно. Вы сами сказали, что не знаете координат своих узлов, поэтому cytoscape этого тоже не знает. Но тем не менее, cose-blikent по-прежнему позиционирует элементы настолько хорошо, насколько это возможно. Положение может измениться, но структура остается прежней. Там действительно нет проблем, которые оправдывают трудности и работу, которую вам придется пройти.
Если вы действительно хотите этого добиться, я полагаю, вы можете сделать это в рамках определенного события, которое произошло:
var nodes = cy.nodes();
var positions = [];
for (node in nodes) {
positions[node] = nodes[node].position(); // save the i'th nodes positions
}
, а затем после того, как вы сверните родителя и разверните его снова, вы можете установить все позиции узлов, которые вы сохранили ранее:
var nodes = cy.nodes();
for (node in nodes) {
nodes[node].position(positions[node]); // set x and y of node
}
cy.nodes().on("expandcollapse.beforecollapse", function(event) { var node = this; ... }) // Triggered before a node is collapsed
cy.nodes().on("expandcollapse.aftercollapse", function(event) { var node = this; ... }) // Triggered after a node is collapsed
cy.nodes().on("expandcollapse.beforeexpand", function(event) { var node = this; ... }) // Triggered before a node is expanded
cy.nodes().on("expandcollapse.afterexpand", function(event) { var node = this; ... }) // Triggered after a node is expanded
var beforeExpand = null;
cy.unbind('expandcollapse.beforeexpand');
cy.nodes().bind('expandcollapse.beforeexpand', function(event) {
if (beforeExpand == null)
beforeExpand = cy.elements().clone(); // save the graph before the first expand
}); // Triggered before a node is expanded
cy.unbind('expandcollapse.aftercollapse');
cy.nodes().bind('expandcollapse.aftercollapse', function(event) {
if(beforeExpand != null) {
cy.elements().remove();
cy.add(beforeExpand); // set the graph to original values
beforeExpand = null;
}
}); // Triggered before a node is expanded
Вот как вы ремонтируете свою демонстрацию:
document.addEventListener('DOMContentLoaded', function() {
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
ready: function() {
var api = this.expandCollapse({
layoutBy: {
name: "cose-bilkent",
animate: "end",
randomize: false,
fit: true // set this to true
},
fisheye: true,
animate: false,
undoable: false
});
api.collapseAll();
},
style: [{
selector: 'node',
style: {
'label': 'data(id)'
}
}],
elements: [{
"group": "nodes",
"data": {
"id": "n_0",
"name": "External Network"
}
}, {
"group": "nodes",
"data": {
"id": "n_4",
"name": "虚拟机网络",
"parent": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "n_3",
"name": "VM Network 2",
"parent": "group2"
}
}, {
"group": "nodes",
"data": {
"id": "v_128",
"name": "bfcui-pc",
"parent": "group0"
}
}, {
"group": "nodes",
"data": {
"id": "v_105",
"name": "bychen-pc",
"parent": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "v_93",
"name": "CE-bj",
"parent": "group2"
}
}, {
"group": "nodes",
"data": {
"id": "v_100",
"name": "changliu-pc",
"parent": "group0"
}
}, {
"group": "nodes",
"data": {
"id": "v_67",
"name": "chaoma-pc",
"parent": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "v_83",
"name": "chenwang",
"parent": "group2"
}
}, {
"group": "nodes",
"data": {
"id": "v_68",
"name": "cwang-pc",
"parent": "group0"
}
}, {
"group": "nodes",
"data": {
"id": "v_15",
"name": "gqpei-bj",
"parent": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "v_1",
"name": "gwxu-pc",
"parent": "group2"
}
}, {
"group": "nodes",
"data": {
"id": "v_118",
"name": "gyzhao-pc",
"parent": "group0"
}
}, {
"group": "nodes",
"data": {
"id": "v_76",
"name": "hlli-pc",
"parent": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "v_18",
"name": "hwzhang-pc",
"parent": "group2"
}
}, {
"group": "nodes",
"data": {
"id": "v_40",
"name": "hxqu-pc"
}
}, {
"group": "nodes",
"data": {
"id": "v_69",
"name": "hxwang-pc",
"parent": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "v_71",
"name": "jbshi-pc",
"parent": "group2"
}
}, {
"group": "nodes",
"data": {
"id": "v_64",
"name": "jdai-pc",
"parent": "group0"
}
}, {
"group": "nodes",
"data": {
"id": "v_16",
"name": "jfxiao-bj",
"parent": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "v_78",
"name": "jhhou-pc",
"parent": "group2"
}
}, {
"group": "nodes",
"data": {
"id": "v_91",
"name": "jjsun-pc",
"parent": "group0"
}
}, {
"group": "nodes",
"data": {
"id": "v_17",
"name": "jppan-bj",
"parent": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "v_45",
"name": "jqwang-pc",
"parent": "group2"
}
}, {
"group": "nodes",
"data": {
"id": "v_50",
"name": "jxli-pc",
"parent": "group0"
}
}, {
"group": "nodes",
"data": {
"id": "v_42",
"name": "jyyou-pc",
"parent": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "v_28",
"name": "jyzhou-pc",
"parent": "group2"
}
}, {
"group": "nodes",
"data": {
"id": "v_46",
"name": "jzhao-pc",
"parent": "group0"
}
}, {
"group": "nodes",
"data": {
"id": "v_19",
"name": "lfeng-pc",
"parent": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "v_65",
"name": "lhzhen-pc",
"parent": "group2"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_1",
"source": "n_0",
"target": "v_1"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_100",
"source": "n_0",
"target": "v_100"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_46",
"source": "n_0",
"target": "v_46"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_64",
"source": "n_0",
"target": "v_64"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_65",
"source": "n_0",
"target": "v_65"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_67",
"source": "n_0",
"target": "v_67"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_69",
"source": "n_0",
"target": "v_69"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_71",
"source": "n_0",
"target": "v_71"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_76",
"source": "n_0",
"target": "v_76"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_78",
"source": "n_0",
"target": "v_78"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_83",
"source": "n_0",
"target": "v_83"
}
}, {
"data": {
"group": "edges",
"id": "n_0v_91",
"source": "n_0",
"target": "v_91"
}
}, {
"data": {
"group": "edges",
"id": "v_1n_0",
"source": "v_1",
"target": "n_0"
}
}, {
"data": {
"group": "edges",
"id": "v_1v_128",
"source": "v_1",
"target": "v_128"
}
}, {
"data": {
"group": "edges",
"id": "v_100n_0",
"source": "v_100",
"target": "n_0"
}
}, {
"data": {
"group": "edges",
"id": "v_118v_16",
"source": "v_118",
"target": "v_16"
}
}, {
"data": {
"group": "edges",
"id": "v_118v_18",
"source": "v_118",
"target": "v_18"
}
}, {
"data": {
"group": "edges",
"id": "v_118v_46",
"source": "v_118",
"target": "v_46"
}
}, {
"data": {
"group": "edges",
"id": "v_118v_67",
"source": "v_118",
"target": "v_67"
}
}, {
"data": {
"group": "edges",
"id": "v_118v_69",
"source": "v_118",
"target": "v_69"
}
}, {
"data": {
"group": "edges",
"id": "v_118v_71",
"source": "v_118",
"target": "v_71"
}
}, {
"data": {
"group": "edges",
"id": "v_118v_78",
"source": "v_118",
"target": "v_78"
}
}, {
"data": {
"group": "edges",
"id": "v_128n_0",
"source": "v_128",
"target": "n_0"
}
}, {
"data": {
"group": "edges",
"id": "v_128v_1",
"source": "v_128",
"target": "v_1"
}
}, {
"data": {
"group": "edges",
"id": "v_128v_105",
"source": "v_128",
"target": "v_105"
}
}, {
"data": {
"group": "edges",
"id": "v_128v_46",
"source": "v_128",
"target": "v_46"
}
}, {
"data": {
"group": "edges",
"id": "v_128v_65",
"source": "v_128",
"target": "v_65"
}
}, {
"data": {
"group": "edges",
"id": "v_15n_0",
"source": "v_15",
"target": "n_0"
}
}, {
"data": {
"group": "edges",
"id": "v_50v_40",
"source": "v_50",
"target": "v_40"
}
}, {
"data": {
"group": "edges",
"id": "v_50v_46",
"source": "v_50",
"target": "v_46"
}
}, {
"data": {
"group": "edges",
"id": "v_50v_64",
"source": "v_50",
"target": "v_64"
}
}, {
"data": {
"group": "edges",
"id": "v_65v_19",
"source": "v_65",
"target": "v_19"
}
}, {
"data": {
"group": "edges",
"id": "v_65v_91",
"source": "v_65",
"target": "v_91"
}
}, {
"data": {
"group": "edges",
"id": "v_67n_0",
"source": "v_67",
"target": "n_0"
}
}, {
"data": {
"group": "edges",
"id": "v_67v_100",
"source": "v_67",
"target": "v_100"
}
}, {
"data": {
"group": "edges",
"id": "v_67v_105",
"source": "v_67",
"target": "v_105"
}
}, {
"data": {
"group": "edges",
"id": "v_67v_42",
"source": "v_67",
"target": "v_42"
}
}, {
"data": {
"group": "edges",
"id": "v_91v_16",
"source": "v_91",
"target": "v_16"
}
}, {
"data": {
"group": "edges",
"id": "v_91v_18",
"source": "v_91",
"target": "v_18"
}
}, {
"data": {
"group": "edges",
"id": "v_91v_28",
"source": "v_91",
"target": "v_28"
}
}, {
"data": {
"group": "edges",
"id": "v_91v_45",
"source": "v_91",
"target": "v_45"
}
}, {
"group": "nodes",
"data": {
"id": "group0"
}
}, {
"group": "nodes",
"data": {
"id": "group1"
}
}, {
"group": "nodes",
"data": {
"id": "group2"
}
}]
});
var api = cy.expandCollapse('get');
var beforeExpand = null;
cy.unbind('expandcollapse.beforeexpand');
cy.nodes().bind('expandcollapse.beforeexpand', function(event) {
if (beforeExpand == null)
beforeExpand = cy.elements().clone(); // save the graph before the first expand
}); // Triggered before a node is expanded
cy.unbind('expandcollapse.aftercollapse');
cy.nodes().bind('expandcollapse.aftercollapse', function(event) {
if(beforeExpand != null) {
cy.elements().remove();
cy.add(beforeExpand); // set the graph to original values
beforeExpand = null;
}
});
});
body {
font-family: helvetica;
font-size: 14px;
}
#cy { /*change your css*/
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 999;
}
h1 {
opacity: 0.5;
font-size: 1em;
}
<script src="https://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="https://unpkg.com/cytoscape@3.1.0/dist/cytoscape.min.js"></script>
<!-- for testing with local version of cytoscape.js -->
<!--<script src="../cytoscape.js/build/cytoscape.js"></script>-->
<script src="https://unpkg.com/cytoscape-cose-bilkent@4.0.0/cytoscape-cose-bilkent.js"></script>
<script src="https://unpkg.com/cytoscape-expand-collapse@3.1.1/cytoscape-expand-collapse.js"></script>
<div id="cy"></div>
Да, при питании с Буфер вывода является точно ответом. Просто включите его перед вызовом метода, который произвел бы (не сама функция, но где Вы называете его, Вы могли перенести его вокруг своего целого сценария или потока сценария, но можно сделать его максимально "трудным", просто перенеся его вокруг вызова метода):
function foo() {
echo "Flush!";
return true;
}
ob_start();
$a = foo();
ob_end_clean();
И никакой вывод сгенерирован.
Разве это не так легко как применение некоторых условий к Вашему коду?
я имею в виду, если переменная = тестирующий затем вывод, еще не делайте?
Для функций, которые имеют результат, что выводы прямо к браузеру как ОЦЕНКА, Вы могли получить результат в ob_start.
Здесь Вы идете:
ob_start();
testFunc();
ob_end_clean();
"Обь" обозначает "выходную буферизацию", смотрят на страницы руководства здесь: http://www.php.net/outcontrol
Да Вы на правильном пути относительно усиления выходных функций буферизации PHP, т.е. ob_start, и ob_end_clean (ищите их на php.net):
<?php
function testFunc() {
echo 'Testing';
return true;
}
ob_start();
$output = testFunc();
ob_end_clean();
echo $output;
?>