Skip to content

Commit 6699fe4

Browse files
committed
Fix position of hirerarchy diagram, highlight main node, add button to reset zoom
1 parent b7405bb commit 6699fe4

File tree

6 files changed

+85
-6
lines changed

6 files changed

+85
-6
lines changed

scala3doc/resources/dotty_res/scripts/ux.js

+54-2
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,22 @@ window.addEventListener("DOMContentLoaded", () => {
5555
hljs.initHighlighting();
5656
});
5757

58+
var zoom;
59+
var transform;
60+
5861
function showGraph() {
5962
if ($("svg#graph").children().length == 0) {
6063
var dotNode = document.querySelector("#dot")
6164
if (dotNode){
6265
var svg = d3.select("#graph");
66+
var radialGradient = svg.append("defs").append("radialGradient").attr("id", "Gradient");
67+
radialGradient.append("stop").attr("stop-color", "#ffd47f").attr("offset", "20%");
68+
radialGradient.append("stop").attr("stop-color", "white").attr("offset", "100%");
69+
6370
var inner = svg.append("g");
6471

6572
// Set up zoom support
66-
var zoom = d3.zoom()
73+
zoom = d3.zoom()
6774
.on("zoom", function({transform}) {
6875
inner.attr("transform", transform);
6976
});
@@ -76,15 +83,60 @@ function showGraph() {
7683
g.setNode(v, {
7784
labelType: "html",
7885
label: g.node(v).label,
79-
style: g.node(v).style
86+
style: g.node(v).style,
87+
id: g.node(v).id
8088
});
8189
});
90+
g.setNode("node0Cluster", {
91+
style: "fill: url(#Gradient);",
92+
id: "node0Cluster"
93+
});
94+
g.setParent("node0", "node0Cluster");
95+
8296
g.edges().forEach(function(v) {
8397
g.setEdge(v, {
8498
arrowhead: "vee"
8599
});
86100
});
87101
render(inner, g);
102+
103+
// Set the 'fit to content graph' upon landing on the page
104+
var bounds = svg.node().getBBox();
105+
var parent = svg.node().parentElement;
106+
var fullWidth = parent.clientWidth || parent.parentNode.clientWidth,
107+
fullHeight = parent.clientHeight || parent.parentNode.clientHeight;
108+
var width = bounds.width,
109+
height = bounds.height;
110+
var midX = bounds.x + width / 2,
111+
midY = bounds.y + height / 2;
112+
if (width == 0 || height == 0) return; // nothing to fit
113+
var scale = Math.min(fullWidth / width, fullHeight / height) * 0.99; // 0.99 to make a little padding
114+
var translate = [fullWidth / 2 - scale * midX, fullHeight / 2 - scale * midY];
115+
116+
transform = d3.zoomIdentity
117+
.translate(translate[0], translate[1])
118+
.scale(scale);
119+
120+
svg.call(zoom.transform, transform);
121+
122+
// This is nasty hack to prevent DagreD3 from stretching cluster. There is similar issue on github since October 2019, but haven't been answered yet. https://github.com/dagrejs/dagre-d3/issues/377
123+
var node0 = d3.select("g#node0")._groups[0][0];
124+
var node0Rect = node0.children[0];
125+
var node0Cluster = d3.select("g#node0Cluster")._groups[0][0];
126+
var node0ClusterRect = node0Cluster.children[0];
127+
node0Cluster.setAttribute("transform", node0.getAttribute("transform"));
128+
node0ClusterRect.setAttribute("width", +node0Rect.getAttribute("width") + 80);
129+
node0ClusterRect.setAttribute("height", +node0Rect.getAttribute("height") + 80);
130+
node0ClusterRect.setAttribute("x", node0Rect.getAttribute("x") - 40);
131+
node0ClusterRect.setAttribute("y", node0Rect.getAttribute("y") - 40);
88132
}
89133
}
90134
}
135+
136+
function zoomOut() {
137+
var svg = d3.select("#graph");
138+
svg
139+
.transition()
140+
.duration(2000)
141+
.call(zoom.transform, transform);
142+
}

scala3doc/resources/dotty_res/styles/diagram.css

+24-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
#graph {
1818
width: 100%;
19-
height: 80%;
19+
height: 400px;
2020
}
2121

2222
.diagram-class a {
@@ -29,3 +29,26 @@
2929
.diagram-class span[data-unresolved-link] {
3030
color: #FFF;
3131
}
32+
33+
.btn {
34+
padding: 8px 16px;
35+
text-align: center;
36+
text-decoration: none;
37+
display: inline-block;
38+
font-size: 16px;
39+
margin: 4px 2px;
40+
transition-duration: 0.4s;
41+
cursor: pointer;
42+
background-color: white;
43+
color: black;
44+
border: 2px solid #003048;
45+
position: absolute;
46+
top: 0;
47+
left: 0;
48+
z-index:2;
49+
}
50+
51+
.btn:hover {
52+
background-color: #003048;
53+
color: white;
54+
}

scala3doc/resources/dotty_res/styles/scalastyle.css

+1
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ footer .pull-right {
610610
.diagram-class {
611611
width: 100%;
612612
max-height: 400px;
613+
position: relative;
613614
}
614615

615616
/* Large Screens */

scala3doc/src/dotty/renderers/DotDiagramBuilder.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object DotDiagramBuilder:
1919

2020
val vWithId = diagram.verteciesWithId
2121
val vertecies = vWithId.map { (vertex, id) =>
22-
s"""node${id} [label="${getHtmlLabel(vertex, renderer)}", style="${getStyle(vertex)}"];\n"""
22+
s"""node${id} [id=node${id}, label="${getHtmlLabel(vertex, renderer)}", style="${getStyle(vertex)}"];\n"""
2323
}.mkString
2424

2525
val edges = diagram.edges.map { (from, to) =>

scala3doc/src/dotty/renderers/MemberRenderer.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ class MemberRenderer(signatureRenderer: SignatureRenderer, buildNode: ContentNod
315315
val graphHtml = MemberExtension.getFrom(m).map(_.graph) match
316316
case Some(graph) if graph.edges.nonEmpty =>
317317
Seq(div( id := "inheritance-diagram", cls := "diagram-class showGraph")(
318+
input(value := "Reset zoom", `type` := "button", cls := "btn", onclick := "zoomOut()"),
318319
svg(id := "graph"),
319320
script(`type` := "text/dot", id := "dot")(
320321
raw(DotDiagramBuilder.build(graph, signatureRenderer))
@@ -334,8 +335,8 @@ class MemberRenderer(signatureRenderer: SignatureRenderer, buildNode: ContentNod
334335
renderTabs(
335336
singleSelection = true,
336337
Tab("Graph", "graph", graphHtml, "showGraph"),
337-
Tab("Super types", "supertypes", supertypes),
338-
Tab("Known subtyes", "subtypes",subtypes),
338+
Tab("Supertypes", "supertypes", supertypes),
339+
Tab("Known subtypes", "subtypes", subtypes),
339340
)
340341

341342
private def buildDocumentableFilter = div(cls := "documentableFilter")(

scala3doc/src/dotty/renderers/html.scala

+2
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ object HTML:
9696
val content = Attr("content")
9797
val testId = Attr("data-test-id")
9898
val alt = Attr("alt")
99+
val value = Attr("value")
100+
val onclick=Attr("onclick")
99101

100102
def raw(content: String): AppliedTag = new AppliedTag(content)
101103
def raw(content: StringBuilder): AppliedTag = content

0 commit comments

Comments
 (0)