@@ -27,13 +27,28 @@ <h2 id="sidebar-title">No node selected</h2>
2727
2828 const BASE_NODE_SIZE = 10 ;
2929
30- function escapeHtml ( value ) {
31- return String ( value || '' )
32- . replace ( / & / g, '&' )
33- . replace ( / < / g, '<' )
34- . replace ( / > / g, '>' )
35- . replace ( / " / g, '"' )
36- . replace ( / ' / g, ''' ) ;
30+ function isNodeInViewport ( node ) {
31+ const nodeBoundingBox = node . renderedBoundingBox ( ) ;
32+ const container = node . cy ( ) . container ( ) ;
33+
34+ const viewportWidth = container . clientWidth ;
35+ const viewportHeight = container . clientHeight ;
36+
37+ return ! (
38+ nodeBoundingBox . x1 < 0 ||
39+ nodeBoundingBox . x2 > viewportWidth ||
40+ nodeBoundingBox . y1 < 0 ||
41+ nodeBoundingBox . y2 > viewportHeight
42+ ) ;
43+ }
44+
45+ function ensureNodeInView ( node ) {
46+ if ( ! isNodeInViewport ( node ) ) {
47+ node . cy ( ) . animate ( {
48+ center : { eles : node } ,
49+ duration : 500
50+ } ) ;
51+ }
3752 }
3853
3954 function renderEntityDetails ( node ) {
@@ -42,18 +57,34 @@ <h2 id="sidebar-title">No node selected</h2>
4257 const aliasEdges = node . connectedEdges ( 'edge[edge_type="alias"]' ) ;
4358 const aliasNodes = aliasEdges . connectedNodes ( 'node[type="alias"]' ) ;
4459 const aliasCount = aliasNodes . length ;
60+
4561 sidebarTitle . textContent =
4662 data . label
4763 + ` (${ aliasCount } alias${ aliasCount !== 1 ? 'es' : '' } )` ;
48-
64+
4965 if ( aliasCount === 0 ) {
5066 details . innerHTML = '<p>No aliases available.</p>' ;
5167 } else {
5268 const aliasList = aliasNodes . map ( aliasNode => {
5369 const aliasLabel = aliasNode . data ( 'label' ) ;
54- return `<li>${ escapeHtml ( aliasLabel ) } </li>` ;
70+ return `<li><a href="#" data-alias-id=" ${ aliasNode . id ( ) } "> ${ aliasLabel } </a> </li>` ;
5571 } ) . join ( '' ) ;
5672 details . innerHTML = `<ul>${ aliasList } </ul>` ;
73+
74+ document . querySelectorAll ( '#node-details li a[data-alias-id]' ) . forEach ( item => {
75+ item . addEventListener ( 'click' , ( e ) => {
76+ const aliasId = e . target . getAttribute ( 'data-alias-id' ) ;
77+ if ( aliasId ) {
78+ const cy = node . cy ( ) ;
79+ const aliasNode = cy . getElementById ( aliasId ) ;
80+ if ( aliasNode . length > 0 ) {
81+ cy . elements ( ) . unselect ( ) ;
82+ aliasNode . select ( ) ;
83+ ensureNodeInView ( aliasNode ) ;
84+ }
85+ }
86+ } ) ;
87+ } ) ;
5788 }
5889 }
5990
@@ -70,11 +101,10 @@ <h2 id="sidebar-title">No node selected</h2>
70101 }
71102 else {
72103 details . innerHTML = occurrences . map ( item => {
73- const link = escapeHtml ( item . link ) ;
74104 const context = item . context ;
75105 return `
76106 <section>
77- <p><a href="${ link } " target="_blank" rel="noopener noreferrer">View on GOV.UK</a></p>
107+ <p><a href="${ item . link } " target="_blank" rel="noopener noreferrer">View on GOV.UK</a></p>
78108 <p>${ context } </p>
79109 </section>
80110 ` ;
@@ -178,8 +208,8 @@ <h2 id="sidebar-title">No node selected</h2>
178208 {
179209 selector : ':selected' ,
180210 style : {
181- 'border-width' : 0 .5,
182- 'border-color' : '#10b981 '
211+ 'border-width' : 1 .5,
212+ 'border-color' : '#ffdd00 '
183213 }
184214 }
185215 ] ,
@@ -193,7 +223,7 @@ <h2 id="sidebar-title">No node selected</h2>
193223 }
194224 } ) ;
195225
196- cy . on ( 'tap ' , 'node' , ( event ) => {
226+ cy . on ( 'select ' , 'node' , ( event ) => {
197227 renderNodeDetails ( event . target ) ;
198228 } ) ;
199229
0 commit comments