@@ -12,10 +12,29 @@ interactively.
1212*/
1313
1414import React from "react"
15+ import { styled } from "@material-ui/core/styles"
1516
16- const ARROW_WIDTH = 2
1717const 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+ } )
1938
2039export const RelationshipArrows = ( { positions, arrows, rowHeight = 100 } ) => {
2140 const constraintGroups : Array <
@@ -28,6 +47,8 @@ export const RelationshipArrows = ({ positions, arrows, rowHeight = 100 }) => {
2847 for ( const arrow of arrows ) {
2948 const { from, to, label } = arrow
3049
50+ if ( ! positions [ from ] || ! positions [ to ] ) return null
51+
3152 const p1 = positions [ from ] . offset
3253 const p2 = positions [ to ] . offset
3354
@@ -55,7 +76,8 @@ export const RelationshipArrows = ({ positions, arrows, rowHeight = 100 }) => {
5576 weight : Math . abs ( xDist ) ,
5677 width : Math . abs ( p1 . left + p1 . width / 2 - p2 . left - p2 . width / 2 ) ,
5778 centerX : ( p1 . left + p2 . left + p1 . width / 2 + p2 . width / 2 ) / 2 ,
58- y
79+ y,
80+ hasLabel : true
5981 } ,
6082 {
6183 type : "vertical" ,
@@ -85,7 +107,8 @@ export const RelationshipArrows = ({ positions, arrows, rowHeight = 100 }) => {
85107 weight : Math . abs ( xDist ) ,
86108 width : Math . abs ( p1 . left + p1 . width / 2 - p2 . left - p2 . width / 2 ) ,
87109 centerX : ( p1 . left + p2 . left + p1 . width / 2 + p2 . width / 2 ) / 2 ,
88- y
110+ y,
111+ hasLabel : true
89112 } ,
90113 {
91114 type : "vertical" ,
@@ -121,7 +144,8 @@ export const RelationshipArrows = ({ positions, arrows, rowHeight = 100 }) => {
121144 weight : Math . abs ( xDist ) ,
122145 width : Math . abs ( p1 . left + p1 . width / 2 - p2 . left - p2 . width / 2 ) ,
123146 centerX : ( p1 . left + x1 + p1 . width / 2 ) / 2 ,
124- y : y1
147+ y : y1 ,
148+ hasLabel : true
125149 } ,
126150 {
127151 type : "vertical" ,
@@ -263,51 +287,77 @@ export const RelationshipArrows = ({ positions, arrows, rowHeight = 100 }) => {
263287 linePoints . push ( points )
264288 }
265289
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+
266297 const svgOffset = { x : 100 , y : 100 }
267298
268299 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+ />
282338 ) ) }
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 >
309359 ) ) }
310- </ svg >
360+ </ div >
311361 )
312362}
313363
0 commit comments