Skip to content
This repository has been archived by the owner on Oct 16, 2023. It is now read-only.

Commit

Permalink
Graph layout is now saved when navigate away from page (#812)
Browse files Browse the repository at this point in the history
* Graph layout is now saved when navigate away from page

* Fixed issue with old graph results still showing after clear

* Updating removed elements to use concat

* Updating to use forEach

Updating removePreviouslyRemovedElements to use forEach

* Updated syntax error

* Altered foreach syntax due to jasmine errors

* gh-496: Fix bug with concat

Co-authored-by: t11947 <[email protected]>
Co-authored-by: t92549 <[email protected]>
  • Loading branch information
3 people committed Jul 14, 2022
1 parent af2d22a commit 2887a23
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 7 deletions.
44 changes: 40 additions & 4 deletions ui/src/main/webapp/app/graph/graph-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ function GraphController($q, graph, config, error, loading, query, operationOpti
events.unsubscribe('resultsCleared', vm.reset);

if (cytoscapeGraph) {
saveGraph();
cytoscapeGraph.destroy();
}
}
Expand All @@ -151,15 +152,35 @@ function GraphController($q, graph, config, error, loading, query, operationOpti
createCytoscapeGraph().then(function(cy) {
cytoscapeGraph = cy;
generateStylesheets();
vm.reset()

if(graph.hasGraphJson()) {
restoreGraph();
cytoscapeGraph.elements().lock();
vm.update(results.get());
cytoscapeGraph.elements().unlock();
} else {
vm.reset();
}
vm.graphLoading = false;
var searchTerm = graph.getSearchTerm();

if (searchTerm !== null && searchTerm !== undefined && searchTerm !== "") {
vm.filter(searchTerm)
}
});
}

var saveGraph = function() {
if(cytoscapeGraph) {
graph.setGraphJson(cytoscapeGraph.json());
}
}

var restoreGraph = function() {
if(graph.hasGraphJson() && cytoscapeGraph && (results.get().edges || results.get().entities)) {
cytoscapeGraph.json(graph.getGraphJson());
cytoscapeGraph.nodes().removeClass("filtered"); // seems to be a bug in cytoscape json
}
}

/**
* Loads cytoscape graph onto an element containing the "graphCy" id. It also registers the
Expand Down Expand Up @@ -416,6 +437,7 @@ function GraphController($q, graph, config, error, loading, query, operationOpti
cytoscapeGraph.getElementById(id).data(elementsToMergeData[id]);
}

removePreviouslyRemovedElements();
vm.redraw();
});

Expand Down Expand Up @@ -598,6 +620,8 @@ function GraphController($q, graph, config, error, loading, query, operationOpti
*/
vm.reset = function() {
vm.clear();
graph.setRemovedElements([]);
saveGraph();
vm.update(results.get());
}

Expand All @@ -610,7 +634,7 @@ function GraphController($q, graph, config, error, loading, query, operationOpti
searchTerm = searchTerm.toLowerCase();
cytoscapeGraph.batch(function() {
var nodes = cytoscapeGraph.nodes();
for(var i in nodes) {
for(var i = 0; i < nodes.length; i++) {
if(nodes[i].data && nodes[i].data('id')) {
if(nodes[i].data('id').toLowerCase().indexOf(searchTerm) === -1) {
nodes[i].addClass("filtered");
Expand All @@ -630,9 +654,21 @@ function GraphController($q, graph, config, error, loading, query, operationOpti
* Removes every selected element in the graph.
*/
vm.removeSelected = function() {
cytoscapeGraph.filter(":selected").remove();
var removedElements = cytoscapeGraph.filter(":selected").remove().toArray();
graph.setRemovedElements(graph.getRemovedElements().concat(removedElements));

cytoscapeGraph.elements().unselect();
vm.selectedElements.entities = [];
vm.selectedElements.edges = [];
}

var removePreviouslyRemovedElements = function() {
var elements = cytoscapeGraph.elements();
graph.getRemovedElements().forEach(function(removedElement) {
var element = elements.getElementById(removedElement.id());
if(element && element.id()) {
element.remove();
}
});
}
}
40 changes: 40 additions & 0 deletions ui/src/main/webapp/app/graph/graph-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ angular.module('app').factory('graph', function() {

var graphConfiguration = null;

var removedElements = [];
var graphJson = {};

var selectedElements = {
entities: [],
edges: []
Expand Down Expand Up @@ -76,6 +79,43 @@ angular.module('app').factory('graph', function() {
searchTerm = angular.copy(search);
}

/**
* Gets the removed elements.
*/
service.getRemovedElements = function() {
return removedElements;
}

/**
* Sets the removed elements.
* @param removedElements;
*/
service.setRemovedElements = function(newRemovedElements) {
removedElements = newRemovedElements
}

/**
* Checks if the graph json has been set.
*/
service.hasGraphJson = function() {
return graphJson && Object.keys(graphJson).length > 0 && Object.keys(graphJson.elements).length > 0;
}

/**
* Gets the graph json.
*/
service.getGraphJson = function() {
return graphJson;
}

/**
* Sets the graph json.
* @param graphJson;
*/
service.setGraphJson = function(newGraphJson) {
graphJson = newGraphJson;
}

/**
* Resets the value of the selected elements
*/
Expand Down
4 changes: 3 additions & 1 deletion ui/src/main/webapp/app/toolbar/toolbar-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function toolbar() {
};
}

function ToolbarController($rootScope, $mdDialog, operationService, results, query, config, loading, events, properties, error, $mdToast, $cookies) {
function ToolbarController($rootScope, $mdDialog, operationService, results, query, config, loading, events, properties, error, $mdToast, $cookies, graph) {
var vm = this;
vm.addMultipleSeeds = false;
vm.appTitle;
Expand Down Expand Up @@ -165,6 +165,7 @@ function ToolbarController($rootScope, $mdDialog, operationService, results, que

vm.executeAll = function() {
var ops = query.getOperations();
graph.setGraphJson(null);
if (ops.length > 0) {
results.clear(false);
loading.load();
Expand All @@ -175,6 +176,7 @@ function ToolbarController($rootScope, $mdDialog, operationService, results, que
}

vm.clearResults = function() {
graph.setGraphJson(null);
results.clear();
}

Expand Down
46 changes: 44 additions & 2 deletions ui/src/test/webapp/app/graph/graph-component-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,24 @@ describe("The Graph Component", function() {
expect(ctrl.update).toHaveBeenCalled();
})

it('should load the graph from the saved graph json when it exists', function() {
var graphJson = {elements: [1,2]};
spyOn(ctrl, 'update').and.stub();
$httpBackend.whenGET('config/config.json').respond(200, {});
graph.setGraphJson(graphJson);
spyOn(injectableCytoscape, 'json')

ctrl.$onInit();

$httpBackend.flush();
jasmine.clock().tick(101);

scope.$digest();

expect(injectableCytoscape.json).toHaveBeenCalledWith(graphJson);
expect(ctrl.update).toHaveBeenCalled();
})

it('should run the filter once loaded if the service holds a filter', function() {
spyOn(ctrl, 'filter').and.stub();
spyOn(ctrl, 'update').and.stub();
Expand Down Expand Up @@ -447,7 +465,16 @@ describe("The Graph Component", function() {

expect(events.unsubscribe).toHaveBeenCalledWith("incomingResults", jasmine.any(Function));
});


it('should save the graph json', function() {
var graphJson = {elements: [1,2]};
spyOn(injectableCytoscape, 'json').and.returnValue(graphJson);

ctrl.$onDestroy();
expect(injectableCytoscape.json).toHaveBeenCalled();
expect(graph.getGraphJson()).toEqual(graphJson);
});

it('should destroy the cytoscape graph cleanly', function() {
spyOn(injectableCytoscape, 'destroy');

Expand Down Expand Up @@ -649,7 +676,15 @@ describe("The Graph Component", function() {

expect(injectableCytoscape.nodes().size()).toEqual(1);
});


it('should save the removed elements', function() {
graph.setRemovedElements([]);
ctrl.removeSelected();

expect(injectableCytoscape.nodes().size()).toEqual(1);
expect(graph.getRemovedElements().length).toEqual(2);
});

it('should unselect all the elements', function() {
expect(injectableCytoscape.elements(':selected').size()).toEqual(1);

Expand Down Expand Up @@ -680,6 +715,13 @@ describe("The Graph Component", function() {
expect(injectableCytoscape.elements().size()).toEqual(3);
});

it('should remove previously removed elements from the results', function() {
graph.setRemovedElements([{id: function(){return "\"foo\""}}]);
injectableCytoscape.elements().restore();
ctrl.update(elements);
expect(injectableCytoscape.elements().size()).toEqual(1);
});

it('should not error when vertex type is unknown', function() {
entityVertexType = undefined;

Expand Down
42 changes: 42 additions & 0 deletions ui/src/test/webapp/app/graph/graph-service-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,48 @@ describe('The Graph service', function() {
});
});

describe('graph.getRemovedElements()', function() {
it('should set and get the removed elements', function() {
var removedElements = [1,3,5,7];
service.setRemovedElements(removedElements);

var result = service.getRemovedElements();

expect(result).toEqual(removedElements);
})
});

describe('graph.getGraphJson()', function() {
it('should set and get the graph json', function() {
var graphJson = {elements: [1,2]};
service.setGraphJson(graphJson);

var result = service.getGraphJson();

expect(result).toEqual(graphJson);
})
});

describe('graph.hasGraphJson()', function() {
it('should return true when the graph json is set', function() {
var graphJson = {elements: [1,2]};
service.setGraphJson(graphJson);

var result = service.hasGraphJson();

expect(result).toEqual(true);
})

it('should return false when the graph json is not set', function() {
var graphJson = {elements: []};
service.setGraphJson(graphJson);

var result = service.hasGraphJson();

expect(result).toEqual(false);
})
});

describe('graph.deselectAll()', function() {

beforeEach(function() {
Expand Down

0 comments on commit 2887a23

Please sign in to comment.