UNPKG

react-native-chart-kit

Version:

Beautiful React Native charts for dashboards, reports, and data-rich mobile apps.

88 lines (87 loc) 3.22 kB
export const lineChartTooltipLineHeight = 18; export const lineChartTooltipLabelLineHeight = 16; const clamp = (value, min, max) => { if (max < min) { return min; } return Math.min(Math.max(value, min), max); }; export const easeLineChartTooltipPosition = (progress) => { const clampedProgress = clamp(progress, 0, 1); return 1 - Math.pow(1 - clampedProgress, 3); }; export const interpolateLineChartTooltipPosition = ({ from, progress, to }) => { const easedProgress = easeLineChartTooltipPosition(progress); return { x: from.x + (to.x - from.x) * easedProgress, y: from.y + (to.y - from.y) * easedProgress }; }; const getTooltipX = ({ chartWidth, edgePadding, anchorX, leftInset = edgePadding, width }) => clamp(anchorX - width / 2, leftInset, chartWidth - width - edgePadding); const getTooltipY = ({ anchorY, chartHeight, config, height, plotY }) => { const minY = config.edgePadding; const maxY = chartHeight - height - config.edgePadding; const aboveY = anchorY - height - config.offset; const belowY = anchorY + config.offset; if (config.placement === "above") { return clamp(aboveY, minY, maxY); } if (config.placement === "below") { return clamp(belowY, minY, maxY); } return aboveY >= plotY ? aboveY : clamp(belowY, minY, maxY); }; export const clampLineChartTooltipToViewport = (tooltip, { leftInset = 4, scrollOffset, viewportWidth }) => ({ ...tooltip, x: clamp(tooltip.x, scrollOffset + leftInset, scrollOffset + viewportWidth - tooltip.width - tooltip.config.edgePadding) }); export const getLineChartTooltipModel = ({ chartHeight, chartWidth, config, measureText, plotX, plotY, selection, theme }) => { if (!config.visible || selection.series.length === 0) { return undefined; } const series = config.shared ? selection.series : selection.series.slice(0, 1); const labelWidth = measureText(selection.xLabel, { fontSize: config.labelFontSize }).width; const seriesTextWidths = series.map((item) => measureText(`${item.label}: ${item.formattedValue}`, { fontSize: config.fontSize }).width); const markerWidth = 12; const contentWidth = Math.max(labelWidth, ...seriesTextWidths) + markerWidth; const width = config.width ?? contentWidth + config.padding * 2; const height = config.padding * 2 + lineChartTooltipLabelLineHeight + series.length * lineChartTooltipLineHeight; const anchor = config.anchor === "pointer" && selection.pointer ? selection.pointer : selection; const x = getTooltipX({ chartWidth, edgePadding: config.edgePadding, leftInset: plotX === undefined ? config.edgePadding : Math.max(config.edgePadding, plotX + config.edgePadding), anchorX: anchor.x, width }); const y = getTooltipY({ anchorY: anchor.y, chartHeight, config, height, plotY }); return { index: selection.index, x, y, width, height, xLabel: selection.xLabel, series, config, theme }; };