Can you get the position of the last xposition value I drew on the chart?
Opened this issue · 5 comments
@zibs Thank you for commenting on my issue
It seems to be a different matter from the issue.
When Line Chart was loaded and drawn
I need xPosition Value for the last value of the data I put in the chart
The render prop value of
points
here would have that information -- is that useful?
I am managing the current value like the code below.
When the chart is rendered, you want the ActiveValueIndicator rendered with the value of showTooltip to be on the far right of the line.
This is why the last xPosition value was required when it was loaded
However, there is no solution to the points value because it has returned to undefined.
<CartesianChart
data={GLUCOSE_DATA}
xKey="rcdTime"
padding={{ top: 70, right: 20, left: 10 }}
yKeys={['glucoseVal']}
domain={{ y: [0, 230] }}
chartPressState={[firstTouch]}
axisOptions={{
font,
axisSide: { x: 'bottom', y: 'right' },
tickCount: { x: 4, y: 2 },
labelOffset: { x: 4, y: 12 },
formatXLabel: value => convertMinutesToTime(value),
}}
renderOutside={({ chartBounds, points }) => (
<>
{isFirstPressActive && (
<>
<ActiveValueIndicator
xPosition={firstTouch.x.position}
yPosition={firstTouch.y.glucoseVal.position}
bottom={chartBounds.bottom}
top={chartBounds.top}
firstTouch={firstTouch}
activeValue={firstTouch.y.glucoseVal.value}
textColor={'#fafafa'}
lineColor={'#71717a'}
indicatorColor={'#7ee17e'}
/>
</>
)}
{showTooltip && (
<>
<ActiveValueIndicator
xInitialPosition={chartBounds.right}
xPosition={firstTouch.x.position}
yPosition={firstTouch.y.glucoseVal.position}
bottom={chartBounds.bottom}
top={chartBounds.top}
firstTouch={firstTouch}
activeValue={firstTouch.y.glucoseVal.value}
firstTouchFlag={firstTouchFlag}
textColor={'#fafafa'}
lineColor={'#71717a'}
indicatorColor={'#7ee17e'}
xPositionTime={firstTouch.x.value.value}
lastGluData={GLUCOSE_LAST_DATA}
lastGluTime={GLUCOSE_LAST_TIME}
/>
</>
)}
{
<Rect
x={10}
y={150}
height={60}
width={chartBounds.right - 10}
color={'rgba(237, 248, 255, 0.5)'}
></Rect>
}
</>
)}
>... </CartesianChart>
@LESANF By using useSharedValue for managing the x and y positions, you ensure that these values are always up-to-date, even when the points value is undefined initially.
import { useSharedValue } from 'react-native-reanimated';
const chartBoundsV = useSharedValue<ChartBounds>({ bottom: 0, left: 0, right: 0, top: 0 });
const positionX = useSharedValue(0);
const positionY = useSharedValue(0);
Here's how you can manage the ActiveValueIndicator based on the active state and ensure the tooltip follows the touch position and moves to the end when the touch ends:
renderOutside={({ chartBounds }) => {
return (
<ActiveValueIndicator
xPosition={isActive ? state.x.position : positionX}
yPosition={isActive ? state.y.close?.position : positionY}
chartBounds={chartBounds}
lineColor={colors.action}
indicatorColor={colors.action}>
{activeValueIndicatorChildren(chartBounds)}
</ActiveValueIndicator>
);
}}
{({ chartBounds, points }) => {
chartBoundsV.value = chartBounds;
positionX.value = points.close[points.close.length - 1].x;
positionY.value = points.close[points.close.length - 1].y ?? 0;
return <GradientArea color={colors.action} points={points.close} chartBounds={chartBounds} />;
}}
If you want to add an external tooltip that both follows the position you press and moves to the end when you finish pressing, you can do something like this. I found this solution, and I hope it helps.
const closePositionYRect = useDerivedValue(() => {
return Math.min(
(isActive ? state.y.close?.position.value : positionY.value) - RECT_TOP_MARGIN,
chartBoundsV.value.bottom - TOTAL_MARGIN - FONT_DEFAULT_HEIGHT * 2,
);
}, [isActive, state.y.close?.position.value, positionY.value, chartBoundsV.value.bottom]);
const activeValueIndicatorChildren = (chartBounds: ChartBounds) => {
const rectX = chartBounds.right + MARGIN_BETWEEN_CHART_AND_BOX;
return (
<>
<RoundedRect
color={'#00A2E8'}
width={activeCloseRectWidth}
height={RECT_HEIGHT}
r={RECT_RADIUS}
x={rectX}
y={closePositionYRect}
/>
</>
);
};