Skip to content

Commit 6b45025

Browse files
iuliuvisovanzibsCopilot
authored
Fix using scroll + scrubbing together (#633)
Co-authored-by: Eli Zibin <1131641+zibs@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 51113dd commit 6b45025

File tree

4 files changed

+99
-3
lines changed

4 files changed

+99
-3
lines changed

.changeset/strange-points-train.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"example": patch
3+
"victory-native": patch
4+
---
5+
6+
all scrolling and scrubbing

example/app/scroll-scrub.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import * as React from "react";
2+
import { View } from "react-native";
3+
import {
4+
CartesianChart,
5+
Line,
6+
useChartPressState,
7+
useChartTransformState,
8+
} from "victory-native";
9+
import { Circle, useFont } from "@shopify/react-native-skia";
10+
import type { SharedValue } from "react-native-reanimated";
11+
import inter from "../assets/inter-medium.ttf";
12+
13+
export default function ScrollAndScrub() {
14+
const font = useFont(inter, 12);
15+
const { state, isActive } = useChartPressState({ x: 0, y: { highTmp: 0 } });
16+
const { state: transformState } = useChartTransformState();
17+
18+
return (
19+
<View style={{ maxHeight: 400, flex: 1 }}>
20+
<CartesianChart
21+
data={DATA}
22+
xKey="day"
23+
yKeys={["highTmp"]}
24+
axisOptions={{
25+
font,
26+
}}
27+
transformConfig={{
28+
pan: {
29+
enabled: true,
30+
dimensions: ["x"],
31+
},
32+
}}
33+
viewport={{
34+
x: [15, 30],
35+
y: [40, 85],
36+
}}
37+
chartPressState={state}
38+
transformState={transformState}
39+
>
40+
{({ points }) => (
41+
<>
42+
<Line points={points.highTmp} color="red" strokeWidth={3} />
43+
{isActive && (
44+
<ToolTip x={state.x.position} y={state.y.highTmp.position} />
45+
)}
46+
</>
47+
)}
48+
</CartesianChart>
49+
</View>
50+
);
51+
}
52+
53+
function ToolTip({ x, y }: { x: SharedValue<number>; y: SharedValue<number> }) {
54+
return <Circle cx={x} cy={y} r={8} color="black" />;
55+
}
56+
57+
const DATA = Array.from({ length: 31 }, (_, i) => ({
58+
day: i,
59+
highTmp: 40 + 30 * Math.random(),
60+
}));

example/consts/routes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ export const ChartRoutes: {
153153
description: "Show example of scrolling chart data.",
154154
path: "/scroll",
155155
},
156+
{
157+
title: "Scroll + Scrub",
158+
description: "Show example of scrolling/panning + scrubbing chart values.",
159+
path: "/scroll-scrub",
160+
},
156161
{
157162
title: "Chart Refs",
158163
description: "This example demonstrates chart interactions using refs.",

lib/src/cartesian/CartesianChart.tsx

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,16 @@ function CartesianChartContent<
444444
touchMap.value[touch.id] = i;
445445

446446
v.isActive.value = true;
447-
handleTouch(v, touch.x, touch.y);
447+
448+
// [3] and [7] are the X and Y translation components of the 4x4 transformation matrix, respectively.
449+
const scrolledX = transformState?.matrix.value?.[3] || 0;
450+
const scrolledY = transformState?.matrix.value?.[7] || 0;
451+
452+
handleTouch(
453+
v,
454+
touch.absoluteX - scrolledX,
455+
touch.absoluteY - scrolledY,
456+
);
448457
} else {
449458
gestureState.value.bootstrap.push([v, touch]);
450459
}
@@ -463,7 +472,15 @@ function CartesianChartContent<
463472
touchMap.value[touch.id] = i;
464473

465474
v.isActive.value = true;
466-
handleTouch(v, touch.x, touch.y);
475+
476+
const scrolledX = transformState?.matrix.value?.[3] || 0;
477+
const scrolledY = transformState?.matrix.value?.[7] || 0;
478+
479+
handleTouch(
480+
v,
481+
touch.absoluteX - scrolledX,
482+
touch.absoluteY - scrolledY,
483+
);
467484
}
468485
})
469486
/**
@@ -488,7 +505,15 @@ function CartesianChartContent<
488505

489506
if (!v || !touch) continue;
490507
if (!v.isActive.value) v.isActive.value = true;
491-
handleTouch(v, touch.x, touch.y);
508+
509+
const scrolledX = transformState?.matrix.value?.[3] || 0;
510+
const scrolledY = transformState?.matrix.value?.[7] || 0;
511+
512+
handleTouch(
513+
v,
514+
touch.absoluteX - scrolledX,
515+
touch.absoluteY - scrolledY,
516+
);
492517
}
493518
})
494519
/**

0 commit comments

Comments
 (0)