@@ -311,10 +311,9 @@ on that package.
311311- Edges connect dependent packages, with thicknesses scaled by total numbers of
312312function calls by all dependent packages.
313313
314- The diagram can be moved and dragged to dynamically explore how packages
315- inter-related. To avoid confusion with gestures or mouse events, moving and
316- zooming are controlled using the sliders below. The initial "Repository"
317- control highlights the selected repository in red.
314+ The diagram can be zoom, moved, and dragged to dynamically explore how packages
315+ inter-related. The initial "Repository" control highlights the selected
316+ repository in red.
318317
319318
320319``` {r}
@@ -380,54 +379,19 @@ s = localStorage.setItem("orgmetricsRepo", selectedNode.toString());
380379```
381380
382381
383- ``` {ojs ForceGraph-plot}
384- width = 928;
385- height = 600;
386-
387- viewof x0 = {
388- let input = Inputs.range([-width, width],
389- {
390- value: -width / 2,
391- step: 10,
392- label: "x"
393- }
394- )
395- d3.select(input).select('input[type="number"]').style("display", "none");
396- return input;
397- }
398-
399- viewof y0 = {
400- let input = Inputs.range([-height, height],
401- {
402- value: -height / 2,
403- step: 10,
404- label: "y"
405- }
406- )
407- d3.select(input).select('input[type="number"]').style("display", "none");
408- return input;
409- }
410-
411- viewof strength = {
412- let input = Inputs.range([0, 800],
413- {
414- value: 50,
415- step: 10,
416- label: "zoom"
417- }
418- )
419- d3.select(input).select('input[type="number"]').style("display", "none");
420- return input;
421- }
422- ```
423-
424-
425382<div style =" margin-top : 20px ; margin-bottom : 20px ;" ></div >
426383
427384
428- ``` {ojs}
385+ ``` {ojs forceSimulation}
386+ width = 928;
387+ height = 600;
388+
429389chart = {
430390
391+ const x0 = -width / 2;
392+ const y0 = -height / 2;
393+ const strength = 50;
394+
431395 const types = Array.from(new Set(pkg_nodes.map(d => d.group)));
432396
433397 const color = d3.scaleOrdinal(types, d3.schemeCategory10);
@@ -444,7 +408,33 @@ chart = {
444408 .attr("height", height)
445409 .attr("style", "max-width: 100%; height: auto; font: 14px sans-serif;");
446410
447- const link = svg.append("g")
411+ const zoom = d3.zoom()
412+ .scaleExtent([0.1, 10])
413+ .on("zoom", (event) => {
414+ // Update the viewBox for panning
415+ const transform = event.transform;
416+ const newX0 = -transform.x;
417+ const newY0 = -transform.y;
418+ const newWidth = width / transform.k;
419+ const newHeight = height / transform.k;
420+
421+ svg.attr("viewBox", [newX0, newY0, newWidth, newHeight]);
422+
423+ // Update strength based on zoom level (inverse relationship)
424+ const newStrength = Math.max(10, Math.min(800, strength * transform.k));
425+
426+ // Update simulation with new strength
427+ simulation.force("charge", d3.forceManyBody().strength(-newStrength));
428+ simulation.alpha(0.3).restart();
429+ });
430+
431+ // apply zoom behaviour to svg:
432+ svg.call(zoom);
433+
434+ // create container for all context that will be transformed:
435+ const container = svg.append("g");
436+
437+ const link = container.append("g")
448438 .attr("fill", "none")
449439 .attr("stroke-width", 1.5)
450440 .selectAll("path")
@@ -453,7 +443,7 @@ chart = {
453443 .attr("stroke", "gray")
454444 .attr("stroke-width", d => 5 * Math.log10(d.value));
455445
456- const node = svg .append("g")
446+ const node = container .append("g")
457447 .selectAll("g")
458448 .data(pkg_nodes)
459449 .join("g")
@@ -493,6 +483,10 @@ chart = {
493483 node.attr("transform", d => `translate(${d.x},${d.y})`);
494484 });
495485
486+ // set initial zoom transform to match current x0, y0:
487+ const initialTransform = d3.zoomIdentity.translate(-x0, -y0);
488+ svg.call(zoom.transform, initialTransform);
489+
496490 invalidation.then(() => simulation.stop());
497491
498492 return Object.assign(svg.node(), {scales: {color}});
@@ -516,6 +510,9 @@ drag = simulation => {
516510 if (!event.active) simulation.alphaTarget(0.3).restart();
517511 d.fx = d.x;
518512 d.fy = d.y;
513+
514+ // prevent zoom behaviour during drag:
515+ event.sourceEvent.stopPropagation();
519516 }
520517
521518 function dragged(event, d) {
0 commit comments