I'm working with Victory Native XL and trying to implement a custom tooltip (ActiveValueIndicator) using SkiaText from @shopify/react-native-skia. The goal is to display the value inside a card-like container (similar to a Paper.Card look) when interacting with the chart.
I currently have this working with SkiaText, but I'm struggling to style it like a card with background color, rounded corners, and padding. I understand that using Skia components is necessary, but I'm unsure how to replicate the card effect effectively.
const ActiveValueIndicator = ({
xPosition,
yPosition,
top,
bottom,
activeValue,
textColor,
lineColor,
indicatorColor,
topOffset = 0,
prefix = "",
suffix = "",
decimalPlaces = 2,
index = 0,
}) => {
const FONT_SIZE = 16;
const LINE_SPACING = FONT_SIZE + 4;
const themeColors = useTheme();
const font = useFont(inter, FONT_SIZE);
const start = useDerivedValue(() => vec(xPosition.value, bottom));
const end = useDerivedValue(() =>
vec(xPosition.value, top + 1.5 * FONT_SIZE + topOffset)
);
const activeValueDisplay = useDerivedValue(
() => `${prefix} ${activeValue.value.toFixed(decimalPlaces)} ${suffix}`
);
const activeValueWidth = useDerivedValue(
() => font?.measureText(activeValueDisplay.value).width || 0
);
const activeValueX = useDerivedValue(
() => xPosition.value - activeValueWidth.value / 2
);
return (
<>
<SkiaLine p1={start} p2={end} color={lineColor} strokeWidth={2} />
<Circle cx={xPosition} cy={yPosition} r={4} color={indicatorColor} />
<Circle
cx={xPosition}
cy={yPosition}
r={3}
color={themeColors.colors.onBackground}
/>
<SkiaText
color={textColor}
font={font}
text={activeValueDisplay}
x={activeValueX}
//y={top + FONT_SIZE + topOffset + index * LINE_SPACING} // Dynamic offset
y={top - FONT_SIZE - topOffset - index * LINE_SPACING}
/>
</>
);
};
<CartesianChart
data={chartData}
xKey="x"
yKeys={yKeys}
padding={{ top: 50, bottom: 15, left: 15, right: 15 }}
chartPressState={[firstTouch]}
xAxis={{
font: robotoLightFont,
labelColor: labelColor,
labelOffset: 0,
tickCount: 5,
axisSide: "bottom",
lineColor: "transparent",
labelPosition: "inset",
formatXLabel: (value) => formatXLabel(value),
}}
yAxis={[
{
font: robotoLightFont,
labelColor: labelColor,
labelOffset: 5,
//tickCount: 5,
axisSide: "left",
lineColor: themeColors.colors.text,
labelPosition: "outset",
formatYLabel: (value) => `${Math.round(value)}`,
domain: [0, maxYValue],
tickValues: tickValues,
},
]}
domainPadding={10}
renderOutside={({ chartBounds, points }) => (
<>
{isFirstPressActive &&
yKeys.map((key, index) => {
const config = yAxisConfig[key] || {};
return (
<ActiveValueIndicator
key={`indicator-${key}`}
xPosition={firstTouch.x.position}
yPosition={firstTouch.y[key]?.position ?? 0}
activeValue={firstTouch.y[key]?.value ?? 0}
bottom={chartBounds.bottom}
top={chartBounds.top}
textColor={labelColor}
lineColor={lineColor}
indicatorColor={config.color || "#000"} // Dynamic color
prefix={config.prefix || ""}
suffix={config.suffix || ""}
decimalPlaces={config.decimalPlaces ?? 2} // Dynamic decimals
index={index}
/>
);
})}
</>
)}
/>
I'm working with Victory Native XL and trying to implement a custom tooltip (ActiveValueIndicator) using SkiaText from @shopify/react-native-skia. The goal is to display the value inside a card-like container (similar to a Paper.Card look) when interacting with the chart.
I currently have this working with SkiaText, but I'm struggling to style it like a card with background color, rounded corners, and padding. I understand that using Skia components is necessary, but I'm unsure how to replicate the card effect effectively.
My current implemeantion: