@@ -6,6 +6,7 @@ const config = require("./config");
66const nx = require ( "notatrix" ) ;
77const utils = require ( "../utils" ) ;
88const v = require ( "./visualiser.js" ) ;
9+ const tree = require ( "./tree.js" ) ;
910
1011/**
1112 * Abstraction over the graph editor. Handles interaction between the graph
@@ -21,7 +22,13 @@ class Graph {
2122 this . app = app ;
2223 this . config = config ;
2324
24- this . v = v ;
25+ if ( this . app . corpus . is_vertical ) {
26+ this . grapher = tree ;
27+ }
28+ else {
29+ this . grapher = v ;
30+ }
31+
2532
2633 // keep track for our progress bar
2734 this . progress = {
@@ -63,6 +70,17 @@ class Graph {
6370 // Basically so empty nodes are easier to deal with
6471 this . presentationId = { } ;
6572
73+ // We want to block the tree view if there is no root
74+ // or if there exists a cycle.
75+ this . treeBlocked = false ;
76+
77+ // Holds all connections between nodes, making it easier
78+ // to traverse the tree.
79+ this . connections = { } ;
80+
81+ // Total number of forms (not counting supertokens)
82+ this . numTokens = 0 ;
83+
6684 // load configuration prefs
6785 this . load ( ) ;
6886 }
@@ -77,7 +95,11 @@ class Graph {
7795 * @return {Array } [Object]
7896 */
7997 get eles ( ) {
98+ // reset variables
8099 this . presentationId = { } ;
100+ this . connections = { } ;
101+ this . numTokens = 0 ;
102+
81103 // helper function to get subscripted index numbers for superTokens
82104 function toSubscript ( str ) {
83105 const subscripts = {
@@ -112,6 +134,9 @@ class Graph {
112134 this . progress . done = 0 ;
113135 this . progress . total = 0 ;
114136
137+ // reset tree blocked
138+ this . treeBlocked = false ;
139+
115140 // cache these
116141 const sent = this . app . corpus . current , format = this . app . corpus . format ;
117142
@@ -124,6 +149,8 @@ class Graph {
124149 // Counts just supertokens
125150 let mwTokenNum = 0 ;
126151
152+ let rootFound = false ;
153+
127154 // walk over all the tokens
128155 sent . index ( ) . iterate ( token => {
129156 // don't draw other analyses
@@ -136,6 +163,10 @@ class Graph {
136163 let pos = format === "CG3" ? token . xpostag || token . upostag : token . upostag || token . xpostag ;
137164 let isRoot = sent . root . dependents . has ( token ) ;
138165
166+ if ( isRoot ) {
167+ rootFound = true ;
168+ }
169+
139170 // after iteration, this will just be the max
140171 this . clumps = clump ;
141172
@@ -169,7 +200,7 @@ class Graph {
169200
170201 this . tokens [ tokenNum ] = token ;
171202
172- this . presentationId [ id ] = tokenNum ;
203+ this . presentationId [ id ] = tokenNum ;
173204
174205 eles . push (
175206 { // "form" node, including pos data
@@ -193,16 +224,22 @@ class Graph {
193224 } ,
194225 ) ;
195226 tokenNum ++ ;
227+ this . numTokens ++ ;
196228 }
197229
198230 } ) ;
199231
232+ if ( ! rootFound ) {
233+ this . treeBlocked = true ;
234+ }
235+
200236 sent . index ( ) . iterate ( token => {
201237 // iterate over the token's heads to get edges
202238 token . mapHeads ( ( head , i ) => {
203239
204- // if not enhanced, only draw the first dependency
205- if ( i && ! sent . options . enhanced )
240+ // if not enhanced or is_vertical
241+ // only draw the first dependency
242+ if ( i && ( ! sent . options . enhanced || this . app . corpus . is_vertical ) )
206243 return ;
207244
208245 this . progress . total += 1 ;
@@ -227,7 +264,18 @@ class Graph {
227264
228265 const presentId = this . presentationId [ id ] ;
229266 const presentHeadId = this . presentationId [ headId ] ;
230-
267+ let depClasses = utils . validate . depEdgeClasses ( sent , token , head ) ;
268+ if ( ! ( presentHeadId in this . connections ) ) {
269+ this . connections [ presentHeadId ] = [ ] ;
270+ }
271+ this . connections [ presentHeadId ] . push ( presentId ) ;
272+
273+ if ( depClasses . includes ( "cycle" ) ) {
274+ this . treeBlocked = true ;
275+ }
276+ if ( String ( id ) . includes ( '.' ) || String ( headId ) . includes ( '.' ) ) {
277+ depClasses += " dotted" ;
278+ }
231279 eles . push ( {
232280 id : `dep_${ presentId } _${ presentHeadId } ` ,
233281 name : `dependency` ,
@@ -242,7 +290,7 @@ class Graph {
242290 targetToken : token ,
243291 label : label ,
244292 enhanced : i ? true : false ,
245- classes : utils . validate . depEdgeClasses ( sent , token , head ) ,
293+ classes : depClasses ,
246294 } ) ;
247295 } ) ;
248296 } ) ;
@@ -258,10 +306,23 @@ class Graph {
258306 * @return {Graph } (chaining)
259307 */
260308 draw ( ) {
261- // cache a ref
309+ if ( this . app . corpus . is_vertical ) {
310+ this . grapher = tree ;
311+ }
312+ else {
313+ this . grapher = v ;
314+ }
262315
263- this . v . bind ( this ) ;
264- this . v . run ( ) ;
316+ if ( ! this . app . corpus . is_vertical || ! this . treeBlocked ) {
317+ this . grapher . bind ( this ) ;
318+ this . grapher . run ( ) ;
319+ }
320+ else {
321+ this . grapher . displayError ( ) ;
322+ console . log ( "Graph contains a cycle or needs a root." ) ;
323+ $ ( "#vertical" ) . click ( ) ;
324+ }
325+
265326
266327 // add the mice and locks from `collab`
267328 this . drawMice ( ) ;
@@ -718,7 +779,7 @@ class Graph {
718779
719780 let id = ele . attr ( "id" ) ;
720781 let sourceNum = parseInt ( id . split ( "_" ) [ 2 ] ) ;
721- let targetNum = parseInt ( id . split ( "_" ) [ 1 ] ) ;
782+ let targetNum = parseInt ( id . split ( "_" ) [ 1 ] ) ;
722783 let src = this . tokens [ sourceNum ] ;
723784 let tar = this . tokens [ targetNum ] ;
724785 tar . modifyHead ( src , deprel ) ;
@@ -751,7 +812,7 @@ class Graph {
751812 try {
752813 let id = ele . attr ( "id" ) ;
753814 let sourceNum = parseInt ( id . split ( "_" ) [ 2 ] ) ;
754- let targetNum = parseInt ( id . split ( "_" ) [ 1 ] ) ;
815+ let targetNum = parseInt ( id . split ( "_" ) [ 1 ] ) ;
755816 let src = this . tokens [ sourceNum ] ;
756817 let tar = this . tokens [ targetNum ] ;
757818 tar . removeHead ( src ) ;
@@ -1106,6 +1167,9 @@ class Graph {
11061167 target . addClass ( "input" ) ;
11071168 let textElement = $ ( '#text-' + target . attr ( 'id' ) ) ;
11081169 let textLabel = textElement . text ( ) . replace ( / [ ⊳ ⊲ ] / , '' ) ;
1170+ if ( textElement . is ( "textPath" ) ) {
1171+ textElement = $ ( '#textContainer-' + target . attr ( 'id' ) ) ;
1172+ }
11091173 let textBCR ;
11101174 if ( target . attr ( 'id' ) . includes ( 'dep' ) ) {
11111175 textBCR = textElement [ 0 ] . getBoundingClientRect ( ) ;
@@ -1163,7 +1227,7 @@ class Graph {
11631227 */
11641228 drawMice ( ) {
11651229 this . app . collab . getMouseNodes ( ) . forEach ( mouse => {
1166- this . v . drawMouse ( mouse ) ;
1230+ this . grapher . drawMouse ( mouse ) ;
11671231 } ) ;
11681232 }
11691233
0 commit comments