@@ -124,7 +124,7 @@ public class HtmlReport extends SimpleHtmlReport {
124124 + "</script>" ;
125125
126126 public static final String FORCE_3D_GRAPH =
127- "<script type=\" module\" >\n " + " // SpriteText will only work as import\n "
127+ "<script type=\" module\" >\n " + "// SpriteText will only work as import\n "
128128 + " // this script block requires type=module since we are using an import\n "
129129 + " import SpriteText from \" https://esm.sh/three-spritetext\" ;\n "
130130 + "\n "
@@ -159,7 +159,7 @@ public class HtmlReport extends SimpleHtmlReport {
159159 + " source: edge.v,\n "
160160 + " target: edge.w,\n "
161161 + " color: graphlibGraph.edge(edge).color || 'white',\n "
162- + " weight: graphlibGraph.edge(edge).weight\n "
162+ + " weight: graphlibGraph.edge(edge).weight, \n "
163163 + " });\n "
164164 + " });\n "
165165 + "\n "
@@ -183,90 +183,86 @@ public class HtmlReport extends SimpleHtmlReport {
183183 + " b.links.push(link);\n "
184184 + " });\n "
185185 + "\n "
186- + " const highlightNodes = new Set();\n "
187- + " const highlightLinks = new Set();\n "
188- + " let hoverNode = null;\n "
189- + "\n "
190- + " // ForceGraph3D()(container)\n "
191- + " // .graphData({ nodes: nodes, links: links })\n "
192- + " // .nodeLabel('id')\n "
193- + " // .nodeAutoColorBy('color')\n "
194- + " // .linkAutoColorBy('color')\n "
195- + " // .linkDirectionalArrowLength(3.5)\n "
196- + " // .linkDirectionalArrowRelPos(1)\n "
197- + " // .width(container.clientWidth)\n "
198- + " // .height(container.clientHeight);\n "
199- + "\n "
200186 + " const Graph = new ForceGraph3D(container)\n "
201187 + " .graphData(gData)\n "
202188 + " .nodeLabel('id')\n "
203- + " // uncomment when adding highlight control GUI\n "
204- + " // .nodeColor(node => highlightNodes.has(node) ? node === hoverNode ? 'rgb(255,0,0,1)' : 'rgba(255,160,0,0.8)' : 'rgba(0,255,255,0.6)')\n "
205- + " // .linkWidth(link => highlightLinks.has(link) ? 4 : 1)\n "
206- + " // .linkDirectionalParticles(link => highlightLinks.has(link) ? 4 : 0)\n "
207- + " .linkDirectionalParticleWidth(4)\n "
208189 + " .width(container.clientWidth)\n "
209- + " .height(container.clientHeight)\n "
210- + " .nodeThreeObject(node => {\n "
211- + " // use node labels instead of spheres\n "
190+ + " .height(container.clientHeight);\n "
191+ + "\n "
192+ + " if(gData.links.length + gData.nodes.length < 4000) {\n "
193+ + " console.log(gData.links.length + gData.nodes.length);\n "
194+ + "\n "
195+ + "\n "
196+ + " // use node labels instead of spheres\n "
197+ + " Graph.nodeThreeObject(node => {\n "
212198 + " const sprite = new SpriteText(node.id);\n "
213199 + " sprite.material.depthWrite = false; // make sprite background transparent\n "
214200 + " sprite.color = node.color;\n "
215201 + " sprite.textHeight = 4;\n "
216202 + " return sprite;\n "
217- + " })\n "
218- + " // code to display weight as link text - may be too much for browsers to handle\n "
219- + " .linkThreeObjectExtend(true)\n "
220- + " .linkThreeObject(link => {\n "
221- + " // extend link with text sprite\n "
222- + " const sprite = new SpriteText(`${link.weight}`);\n "
223- + " sprite.color = 'lightgrey';\n "
224- + " sprite.textHeight = 3;\n "
225- + " return sprite;\n "
226- + " })\n "
227- + " .linkPositionUpdate((sprite, { start, end }) => {\n "
228- + " const middlePos = Object.assign(...['x', 'y', 'z'].map(c => ({\n "
229- + " [c]: start[c] + (end[c] - start[c]) / 2 // calc middle point\n "
230- + " })));\n "
203+ + " });\n "
204+ + "\n "
205+ + " // code to display weight as link text\n "
206+ + " // may be too much for browsers to handle\n "
207+ + " // Graph\n "
208+ + " // .linkThreeObjectExtend(true)\n "
209+ + " // .linkThreeObject(link => {\n "
210+ + " // // extend link with text sprite\n "
211+ + " // const sprite = new SpriteText(`${link.weight}`);\n "
212+ + " // sprite.color = 'lightgrey';\n "
213+ + " // sprite.textHeight = 3;\n "
214+ + " // return sprite;\n "
215+ + " // })\n "
216+ + " // .linkPositionUpdate((sprite, {start, end}) => {\n "
217+ + " // const middlePos = Object.assign(...['x', 'y', 'z'].map(c => ({\n "
218+ + " // [c]: start[c] + (end[c] - start[c]) / 2 // calc middle point\n "
219+ + " // })));\n "
220+ + " //\n "
221+ + " // // Position sprite\n "
222+ + " // Object.assign(sprite.position, middlePos);\n "
223+ + " // });\n "
224+ + "\n "
231225 + "\n "
232- + " // Position sprite\n "
233- + " Object.assign(sprite.position, middlePos);\n "
234- + " })\n "
235226 + " // code to highlight nodes & links\n "
236227 + " // TODO: enable via control - see Manipulate Link Force Distance for example\n "
237- + " // .onNodeHover(node => {\n "
238- + " // // no state change\n "
239- + " // if ((!node && !highlightNodes.size) || (node && hoverNode === node)) return;\n "
240- + " //\n "
241- + " // highlightNodes.clear();\n "
242- + " // highlightLinks.clear();\n "
243- + " // if (node) {\n "
244- + " // highlightNodes.add(node);\n "
245- + " // node.neighbors.forEach(neighbor => highlightNodes.add(neighbor));\n "
246- + " // node.links.forEach(link => highlightLinks.add(link));\n "
247- + " // }\n "
248- + " //\n "
249- + " // hoverNode = node || null;\n "
250- + " //\n "
251- + " // updateHighlight(Graph);\n "
252- + " // })\n "
253- + " // .onLinkHover(link => {\n "
254- + " // highlightNodes.clear();\n "
255- + " // highlightLinks.clear();\n "
256- + " //\n "
257- + " // if (link) {\n "
258- + " // highlightLinks.add(link);\n "
259- + " // highlightNodes.add(link.source);\n "
260- + " // highlightNodes.add(link.target);\n "
261- + " // }\n "
262- + " //\n "
263- + " // updateHighlight(Graph);\n "
264- + " // })\n "
265- + " ;\n "
228+ + " const highlightNodes = new Set();\n "
229+ + " const highlightLinks = new Set();\n "
230+ + " let hoverNode = null;\n "
231+ + " Graph\n "
232+ + " .nodeColor(node => highlightNodes.has(node) ? node === hoverNode ? 'rgb(255,0,0,1)' : 'rgba(255,160,0,0.8)' : 'rgba(0,255,255,0.6)')\n "
233+ + " .linkWidth(link => highlightLinks.has(link) ? 4 : 1)\n "
234+ + " .linkDirectionalParticles(link => highlightLinks.has(link) ? 4 : 0)\n "
235+ + " .linkDirectionalParticleWidth(4)\n "
236+ + " .onNodeHover(node => {\n "
237+ + " // no state change\n "
238+ + " if ((!node && !highlightNodes.size) || (node && hoverNode === node)) return;\n "
266239 + "\n "
267- + " Graph\n "
268- + " .d3Force('link')\n "
269- + " .distance(link => (1/link.weight) * 200);\n "
240+ + " highlightNodes.clear();\n "
241+ + " highlightLinks.clear();\n "
242+ + " if (node) {\n "
243+ + " highlightNodes.add(node);\n "
244+ + " node.neighbors.forEach(neighbor => highlightNodes.add(neighbor));\n "
245+ + " node.links.forEach(link => highlightLinks.add(link));\n "
246+ + " }\n "
247+ + "\n "
248+ + " hoverNode = node || null;\n "
249+ + "\n "
250+ + " updateHighlight(Graph);\n "
251+ + " })\n "
252+ + " .onLinkHover(link => {\n "
253+ + " highlightNodes.clear();\n "
254+ + " highlightLinks.clear();\n "
255+ + "\n "
256+ + " if (link) {\n "
257+ + " highlightLinks.add(link);\n "
258+ + " highlightNodes.add(link.source);\n "
259+ + " highlightNodes.add(link.target);\n "
260+ + " }\n "
261+ + "\n "
262+ + " updateHighlight(Graph);\n "
263+ + " });\n "
264+ + "\n "
265+ + " }\n "
270266 + " }\n "
271267 + "\n "
272268 + " // used by highlighting functionality\n "
@@ -279,7 +275,7 @@ public class HtmlReport extends SimpleHtmlReport {
279275 + " }\n "
280276 + "\n "
281277 + " // needed to allow the button to open the graph\n "
282- + " window.createForceGraph = createForceGraph;\n "
278+ + " window.createForceGraph = createForceGraph;"
283279 + " </script>" ;
284280
285281 // Created by generative AI and modified
@@ -527,7 +523,7 @@ public String renderClassGraphDotImage() {
527523 stringBuilder .append ("</script>\n " );
528524 } else {
529525 // revisit and add D3 SVG popup button
530- stringBuilder .append ("<div align=\" center\" >\n Map is too big to render SVG quickly</div>\n " );
526+ stringBuilder .append ("<div align=\" center\" >\n Class Map SVG is too big to render SVG quickly</div>\n " );
531527 }
532528
533529 return stringBuilder .toString ();
@@ -614,7 +610,8 @@ public String renderCycleDotImage(RankedCycle cycle) {
614610 stringBuilder .append ("</script>\n " );
615611 } else {
616612 // revisit and add D3 SVG popup button
617- stringBuilder .append ("<div align=\" center\" >\n Cycle is too big to render SVG quickly</div>\n " );
613+ stringBuilder .append (
614+ "<div align=\" center\" >\n Cycle " + cycleName + " SVG is too big to render SVG quickly</div>\n " );
618615 }
619616
620617 stringBuilder .append ("<br/>\n " );
0 commit comments