Skip to content

Commit 65fd5f3

Browse files
committed
fix: infinite render in chart measure
1 parent 4fcd362 commit 65fd5f3

File tree

9 files changed

+416
-342
lines changed

9 files changed

+416
-342
lines changed

src/components/AxisLinear.tsx

Lines changed: 162 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
import React from 'react'
1+
import React from 'react';
22
//
3-
import { translateX, translateY, translate } from '../utils/Utils'
3+
import { translateX, translateY, translate } from '../utils/Utils';
44

5-
import Path from '../primitives/Path'
6-
import Line from '../primitives/Line'
7-
import Text from '../primitives/Text'
8-
import Group from '../primitives/Group'
5+
import Path from '../primitives/Path';
6+
import Line from '../primitives/Line';
7+
import Text from '../primitives/Text';
8+
import Group from '../primitives/Group';
99

1010
import {
1111
positionTop,
1212
positionRight,
1313
positionBottom,
1414
positionLeft,
1515
axisTypeOrdinal,
16-
} from '../utils/Constants.js'
17-
import useChartContext from '../hooks/useChartContext'
18-
import useMeasure from './AxisLinear.useMeasure'
16+
} from '../utils/Constants.js';
17+
import useChartContext from '../hooks/useChartContext';
18+
import useMeasure from './AxisLinear.useMeasure';
1919

2020
const defaultStyles = {
2121
line: {
@@ -26,7 +26,7 @@ const defaultStyles = {
2626
fontSize: 10,
2727
fontFamily: 'sans-serif',
2828
},
29-
}
29+
};
3030

3131
export default function AxisLinear(axis) {
3232
const {
@@ -49,202 +49,211 @@ export default function AxisLinear(axis) {
4949
tickOffset,
5050
gridOffset,
5151
spacing,
52-
id,
53-
} = axis
54-
const [rotation, setRotation] = React.useState(0)
55-
const { gridWidth, gridHeight, dark } = useChartContext()
52+
labelRotation,
53+
} = axis;
54+
const [showRotated, setShowRotated] = React.useState(false);
55+
const [rotation, setRotation] = React.useState(0);
56+
const { gridWidth, gridHeight, dark } = useChartContext();
5657

57-
const elRef = React.useRef()
58+
const elRef = React.useRef();
5859

59-
useMeasure({ ...axis, elRef, rotation, gridWidth, gridHeight, setRotation })
60+
useMeasure({
61+
...axis,
62+
elRef,
63+
rotation,
64+
gridWidth,
65+
gridHeight,
66+
setRotation,
67+
showRotated,
68+
setShowRotated,
69+
});
6070

6171
// Not ready? Render null
6272
if (!show) {
63-
return null
73+
return null;
6474
}
6575

66-
let axisPath
76+
let axisPath;
6777
if (vertical) {
6878
if (position === positionLeft) {
6979
axisPath = `
7080
M ${-tickSizeOuter}, ${range0}
7181
H 0
7282
V ${range1}
7383
H ${-tickSizeOuter}
74-
`
84+
`;
7585
} else {
7686
axisPath = `
7787
M ${tickSizeOuter}, ${range0}
7888
H 0
7989
V ${range1}
8090
H ${tickSizeOuter}
81-
`
91+
`;
8292
}
8393
} else if (position === positionBottom) {
8494
axisPath = `
8595
M 0, ${tickSizeOuter}
8696
V 0
8797
H ${range1}
8898
V ${tickSizeOuter}
89-
`
99+
`;
90100
} else {
91101
axisPath = `
92102
M 0, ${-tickSizeOuter}
93103
V 0
94104
H ${range1}
95105
V ${-tickSizeOuter}
96-
`
106+
`;
97107
}
98108

99-
let showGridLine
109+
let showGridLine;
100110
if (typeof showGrid === 'boolean') {
101-
showGridLine = showGrid
111+
showGridLine = showGrid;
102112
} else if (type === axisTypeOrdinal) {
103-
showGridLine = false
113+
showGridLine = false;
104114
} else {
105-
showGridLine = true
115+
showGridLine = true;
106116
}
107117

108118
// Combine default styles with style props
109119
const axisStyles = {
110120
...defaultStyles,
111121
...styles,
112-
}
122+
};
113123

