1- # Changes Graph
2-
3- <lively-import src =" _navigation.html " ></lively-import >
4-
51<div >
6- url <input style =" width :500px " id =" url " value =" " ><br >
7- limit <input id =" limit " >
2+ limit <input id =" limit " > url <input style =" width :500px " id =" url " value =" " ><br >
83</div >
94
105<script >
116 import Paths from " src/client/paths.js"
127 import moment from " src/external/moment.js" ;
138 import diff from ' src/external/diff-match-patch.js' ;
149 import AnsiColorFilter from " src/external/ansi-to-html.js"
15-
10+ import ViewNav from ' src/client/viewnav.js '
1611
1712
1813 class ChangesGraph {
@@ -32,7 +27,8 @@ limit <input id="limit">
3227 this .ctx = ctx
3328 var dmp = new diff.diff_match_patch ();
3429 var baseUrl = lively4url + " /"
35- var url = " https://lively-kernel.org/lively4/lively4-jens/src/client/auth-dropbox.js"
30+ // var url = "https://lively-kernel.org/lively4/lively4-jens/src/client/auth-dropbox.js"
31+ var url = " https://lively-kernel.org/lively4/lively4-jens/src/client/"
3632
3733 this .query (" input#url" ).value = url
3834 var limitElement = this .query (" input#limit" )
@@ -65,6 +61,68 @@ limit <input id="limit">
6561 var baseDataChildrenMap
6662
6763 var changes
64+
65+ let edges, nodes, selectedChange, selectedNode, fullNodes, parents
66+ let pane, svgNodes
67+
68+ const DashedEdgeStyle = ` [color="gray" style="dashed" arrowhead="open" arrowsize=.7]`
69+
70+ function key (id ) {
71+ return " _" + id .replace (/ [^ a-z0-9A-Z _] / g ," " )
72+ }
73+
74+ function addEdge (a , b , style = " " ) {
75+ edges .add (key (a) + " -> " + key (b) + style)
76+ }
77+
78+ function findConnectingPath (version , path , depth = 0 , visited = new Set ()) {
79+ if (! version) throw new Error (" version missing" )
80+ if (visited .has (version)) return
81+ visited .add (version)
82+ if (depth > 10000 ) {
83+ // addEdges(path)
84+ // console.log("stop search at depth " + depth + " path: ", path)
85+ return null
86+ }
87+ if (! path) path = [version]
88+ // console.log("findConnectionPath ", version, path)
89+ var change = baseDataMap .get (version)
90+ if (! change) {
91+ debugger
92+ return // nothing found? should this happen
93+ }
94+ var parents = change .parents .split (" " )
95+ for (var eaParentVersion of parents) {
96+ if (fullNodes .has (eaParentVersion) ) {
97+ return path .concat ([eaParentVersion]) // found something!
98+ } else {
99+ // depth first search
100+ var found = eaParentVersion && findConnectingPath (eaParentVersion, path .concat ([eaParentVersion]), depth + 1 , visited)
101+ if (found) {
102+ // console.log("found ... " + found)
103+ return found
104+ }
105+ }
106+ }
107+ return null
108+ }
109+
110+ function addEdges (path ) {
111+ var lastVersion
112+ path .forEach (ea => {
113+ if (ea && lastVersion) {
114+ addEdge (lastVersion, ea)
115+ }
116+ lastVersion = ea
117+ })
118+ }
119+
120+ function addShortPath (path ) {
121+ addEdge (path .first , path .last , DashedEdgeStyle)
122+ // var shortCut = ""+path.first + "_TO_" + path.last
123+ // addEdge(path.first, shortCut)
124+ // addEdge(shortCut, path.last)
125+ }
68126
69127 var updateTable = async () => {
70128
@@ -97,24 +155,13 @@ limit <input id="limit">
97155 changes = new Map ()
98156
99157
100- var fullNodes = new Set ()
101- var parents = new Set ()
102-
103- var DashedEdgeStyle = ` [color="gray" style="dashed" arrowhead="open" arrowsize=.7]`
158+ fullNodes = new Set ()
159+ parents = new Set ()
104160
105161
106- var edges = new Set ()
107- var nodes = []
108- var selectedChange
109- var selectedNode
110-
111- function key (id ) {
112- return " _" + id .replace (/ [^ a-z0-9A-Z _] / g ," " )
113- }
114-
115- function addEdge (a , b , style = " " ) {
116- edges .add (key (a) + " -> " + key (b) + style)
117- }
162+ edges = new Set ()
163+ nodes = []
164+
118165
119166 data .forEach (ea => {
120167 var version = ea .version
@@ -158,54 +205,7 @@ limit <input id="limit">
158205 }
159206 })
160207
161- function findConnectingPath (version , path , depth = 0 , visited = new Set ()) {
162- if (! version) throw new Error (" version missing" )
163- if (visited .has (version)) return
164- visited .add (version)
165- if (depth > 10000 ) {
166- // addEdges(path)
167- // console.log("stop search at depth " + depth + " path: ", path)
168- return null
169- }
170- if (! path) path = [version]
171- // console.log("findConnectionPath ", version, path)
172- var change = baseDataMap .get (version)
173- if (! change) {
174- debugger
175- return // nothing found? should this happen
176- }
177- var parents = change .parents .split (" " )
178- for (var eaParentVersion of parents) {
179- if (fullNodes .has (eaParentVersion) ) {
180- return path .concat ([eaParentVersion]) // found something!
181- } else {
182- // depth first search
183- var found = eaParentVersion && findConnectingPath (eaParentVersion, path .concat ([eaParentVersion]), depth + 1 , visited)
184- if (found) {
185- // console.log("found ... " + found)
186- return found
187- }
188- }
189- }
190- return null
191- }
192-
193- function addEdges (path ) {
194- var lastVersion
195- path .forEach (ea => {
196- if (ea && lastVersion) {
197- addEdge (lastVersion, ea)
198- }
199- lastVersion = ea
200- })
201- }
202-
203- function addShortPath (path ) {
204- addEdge (path .first , path .last , DashedEdgeStyle)
205- // var shortCut = ""+path.first + "_TO_" + path.last
206- // addEdge(path.first, shortCut)
207- // addEdge(shortCut, path.last)
208- }
208+
209209
210210
211211 graphviz .innerHTML = ` <` + ` script type="graphviz">digraph {
@@ -214,7 +214,11 @@ limit <input id="limit">
214214 }<` + ` /script>}`
215215 await graphviz .updateViz ()
216216
217- graphviz .shadowRoot .querySelectorAll (" g.node" ).forEach (ea => {
217+ var scrollToData = tanglingParents .first
218+
219+ svgNodes = graphviz .shadowRoot .querySelectorAll (" g.node" )
220+
221+ svgNodes .forEach (ea => {
218222 ea .addEventListener (" click" , async (evt ) => {
219223 var key = ea .querySelector (' title' ).textContent
220224 var change = changes .get (key)
@@ -224,10 +228,18 @@ limit <input id="limit">
224228 lively .openInspector ({baseDataMap, baseDataChildrenMap, change})
225229 return
226230 }
227-
231+ // hide previous selected node
228232 if (selectedNode) {
229- selectedNode .querySelector (" polygon" ).setAttribute (" fill" , " none" )
233+ selectedNode .querySelector (" polygon" ).setAttribute (" fill" , " none" )
234+ }
235+ // toggle details by clicking it
236+ if (selectedNode == ea) {
237+ selectedNode = null
238+ details .innerHTML = " "
239+ lively .setGlobalPosition (details, lively .pt (0 ,0 )) // move out of the way
240+ return
230241 }
242+
231243 selectedNode = ea
232244 selectedNode .querySelector (" polygon" ).setAttribute (" fill" , " lightgray" )
233245 selectedChange = change
@@ -242,6 +254,20 @@ limit <input id="limit">
242254 lively .setGlobalPosition (details, lively .getGlobalBounds (selectedNode).topRight ().addPt (lively .pt (10 ,0 )))
243255 })
244256 })
257+
258+ lively .sleep (0 ).then (() => {
259+ if (pane) {
260+ let pos = lively .getGlobalPosition (_ .first (svgNodes))
261+ let panePos = lively .getGlobalPosition (pane)
262+ let delta = pos .subPt (panePos)
263+ pane .scrollLeft = delta .x - lively .getExtent (pane).y / 2
264+ pane .scrollTop = delta .y - 100
265+ lively .notify (" scroll to: " + delta )
266+
267+ } else {
268+ lively .notify (" no pane to scroll into..." )
269+ }
270+ })
245271 }
246272
247273 var details = < div id= " details" >< / div>
@@ -267,13 +293,43 @@ limit <input id="limit">
267293 padding: 5px;
268294 }
269295 `
296+
297+
298+ graphviz .style .display = " inline-block" // so it takes the width of children and not parent
299+
300+ pane = < div id= " root" style= " z-index: -1; position: absolute; top: 0px; left: 0px; overflow-x: auto; overflow-y: scroll; width: calc(100% - 0px); height: calc(100% - 0px);" >
301+ {style}
302+ < div style= " height: 20px" >< / div>
303+ < h2> Change Graph< / h2>
304+ {graphviz}
305+ {details}
306+ < / div>
307+
308+
309+ var lastMove
310+ function onPanningMove (evt ) {
311+ var pos = lively .getPosition (evt)
312+ var delta = pos .subPt (lastMove)
313+ pane .scrollTop -= delta .y
314+ pane .scrollLeft -= delta .x
315+ lastMove = pos
270316
271- var div = document .createElement (" div" )
272- div .id = " root"
273- div .appendChild (style)
274- div .appendChild (graphviz)
275- div .appendChild (details)
276- return div
317+ }
318+
319+ pane .addEventListener (" pointerdown" , evt => {
320+ if (evt .ctrlKey ) {
321+ lastMove = lively .getPosition (evt)
322+ lively .addEventListener (" changegraph" , document .body .parentElement , " pointermove" , evt => onPanningMove (evt))
323+ lively .addEventListener (" changegraph" , document .body .parentElement , " pointerup" , evt => {
324+ lively .removeEventListener (" changegraph" , document .body .parentElement )
325+ })
326+ evt .stopPropagation ()
327+ evt .preventDefault ()
328+ }
329+ }, true )
330+
331+
332+ return pane
277333 }
278334 }
279335 ChangesGraph .create (this )
0 commit comments