Skip to content

Commit 2fe30b0

Browse files
committed
Improved the angled label renderer so they don't get cut off and we get tick marks
1 parent b138709 commit 2fe30b0

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

apps/webapp/app/components/code/QueryResultsChart.tsx

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ export const QueryResultsChart = memo(function QueryResultsChart({
884884

885885
// Determine appropriate angle for X-axis labels based on granularity
886886
const xAxisAngle = timeGranularity === "hours" || timeGranularity === "seconds" ? -45 : 0;
887-
const xAxisHeight = xAxisAngle !== 0 ? 60 : undefined;
887+
const xAxisHeight = xAxisAngle !== 0 ? 65 : undefined;
888888

889889
// Check if the data would produce duplicate labels at the current granularity.
890890
// Only use the custom tick renderer (with interval:0) when duplicates exist,
@@ -901,11 +901,10 @@ export const QueryResultsChart = memo(function QueryResultsChart({
901901
return labels.size < data.length;
902902
}, [isDateBased, timeGranularity, data, xDataKey]);
903903

904-
// Custom tick renderer for date-based axes: shows either a text label or
905-
// a small tick mark, but never both. This avoids duplicate labels while
906-
// still giving visual markers for unlabelled data points.
904+
// Custom tick renderer for date-based axes: renders a tick mark alongside
905+
// each label, and for unlabelled points (de-duplicated) just a subtle tick mark.
907906
const dateAxisTick = useMemo(() => {
908-
if (!isDateBased || !xAxisTickFormatter || !hasDuplicateLabels) return undefined;
907+
if (!isDateBased || !xAxisTickFormatter) return undefined;
909908
return (props: Record<string, unknown>) => {
910909
const { x, y, payload } = props as { x: number; y: number; payload: { value: number } };
911910
const label = xAxisTickFormatter(payload.value);
@@ -914,16 +913,25 @@ export const QueryResultsChart = memo(function QueryResultsChart({
914913
if (label) {
915914
return (
916915
<g>
917-
<line x1={x as number} y1={axisY} x2={x as number} y2={axisY - 3} stroke="#878C99" strokeWidth={1} />
916+
<line
917+
x1={x as number}
918+
y1={axisY}
919+
x2={x as number}
920+
y2={axisY - 3}
921+
stroke="#878C99"
922+
strokeWidth={1}
923+
/>
918924
<text
919925
x={x}
920926
y={axisY}
921-
dy={16}
927+
dy={10}
922928
fill="#878C99"
923929
fontSize={11}
924930
textAnchor={xAxisAngle !== 0 ? "end" : "middle"}
925931
style={{ fontVariantNumeric: "tabular-nums" }}
926-
transform={xAxisAngle !== 0 ? `rotate(${xAxisAngle}, ${x}, ${axisY + 16})` : undefined}
932+
transform={
933+
xAxisAngle !== 0 ? `rotate(${xAxisAngle}, ${x}, ${axisY + 10})` : undefined
934+
}
927935
>
928936
{label}
929937
</text>
@@ -942,7 +950,7 @@ export const QueryResultsChart = memo(function QueryResultsChart({
942950
/>
943951
);
944952
};
945-
}, [isDateBased, xAxisTickFormatter, xAxisAngle, hasDuplicateLabels]);
953+
}, [isDateBased, xAxisTickFormatter, xAxisAngle]);
946954

947955
// Validation — all hooks must be above this point
948956
if (!xAxisColumn) {
@@ -964,7 +972,14 @@ export const QueryResultsChart = memo(function QueryResultsChart({
964972
// Base x-axis props shared by all chart types
965973
const baseXAxisProps = {
966974
...(dateAxisTick
967-
? { tick: dateAxisTick, tickLine: false, tickFormatter: undefined, interval: 0 }
975+
? {
976+
tick: dateAxisTick,
977+
tickLine: false,
978+
tickFormatter: undefined,
979+
// Only force every tick to render when there are duplicates to de-duplicate;
980+
// otherwise let Recharts auto-space to avoid label collisions
981+
...(hasDuplicateLabels ? { interval: 0 } : {}),
982+
}
968983
: { tickFormatter: xAxisTickFormatter }),
969984
angle: xAxisAngle,
970985
textAnchor: xAxisAngle !== 0 ? ("end" as const) : ("middle" as const),

0 commit comments

Comments
 (0)