impact-analysis 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,295 @@
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Impact Analysis</title>
7
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
8
+ <link rel="preconnect" href="https://fonts.googleapis.com">
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
+ <link href="https://fonts.googleapis.com/css2?family=Exo+2:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
11
+ <style>
12
+ body { font-family: "Exo 2", serif; background-color: #282828; color: #fff; overflow-x: hidden;
13
+ font-optical-sizing: auto; margin: 0; padding: 0; text-align: center; font-weight: 400;}
14
+ svg { width: 100%; height: 100vh; }
15
+ circle { cursor: pointer; }
16
+ text { font-size: 12px; fill: #fff; }
17
+ line { stroke: #fefefe; stroke-opacity: 0.6; }
18
+ #tooltip { position: absolute; background: #fff;color: #000; padding: 8px; border: 1px solid #ddd; display: none; }
19
+ .svg-wrapper{ padding: 10px; }
20
+ .impact-file-list {
21
+ display: list-item;
22
+ list-style: number;
23
+ text-align: left;
24
+ padding-left: 7px;
25
+ }
26
+ .impact-analysis-table {
27
+ width: 100%; border-collapse: collapse;
28
+ }
29
+ .impact-analysis-table td {
30
+ padding: 10px 20px;
31
+ }
32
+ th {
33
+ padding: 10px;
34
+ }
35
+ td:first-child {
36
+ background: #91fd9117;
37
+ }
38
+ .btn-theme {
39
+ min-width: 142px;
40
+ padding: 12px 16px;
41
+ font-size: 14px;
42
+ border-radius: 100px;
43
+ border: 1px solid #565454;
44
+ outline: none;
45
+ box-shadow: none;
46
+ cursor: pointer;
47
+ transition: all .3s ease-in-out;
48
+ text-decoration: none;
49
+ display: inline-flex;
50
+ align-items: center;
51
+ font-family: "Exo 2", serif;
52
+ background: #222;
53
+ color: #fff;
54
+ }
55
+
56
+ .btn-active {
57
+ background: #1f4afe;
58
+ background: linear-gradient(90deg,#1f4afe 35%,#167cfc);
59
+ color: #fff
60
+ }
61
+
62
+ .btn-svg path {
63
+ fill: #fefefe;
64
+ }
65
+
66
+ .btn-active:hover svg path {
67
+ fill: #1f4afe;
68
+ }
69
+
70
+ .btn-theme:hover svg path {
71
+ fill: #1f4afe;
72
+ }
73
+
74
+ .btn-theme:hover {
75
+ background: #fff;
76
+ color: #1f4afe;
77
+ border: 1px solid #1F4AFE
78
+ }
79
+
80
+ .btn-svg {
81
+ width: 20px;
82
+ height: 20px;
83
+ margin-right: 10px;
84
+ }
85
+
86
+ th {
87
+ background: #1f4afe;
88
+ background: linear-gradient(90deg,#1f4afe 35%,#167cfc);
89
+ width: 50%;
90
+ }
91
+
92
+ th:last-child {
93
+ background: #1f4afe;
94
+ background: linear-gradient(-90deg,#1f4afe 35%,#167cfc);
95
+ }
96
+ </style>
97
+ </head>
98
+ <body>
99
+ <h1>Impact Analysis</h1>
100
+ <div id="tooltip"></div>
101
+ <div style="text-align: center; margin-bottom: 10px;">
102
+ <button id="graphViewBtn" class="btn-theme btn-active"><svg class="btn-svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve">
103
+ <g><g><path fill="#000000" d="M224.5,7.9c-11.8,0-21.5,9.6-21.5,21.5c0,7.4,3.8,14,9.6,17.9l-40.5,106.9c-1.1-0.2-2.3-0.3-3.4-0.3c-5.2,0-9.8,1.9-13.5,4.9l-40.6-33.5c1.6-3,2.6-6.4,2.6-10c0-11.8-9.6-21.5-21.5-21.5c-11.8,0-21.5,9.6-21.5,21.5c0,6.4,2.9,12.1,7.3,16l-43.3,75.3c-2.2-0.7-4.5-1.3-6.9-1.3c-11.8,0-21.5,9.6-21.5,21.5c0,11.8,9.6,21.5,21.5,21.5c11.8,0,21.5-9.6,21.5-21.5c0-6.3-2.8-11.9-7.1-15.8l43.3-75.4c2.1,0.7,4.3,1.2,6.7,1.2c5.1,0,9.7-1.9,13.4-4.8l40.6,33.6c-1.6,3-2.5,6.3-2.5,9.9c0,11.8,9.6,21.5,21.5,21.5c11.8,0,21.5-9.6,21.5-21.5c0-7.6-4-14.3-10-18.1l40.5-106.7c1.3,0.2,2.6,0.4,3.9,0.4c11.8,0,21.5-9.6,21.5-21.5C246,17.5,236.4,7.9,224.5,7.9L224.5,7.9z M31.5,239.6c-7.1,0-12.9-5.8-12.9-12.9c0-7.1,5.8-12.9,12.9-12.9c7.1,0,12.9,5.8,12.9,12.9C44.3,233.8,38.6,239.6,31.5,239.6z M95.7,128c-7.1,0-12.9-5.8-12.9-12.9c0-7.1,5.8-12.9,12.9-12.9c7.1,0,12.9,5.8,12.9,12.9C108.6,122.3,102.8,128,95.7,128z M168.7,188.1c-7.1,0-12.9-5.8-12.9-12.9c0-7.1,5.8-12.9,12.9-12.9c7.1,0,12.9,5.8,12.9,12.9C181.6,182.3,175.8,188.1,168.7,188.1L168.7,188.1z M224.5,42.2c-7.1,0-12.9-5.8-12.9-12.9c0-7.1,5.8-12.9,12.9-12.9c7.1,0,12.9,5.8,12.9,12.9C237.4,36.5,231.6,42.2,224.5,42.2L224.5,42.2z"/></g></g>
104
+ </svg> Graph View</button>
105
+ <button id="tableViewBtn" class="btn-theme"><svg class="btn-svg" width="12px" height="12px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
106
+ </defs>
107
+ <g id="64px-Line" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
108
+ <g id="db-table">
109
+
110
+ </g>
111
+ <path d="M56,12 C56,9.794 54.206,8 52,8 L10,8 C7.794,8 6,9.794 6,12 L6,54 C6,56.206 7.794,58 10,58 L52,58 C54.206,58 56,56.206 56,54 L56,12 L56,12 Z M30,22 L30,32 L20,32 L20,22 L30,22 L30,22 Z M42,22 L42,32 L32,32 L32,22 L42,22 L42,22 Z M54,22 L54,32 L44,32 L44,22 L54,22 L54,22 Z M18,32 L8,32 L8,22 L18,22 L18,32 L18,32 Z M8,34 L18,34 L18,44 L8,44 L8,34 L8,34 Z M20,34 L30,34 L30,44 L20,44 L20,34 L20,34 Z M30,46 L30,56 L20,56 L20,46 L30,46 L30,46 Z M32,46 L42,46 L42,56 L32,56 L32,46 L32,46 Z M32,44 L32,34 L42,34 L42,44 L32,44 L32,44 Z M44,34 L54,34 L54,44 L44,44 L44,34 L44,34 Z M10,10 L52,10 C53.103,10 54,10.897 54,12 L54,20 L8,20 L8,12 C8,10.897 8.897,10 10,10 L10,10 Z M8,54 L8,46 L18,46 L18,56 L10,56 C8.897,56 8,55.103 8,54 L8,54 Z M52,56 L44,56 L44,46 L54,46 L54,54 C54,55.103 53.103,56 52,56 L52,56 Z" id="Shape" fill="#000000">
112
+
113
+ </path>
114
+ </g>
115
+ </svg> Table View</button>
116
+ </div>
117
+
118
+ <div id="graphView" style="display: block;">
119
+ <svg id="svgGraph" width="1000" height="600"></svg>
120
+ </div>
121
+
122
+ <div id="tableView" style="display: none;padding: 20px;">
123
+ <table class="impact-analysis-table" border="1">
124
+ <thead>
125
+ <tr>
126
+ <th>Changed File</th>
127
+ <th>Impacted Files</th>
128
+ </tr>
129
+ </thead>
130
+ <tbody id="tableBody"></tbody>
131
+ </table>
132
+ </div>
133
+
134
+
135
+ <script>
136
+ const impactData = [];
137
+ function getFileName(path) {
138
+ return path.split(/[/\\\\]/).pop();
139
+ }
140
+
141
+ const nodesMap = new Map();
142
+ impactData.forEach(d => {
143
+ nodesMap.set(d.changedFile, { id: d.changedFile, name: getFileName(d.changedFile), isChangedFile: true });
144
+ d.impactsTo.forEach(target => {
145
+ nodesMap.set(target, { id: target, name: getFileName(target), isChangedFile: false });
146
+ });
147
+ });
148
+ const nodes = Array.from(nodesMap.values());
149
+ const links = [];
150
+ const impactMap = new Map();
151
+
152
+ impactData.forEach(d => {
153
+ d.impactsTo.forEach(target => {
154
+ links.push({ source: d.changedFile, target });
155
+ if (!impactMap.has(target)) impactMap.set(target, new Set());
156
+ impactMap.get(target).add(d.changedFile);
157
+ });
158
+ });
159
+
160
+ impactMap.forEach((sources, target) => {
161
+ sources.forEach(source1 => {
162
+ sources.forEach(source2 => {
163
+ if (source1 !== source2) {
164
+ links.push({ source: source1, target: source2 });
165
+ }
166
+ });
167
+ });
168
+ });
169
+
170
+ const graph = { nodes, links };
171
+
172
+ const width = window.innerWidth;
173
+ const height = window.innerHeight - 100;
174
+
175
+ const svg = d3.select("#svgGraph")
176
+ .attr("width", width)
177
+ .attr("height", height);
178
+
179
+ const simulation = d3.forceSimulation(graph.nodes)
180
+ .force("link", d3.forceLink(graph.links)
181
+ .id(d => d.id)
182
+ .distance(80) // Reduce distance for a more compact layout
183
+ )
184
+ .force("charge", d3.forceManyBody()
185
+ .strength(-50) // Decrease negative strength to reduce spacing
186
+ )
187
+ .force("center", d3.forceCenter(width / 2, height / 2))
188
+ .force("collision", d3.forceCollide()
189
+ .radius(35) // Adjust radius to ensure nodes don't overlap but are closer
190
+ )
191
+ .on("tick", ticked);
192
+
193
+ const link = svg.append("g")
194
+ .selectAll("line")
195
+ .data(graph.links)
196
+ .enter().append("line")
197
+ .attr("stroke", "#aaa");
198
+
199
+ const nodeGroup = svg.append("g")
200
+ .selectAll("g")
201
+ .data(graph.nodes)
202
+ .enter().append("g")
203
+ .call(d3.drag()
204
+ .on("start", dragStarted)
205
+ .on("drag", dragged)
206
+ .on("end", dragEnded));
207
+
208
+ const node = nodeGroup.append("circle")
209
+ .attr("r", 10)
210
+ .attr("fill", d => d.isChangedFile ? "red" : "steelblue");
211
+
212
+ const labels = nodeGroup.append("text")
213
+ .attr("x", 12)
214
+ .attr("y", 5)
215
+ .text(d => d.name);
216
+
217
+ simulation.on("tick", () => {
218
+ link.attr("x1", d => d.source.x)
219
+ .attr("y1", d => d.source.y)
220
+ .attr("x2", d => d.target.x)
221
+ .attr("y2", d => d.target.y);
222
+
223
+ nodeGroup.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
224
+ });
225
+
226
+ function dragStarted(event, d) {
227
+ if (!event.active) simulation.alphaTarget(0.3).restart();
228
+ d.fx = d.x;
229
+ d.fy = d.y;
230
+ }
231
+
232
+ function dragged(event, d) {
233
+ d.fx = event.x;
234
+ d.fy = event.y;
235
+ }
236
+
237
+ function dragEnded(event, d) {
238
+ if (!event.active) simulation.alphaTarget(0);
239
+ d.fx = null;
240
+ d.fy = null;
241
+ }
242
+
243
+ document.getElementById("graphViewBtn").addEventListener("click", function () {
244
+ document.getElementById("graphView").style.display = "block";
245
+ document.getElementById("tableView").style.display = "none";
246
+ setActiveButton(this);
247
+ });
248
+
249
+ document.getElementById("tableViewBtn").addEventListener("click", function () {
250
+ document.getElementById("graphView").style.display = "none";
251
+ document.getElementById("tableView").style.display = "block";
252
+ setActiveButton(this);
253
+ generateTableView(impactData);
254
+ });
255
+
256
+ function setActiveButton(activeBtn) {
257
+ document.querySelectorAll(".btn-theme").forEach(button => {
258
+ button.classList.remove("btn-active");
259
+ });
260
+ activeBtn.classList.add("btn-active");
261
+ }
262
+
263
+ function generateTableView(data) {
264
+ const tableBody = document.getElementById("tableBody");
265
+ tableBody.innerHTML = "";
266
+
267
+ data.forEach(row => {
268
+ const tr = document.createElement("tr");
269
+
270
+ const tdFile = document.createElement("td");
271
+ tdFile.textContent = row.changedFile;
272
+ tr.appendChild(tdFile);
273
+
274
+ const tdImpact = document.createElement("td");
275
+ tdImpact.textContent = row.impactsTo.length ? row.impactsTo.join(", ") : "None";
276
+ tr.appendChild(tdImpact);
277
+
278
+ tableBody.appendChild(tr);
279
+ });
280
+ }
281
+ function ticked() {
282
+ node.attr("cx", d => d.x = Math.max(20, Math.min(width - 20, d.x)))
283
+ .attr("cy", d => d.y = Math.max(20, Math.min(height - 20, d.y)));
284
+
285
+ link.attr("x1", d => d.source.x)
286
+ .attr("y1", d => d.source.y)
287
+ .attr("x2", d => d.target.x)
288
+ .attr("y2", d => d.target.y);
289
+ }
290
+
291
+
292
+
293
+ </script>
294
+ </body>
295
+ </html>
package/index.mjs CHANGED
@@ -149,7 +149,7 @@ function generateGraphData(dependencyData) {
149
149
  if (!nodes.has(impactedFile)) {
150
150
  nodes.set(impactedFile, { id: impactedFileName, path: impactedFile, isChangedFile: false });
151
151
  }
152
- links.push({ source: changedFile, target: impactedFileName });
152
+ links.push({ id: changedFile, source: changedFile, target: impactedFileName });
153
153
  });
154
154
  });
155
155
 
@@ -160,7 +160,6 @@ function generateGraphData(dependencyData) {
160
160
  }
161
161
 
162
162
  const graphData = generateGraphData(results);
163
-
164
163
  const htmlContent = `
165
164
  <!DOCTYPE html>
166
165
  <html lang="en">
@@ -222,10 +221,18 @@ const htmlContent = `
222
221
  color: #fff
223
222
  }
224
223
 
224
+ .btn-svg path {
225
+ fill: #fefefe;
226
+ }
227
+
225
228
  .btn-active:hover svg path {
226
229
  fill: #1f4afe;
227
230
  }
228
231
 
232
+ .btn-theme:hover svg path {
233
+ fill: #1f4afe;
234
+ }
235
+
229
236
  .btn-theme:hover {
230
237
  background: #fff;
231
238
  color: #1f4afe;
@@ -238,13 +245,10 @@ const htmlContent = `
238
245
  margin-right: 10px;
239
246
  }
240
247
 
241
- .btn-svg path {
242
- fill: #fefefe;
243
- }
244
-
245
248
  th {
246
249
  background: #1f4afe;
247
250
  background: linear-gradient(90deg,#1f4afe 35%,#167cfc);
251
+ width: 50%;
248
252
  }
249
253
 
250
254
  th:last-child {
@@ -291,151 +295,161 @@ const htmlContent = `
291
295
 
292
296
 
293
297
  <script>
294
- const graph = ${JSON.stringify(graphData)};
295
-
296
- const width = window.innerWidth;
297
- const height = window.innerHeight - 100;
298
-
299
- const svg = d3.select("#svgGraph")
300
- .attr("width", width)
301
- .attr("height", height);
302
-
303
- const simulation = d3.forceSimulation(graph.nodes)
304
- .force("link", d3.forceLink(graph.links).id(d => d.id).distance(150)) // Increased distance for better spacing
305
- .force("charge", d3.forceManyBody().strength(-200)) // Stronger repulsion to avoid overlap
306
- .force("center", d3.forceCenter(width / 2, height / 2)) // Centering the graph
307
- .force("collision", d3.forceCollide().radius(20)) // Prevents overlap
308
- .on("tick", ticked);
309
-
310
- const link = svg.selectAll("line")
311
- .data(graph.links)
312
- .enter().append("line");
313
-
314
- const node = svg.selectAll("circle")
315
- .data(graph.nodes)
316
- .enter().append("circle")
317
- .attr("r", d => d.isChangedFile ? 18 : 12) // Slightly larger nodes
318
- .attr("fill", d => d.isChangedFile ? "#ff4500" : "#007bff") // Bright orange for changedFile, blue for others
319
- .style("stroke", "#fff") // White border for clarity
320
- .style("stroke-width", 2)
321
- .call(drag(simulation));
322
-
323
- const tooltip = d3.select("#tooltip");
324
-
325
- node.on("mouseover", (event, d) => {
326
- tooltip.style("display", "block")
327
- .html(\`<strong>\${d.isChangedFile ? d.id : d.path}</strong>\`)
328
- .style("left", (event.pageX + 10) + "px")
329
- .style("top", (event.pageY - 10) + "px");
330
- }).on("mouseout", () => tooltip.style("display", "none"));
331
-
332
- svg.selectAll("text")
333
- .data(graph.nodes)
334
- .enter().append("text")
335
- .attr("dy", 4)
336
- .attr("x", 12)
337
- .text(d => d.isChangedFile ? d.name : d.id);
338
-
339
- simulation.on("tick", () => {
340
- link.attr("x1", d => clamp(d.source.x, 0, width))
341
- .attr("y1", d => clamp(d.source.y, 0, height))
342
- .attr("x2", d => clamp(d.target.x, 0, width))
343
- .attr("y2", d => clamp(d.target.y, 0, height));
344
-
345
- node.attr("cx", d => clamp(d.x, 10, width - 10))
346
- .attr("cy", d => clamp(d.y, 10, height - 10));
347
-
348
- svg.selectAll("text")
349
- .attr("x", d => clamp(d.x + 20, 10, width - 10))
350
- .attr("y", d => clamp(d.y + 6, 10, height - 10));
351
- });
352
- function clamp(value, min, max) {
353
- return Math.max(min, Math.min(max, value));
354
- }
298
+ const impactData = ${JSON.stringify(dependencyJson)};
299
+ function getFileName(path) {
300
+ return path.split(/[/\\\\\\\\]/).pop();
301
+ }
355
302
 
356
- function drag(simulation) {
357
- function dragstarted(event, d) {
358
- if (!event.active) simulation.alphaTarget(0.3).restart();
359
- d.fx = d.x;
360
- d.fy = d.y;
361
- }
303
+ const nodesMap = new Map();
304
+ impactData.forEach(d => {
305
+ nodesMap.set(d.changedFile, { id: d.changedFile, name: getFileName(d.changedFile), isChangedFile: true });
306
+ d.impactsTo.forEach(target => {
307
+ nodesMap.set(target, { id: target, name: getFileName(target), isChangedFile: false });
308
+ });
309
+ });
310
+ const nodes = Array.from(nodesMap.values());
311
+ const links = [];
312
+ const impactMap = new Map();
313
+
314
+ impactData.forEach(d => {
315
+ d.impactsTo.forEach(target => {
316
+ links.push({ source: d.changedFile, target });
317
+ if (!impactMap.has(target)) impactMap.set(target, new Set());
318
+ impactMap.get(target).add(d.changedFile);
319
+ });
320
+ });
362
321
 
363
- function dragged(event, d) {
364
- d.fx = clamp(event.x, 10, width - 10);
365
- d.fy = clamp(event.y, 10, height - 10);
366
- }
322
+ impactMap.forEach((sources, target) => {
323
+ sources.forEach(source1 => {
324
+ sources.forEach(source2 => {
325
+ if (source1 !== source2) {
326
+ links.push({ source: source1, target: source2 });
327
+ }
328
+ });
329
+ });
330
+ });
367
331
 
368
- function dragended(event, d) {
369
- if (!event.active) simulation.alphaTarget(0);
370
- d.fx = null;
371
- d.fy = null;
372
- }
332
+ const graph = { nodes, links };
333
+
334
+ const width = window.innerWidth;
335
+ const height = window.innerHeight - 100;
336
+
337
+ const svg = d3.select("#svgGraph")
338
+ .attr("width", width)
339
+ .attr("height", height);
340
+
341
+ const simulation = d3.forceSimulation(graph.nodes)
342
+ .force("link", d3.forceLink(graph.links)
343
+ .id(d => d.id)
344
+ .distance(80)
345
+ )
346
+ .force("charge", d3.forceManyBody()
347
+ .strength(-50)
348
+ )
349
+ .force("center", d3.forceCenter(width / 2, height / 2))
350
+ .force("collision", d3.forceCollide()
351
+ .radius(35)
352
+ )
353
+ .on("tick", ticked);
354
+
355
+ const link = svg.append("g")
356
+ .selectAll("line")
357
+ .data(graph.links)
358
+ .enter().append("line")
359
+ .attr("stroke", "#aaa");
360
+
361
+ const nodeGroup = svg.append("g")
362
+ .selectAll("g")
363
+ .data(graph.nodes)
364
+ .enter().append("g")
365
+ .call(d3.drag()
366
+ .on("start", dragStarted)
367
+ .on("drag", dragged)
368
+ .on("end", dragEnded));
369
+
370
+ const node = nodeGroup.append("circle")
371
+ .attr("r", 10)
372
+ .attr("fill", d => d.isChangedFile ? "red" : "steelblue");
373
+
374
+ const labels = nodeGroup.append("text")
375
+ .attr("x", 12)
376
+ .attr("y", 5)
377
+ .text(d => d.name);
378
+
379
+ simulation.on("tick", () => {
380
+ link.attr("x1", d => d.source.x)
381
+ .attr("y1", d => d.source.y)
382
+ .attr("x2", d => d.target.x)
383
+ .attr("y2", d => d.target.y);
384
+
385
+ nodeGroup.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
386
+ });
387
+
388
+ function dragStarted(event, d) {
389
+ if (!event.active) simulation.alphaTarget(0.3).restart();
390
+ d.fx = d.x;
391
+ d.fy = d.y;
392
+ }
373
393
 
374
- return d3.drag()
375
- .on("start", dragstarted)
376
- .on("drag", dragged)
377
- .on("end", dragended);
378
- }
379
- function ticked() {
380
- link
381
- .attr("x1", d => d.source.x)
382
- .attr("y1", d => d.source.y)
383
- .attr("x2", d => d.target.x)
384
- .attr("y2", d => d.target.y);
385
-
386
- node
387
- .attr("cx", d => d.x)
388
- .attr("cy", d => d.y);
389
-
390
- label
391
- .attr("x", d => d.x + 10)
392
- .attr("y", d => d.y + 5);
393
- }
394
+ function dragged(event, d) {
395
+ d.fx = event.x;
396
+ d.fy = event.y;
397
+ }
394
398
 
395
- document.getElementById("graphViewBtn").addEventListener("click", function () {
396
- document.getElementById("graphView").style.display = "block";
397
- document.getElementById("tableView").style.display = "none";
398
- setActiveButton(this);
399
- });
400
-
401
- document.getElementById("tableViewBtn").addEventListener("click", function () {
402
- document.getElementById("graphView").style.display = "none";
403
- document.getElementById("tableView").style.display = "block";
404
- setActiveButton(this);
405
- generateTableView(${JSON.stringify(dependencyJson)});
406
- });
407
-
408
- function setActiveButton(activeBtn) {
409
- document.querySelectorAll(".btn-theme").forEach(button => {
410
- button.classList.remove("btn-active");
411
- });
412
- activeBtn.classList.add("btn-active");
413
- }
399
+ function dragEnded(event, d) {
400
+ if (!event.active) simulation.alphaTarget(0);
401
+ d.fx = null;
402
+ d.fy = null;
403
+ }
414
404
 
415
- function generateTableView(data) {
416
- const tableData = data;
417
- var tableBody = document.getElementById("tableBody");
418
- tableBody.innerHTML = "";
419
- if (!Array.isArray(tableData) || tableData.length === 0) {
420
- tableBody.innerHTML = '<tr><td colspan="2">No data available</td></tr>';
421
- return;
422
- }
423
- tableData.forEach(function (result) {
424
- var row = document.createElement("tr");
405
+ document.getElementById("graphViewBtn").addEventListener("click", function () {
406
+ document.getElementById("graphView").style.display = "block";
407
+ document.getElementById("tableView").style.display = "none";
408
+ setActiveButton(this);
409
+ });
410
+
411
+ document.getElementById("tableViewBtn").addEventListener("click", function () {
412
+ document.getElementById("graphView").style.display = "none";
413
+ document.getElementById("tableView").style.display = "block";
414
+ setActiveButton(this);
415
+ generateTableView(impactData);
416
+ });
425
417
 
426
- var changedFileCell = document.createElement("td");
427
- changedFileCell.textContent = result.changedFile;
418
+ function setActiveButton(activeBtn) {
419
+ document.querySelectorAll(".btn-theme").forEach(button => {
420
+ button.classList.remove("btn-active");
421
+ });
422
+ activeBtn.classList.add("btn-active");
423
+ }
428
424
 
429
- var impactsToCell = document.createElement("td");
430
- impactsToCell.innerHTML = result.impactsTo.map(function (file) {
431
- return '<div class="impact-file-list">' + file + '</div>';
432
- }).join("");
425
+ function generateTableView(data) {
426
+ const tableBody = document.getElementById("tableBody");
427
+ tableBody.innerHTML = "";
428
+
429
+ data.forEach(row => {
430
+ const tr = document.createElement("tr");
431
+
432
+ const tdFile = document.createElement("td");
433
+ tdFile.textContent = row.changedFile;
434
+ tr.appendChild(tdFile);
435
+
436
+ const tdImpact = document.createElement("td");
437
+ tdImpact.textContent = row.impactsTo.length ? row.impactsTo.join(", ") : "No Impact";
438
+ tr.appendChild(tdImpact);
439
+
440
+ tableBody.appendChild(tr);
441
+ });
442
+ }
443
+ function ticked() {
444
+ node.attr("cx", d => d.x = Math.max(20, Math.min(width - 20, d.x)))
445
+ .attr("cy", d => d.y = Math.max(20, Math.min(height - 20, d.y)));
446
+
447
+ link.attr("x1", d => d.source.x)
448
+ .attr("y1", d => d.source.y)
449
+ .attr("x2", d => d.target.x)
450
+ .attr("y2", d => d.target.y);
451
+ }
433
452
 
434
- row.appendChild(changedFileCell);
435
- row.appendChild(impactsToCell);
436
- tableBody.appendChild(row);
437
- });
438
- }
439
453
 
440
454
 
441
455
  </script>
package/index.zip ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "impact-analysis",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Tool to analyze code impact based on changed files and dependencies.",
5
5
  "main": "index.js",
6
6
  "scripts": {