### Setup D3 Graphviz Visualization (JavaScript) Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.identity(A__this,_untyped_i)_-1778620129.html Initializes the D3.js Graphviz instance, configures attributes for scaling and centering the SVG, and defines the `renderGraph` function to load and display a DOT graph string. Includes zoom setup and a transformation utility function. ```javascript d3.select('#descriptions').style('height', d3.select('#graph').node().offsetHeight + "px"); /* Graph visualization setup */ const scale = 0.8; function attributer(datum, index, nodes) { // taken from https://stackoverflow.com/questions/67626414/scale-and-center-d3-graphviz-graph var selection = d3.select(this); if (datum.tag == "svg") { datum.attributes = { ...datum.attributes, width: '100%', height: d3.select('#graph').node().offsetHeight + 'px', }; const px2pt = 3 / 4; const graphWidth = datum.attributes.viewBox.split(' ')[2] / px2pt; const graphHeight = datum.attributes.viewBox.split(' ')[3] / px2pt; const w = graphWidth / scale; const h = graphHeight / scale; const x = -(w - graphWidth) / 2; const y = -(h - graphHeight) / 2; const viewBox = `${x * px2pt} ${y * px2pt} ${w * px2pt} ${h * px2pt}`; selection.attr('viewBox', viewBox); datum.attributes.viewBox = viewBox; } } const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); /*,\"shape\"=\"rect\",\"id\"=\"node0\",\"color\"=\"black\",\"style\"=\"dashed\"]\n\"node3\" [\"label\"=,\"shape\"=\"rect\",\"id\"=\"node3\",\"color\"=\"black\"]\n\"node0\" -> \"node3\" [\"color\"=\"black\"]\n}"; /*]]>*/ /* Zooming setup */ var zoom = d3.zoom().on("zoom", zoomed); function zoomed(e) { g.attr("transform", e.transform); } // initial transformation of the graph var svg = null; var g = null; var itTX = 0; var itTY = 0; function getTransformation(transform) { // taken from: https://stackoverflow.com/questions/38224875/how-can-d3-transform-be-used-in-d3-v4 var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); g.setAttributeNS(null, "transform", transform); var matrix = g.transform.baseVal.consolidate().matrix; var a=matrix.a, b=matrix.b, c=matrix.c, d=matrix.d, e=matrix.e, f=matrix.f; var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * 180 / Math.PI, skewX: Math.atan(skewX) * 180 / Math.PI, scaleX: scaleX, scaleY: scaleY }; } function renderGraph(dotString) { graphviz.renderDot(dotString, function () { d3.selectAll('.node').on('click', function () { selectNode(this); }); svg = d3.select('#graph').select('svg'); svg.call(zoom); g = svg.select('g'); var it = getTransformation(g.attr("transform")); itTX = it.translateX; itTY = it.translateY; }); } renderGraph(graph); ``` -------------------------------- ### Setup Split Pane Functionality JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_tests.helper(tests__this,_untyped_i,_untyped_dispatcher)_-1778625864.html Initializes variables and sets up mouse event listeners on the separator element to enable dragging and resizing of the graph and descriptions panels. ```JavaScript const separator = document.getElementById("separator"); const first = document.getElementById("graph"); const second = document.getElementById("descriptions"); var md; separator.onmousedown = onMouseDown; function onMouseDown(e) { md = {e, offsetLeft: separator.offsetLeft, offsetTop: separator.offsetTop, firstWidth: first.offsetWidth, secondWidth: second.offsetWidth }; document.onmousemove = onMouseMove; document.onmouseup = () => { document.onmousemove = document.onmouseup = null; } } function onMouseMove(e) { var delta = {x: e.clientX - md.e.clientX, y: e.clientY - md.e.clientY}; delta.x = Math.min(Math.max(delta.x, -md.firstWidth), md.secondWidth); separator.style.left = md.offsetLeft + delta.x + "px"; first.style.width = (md.firstWidth + delta.x) + "px"; second.style.width = (md.secondWidth - delta.x) + "px"; } ``` -------------------------------- ### Initial Graph Rendering - JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.A(A__this)_-1778639473.html Calls the `renderGraph` function with the predefined DOT graph string (`graph`) to display the initial visualization when the page loads. This starts the process of rendering the graph and setting up interactions. ```JavaScript renderGraph(graph); ``` -------------------------------- ### Setup D3 Zoom Behavior Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.A(A__this)_-1778639473.html Creates a D3 zoom behavior instance and attaches the 'zoomed' function as the event handler for zoom events. ```JavaScript var zoom = d3.zoom().on("zoom", zoomed); ``` -------------------------------- ### Render Graph and Setup Interactions (JS) Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.getOne(A__this)_-1778621183.html Defines the `renderGraph` function which uses graphviz to render the DOT string, then attaches click handlers to nodes for selection and applies the D3 zoom behavior to the SVG. ```JavaScript function renderGraph(dotString) { graphviz.renderDot(dotString, function () { d3.selectAll('.node').on('click', function () { selectNode(this); }); svg = d3.select('#graph').select('svg'); svg.call(zoom); g = svg.select('g'); var it = getTransformation(g.attr("transform")); itTX = it.translateX; itTY = it.translateY; }); } ``` -------------------------------- ### Render Graph and Setup Interactions Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.identity(A__this,_untyped_i)_-1081452707.html Renders the graph using the provided DOT string via Graphviz. After rendering, it selects the SVG and graph group elements, applies the D3 zoom behavior, stores the initial transformation, and sets up click handlers for graph nodes to enable selection. ```javascript function renderGraph(dotString) { graphviz.renderDot(dotString, function () { d3.selectAll('.node').on('click', function () { selectNode(this); }); svg = d3.select('#graph').select('svg'); svg.call(zoom); g = svg.select('g'); var it = getTransformation(g.attr("transform")); itTX = it.translateX; itTY = it.translateY; }); } renderGraph(graph); ``` -------------------------------- ### Setup D3 Zoom Behavior JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_tests.helper(tests__this,_untyped_i,_untyped_dispatcher)_-1778625864.html Sets up the D3 zoom behavior and defines the 'zoomed' function which applies the zoom transformation to the graph group element. ```JavaScript var zoom = d3.zoom().on("zoom", zoomed); function zoomed(e) { g.attr("transform", e.transform); } ``` -------------------------------- ### Setup Split Pane Resizing JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.identity(A__this,_untyped_i)_-1778624996.html Implements drag-and-drop functionality using mouse events to resize two adjacent panels ('graph' and 'descriptions') by dragging a separator element. ```javascript const separator = document.getElementById("separator"); const first = document.getElementById("graph"); const second = document.getElementById("descriptions"); var md; separator.onmousedown = onMouseDown; function onMouseDown(e) { md = {e, offsetLeft: separator.offsetLeft, offsetTop: separator.offsetTop, firstWidth: first.offsetWidth, secondWidth: second.offsetWidth }; document.onmousemove = onMouseMove; document.onmouseup = () => { document.onmousemove = document.onmouseup = null; } } function onMouseMove(e) { var delta = {x: e.clientX - md.e.clientX, y: e.clientY - md.e.clientY}; delta.x = Math.min(Math.max(delta.x, -md.firstWidth), md.secondWidth); separator.style.left = md.offsetLeft + delta.x + "px"; first.style.width = (md.firstWidth + delta.x) + "px"; second.style.width = (md.secondWidth - delta.x) + "px"; } ``` -------------------------------- ### Setup D3 Zoom Behavior (JS) Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.getOne(A__this)_-1778621183.html Sets up D3 zoom behavior, defining the `zoomed` function to apply the transform to the graph group element (`g`). ```JavaScript var zoom = d3.zoom().on("zoom", zoomed); function zoomed(e) { g.attr("transform", e.transform); } ``` -------------------------------- ### Setup Legend Modal Display JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.identity(A__this,_untyped_i)_-1778624996.html Implements functionality to show and hide a modal element ('legend') when the 'legendButton' is clicked or the modal/close button is clicked, respectively. ```javascript var modal = d3.select("#legend").on('click', function() { d3.select(this).style('display', 'none'); }); var btn = d3.select("#legendButton").on('click', function() { modal.style('display', 'block'); }); var span = d3.select(".close").on('click', function() { modal.style('display', 'none'); }); ``` -------------------------------- ### Split Pane Initialization Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.A(A__this)_-1778639473.html Gets references to the split pane elements (separator, graph, descriptions) and initializes a variable to store mouse down state. ```JavaScript const separator = document.getElementById("separator"); const first = document.getElementById("graph"); const second = document.getElementById("descriptions"); var md; ``` -------------------------------- ### Render Graph and Setup Interactions D3.js JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.identity(A__this,_untyped_i)_-1778624996.html Renders the provided DOT graph string using Graphviz, sets up click handlers for nodes to enable selection, and applies D3 zoom behavior to the rendered SVG. ```javascript function renderGraph(dotString) { graphviz.renderDot(dotString, function () { d3.selectAll('.node').on('click', function () { selectNode(this); }); svg = d3.select('#graph').select('svg'); svg.call(zoom); g = svg.select('g'); var it = getTransformation(g.attr("transform")); itTX = it.translateX; itTY = it.translateY; }); } ``` -------------------------------- ### Setup Search and Centering Logic D3.js JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.identity(A__this,_untyped_i)_-1778624996.html Initializes variables for search results and defines the `centerToSearch` function to pan and zoom the graph view to center on the currently selected search result node. ```javascript // Reset searchbar contents on load d3.select('#search').node().value = ""; var hits = []; var hit = -1; function centerToSearch() { hits.filter(function (d, i) { return i === hit; }).each(function (d, i) { selectNode(this); var gbbox = g.node().getBBox(); var gX = gbbox.x + (gbbox.width/2); var gY = gbbox.y + (gbbox.height/2); var bbox = this.getBBox(); var tX = bbox.x + (bbox.width/2); var tY = bbox.y + (bbox.height/2); var offsetX = gX - tX; var offsetY = gY - tY; var curr = getTransformation(g.attr("transform")); var transform = d3.zoomIdentity // reset to initial position .translate(itTX, itTY) // keep current scale .scale(curr.scaleX) // move to node center .translate(offsetX, offsetY); svg.transition("zooming") .duration(150) .ease(d3.easeLinear) .call(zoom.transform, transform); }); } ``` -------------------------------- ### Accordion Setup Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.A(A__this)_-1778639473.html Iterates through elements with the class 'accordion', adding a click event listener to each. The listener toggles an 'active' class and shows/hides the next sibling element (the panel). ```JavaScript var acc = document.getElementsByClassName("accordion"); var i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function() { this.classList.toggle("active"); var panel = this.nextElementSibling; if (panel.style.display === "block") { panel.style.display = "none"; } else { panel.style.display = "block"; } }); } ``` -------------------------------- ### Render Graph and Setup Interactions Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.getOne(A__this)_-1778621183.html Renders the DOT graph string using graphviz. After rendering, it attaches click event listeners to graph nodes for selection and applies the D3 zoom behavior to the SVG element. ```javascript function renderGraph(dotString) { graphviz.renderDot(dotString, function () { d3.selectAll('.node').on('click', function () { selectNode(this); }); svg = d3.select('#graph').select('svg'); svg.call(zoom); g = svg.select('g'); var it = getTransformation(g.attr("transform")); itTX = it.translateX; itTY = it.translateY; }); } ``` -------------------------------- ### Helper to Get SVG Transformation Matrix Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_tests.main(tests__this).html Provides a utility function to parse an SVG transform string and extract its components (translate, rotate, skew, scale) into a structured object. ```JavaScript // initial transformation of the graph var svg = null; var g = null; var itTX = 0; var itTY = 0; function getTransformation(transform) { // taken from: https://stackoverflow.com/questions/38224875/how-can-d3-transform-be-used-in-d3-v4 var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); g.setAttributeNS(null, "transform", transform); var matrix = g.transform.baseVal.consolidate().matrix; var a=matrix.a, b=matrix.b, c=matrix.c, d=matrix.d, e=matrix.e, f=matrix.f; var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * 180 / Math.PI, skewX: Math.atan(skewX) * 180 / Math.PI, scaleX: scaleX, scaleY: scaleY }; } ``` -------------------------------- ### Setup D3 Zoom Behavior - D3.js Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.getPositive(A__this,_untyped_i)_-1778620222.html Initializes D3's zoom behavior and defines the `zoomed` function. The `zoomed` function is called on zoom events and applies the current transform to the graph group element (`g`). ```javascript var zoom = d3.zoom().on("zoom", zoomed); function zoomed(e) { g.attr("transform", e.transform); } ``` -------------------------------- ### Initializing D3-Graphviz and SVG Attributer (JavaScript) Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-sdk/src/main/resources/html-graph/viewer.html Sets up the D3-Graphviz instance targeting the '#graph' element. Includes a custom 'attributer' function to dynamically adjust the SVG viewBox and dimensions for scaling and centering. ```JavaScript d3.select('#descriptions').style('height', d3.select('#graph').node().offsetHeight + "px"); /* Graph visualization setup */ const scale = 0.8; function attributer(datum, index, nodes) { // taken from https://stackoverflow.com/questions/67626414/scale-and-center-d3-graphviz-graph var selection = d3.select(this); if (datum.tag == "svg") { datum.attributes = { ...datum.attributes, width: '100%', height: d3.select('#graph').node().offsetHeight + 'px', }; const px2pt = 3 / 4; const graphWidth = datum.attributes.viewBox.split(' ')[2] / px2pt; const graphHeight = datum.attributes.viewBox.split(' ')[3] / px2pt; const w = graphWidth / scale; const h = graphHeight / scale; const x = -(w - graphWidth) / 2; const y = -(h - graphHeight) / 2; const viewBox = `${x * px2pt} ${y * px2pt} ${w * px2pt} ${h * px2pt}`; selection.attr('viewBox', viewBox); datum.attributes.viewBox = viewBox; } } const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); ``` -------------------------------- ### Get Transformation Matrix Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.A(A__this)_-1778639473.html A utility function to parse an SVG transform attribute string and extract translation, rotation, skew, and scale components. ```JavaScript function getTransformation(transform) { // taken from: https://stackoverflow.com/questions/38224875/how-can-d3-transform-be-used-in-d3-v4 var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); g.setAttributeNS(null, "transform", transform); var matrix = g.transform.baseVal.consolidate().matrix; var a=matrix.a, b=matrix.b, c=matrix.c, d=matrix.d, e=matrix.e, f=matrix.f; var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * 180 / Math.PI, skewX: Math.atan(skewX) * 180 / Math.PI, scaleX: scaleX, scaleY: scaleY }; } ``` -------------------------------- ### Implement Graph Search and Navigation Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_tests.main(tests__this).html Sets up search functionality allowing users to find nodes by text content. It highlights matching nodes, enables navigation between hits, and centers the view on the currently selected search result. ```JavaScript /* Search */ // Reset searchbar contents on load d3.select('#search').node().value = ""; var hits = []; var hit = -1; function centerToSearch() { hits.filter(function (d, i) { return i === hit; }).each(function (d, i) { selectNode(this); var gbbox = g.node().getBBox(); var gX = gbbox.x + (gbbox.width/2); var gY = gbbox.y + (gbbox.height/2); var bbox = this.getBBox(); var tX = bbox.x + (bbox.width/2); var tY = bbox.y + (bbox.height/2); var offsetX = gX - tX; var offsetY = gY - tY; var curr = getTransformation(g.attr("transform")); var transform = d3.zoomIdentity // reset to initial position .translate(itTX, itTY) // keep current scale .scale(curr.scaleX) // move to node center .translate(offsetX, offsetY); svg.transition("zooming") .duration(150) .ease(d3.easeLinear) .call(zoom.transform, transform); }); } d3.select('#search').on('input', function (e) { var query = e.target.value; if (query !== "") hits = d3.selectAll('.node').filter(function (d, i) { return d3.select(this).select('text').text().includes(query); }); if (query === "" || hits.size() == 0) { hit = -1; d3.select('#next').attr('disabled', true); d3.select('#prev').attr('disabled', true); d3.select('.node-selected').classed('node-selected', false); d3.select(this).classed('no-results', true); } else { hit = 0; d3.select('#next').attr('disabled', null); d3.select('#prev').attr('disabled', null); d3.select(this).classed('no-results', false); centerToSearch(); } }); d3.select('#next').on('click', function (e) { if (hit != -1) { hit = (hit + 1) % hits.size(); centerToSearch(); } }); d3.select('#prev').on('click', function (e) { if (hit != -1) { hit = ((hit - 1) + hits.size()) % hits.size(); centerToSearch(); } }); ``` -------------------------------- ### Getting SVG Transformation - D3.js - JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.identity(A__this,_untyped_i)_-1778620129.html Utility function to parse an SVG transform string and extract its translation, rotation, skew, and scale components. ```JavaScript var svg = null; var g = null; var itTX = 0; var itTY = 0; function getTransformation(transform) { // taken from: https://stackoverflow.com/questions/38224875/how-can-d3-transform-be-used-in-d3-v4 var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); g.setAttributeNS(null, "transform", transform); var matrix = g.transform.baseVal.consolidate().matrix; var a=matrix.a, b=matrix.b, c=matrix.c, d=matrix.d, e=matrix.e, f=matrix.f; var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * 180 / Math.PI, skewX: Math.atan(skewX) * 180 / Math.PI, scaleX: scaleX, scaleY: scaleY }; } ``` -------------------------------- ### Initialize D3-Graphviz Instance (JS) Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.getOne(A__this)_-1778621183.html Initializes the d3-graphviz instance targeting the `#graph` element, applying the custom `attributer` function and enabling zooming. ```JavaScript const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); ``` -------------------------------- ### Initialize and Render Graph (JavaScript) Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-sdk/src/main/resources/html-graph/viewer-compound.html Sets up the D3-Graphviz instance with the custom attributer and zoom behavior. Defines the `renderGraph` function which takes a DOT string, renders the graph, and attaches click event listeners to the graph nodes for selection. ```JavaScript const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); /**\/ function renderGraph(dotString) { graphviz.renderDot(dotString, function () { d3.selectAll('.node').on('click', function () { selectNode(this); }); svg = d3.select('#graph').select('svg'); svg.call(zoom); g = svg.select('g'); var it = getTransformation(g.attr("transform")); itTX = it.translateX; itTY = it.translateY; }); } ``` -------------------------------- ### Initialize Graphviz Instance Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.A(A__this)_-1778639473.html Initializes the D3-Graphviz instance, binding it to the '#graph' element, applying the custom attributer function for scaling, and enabling zoom. ```JavaScript const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); ``` -------------------------------- ### Initialize D3-Graphviz Instance JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_tests.helper(tests__this,_untyped_i,_untyped_dispatcher)_-1778625864.html Initializes the D3-Graphviz instance for the element with ID 'graph', applying the custom attributer function for scaling and enabling zooming. ```JavaScript const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); ``` -------------------------------- ### Setup D3 Zoom Behavior JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.identity(A__this,_untyped_i)_-1778624996.html Sets up D3's zoom behavior and defines the `zoomed` function to apply the transform event to the graph group element. ```javascript var zoom = d3.zoom().on("zoom", zoomed); function zoomed(e) { g.attr("transform", e.transform); } ``` -------------------------------- ### Initialize D3-Graphviz - D3.js - JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.A(A__this)_-1778639473.html Initializes the D3-Graphviz instance bound to the '#graph' element. Configures it to use the custom `attributer` function for scaling and centering and enables interactive zooming. ```JavaScript const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); ``` -------------------------------- ### Initializing Split Pane and Mouse Down Event Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_tests.main(tests__this).html Selects DOM elements for the split pane separator and the two resizable panels. Defines the `onMouseDown` function to capture initial state (mouse position, element dimensions) when the separator is clicked, and attaches mouse move/up listeners. ```javascript const separator = document.getElementById("separator"); const first = document.getElementById("graph"); const second = document.getElementById("descriptions"); var md; separator.onmousedown = onMouseDown; function onMouseDown(e) { md = {e, offsetLeft: separator.offsetLeft, offsetTop: separator.offsetTop, firstWidth: first.offsetWidth, secondWidth: second.offsetWidth }; document.onmousemove = onMouseMove; document.onmouseup = () => { document.onmousemove = document.onmouseup = null; } } ``` -------------------------------- ### Get Transformation Matrix Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.getOne(A__this)_-1778621183.html A helper function to extract translation, rotation, skew, and scale components from an SVG transform string. This is useful for calculating current transformation state. ```javascript function getTransformation(transform) { // taken from: https://stackoverflow.com/questions/38224875/how-can-d3-transform-be-used-in-d3-v4 var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); g.setAttributeNS(null, "transform", transform); var matrix = g.transform.baseVal.consolidate().matrix; var a=matrix.a, b=matrix.b, c=matrix.c, d=matrix.d, e=matrix.e, f=matrix.f; var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * 180 / Math.PI, skewX: Math.atan(skewX) * 180 / Math.PI, scaleX: scaleX, scaleY: scaleY }; } ``` -------------------------------- ### Setting Up Split Pane JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.getPositive(A__this,_untyped_i)_-1778620222.html Initializes variables and the mouse down event handler for the split pane functionality. This allows the user to drag a separator (`#separator`) to resize the graph (`#graph`) and descriptions (`#descriptions`) panels. ```JavaScript const separator = document.getElementById("separator"); const first = document.getElementById("graph"); const second = document.getElementById("descriptions"); var md; separator.onmousedown = onMouseDown; function onMouseDown(e) { md = {e, offsetLeft: separator.offsetLeft, offsetTop: separator.offsetTop, firstWi ``` -------------------------------- ### Initializing D3-Graphviz Instance Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.identity(A__this,_untyped_i)_-1081452707.html Initializes the D3-Graphviz library on the element with ID 'graph', applying the custom attributer function and enabling zooming. ```JavaScript const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); ``` -------------------------------- ### Setup D3 Zoom Behavior JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.identity(A__this,_untyped_i)_-1778624996.html Defines the D3 zoom behavior and the handler function 'zoomed' which applies the current transform to the graph's group element. ```JavaScript var zoom = d3.zoom().on("zoom", zoomed); function zoomed(e) { g.attr("transform", e.transform); } ``` -------------------------------- ### D3.js Zoom Setup Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.getOne(A__this)_-1778621183.html Sets up a D3.js zoom behavior and defines the `zoomed` function. The `zoomed` function applies the current zoom transform to the graph group element (`g`). ```javascript var zoom = d3.zoom().on("zoom", zoomed); function zoomed(e) { g.attr("transform", e.transform); } ``` -------------------------------- ### Implementing Node Search and Navigation (JavaScript) Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-sdk/src/main/resources/html-graph/viewer.html Adds input and click listeners for the search bar and navigation buttons ('#next', '#prev'). It filters graph nodes based on the search query, highlights results, and centers the view on the current hit. ```JavaScript /* Search */ // Reset searchbar contents on load d3.select('#search').node().value = ""; var hits = []; var hit = -1; function centerToSearch() { hits.filter(function (d, i) { return i === hit; }).each(function (d, i) { selectNode(this); var gbbox = g.node().getBBox(); var gX = gbbox.x + (gbbox.width/2); var gY = gbbox.y + (gbbox.height/2); var bbox = this.getBBox(); var tX = bbox.x + (bbox.width/2); var tY = bbox.y + (bbox.height/2); var offsetX = gX - tX; var offsetY = gY - tY; var curr = getTransformation(g.attr("transform")); var transform = d3.zoomIdentity // reset to initial position .translate(itTX, itTY) // keep current scale .scale(curr.scaleX) // move to node center .translate(offsetX, offsetY); svg.transition("zooming") .duration(150) .ease(d3.easeLinear) .call(zoom.transform, transform); }); } d3.select('#search').on('input', function (e) { var query = e.target.value; if (query !== "") hits = d3.selectAll('.node').filter(function (d, i) { return d3.select(this).select('text').text().includes(query); }); if (query === "" || hits.size() == 0) { hit = -1; d3.select('#next').attr('disabled', true); d3.select('#prev').attr('disabled', true); d3.select('.node-selected').classed('node-selected', false); d3.select(this).classed('no-results', true); } else { hit = 0; d3.select('#next').attr('disabled', null); d3.select('#prev').attr('disabled', null); d3.select(this).classed('no-results', false); centerToSearch(); } }); d3.select('#next').on('click', function (e) { if (hit != -1) { hit = (hit + 1) % hits.size(); centerToSearch(); } }); d3.select('#prev').on('click', function (e) { if (hit != -1) { hit = ((hit - 1) + hits.size()) % hits.size(); centerToSearch(); } }); ``` -------------------------------- ### Initialize Graphviz Instance - D3.js Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.getPositive(A__this,_untyped_i)_-1778620222.html Initializes a D3.js Graphviz instance bound to the element with ID "graph". It applies the custom `attributer` function for scaling and enables zooming. ```javascript const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); ``` -------------------------------- ### Initialize Descriptions Panel Height (JS) Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.getOne(A__this)_-1778621183.html Sets the height of the descriptions panel (`#descriptions`) to match the height of the graph panel (`#graph`) using D3. ```JavaScript d3.select('#descriptions').style('height', d3.select('#graph').node().offsetHeight + "px"); ``` -------------------------------- ### Implement Resizable Split Pane Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_tests.main(tests__this).html Adds drag functionality to a separator element to allow resizing of two adjacent panels ('graph' and 'descriptions') by adjusting their widths based on mouse movement. ```JavaScript /* Split pane */ // taken from https://stackoverflow.com/questions/12194469/best-way-to-do-a-split-pane-in-html const separator = document.getElementById("separator"); const first = document.getElementById("graph"); const second = document.getElementById("descriptions"); var md; separator.onmousedown = onMouseDown; function onMouseDown(e) { md = {e, offsetLeft: separator.offsetLeft, offsetTop: separator.offsetTop, firstWidth: first.offsetWidth, secondWidth: second.offsetWidth }; document.onmousemove = onMouseMove; document.onmouseup = () => { document.onmousemove = document.onmouseup = null; } } function onMouseMove(e) { var delta = {x: e.clientX - md.e.clientX, y: e.clientY - md.e.clientY}; delta.x = Math.min(Math.max(delta.x, -md.firstWidth), md.secondWidth); separator.style.left = md.offsetLeft + delta.x + "px"; first.style.width = (md.firstWidth + delta.x) + "px"; second.style.width = (md.secondWidth - delta.x) + "px"; } ``` -------------------------------- ### Initialize Description Panel Height Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.A(A__this)_-1778639473.html Sets the initial height of the description panel to match the height of the graph container, ensuring a consistent layout. ```JavaScript d3.select('#descriptions').style('height', d3.select('#graph').node().offsetHeight + "px"); ``` -------------------------------- ### Initialize Descriptions Pane Height - D3.js Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.getPositive(A__this,_untyped_i)_-1778620222.html Sets the height of the descriptions pane to match the height of the graph pane using D3.js. This ensures the layout is consistent. ```javascript d3.select('#descriptions').style('height', d3.select('#graph').node().offsetHeight + "px"); ``` -------------------------------- ### Navigating Search Results with D3.js Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_tests.main(tests__this).html Implements click handlers for 'next' and 'prev' buttons to cycle through the filtered search results (hits). Calls `centerToSearch()` to focus on the current hit. ```javascript d3.select('#next').on('click', function (e) { if (hit != -1) { hit = (hit + 1) % hits.size(); centerToSearch(); } }); d3.select('#prev').on('click', function (e) { if (hit != -1) { hit = ((hit - 1) + hits.size()) % hits.size(); centerToSearch(); } }); ``` -------------------------------- ### Set Descriptions Pane Height Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_tests.helper(tests__this,_untyped_i,_untyped_dispatcher)_-1778625864.html Sets the height of the descriptions pane ('#descriptions') to match the height of the graph pane ('#graph') using D3.js. This ensures the layout is visually consistent, particularly in a split pane setup. ```javascript d3.select('#descriptions').style('height', d3.select('#graph').node().offsetHeight + "px"); ``` -------------------------------- ### Initializing D3-Graphviz JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.getPositive(A__this,_untyped_i)_-1778620222.html Initializes the D3-Graphviz instance on the element with ID `#graph`. It applies the custom `attributer` function for scaling and centering and enables zooming. ```JavaScript const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); ``` -------------------------------- ### Initialize D3-Graphviz Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.getOne(A__this)_-1778621183.html Initializes the D3-graphviz instance bound to the element with ID 'graph'. It configures the instance to use the custom `attributer` function for scaling and centering and enables zooming. ```javascript const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); ``` -------------------------------- ### Get SVG Transformation Matrix Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.identity(A__this,_untyped_i)_-1081452707.html Provides a utility function to parse an SVG transform attribute string and return an object containing the translation, rotation, skew, and scale components. This is useful for analyzing the current state of a transformed element. ```javascript function getTransformation(transform) { // taken from: https://stackoverflow.com/questions/38224875/how-can-d3-transform-be-used-in-d3-v4 var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); g.setAttributeNS(null, "transform", transform); var matrix = g.transform.baseVal.consolidate().matrix; var a=matrix.a, b=matrix.b, c=matrix.c, d=matrix.d, e=matrix.e, f=matrix.f; var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * 180 / Math.PI, skewX: Math.atan(skewX) * 180 / Math.PI, scaleX: scaleX, scaleY: scaleY }; } ``` -------------------------------- ### Initialize D3-Graphviz Instance Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.identity(A__this,_untyped_i)_-1081452707.html Initializes the D3-Graphviz instance bound to the '#graph' element. It applies the custom attributer function for scaling and enables zooming. ```javascript const graphviz = d3.select("#graph").graphviz() .attributer(attributer) .zoom(true); ``` -------------------------------- ### Get SVG Transformation Matrix - JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.A(A__this)_-1778639473.html Helper function to parse an SVG transform string and extract translation, rotation, skew, and scale components. It creates a temporary SVG group element to leverage the browser's SVGMatrix API for accurate parsing. ```JavaScript function getTransformation(transform) { // taken from: https://stackoverflow.com/questions/38224875/how-can-d3-transform-be-used-in-d3-v4 var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); g.setAttributeNS(null, "transform", transform); var matrix = g.transform.baseVal.consolidate().matrix; var a=matrix.a, b=matrix.b, c=matrix.c, d=matrix.d, e=matrix.e, f=matrix.f; var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * 180 / Math.PI, skewX: Math.atan(skewX) * 180 / Math.PI, scaleX: scaleX, scaleY: scaleY }; } ``` -------------------------------- ### D3 Zoom Setup and Handler Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.identity(A__this,_untyped_i)_-1081452707.html Sets up D3's zoom behavior and defines the 'zoomed' function. The 'zoomed' function applies the current zoom transform to the graph's main group element ('g'), effectively zooming and panning the graph. ```javascript var zoom = d3.zoom().on("zoom", zoomed); function zoomed(e) { g.attr("transform", e.transform); } ``` -------------------------------- ### Initialize Descriptions Panel Height Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html-sub/untyped_A.identity(A__this,_untyped_i)_-1081452707.html Sets the initial height of the descriptions panel to match the height of the graph visualization panel using D3.js. ```javascript d3.select('#descriptions').style('height', d3.select('#graph').node().offsetHeight + "px"); ``` -------------------------------- ### Setup D3.js Zoom Behavior Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_tests.helper(tests__this,_untyped_i,_untyped_dispatcher)_-1778625864.html Sets up the D3.js zoom behavior. It defines the 'zoomed' function which applies the current zoom transform from the event ('e') to the graph group element ('g'). The zoom behavior is later applied to the SVG element. ```javascript var zoom = d3.zoom().on("zoom", zoomed); function zoomed(e) { g.attr("transform", e.transform); } ``` -------------------------------- ### Setup D3 Zoom Behavior - D3.js - JavaScript Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-analyses/imp-testcases/visualization/html/untyped_A.A(A__this)_-1778639473.html Initializes D3's zoom behavior and defines the `zoomed` function. The `zoomed` function is the callback executed during zoom events, applying the current transform to the graph group element (`g`) to visually update the graph's position and scale. ```JavaScript var zoom = d3.zoom().on("zoom", zoomed); function zoomed(e) { g.attr("transform", e.transform); } ``` -------------------------------- ### Handling Node Selection and Description Display (JavaScript) Source: https://github.com/lisa-analyzer/lisa/blob/master/lisa/lisa-sdk/src/main/resources/html-graph/viewer.html Implements the 'selectNode' function which highlights the clicked graph node and shows the corresponding description header based on the node's ID. ```JavaScript function selectNode(target) { d3.select('.node-selected').classed('node-selected', false); d3.select(target).classed('node-selected', true); // Show corresponding header var id = d3.select(target).attr('id'); d3.selectAll('.header-info').classed('header-hidden', true); d3.select('#header-' + id).classed('header-hidden', false); } ```