Поведение узла группы Expand странно, когда запрашивать дочерние данные с помощью ajax с помощью cytoscape.js-expand-collapse - PullRequest
0 голосов
/ 15 февраля 2019

Я учусь cytoscape.js и связанного с ним расширения cytoscape.js-expand-collapse и меня привлекают его удивительные возможности.

Я попытался сделать демонстрацию, котораякогда откроете узел, запросите дочерние узлы с помощью ajax с сервера и разверните группу.

Я считаю, что расширение cytoscape.js-expand-collapse имеет утилиту cue.Когда у узла есть дочерние узлы, он будет показывать значок cue.

В моей демонстрации я не знаю дочерние узлы, прежде чем развернуть его.Поэтому я добавляю фиктивный узел в исходное состояние.

При развертывании узла мне нужно удалить фиктивный узел, запросить реальные дочерние узлы, добавить в группу и ретранслировать график.

Как выполнить ретрансляцию?Я нахожу два пути.Один из способов - вызвать expand API расширения, другой - вызвать cy.layout().Ни один из методов не является удовлетворительным.

Если я разверну узел с помощью expand метода cytoscape.js-expand-collapse, весь график всегда будет смещаться на сцену или даже вылетать за пределы экрана.

param.options.layoutBy = {
        name: 'cose-bilkent',
        fit: false,
        randomize: false,
        idealEdgeLength : 150
    };
api.expand(param.nodes, param.options);

Если развернуть узел с помощью cy.layout({name:'cose-bilkent'}), компоновка выглядит хорошо, но значок метки неправильный.(При развертывании узла должен отображаться значок минус, а не значок плюс)

var layout = cy.layout({
    name: 'cose-bilkent',
    fit: false,
    randomize: false,
    idealEdgeLength : 150
});
layout.run();

Мне нужно объединить преимущества!При развертывании узла макет выглядит хорошо, а значок метки правильный.

Смотрите мою демонстрацию.Обновите демо-версию, чтобы исправить некоторые проблемы, теперь моя демоверсия может хорошо работать.

document.addEventListener('DOMContentLoaded', function(){
				initGraph();
			});
			
			function initGraph(){
				var cy = window.cy = cytoscape({
					container: document.getElementById('cy'),

					ready: function(){
						var api = window.api = this.expandCollapse({
							layoutBy: {
								name: "cose-bilkent",
								animate: "end",
								randomize: false,
								fit: false
							},
							fisheye: false,
							animate: false,
							undoable: true
						});
						api.collapseAll();
					},

					style: [
						{
							selector: 'node',
							style: {
								'background-color': '#ad1a66',
								'label':'data(name)',
							}
						},

						{
							selector: ':parent',
							style: {
								'background-opacity': 0.333
							}
						},

						{
							selector: "node.cy-expand-collapse-collapsed-node",
							style: {
								"background-color": "darkblue",
								"shape": "rectangle"
							}
						},

						{
							selector: 'edge',
							style: {
								'width': 3,
								'line-color': '#ad1a66'
							}
						}
					],

					elements: initData()
				});
				
				initListeners();
        
        cy.on('layoutstop', centerGraph);
		function centerGraph(){
			cy.center();
			cy.off('layoutstop', centerGraph);
		}
			}
			
			
			function initData(){
				var me = this, i;
				
				var groupNum = 5, groups = [], dummy = [], edges = [];
				for(i = 0; i < groupNum; i++){
					groups.push({
						group:'nodes', 
						data:{
							id:'group'+i, 
							name:'group'+i
						}
					});
					dummy.push({// Insert dummy node in order to show cue icon.
						group:'nodes', 
						data:{
							id:'dummy'+i,
          name:'dummy'+i,
							parent : 'group'+i
						}
					});
				}
				var s,t;
				for(i = 0; i < groupNum - 1; i++){
					s = dummy[i].data.id;
					for(j = i+1; j < groupNum; j++){
						t = dummy[j].data.id;
						edges.push({"group":'edges',data:{"id":s+"_"+t, source:s, target:t}});
					}
				}
				return groups.concat(edges).concat(dummy);
			}
			
			function initListeners(){
				var ur = cy.undoRedo();
		ur.action("expand", function(param){
			var collapsedChildren = param.nodes._private.data.collapsedChildren;
			if(collapsedChildren 
					&& collapsedChildren.length == 1
					&& collapsedChildren[0]._private.data.id.indexOf('dummy') >= 0){
				openTargetNode(param.nodes);
				param.options.layoutBy = {
			  			name: 'cose-bilkent',
						fit: false,
						randomize: false,
						idealEdgeLength : 150
			  		};
				if(document.getElementById('switch').checked){
					var layout = cy.layout({
		  			name: 'cose-bilkent',
					fit: false,
					randomize: false,
					idealEdgeLength : 150
		  		});
				layout.run();
				return;
				}
				
			}else{
				param.options.layoutBy = null;
			}
			param.options.layoutBy = {
		  			name: 'cose-bilkent',
					fit: false,
					randomize: false,
					idealEdgeLength : 150
		  		};
			api.expand(param.nodes, param.options);
		});
		ur.action("collapse", function(param){
			param.options.layoutBy = {
		  			name: 'cose-bilkent',
					fit: false,
					randomize: false,
					idealEdgeLength : 150
		  		};
			api.collapse(param.nodes, param.options);
		});
			}
			
			
			function openTargetNode(target){
		var me = this;
  		var targetPosition = target.position();
  		var childNum = 5, innerLinks = 10, i, j, counter = 0;
  		
  		for(i = 0; i < childNum; i++){
  			cy.add({
  				group: 'nodes', 
  				data: { id: target.id() + i, name: target.id() + i, parent: target.id() }, 
  				position:{x:targetPosition.x, y: targetPosition.y}
  			});
  		}
  		for(i = 0; i < childNum - 1; i++){
  			s = target.id() + i;
  			for(j = i + 1; j < childNum && counter++ < innerLinks; j++){
	  			t = target.id() + j;
	  			cy.add({ 
	  				group: 'edges', 
	  				data: { id: s+"-"+t, source: s, target: t }
	  			});
	  		}
  		}
  		
  		var neighborhood = target.neighborhood(), nodes = [];
  		for(i = 0; i <neighborhood.length; i++){
  			if(target.neighborhood()[i].isNode()){
  				nodes.push(target.neighborhood()[i]._private.data.id);
  			}
  		}
  		
  		var s, t, j = 0;
  		for(i = 0; i < nodes.length; i++){
  			s = target.id() + (j++)%childNum;
  			t = nodes[i];
  			cy.add({
  				group: 'edges', 
  				data: { id: s+"-"+t, source: s, target: t }
  			});
  		}
  		
  		cy.remove(cy.$('#' + target._private.data.collapsedChildren[0]._private.data.id));
  		cy.remove(target.connectedEdges());
	}
	
	function switchHandler(a, b){
		initGraph();
	}
body {
				font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
				font-size: 14px;
			}

			#cy {
				z-index: 999;
				width: 85%;
				height: 85%;
				float: left;
			}

			h1 {
				opacity: 0.5;
				font-size: 1em;
				font-weight: bold;
			}
<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>

<script src="https://unpkg.com/cytoscape-cose-bilkent@4.0.0/cytoscape-cose-bilkent.js"></script>

<script src="https://cdn.jsdelivr.net/npm/cytoscape.js-undo-redo@1.0.1/cytoscape-undo-redo.js"></script>

<script src="https://unpkg.com/cytoscape-expand-collapse@3.1.1/cytoscape-expand-collapse.js"></script>

<div>
		<input id="switch" type="checkbox" onclick=switchHandler(this)>Layout without cytoscape-expand-collapse</input>
</div>
<div id="cy"></div>
...