Commit 59d0bcdb authored by David Bühler's avatar David Bühler

Merge branch 'feature/dive/zooms' into 'master'

Feature/dive/zooms

See merge request frama-c/frama-c!2890
parents d69cd422 b8fce48e
......@@ -62,6 +62,7 @@
"cytoscape-cxtmenu": "^3.1.2",
"cytoscape-dagre": "^2.2.2",
"cytoscape-klay": "^3.1.3",
"cytoscape-panzoom": "^2.5.3",
"cytoscape-popper": "^1.0.7",
"immutable": "^4.0.0-rc.12",
"lodash": "^4.17.15",
......
......@@ -10,6 +10,7 @@ import * as API from 'api/plugins/dive';
import Cytoscape from 'cytoscape';
import CytoscapeComponent from 'react-cytoscapejs';
import './cytoscape_libs';
import 'cytoscape-panzoom/cytoscape.js-panzoom.css';
import tippy, * as Tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';
......@@ -34,6 +35,7 @@ interface Cxtcommand {
interface CytoscapeExtended extends Cytoscape.Core {
cxtmenu(options: any): void;
panzoom(options: any): void;
}
function callstackToString(callstack: API.callstack): string {
......@@ -52,6 +54,19 @@ function buildCxtMenu(
});
}
/* double click events for Cytoscape */
function enableDoubleClickEvents(cy: Cytoscape.Core, delay = 350) {
let last: Cytoscape.EventObject | undefined;
cy.on('click', (e) => {
if (last && last.target === e.target &&
e.timeStamp - last.timeStamp < delay) {
e.target.trigger('double-click', e);
}
last = e;
});
}
/* The Dive class handles the selection of nodes according to user actions.
To prevent cytoscape to automatically select (and unselect) nodes wrongly,
we make some nodes unselectable. We then use the functions below to make
......@@ -83,8 +98,17 @@ class Dive {
this.cy = cy || Cytoscape();
this.headless = this.cy.container() === null;
this.cy.elements().remove();
this.cy.off('click'); // Remove previous listeners
// Remove previous listeners
this.cy.off('click');
this.cy.off('double-click');
// Add new listeners
enableDoubleClickEvents(this.cy);
this.cy.on('click', 'node', (event) => this.clickNode(event.target));
this.cy.on('double-click', '$node > node', // compound nodes
(event) => this.doubleClickNode(event.target));
(this.cy as CytoscapeExtended).panzoom({});
this.layout = 'cose-bilkent';
......@@ -273,9 +297,8 @@ class Dive {
for (const dep of data.deps) {
const src = this.cy.$id(dep.src);
const dst = this.cy.$id(dep.dst);
const isRoot = dst?.data('is_root');
this.cy.add({
data: { ...dep, source: dep.src, target: dep.dst, is_root: isRoot },
data: { ...dep, source: dep.src, target: dep.dst },
group: 'edges',
classes: src?.hasClass('new') || dst?.hasClass('new') ? 'new' : '',
});
......@@ -436,6 +459,10 @@ class Dive {
node.unselectify();
}
doubleClickNode(node: Cytoscape.NodeSingular) {
this.cy.animate({ fit: { eles: node, padding: 10 } });
}
selectLocation(location: States.Location | undefined, doExplore: boolean) {
if (!location) {
// Reset whole graph if no location is selected.
......@@ -458,14 +485,13 @@ class Dive {
_.some(ele.data().origins, this.selectedLocation)
);
this.cy.$(':selected').forEach(unselect);
this.cy.$('.multiple-selection').removeClass('multiple-selection');
this.cy.$('.selection').removeClass('selection');
select(node);
const edges = node.incomers('edge');
edges.unselect();
const relevantEdges = edges.filter(hasOrigin);
if (relevantEdges.empty())
edges.select();
else
relevantEdges.select();
edges.addClass('multiple-selection');
relevantEdges.addClass('selection');
}
}
......
......@@ -2,18 +2,23 @@
This prevents Hot Module Reloading for modules where Cytescope.use is used.
Grouping all Cytoscape plugins registrations here solves the problem. */
import Cytoscape from 'cytoscape' ;
import Cytoscape from 'cytoscape';
import CytoscapeMenu from 'cytoscape-cxtmenu';
import CytoscapePopper from 'cytoscape-popper';
import CytoscapeLayoutDagre from 'cytoscape-dagre';
import CytoscapeLayoutCola from 'cytoscape-cola';
import CytoscapeLayoutCoseBilkent from 'cytoscape-cose-bilkent';
import CytoscapeLayoutKlay from 'cytoscape-klay';
import CxtMenu from 'cytoscape-cxtmenu';
import Popper from 'cytoscape-popper';
import Panzoom from 'cytoscape-panzoom';
Cytoscape.use(CytoscapePopper);
Cytoscape.use(CytoscapeMenu);
Cytoscape.use(CytoscapeLayoutDagre);
Cytoscape.use(CytoscapeLayoutCola);
Cytoscape.use(CytoscapeLayoutCoseBilkent);
Cytoscape.use(CytoscapeLayoutKlay);
// Layouts
import Dagre from 'cytoscape-dagre';
import Cola from 'cytoscape-cola';
import CoseBilkent from 'cytoscape-cose-bilkent';
import Klay from 'cytoscape-klay';
Cytoscape.use(Popper);
Cytoscape.use(CxtMenu);
Panzoom(Cytoscape); // register extension
Cytoscape.use(Dagre);
Cytoscape.use(Cola);
Cytoscape.use(CoseBilkent);
Cytoscape.use(Klay);
......@@ -15,14 +15,6 @@
"text-wrap" : "wrap"
}
},
{
"selector": "node:selected",
"style": {
"overlay-color": "#8bf",
"overlay-padding": "10px",
"overlay-opacity": 0.4
}
},
{
"selector": "node[label]",
"style": {
......@@ -58,18 +50,19 @@
}
},
{
"selector": "edge:selected",
"selector": "edge.multiple-selection",
"style": {
"color": "#48f",
"overlay-color": "#8bf",
"overlay-color": "#aaa",
"overlay-padding": "10px",
"overlay-opacity": 0.4
}
},
{
"selector": "edge[?is_root]",
"selector": "edge.selection, :selected",
"style": {
"width": 4
"overlay-color": "#8bf",
"overlay-padding": "10px",
"overlay-opacity": 0.4
}
},
{
......
......@@ -3008,6 +3008,13 @@ cytoscape-klay@^3.1.3:
dependencies:
klayjs "^0.4.1"
cytoscape-panzoom@^2.5.3:
version "2.5.3"
resolved "https://registry.yarnpkg.com/cytoscape-panzoom/-/cytoscape-panzoom-2.5.3.tgz#edf041b5aa8be1cbe3c001f16a8b2193b46127a7"
integrity sha512-//qLOqbbFUCGddarNKHDZArItOJHgnkQ1TvxI9nV2/8aOOl/5wuEOHmra3fL/aWSjB4AYpYTG4LX7w96uWfRTQ==
dependencies:
jquery "^1.4 || ^2.0 || ^3.0"
cytoscape-popper@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/cytoscape-popper/-/cytoscape-popper-1.0.7.tgz#8154ff507d0cc1a17952f00643e71fc1f8ea9fae"
......@@ -5396,6 +5403,11 @@ jest-worker@^25.1.0:
merge-stream "^2.0.0"
supports-color "^7.0.0"
"jquery@^1.4 || ^2.0 || ^3.0":
version "3.5.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5"
integrity sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==
js-base64@^2.1.9:
version "2.5.2"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209"
......
......@@ -2,13 +2,13 @@
STDOPT: +"-dive-from-variables many_values::__retres,many_writes::x"
*/
int t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14;
int *pt[14] = {
&t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9, &t10, &t11, &t12, &t13, &t14
};
int many_values(int x)
{
int t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0;
int *pt[14] = {
&t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9, &t10, &t11, &t12, &t13, &t14
};
if (x >= 0 && x < 14)
return *pt[x];
else
......@@ -17,6 +17,8 @@ int many_values(int x)
int many_writes()
{
int t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0;
int x = 0;
x += t1;
x += t2;
......
......@@ -25,12 +25,10 @@ digraph G {
cp25 [label=<*(pt[x])>, shape=parallelogram, fillcolor="#AACCFF",
color="#88AAFF", style="filled,dotted", ];
subgraph cluster_cs_1 { label=<many_writes>; cp2;
subgraph cluster_cs_1 { label=<many_writes>; cp22;cp20;cp18;cp16;cp14;cp12;cp10;cp8;cp6;cp4;cp2;
};
subgraph cluster_cs_2 { label=<many_values>; cp25;cp24;
};
subgraph cluster_file_1 { label=<tests/dive/manydeps.i>; cp22;cp20;cp18;cp16;cp14;cp12;cp10;cp8;cp6;cp4;
};
cp2 -> cp2 [style="bold", ];
cp4 -> cp2;
......
......@@ -6,7 +6,7 @@
[eva:summary] ====== ANALYSIS SUMMARY ======
----------------------------------------------------------------------------
3 functions analyzed (out of 3): 100% coverage.
In these functions, 32 statements reached (out of 32): 100% coverage.
In these functions, 61 statements reached (out of 61): 100% coverage.
----------------------------------------------------------------------------
No errors or warnings raised during the analysis.
----------------------------------------------------------------------------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment