11import React from 'react'
22import useChartState from '../hooks/useChartState'
33import useIsomorphicLayoutEffect from '../hooks/useIsomorphicLayoutEffect'
4- import usePrevious from '../hooks/usePrevious '
4+ import { axisTypeOrdinal } from '../utils/Constants '
55import { round } from '../utils/Utils'
66
7- const radiansToDegrees = r => r * ( 180 / Math . PI )
8- const degreesToRadians = d => d * ( Math . PI / 180 )
9-
107const getElBox = el => {
118 var rect = el . getBoundingClientRect ( )
129 return {
@@ -30,8 +27,6 @@ export default function useMeasure({
3027 position,
3128 tickSizeInner,
3229 tickSizeOuter,
33- transform,
34- barSize,
3530 labelRotation,
3631 tickPadding,
3732 tickCount,
@@ -40,19 +35,20 @@ export default function useMeasure({
4035 vertical,
4136 gridWidth,
4237 gridHeight,
43- ticks,
44- scale,
4538} ) {
46- const disallowListRef = React . useRef ( [ ] )
47- const axisDimensionsHistoryRef = React . useRef ( [ ] )
48-
49- const [ axisDimensions , setChartState ] = useChartState (
50- state => state . axisDimensions
39+ const [ estimatedTickCount , setChartState ] = useChartState (
40+ state => state . estimatedTickCounts [ id ]
41+ )
42+ const [ tickLabelSkipRatio ] = useChartState (
43+ state => state . tickLabelSkipRatios [ id ]
44+ )
45+ const [ axisDimension ] = useChartState (
46+ state => state . axisDimensions ?. [ position ] ?. [ id ]
5147 )
5248
5349 const measureDimensions = React . useCallback ( ( ) => {
5450 if ( ! elRef . current ) {
55- if ( axisDimensions [ position ] ?. [ id ] ) {
51+ if ( axisDimension ) {
5652 // If the entire axis is hidden, then we need to remove the axis dimensions
5753 setChartState ( state => {
5854 const newAxes = state . axisDimensions [ position ] || { }
@@ -70,30 +66,13 @@ export default function useMeasure({
7066 }
7167
7268 let gridSize = ! vertical ? gridWidth : gridHeight
73- let calculatedTickCount = tickCount
7469 let width = 0
7570 let height = 0
7671 let top = 0
7772 let bottom = 0
7873 let left = 0
7974 let right = 0
8075
81- // Measure the distances between ticks
82- let smallestTickGap = gridSize // This is just a ridiculously large tick spacing that would never happen (hopefully)
83-
84- Array ( ...elRef . current . querySelectorAll ( '.tick' ) )
85- . map ( el => getElBox ( el ) )
86- . reduce ( ( prev , current ) => {
87- if ( prev ) {
88- smallestTickGap = Math . min (
89- smallestTickGap ,
90- vertical ? current . top - prev . top : current . left - prev . left
91- )
92- }
93-
94- return current
95- } , false )
96-
9776 const domainDims = getElBox ( elRef . current . querySelector ( '.domain' ) )
9877
9978 const measureLabelDims = Array (
@@ -134,26 +113,70 @@ export default function useMeasure({
134113 [ ]
135114 )
136115
137- // Auto-fit ticks in "auto" tick mode
138- if ( tickCount === 'auto' && type !== 'ordinal' ) {
139- const largestMeasureLabelSize = ! vertical
140- ? widestMeasureLabel ?. width || 0
141- : tallestMeasureLabel ?. height || 0
116+ let smallestTickGap = gridSize
117+
118+ if ( measureLabelDims . length > 1 ) {
119+ measureLabelDims . reduce ( ( prev , current ) => {
120+ if ( prev ) {
121+ smallestTickGap = Math . min (
122+ smallestTickGap ,
123+ vertical ? current . top - prev . top : current . left - prev . left
124+ )
125+ }
126+
127+ return current
128+ } , false )
129+ }
142130
131+ const largestMeasureLabelSize = ! vertical
132+ ? widestMeasureLabel ?. width || 0
133+ : tallestMeasureLabel ?. height || 0
134+
135+ // Auto-fit ticks in "auto" tick mode for non-ordinal scales
136+ if ( tickCount === 'auto' && type !== 'ordinal' ) {
143137 // if it's on, determine how many ticks we could display if they were all flat
144138 // How many ticks can we fit in the available axis space?
145- const estimatedTickCount = Math . floor (
146- ( gridSize + largestMeasureLabelSize + tickPadding ) /
147- ( largestMeasureLabelSize + tickPadding )
139+ let calculatedTickCount = Math . floor (
140+ ( gridSize + largestMeasureLabelSize + tickPadding * 2 ) /
141+ ( largestMeasureLabelSize + tickPadding * 2 )
148142 )
149143
150144 calculatedTickCount = Math . max (
151- Math . min ( estimatedTickCount , maxTickCount ) ,
145+ Math . min ( calculatedTickCount , maxTickCount ) ,
152146 minTickCount
153147 )
148+
149+ if ( calculatedTickCount !== estimatedTickCount ) {
150+ setChartState ( old => ( {
151+ ...old ,
152+ estimatedTickCounts : {
153+ ...old . estimatedTickCounts ,
154+ [ id ] : calculatedTickCount ,
155+ } ,
156+ } ) )
157+ }
154158 }
155159
156- if ( ! vertical ) {
160+ // Visual Skipping of axis labels if they overlap (rotation not included)
161+ const newTickLabelSkipRatio = ! rotation
162+ ? Math . max (
163+ 1 ,
164+ Math . ceil ( ( largestMeasureLabelSize + tickPadding ) / smallestTickGap )
165+ )
166+ : 1
167+
168+ if ( newTickLabelSkipRatio !== tickLabelSkipRatio ) {
169+ setChartState ( old => ( {
170+ ...old ,
171+ tickLabelSkipRatios : {
172+ ...old . tickLabelSkipRatios ,
173+ [ id ] : newTickLabelSkipRatio ,
174+ } ,
175+ } ) )
176+ }
177+
178+ // Rotate ticks for non-time horizontal axes
179+ if ( ! vertical && type === axisTypeOrdinal ) {
157180 const newRotation =
158181 ( widestMeasureLabel ?. width || 0 ) + tickPadding > smallestTickGap
159182 ? labelRotation
@@ -166,12 +189,16 @@ export default function useMeasure({
166189
167190 // Axis overflow measurements
168191 if ( ! vertical ) {
169- const leftMostLabelDim = realLabelDims . reduce ( ( d , labelDim ) =>
170- labelDim . left < d . left ? labelDim : d
171- )
172- const rightMostLabelDim = realLabelDims . reduce ( ( d , labelDim ) =>
173- labelDim . right > d . right ? labelDim : d
174- )
192+ const leftMostLabelDim = realLabelDims . length
193+ ? realLabelDims . reduce ( ( d , labelDim ) =>
194+ labelDim . left < d . left ? labelDim : d
195+ )
196+ : null
197+ const rightMostLabelDim = realLabelDims . length
198+ ? realLabelDims . reduce ( ( d , labelDim ) =>
199+ labelDim . right > d . right ? labelDim : d
200+ )
201+ : null
175202
176203 left = round (
177204 Math . max ( 0 , domainDims . left - leftMostLabelDim ?. left ) ,
@@ -229,14 +256,13 @@ export default function useMeasure({
229256 bottom,
230257 left,
231258 right,
232- tickCount : calculatedTickCount ,
233259 }
234260
235261 // Only update the axisDimensions if something has changed
236262 if (
237- ! axisDimensions ?. [ position ] ?. [ id ] ||
263+ ! axisDimension ||
238264 Object . keys ( newDimensions ) . some ( key => {
239- return newDimensions [ key ] !== axisDimensions [ position ] [ id ] [ key ]
265+ return newDimensions [ key ] !== axisDimension [ key ]
240266 } )
241267 ) {
242268 setChartState ( state => ( {
@@ -251,8 +277,9 @@ export default function useMeasure({
251277 } ) )
252278 }
253279 } , [
254- axisDimensions ,
280+ axisDimension ,
255281 elRef ,
282+ estimatedTickCount ,
256283 gridHeight ,
257284 gridWidth ,
258285 id ,
@@ -264,6 +291,7 @@ export default function useMeasure({
264291 setChartState ,
265292 setRotation ,
266293 tickCount ,
294+ tickLabelSkipRatio ,
267295 tickPadding ,
268296 tickSizeInner ,
269297 tickSizeOuter ,
0 commit comments