@@ -12,10 +12,29 @@ interactively.
12
12
*/
13
13
14
14
import React from "react"
15
+ import { styled } from "@material-ui/core/styles"
15
16
16
- const ARROW_WIDTH = 2
17
17
const X_SEP_DIST = 5
18
- const Y_SEP_DIST = 12
18
+ const Y_SEP_DIST = 16
19
+
20
+ const ArrowLabel = styled ( "div" ) ( {
21
+ position : "absolute" ,
22
+ transform : "translate(-50%,0%)" ,
23
+ padding : 1 ,
24
+ paddingLeft : 4 ,
25
+ paddingRight : 4 ,
26
+ fontSize : 11 ,
27
+ color : "#fff" ,
28
+ border : "1px solid rgba(0,0,0,0.2)" ,
29
+ // transition: "transform 120ms",
30
+ borderRadius : 4 ,
31
+ fontWeight : "bold" ,
32
+ "&:hover" : {
33
+ zIndex : 999 ,
34
+ cursor : "pointer" ,
35
+ transform : "translate(-50%, 0%) scale(1.05,1.05)"
36
+ }
37
+ } )
19
38
20
39
export const RelationshipArrows = ( { positions, arrows, rowHeight = 100 } ) => {
21
40
const constraintGroups : Array <
@@ -28,6 +47,8 @@ export const RelationshipArrows = ({ positions, arrows, rowHeight = 100 }) => {
28
47
for ( const arrow of arrows ) {
29
48
const { from, to, label } = arrow
30
49
50
+ if ( ! positions [ from ] || ! positions [ to ] ) return null
51
+
31
52
const p1 = positions [ from ] . offset
32
53
const p2 = positions [ to ] . offset
33
54
@@ -55,7 +76,8 @@ export const RelationshipArrows = ({ positions, arrows, rowHeight = 100 }) => {
55
76
weight : Math . abs ( xDist ) ,
56
77
width : Math . abs ( p1 . left + p1 . width / 2 - p2 . left - p2 . width / 2 ) ,
57
78
centerX : ( p1 . left + p2 . left + p1 . width / 2 + p2 . width / 2 ) / 2 ,
58
- y
79
+ y,
80
+ hasLabel : true
59
81
} ,
60
82
{
61
83
type : "vertical" ,
@@ -85,7 +107,8 @@ export const RelationshipArrows = ({ positions, arrows, rowHeight = 100 }) => {
85
107
weight : Math . abs ( xDist ) ,
86
108
width : Math . abs ( p1 . left + p1 . width / 2 - p2 . left - p2 . width / 2 ) ,
87
109
centerX : ( p1 . left + p2 . left + p1 . width / 2 + p2 . width / 2 ) / 2 ,
88
- y
110
+ y,
111
+ hasLabel : true
89
112
} ,
90
113
{
91
114
type : "vertical" ,
@@ -121,7 +144,8 @@ export const RelationshipArrows = ({ positions, arrows, rowHeight = 100 }) => {
121
144
weight : Math . abs ( xDist ) ,
122
145
width : Math . abs ( p1 . left + p1 . width / 2 - p2 . left - p2 . width / 2 ) ,
123
146
centerX : ( p1 . left + x1 + p1 . width / 2 ) / 2 ,
124
- y : y1
147
+ y : y1 ,
148
+ hasLabel : true
125
149
} ,
126
150
{
127
151
type : "vertical" ,
@@ -263,51 +287,77 @@ export const RelationshipArrows = ({ positions, arrows, rowHeight = 100 }) => {
263
287
linePoints . push ( points )
264
288
}
265
289
290
+ const labelPositions = constraintGroups . map ( ( group , i ) => {
291
+ const labelConstraintIndex = group . findIndex ( c => c . hasLabel )
292
+ const p1 = linePoints [ i ] [ labelConstraintIndex ]
293
+ const p2 = linePoints [ i ] [ labelConstraintIndex + 1 ]
294
+ return [ ( p1 [ 0 ] + p2 [ 0 ] ) / 2 , ( p1 [ 1 ] + p2 [ 1 ] ) / 2 ]
295
+ } )
296
+
266
297
const svgOffset = { x : 100 , y : 100 }
267
298
268
299
return (
269
- < svg width = "600" height = "600" >
270
- < defs >
271
- { arrows . map ( ( arrow , i ) => (
272
- < marker
273
- id = { "arrowhead" + i }
274
- markerWidth = "5"
275
- markerHeight = "5"
276
- refX = "0"
277
- refY = "2.5"
278
- orient = "auto"
279
- >
280
- < polygon fill = { arrow . color || "#000" } points = "0 0, 6 2.5, 0 5" />
281
- </ marker >
300
+ < div
301
+ style = { {
302
+ position : "absolute" ,
303
+ left : - svgOffset . x ,
304
+ top : - svgOffset . y
305
+ } }
306
+ >
307
+ < svg width = "600" height = "600" >
308
+ < defs >
309
+ { arrows . map ( ( arrow , i ) => (
310
+ < marker
311
+ id = { "arrowhead" + i }
312
+ markerWidth = "5"
313
+ markerHeight = "5"
314
+ refX = "0"
315
+ refY = "2.5"
316
+ orient = "auto"
317
+ >
318
+ < polygon fill = { arrow . color || "#000" } points = "0 0, 6 2.5, 0 5" />
319
+ </ marker >
320
+ ) ) }
321
+ </ defs >
322
+ { linePoints . map ( ( lp , i ) => (
323
+ < polyline
324
+ key = { i }
325
+ stroke = { arrows [ i ] . color || "#000" }
326
+ fill = "none"
327
+ marker-end = { `url(#arrowhead${ i } )` }
328
+ stroke-width = "2"
329
+ points = { lp
330
+ . map (
331
+ ( [ x , y ] , i ) =>
332
+ `${ svgOffset . x + x } ,${ svgOffset . y +
333
+ y -
334
+ ( i === lp . length - 1 ? 10 : 0 ) } `
335
+ )
336
+ . join ( " " ) }
337
+ />
282
338
) ) }
283
- </ defs >
284
- { linePoints . map ( ( lp , i ) => (
285
- < polyline
286
- key = { i }
287
- stroke = { arrows [ i ] . color || "#000" }
288
- fill = "none"
289
- marker-end = { `url(#arrowhead${ i } )` }
290
- stroke-width = "2"
291
- points = { lp
292
- . map (
293
- ( [ x , y ] , i ) =>
294
- `${ svgOffset . x + x } ,${ svgOffset . y +
295
- y -
296
- ( i === lp . length - 1 ? 10 : 0 ) } `
297
- )
298
- . join ( " " ) }
299
- />
300
- ) ) }
301
- { Object . values ( positions ) . map ( p => (
302
- < rect
303
- x = { p . offset . left + svgOffset . x }
304
- y = { p . offset . top + svgOffset . y }
305
- width = { p . offset . width }
306
- height = { p . offset . height }
307
- fill = "rgba(0,0,0,0.5)"
308
- />
339
+ { Object . values ( positions ) . map ( p => (
340
+ < rect
341
+ x = { p . offset . left + svgOffset . x }
342
+ y = { p . offset . top + svgOffset . y }
343
+ width = { p . offset . width }
344
+ height = { p . offset . height }
345
+ fill = "rgba(0,0,0,0.5)"
346
+ />
347
+ ) ) }
348
+ </ svg >
349
+ { arrows . map ( ( arrow , i ) => (
350
+ < ArrowLabel
351
+ style = { {
352
+ left : svgOffset . x + labelPositions [ i ] [ 0 ] ,
353
+ top : svgOffset . y - 7 + labelPositions [ i ] [ 1 ] ,
354
+ backgroundColor : arrow . color
355
+ } }
356
+ >
357
+ arrow{ i }
358
+ </ ArrowLabel >
309
359
) ) }
310
- </ svg >
360
+ </ div >
311
361
)
312
362
}
313
363
0 commit comments