1
+ import { ScaleLinear , ScaleTime } from 'd3-scale'
1
2
import React from 'react'
2
3
3
- import { Axis as VisAxis } from '@visx/axis'
4
- import { GridRows , GridColumns } from '@visx/grid'
5
- import { Line } from '@visx/shape'
6
-
7
4
import { Axis } from '../types'
8
- import { translate } from '../utils/Utils'
5
+ import { getTickPx , translate } from '../utils/Utils'
6
+ import useChartContext from '../utils/chartContext'
9
7
//
10
8
import useMeasure from './AxisLinear.useMeasure'
11
- import useChartContext from './Chart'
12
9
13
10
export default function AxisLinearComp < TDatum > ( axis : Axis < TDatum > ) {
14
11
const [ showRotated , setShowRotated ] = React . useState ( false )
@@ -31,12 +28,46 @@ export default function AxisLinearComp<TDatum>(axis: Axis<TDatum>) {
31
28
setShowRotated,
32
29
} )
33
30
34
- const GridComponent = axis . isVertical ? GridRows : GridColumns
35
-
36
31
const renderAxis = ( isOuter : boolean ) => {
37
32
const isRotated = ! isOuter && showRotated
38
33
39
34
const scale = isOuter ? axis . outerScale : axis . scale
35
+ const [ rangeStart , rangeEnd ] = scale . range ( )
36
+
37
+ const getTicks = (
38
+ scale : ScaleTime < any , any > | ScaleLinear < any , any > ,
39
+ num : number
40
+ ) => {
41
+ if ( scale . ticks ) {
42
+ return scale . ticks ( num )
43
+ }
44
+
45
+ return scale . domain ( )
46
+ }
47
+
48
+ const resolvedHeight = isOuter ? height : gridDimensions . gridHeight
49
+ const resolvedWidth = isOuter ? width : gridDimensions . gridWidth
50
+
51
+ const [ lineFrom , lineTo ] =
52
+ axis . position === 'left'
53
+ ? [
54
+ { x : 0 , y : rangeStart } ,
55
+ { x : 0 , y : rangeEnd } ,
56
+ ]
57
+ : axis . position === 'right'
58
+ ? [
59
+ { x : resolvedWidth , y : rangeStart } ,
60
+ { x : resolvedWidth , y : rangeEnd } ,
61
+ ]
62
+ : axis . position === 'top'
63
+ ? [
64
+ { x : rangeStart , y : 0 } ,
65
+ { x : rangeEnd , y : 0 } ,
66
+ ]
67
+ : [
68
+ { x : rangeStart , y : resolvedHeight } ,
69
+ { x : rangeEnd , y : resolvedHeight } ,
70
+ ]
40
71
41
72
return (
42
73
< g
@@ -48,119 +79,120 @@ export default function AxisLinearComp<TDatum>(axis: Axis<TDatum>) {
48
79
: translate ( gridDimensions . gridX , gridDimensions . gridY ) ,
49
80
} }
50
81
>
51
- { axis . showGrid && ! isOuter ? (
52
- < GridComponent
53
- { ...{
54
- scale : scale ,
55
- stroke : dark ? 'rgba(255,255,255, .05)' : 'rgba(0,0,0, .05)' ,
56
- height : ! axis . isVertical ? gridDimensions . gridHeight : 0 ,
57
- width : axis . isVertical ? gridDimensions . gridWidth : 0 ,
58
- } }
59
- />
60
- ) : null }
61
- < VisAxis
62
- { ...{
63
- scale,
64
- orientation : axis . position ,
65
- top :
66
- axis . position === 'bottom'
67
- ? isOuter
68
- ? height
69
- : gridDimensions . gridHeight
70
- : undefined ,
71
- left :
72
- axis . position === 'right'
73
- ? isOuter
74
- ? width
75
- : gridDimensions . gridWidth
76
- : undefined ,
77
- // tickLength: axis.tickSizeOuter,
82
+ < g
83
+ className = { `Axis` }
84
+ style = { {
85
+ ...( isOuter
86
+ ? {
87
+ opacity : showDebugAxes ? 0.5 : 0 ,
88
+ pointerEvents : 'none' ,
89
+ }
90
+ : {
91
+ opacity : 1 ,
92
+ pointerEvents : 'all' ,
93
+ } ) ,
78
94
} }
79
95
>
80
- { props => {
96
+ < line
97
+ className = "domain"
98
+ x1 = { lineFrom . x }
99
+ y1 = { lineFrom . y }
100
+ x2 = { lineTo . x }
101
+ y2 = { lineTo . y }
102
+ stroke = { dark ? 'rgba(255,255,255, .2)' : 'rgba(0,0,0, .2)' }
103
+ />
104
+ { getTicks ( scale as ScaleTime < any , any > , 10 ) . map ( ( tick , i ) => {
105
+ const px = getTickPx ( scale , tick )
106
+
107
+ const [ tickFrom , tickTo , gridTo ] =
108
+ axis . position === 'left'
109
+ ? [
110
+ { x : 0 , y : px } ,
111
+ { x : - 8 , y : px } ,
112
+ { x : resolvedWidth , y : px } ,
113
+ ]
114
+ : axis . position === 'right'
115
+ ? [
116
+ { x : resolvedWidth , y : px } ,
117
+ { x : resolvedWidth + 8 , y : px } ,
118
+ { x : 0 , y : px } ,
119
+ ]
120
+ : axis . position === 'top'
121
+ ? [
122
+ { x : px , y : 0 } ,
123
+ { x : px , y : - 8 } ,
124
+ { x : px , y : resolvedHeight } ,
125
+ ]
126
+ : [
127
+ { x : px , y : resolvedHeight } ,
128
+ { x : px , y : resolvedHeight + 8 } ,
129
+ { x : px , y : 0 } ,
130
+ ]
131
+
132
+ let { x : tickLabelX , y : tickLabelY } = tickTo
133
+
134
+ if ( axis . position === 'top' ) {
135
+ tickLabelY -= 5
136
+ } else if ( axis . position === 'bottom' ) {
137
+ tickLabelY += 5
138
+ } else if ( axis . position === 'left' ) {
139
+ tickLabelX -= 5
140
+ } else if ( axis . position === 'right' ) {
141
+ tickLabelX += 5
142
+ }
143
+
81
144
return (
82
- < g
83
- className = { `Axis` }
84
- style = { {
85
- ...( isOuter
86
- ? {
87
- opacity : showDebugAxes ? 0.5 : 0 ,
88
- pointerEvents : 'none' ,
89
- }
90
- : {
91
- opacity : 1 ,
92
- pointerEvents : 'all' ,
93
- } ) ,
94
- } }
95
- >
96
- < Line
97
- className = "domain"
98
- from = { props . axisFromPoint }
99
- to = { props . axisToPoint }
100
- stroke = { dark ? 'rgba(255,255,255, .2)' : 'rgba(0,0,0, .2)' }
101
- // strokeWidth={props.strokeWidth}
102
- // strokeDasharray={props.strokeDasharray}
103
- />
104
- { props . ticks . map ( ( tick , i ) => {
105
- let tickX = tick . to . x
106
- let tickY = tick . to . y
107
-
108
- if ( axis . position === 'top' ) {
109
- tickY -= props . tickLength ?? 0
110
- } else if ( axis . position === 'bottom' ) {
111
- tickY += props . tickLength ?? 0
112
- } else if ( axis . position === 'left' ) {
113
- tickX -= props . tickLength ?? 0
114
- } else if ( axis . position === 'right' ) {
115
- tickX += props . tickLength ?? 0
116
- }
117
-
118
- return (
119
- < g key = { `vx-tick-${ tick . value } -${ i } ` } className = { 'tick' } >
120
- { ! isOuter ? (
121
- < Line
122
- from = { tick . from }
123
- to = { tick . to }
124
- stroke = {
125
- dark ? 'rgba(255,255,255, .2)' : 'rgba(0,0,0, .2)'
126
- }
127
- />
128
- ) : null }
129
- < text
130
- className = "tickLabel"
131
- style = { {
132
- fontSize : 10 ,
133
- fill : dark
134
- ? 'rgba(255,255,255, .7)'
135
- : 'rgba(0,0,0, .7)' ,
136
- dominantBaseline : isRotated
137
- ? 'central'
138
- : axis . position === 'bottom'
139
- ? 'hanging'
140
- : axis . position === 'top'
141
- ? 'alphabetic'
142
- : 'central' ,
143
- textAnchor : isRotated
144
- ? 'end'
145
- : axis . position === 'right'
146
- ? 'start'
147
- : axis . position === 'left'
148
- ? 'end'
149
- : 'middle' ,
150
- } }
151
- transform = { `translate(${ tickX } , ${ tickY } ) rotate(${
152
- isRotated ? ( axis . position === 'top' ? 60 : - 60 ) : 0
153
- } )`}
154
- >
155
- { tick . formattedValue }
156
- </ text >
157
- </ g >
158
- )
159
- } ) }
145
+ < g key = { `vx-tick-${ tick } -${ i } ` } className = { 'tick' } >
146
+ { ( axis . showGrid ?? true ) && ! isOuter ? (
147
+ < line
148
+ x1 = { tickFrom . x }
149
+ y1 = { tickFrom . y }
150
+ x2 = { gridTo . x }
151
+ y2 = { gridTo . y }
152
+ stroke = {
153
+ dark ? 'rgba(255,255,255, .05)' : 'rgba(0,0,0, .05)'
154
+ }
155
+ />
156
+ ) : null }
157
+ { ! isOuter ? (
158
+ < line
159
+ x1 = { tickFrom . x }
160
+ y1 = { tickFrom . y }
161
+ x2 = { tickTo . x }
162
+ y2 = { tickTo . y }
163
+ stroke = { dark ? 'rgba(255,255,255, .2)' : 'rgba(0,0,0, .2)' }
164
+ />
165
+ ) : null }
166
+ < text
167
+ className = "tickLabel"
168
+ style = { {
169
+ fontSize : 10 ,
170
+ fill : dark ? 'rgba(255,255,255, .7)' : 'rgba(0,0,0, .7)' ,
171
+ dominantBaseline : isRotated
172
+ ? 'central'
173
+ : axis . position === 'bottom'
174
+ ? 'hanging'
175
+ : axis . position === 'top'
176
+ ? 'alphabetic'
177
+ : 'central' ,
178
+ textAnchor : isRotated
179
+ ? 'end'
180
+ : axis . position === 'right'
181
+ ? 'start'
182
+ : axis . position === 'left'
183
+ ? 'end'
184
+ : 'middle' ,
185
+ } }
186
+ transform = { `translate(${ tickLabelX } , ${ tickLabelY } ) rotate(${
187
+ isRotated ? ( axis . position === 'top' ? 60 : - 60 ) : 0
188
+ } )`}
189
+ >
190
+ { axis . format ( tick as any ) }
191
+ </ text >
160
192
</ g >
161
193
)
162
- } }
163
- </ VisAxis >
194
+ } ) }
195
+ </ g >
164
196
</ g >
165
197
)
166
198
}
0 commit comments