1
1
import { useToken } from '@chakra-ui/core' ;
2
2
import * as React from 'react' ;
3
+ import { useMemo } from 'react' ;
3
4
import { clamp } from '../hooks/utils' ;
4
5
5
6
export interface PulseWaveProps {
6
7
highOffset : number | null ;
7
8
highLength : number | null ;
8
9
x : number ;
10
+ tickStart : number ;
11
+ totalLength : number ;
9
12
}
10
13
11
14
export function PulseWave ( props : PulseWaveProps ) {
12
- const { highLength, highOffset, x } = props ;
15
+ const { highLength, highOffset, x, tickStart , totalLength } = props ;
13
16
14
- const blue = useToken ( 'colors' , 'blue.300' ) ;
17
+ const [ blue , gray ] = useToken ( 'colors' , [ 'blue.300' , 'gray.300' ] ) ;
15
18
16
- const height = 80 ;
19
+ const arrowSize = 6 ;
20
+ const axisMargin = arrowSize * 2 ;
21
+
22
+ const height = 80 + 2 * axisMargin + arrowSize ;
17
23
const margin = 8 ;
18
24
19
- const lowY = height - margin ;
25
+ const lowY = height - margin - 2 * axisMargin ;
20
26
const highY = margin ;
21
27
22
- const line = ( ) => {
28
+ const axisY = height - arrowSize - axisMargin ;
29
+
30
+ const tickStep = 200 ;
31
+
32
+ const line = useMemo ( ( ) => {
23
33
if ( highOffset !== null && highLength !== null ) {
24
34
const highX = clamp ( highOffset + highLength , 0 , 100 ) ;
25
35
return (
@@ -39,7 +49,12 @@ export function PulseWave(props: PulseWaveProps) {
39
49
} else {
40
50
return < line x1 = "0" y1 = { lowY } x2 = "100%" y2 = { lowY } /> ;
41
51
}
42
- } ;
52
+ } , [ highLength , highOffset , highY , lowY ] ) ;
53
+
54
+ const ticks = useMemo ( ( ) => {
55
+ const nTicks = Math . floor ( ( totalLength - tickStart ) / tickStep ) ;
56
+ return [ ...Array ( nTicks ) . keys ( ) ] . map ( x => tickStart + tickStep * x ) ;
57
+ } , [ tickStart , totalLength ] ) ;
43
58
44
59
return (
45
60
< svg
@@ -50,7 +65,46 @@ export function PulseWave(props: PulseWaveProps) {
50
65
shapeRendering = "crispedges"
51
66
style = { { clipPath : `inset(0 ${ 100 - x } % 0 0)` } }
52
67
>
53
- < g stroke = { blue } > { line ( ) } </ g >
68
+ < g stroke = { blue } > { line } </ g >
69
+ < g stroke = { gray } strokeWidth = "2" >
70
+ < line x1 = "0" x2 = "100%" y1 = { axisY } y2 = { axisY } />
71
+ < line
72
+ x1 = "0"
73
+ x2 = { arrowSize }
74
+ y1 = { axisY - axisMargin / 2 }
75
+ y2 = { axisY }
76
+ style = { { transform : `translate(calc(100% - ${ arrowSize } px))` } }
77
+ />
78
+ < line
79
+ x1 = { arrowSize }
80
+ x2 = "0"
81
+ y1 = { axisY }
82
+ y2 = { axisY + axisMargin / 2 }
83
+ style = { { transform : `translate(calc(100% - ${ arrowSize } px))` } }
84
+ />
85
+
86
+ { ticks . map ( x => (
87
+ < g key = { x } >
88
+ < line
89
+ x1 = { `${ ( x * 100 ) / totalLength } %` }
90
+ x2 = { `${ ( x * 100 ) / totalLength } %` }
91
+ y1 = { axisY }
92
+ y2 = { axisY - axisMargin / 2 }
93
+ />
94
+ < text
95
+ x = { `${ ( x * 100 ) / totalLength } %` }
96
+ y = { axisY + axisMargin }
97
+ textAnchor = "middle"
98
+ dominantBaseline = "middle"
99
+ strokeWidth = "0"
100
+ fontSize = "small"
101
+ fill = { gray }
102
+ >
103
+ { x }
104
+ </ text >
105
+ </ g >
106
+ ) ) }
107
+ </ g >
54
108
</ svg >
55
109
) ;
56
110
}
0 commit comments