Skip to content

Commit 77bf88b

Browse files
committed
implement propoer zoom and drag in index.qmd network diagram
1 parent 71567ac commit 77bf88b

File tree

3 files changed

+48
-51
lines changed

3 files changed

+48
-51
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: orgmetrics
22
Title: Metrics for Your GitHub Organization
3-
Version: 0.1.2.111
3+
Version: 0.1.2.112
44
Authors@R:
55
person("Mark", "Padgham", , "[email protected]", role = c("aut", "cre"),
66
comment = c(ORCID = "0000-0003-2172-5265"))

codemeta.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"codeRepository": "https://github.com/ropensci-review-tools/orgmetrics",
99
"issueTracker": "https://github.com/ropensci-review-tools/orgmetrics/issues",
1010
"license": "https://spdx.org/licenses/GPL-3.0",
11-
"version": "0.1.2.111",
11+
"version": "0.1.2.112",
1212
"programmingLanguage": {
1313
"@type": "ComputerLanguage",
1414
"name": "R",

inst/extdata/quarto/index.qmd

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -311,10 +311,9 @@ on that package.
311311
- Edges connect dependent packages, with thicknesses scaled by total numbers of
312312
function 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+
429389
chart = {
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

Comments
 (0)