114-
return (
115-
<Group
116-
ref={elRef}
117-
className="Axis"
118-
style={{
119-
pointerEvents: 'none',
120-
transform:
121-
position === positionRight
122-
? translateX(gridWidth)
123-
: position === positionBottom
124-
? translateY(gridHeight)
125-
: undefined,
126-
}}
127-
>
128-
<Path
129-
className="domain"
130-
d={axisPath}
124+
const renderAxis = (isRotated: boolean) => {
125+
const show = isRotated ? showRotated : !showRotated;
126+
127+
return (
128+
<Group
129+
className={`Axis ${isRotated ? 'rotated' : 'unrotated'}`}
131130
style={{
132-
stroke: dark ? 'rgba(255,255,255, .1)' : 'rgba(0,0,0, .1)',
133-
...axisStyles.line,
131+
transform:
132+
position === positionRight
133+
? translateX(gridWidth)
134+
: position === positionBottom
135+
? translateY(gridHeight)
136+
: undefined,
137+
...(show
138+
? {
139+
opacity: 1,
140+
pointerEvents: 'all',
141+
}
142+
: {
143+
opacity: 0,
144+
pointerEvents: 'none',
145+
}),
134146
}}
135-
/>
136-
<Group className="ticks">
137-
{ticks.map((tick, i) => (
138-
<Group
139-
key={[String(tick), i].join('_')}
140-
className="tick"
141-
style={{
142-
transform: transform(scale(tick) || 0),
143-
}}
144-
>
145-
{/* Render the grid line */}
146-
{showGridLine && (
147-
<Line
148-
className="gridLine"
149-
x1={vertical ? 0 : gridOffset}
150-
x2={vertical ? scaleMax : gridOffset}
151-
y1={vertical ? gridOffset : 0}
152-
y2={vertical ? gridOffset : scaleMax}
153-
style={{
154-
stroke: dark ? 'rgba(255,255,255, .1)' : 'rgba(0,0,0, .1)',
155-
strokeWidth: 1,
156-
...axisStyles.line,
157-
}}
158-
/>
159-
)}
160-
{/* Render the tick line */}
161-
{showTicks ? (
162-
<g className="labelGroup">
147+
>
148+
<Path
149+
className="domain"
150+
d={axisPath}
151+
style={{
152+
stroke: dark ? 'rgba(255,255,255, .1)' : 'rgba(0,0,0, .1)',
153+
...axisStyles.line,
154+
}}
155+
/>
156+
<Group className="ticks">
157+
{ticks.map((tick, i) => (
158+
<Group
159+
key={[String(tick), i].join('_')}
160+
className="tick"
161+
style={{
162+
transform: transform(scale(tick) || 0),
163+
}}
164+
>
165+
{/* Render the grid line */}
166+
{showGridLine && (
163167
<Line
164-
className="tickline"
165-
x1={vertical ? 0 : tickOffset}
166-
x2={
167-
vertical ? directionMultiplier * tickSizeInner : tickOffset
168-
}
169-
y1={vertical ? tickOffset : 0}
170-
y2={
171-
vertical ? tickOffset : directionMultiplier * tickSizeInner
172-
}
168+
className="gridLine"
169+
x1={vertical ? 0 : gridOffset}
170+
x2={vertical ? scaleMax : gridOffset}
171+
y1={vertical ? gridOffset : 0}
172+
y2={vertical ? gridOffset : scaleMax}
173173
style={{
174-
stroke: dark ? 'rgba(255,255,255, .1)' : 'rgba(0,0,0, .1)',
174+
stroke: dark
175+
? 'rgba(255,255,255, .05)'
176+
: 'rgba(0,0,0, .05)',
175177
strokeWidth: 1,
176178
...axisStyles.line,
177179
}}
178180
/>
179-
<Text
180-
className="tickLabel"
181-
style={{
182-
fill: dark ? 'white' : 'black',
183-
...axisStyles.tick,
184-
transform: `${translate(
185-
vertical ? directionMultiplier * spacing : tickOffset,
186-
vertical ? tickOffset : directionMultiplier * spacing
187-
)} rotate(${-rotation}deg)`,
188-
}}
189-
dominantBaseline={
190-
rotation
191-
? 'central'
192-
: position === positionBottom
193-
? 'hanging'
194-
: position === positionTop
195-
? 'alphabetic'
196-
: 'central'
197-
}
198-
textAnchor={
199-
rotation
200-
? 'end'
201-
: position === positionRight
202-
? 'start'
203-
: position === positionLeft
204-
? 'end'
205-
: 'middle'
206-
}
207-
>
208-
{format(tick, i)}
209-
</Text>
210-
<Text
211-
className="tickLabel-measurer"
212-
style={{
213-
...axisStyles.tick,
214-
transform: `${translate(
215-
vertical ? directionMultiplier * spacing : tickOffset,
216-
vertical ? tickOffset : directionMultiplier * spacing
217-
)}`,
218-
fill: 'red',
219-
opacity: 0,
220-
pointerEvents: 'none',
221-
}}
222-
dominantBaseline={
223-
rotation
224-
? 'central'
225-
: position === positionBottom
226-
? 'hanging'
227-
: position === positionTop
228-
? 'alphabetic'
229-
: 'central'
230-
}
231-
textAnchor={
232-
rotation
233-
? 'end'
234-
: position === positionRight
235-
? 'start'
236-
: position === positionLeft
237-
? 'end'
238-
: 'middle'
239-
}
240-
>
241-
{format(tick, i)}
242-
</Text>
243-
</g>
244-
) : null}
245-
</Group>
246-
))}
181+
)}
182+
{/* Render the tick line */}
183+
{showTicks ? (
184+
<g className="labelGroup">
185+
<Line
186+
className="tickline"
187+
x1={vertical ? 0 : tickOffset}
188+
x2={
189+
vertical
190+
? directionMultiplier * tickSizeInner
191+
: tickOffset
192+
}
193+
y1={vertical ? tickOffset : 0}
194+
y2={
195+
vertical
196+
? tickOffset
197+
: directionMultiplier * tickSizeInner
198+
}
199+
style={{
200+
stroke: dark
201+
? 'rgba(255,255,255, .1)'
202+
: 'rgba(0,0,0, .1)',
203+
strokeWidth: 1,
204+
...axisStyles.line,
205+
}}
206+
/>
207+
<Text
208+
className="tickLabel"
209+
style={{
210+
fill: dark ? 'white' : 'black',
211+
...axisStyles.tick,
212+
transform: `${translate(
213+
vertical ? directionMultiplier * spacing : tickOffset,
214+
vertical ? tickOffset : directionMultiplier * spacing
215+
)} rotate(${
216+
isRotated
217+
? position === 'top'
218+
? labelRotation
219+
: -labelRotation
220+
: 0
221+
}deg)`,
222+
}}
223+
dominantBaseline={
224+
isRotated
225+
? 'central'
226+
: position === positionBottom
227+
? 'hanging'
228+
: position === positionTop
229+
? 'alphabetic'
230+
: 'central'
231+
}
232+
textAnchor={
233+
isRotated
234+
? 'end'
235+
: position === positionRight
236+
? 'start'
237+
: position === positionLeft
238+
? 'end'
239+
: 'middle'
240+
}
241+
>
242+
{format(tick, i)}
243+
</Text>
244+
</g>
245+
) : null}
246+
</Group>
247+
))}
248+
</Group>
247249
</Group>
250+
);
251+
};
252+
253+
return (
254+
<Group ref={elRef}>
255+
{renderAxis(false)}
256+
{renderAxis(true)}
248257
</Group>
249-
)
258+
);
250259
}

0 commit comments

Comments
 (0)