import {
Group,
Text as SkiaText,
type SkFont,
} from "@shopify/react-native-skia";
import { useDerivedValue } from "react-native-reanimated";
import type { ChartPadding } from "../draw/line";
import type { MultiEngineState } from "../core/useLiveChartEngine";
const LABEL_GAP = 8;
function SeriesValueLabelAtIndex({
index,
engine,
padding,
color,
font,
dotRadius,
}: {
index: number;
engine: MultiEngineState;
padding: ChartPadding;
color: string;
font: SkFont;
dotRadius: number;
}) {
const labelX = useDerivedValue(() => {
const w = engine.canvasWidth.value;
if (w === 0) return -200;
return w - padding.right + dotRadius + LABEL_GAP;
});
const labelY = useDerivedValue(() => {
const h = engine.canvasHeight.value;
if (h === 0) return -200;
const s = engine.series.value;
const displays = engine.displaySeriesValues.value;
if (index >= s.length) return -200;
const chartH = h - padding.top - padding.bottom;
const dMin = engine.displayMin.value;
const dMax = engine.displayMax.value;
const valRange = dMax - dMin;
const v = displays[index] ?? s[index].value;
const y =
valRange === 0
? padding.top + chartH / 2
: padding.top + ((dMax - v) / valRange) * chartH;
const fm = font.getMetrics();
return y - (fm.ascent + fm.descent) / 2;
});
const text = useDerivedValue(() => {
const s = engine.series.value;
if (index >= s.length) return "";
return s[index].label ?? s[index].id;
});
const opacity = useDerivedValue(() => {
const s = engine.series.value;
const op = engine.seriesOpacities.value;
if (index >= s.length || index >= op.length) return 0;
return op[index] ?? 0;
});
return (
);
}
export function MultiSeriesValueLabels({
engine,
padding,
colors,
font,
dotRadius,
seriesCount,
}: {
engine: MultiEngineState;
padding: ChartPadding;
colors: string[];
font: SkFont;
dotRadius: number;
/** Number of live series slots to mount. */
seriesCount: number;
}) {
return (
{Array.from({ length: seriesCount }, (_, i) => (
))}
);
}