diff --git a/examples/simple/src/components/MultipleAxes.tsx b/examples/simple/src/components/MultipleAxes.tsx index def39b0c..8c53dbce 100644 --- a/examples/simple/src/components/MultipleAxes.tsx +++ b/examples/simple/src/components/MultipleAxes.tsx @@ -17,6 +17,8 @@ export default function MultipleAxes() { >( () => ({ getValue: (datum) => datum.primary as unknown as Date, + // Pad the automatically detected time scale with half of the band-size + padBandRange: true, }), [] ); diff --git a/src/seriesTypes/Bar.tsx b/src/seriesTypes/Bar.tsx index 19d7ab2e..201b16fb 100644 --- a/src/seriesTypes/Bar.tsx +++ b/src/seriesTypes/Bar.tsx @@ -41,23 +41,13 @@ export default function BarComponent({ {series.datums.map((datum, i) => { const dataStyle = getDatumStatusStyle(datum, focusedDatum) - const x = clampPxToAxis( - 0, + const [x, width] = clampPxToAxis( getRectX(datum, primaryAxis, secondaryAxis) ?? NaN, - xAxis - ) - const y = clampPxToAxis( - 0, - getRectY(datum, primaryAxis, secondaryAxis) ?? NaN, - yAxis - ) - const width = clampPxToAxis( - x, getWidth(datum, primaryAxis, secondaryAxis) ?? NaN, xAxis ) - const height = clampPxToAxis( - y, + const [y, height] = clampPxToAxis( + getRectY(datum, primaryAxis, secondaryAxis) ?? NaN, getHeight(datum, primaryAxis, secondaryAxis) ?? NaN, yAxis ) @@ -216,12 +206,22 @@ function getSecondary( return secondaryAxis.scale(datum.secondaryValue) ?? NaN } -function clampPxToAxis(base: number, px: number, axis: Axis) { +function clampPxToAxis( + startPx: number, + lengthPx: number, + axis: Axis +) { const range = axis.scale.range() if (axis.isVertical) { range.reverse() } - return Math.max(range[0], Math.min(px, range[1] - base)) + const safe = (num: number) => Math.max(range[0], Math.min(num, range[1])) + + const safeStart = safe(startPx) + const safeEnd = safe(startPx + lengthPx) + const safeLength = safeEnd - safeStart + + return [safeStart, safeLength] as const } diff --git a/src/types.ts b/src/types.ts index e38208cf..31df2b76 100644 --- a/src/types.ts +++ b/src/types.ts @@ -267,6 +267,7 @@ export type AxisTimeOptions = AxisOptionsBase & { max?: Date hardMin?: Date hardMax?: Date + padBandRange?: boolean formatters?: { scale?: ( value: Date, diff --git a/src/utils/buildAxis.linear.ts b/src/utils/buildAxis.linear.ts index 910f17a3..6a2e1d2a 100644 --- a/src/utils/buildAxis.linear.ts +++ b/src/utils/buildAxis.linear.ts @@ -168,7 +168,7 @@ function buildTimeAxis( const outerScale = scale.copy().range(outerRange) - // Supplmentary band scale + // Supplementary band scale const primaryBandScale = isPrimary ? buildPrimaryBandScale(options, scale, series, range) : undefined @@ -177,6 +177,19 @@ function buildTimeAxis( ? buildSeriesBandScale(options, primaryBandScale, series) : undefined + const primaryBandWidth = primaryBandScale?.bandwidth() + + if (options.padBandRange && primaryBandWidth) { + const bandStart = scale.invert(0) + const bandEnd = scale.invert(primaryBandWidth) + const diff = bandEnd.valueOf() - bandStart.valueOf() + + scale.domain([ + new Date(scale.domain()[0].valueOf() - diff / 2), + new Date(scale.domain()[1].valueOf() + diff / 2), + ]) + } + const defaultFormat = scale.tickFormat() const formatters = {} as AxisTime['formatters']