diff --git a/packages/charts/api/charts.api.md b/packages/charts/api/charts.api.md index 4ad1580f16..3e1c496457 100644 --- a/packages/charts/api/charts.api.md +++ b/packages/charts/api/charts.api.md @@ -626,7 +626,7 @@ export const DEFAULT_TOOLTIP_SNAP = true; export const DEFAULT_TOOLTIP_TYPE: "vertical"; // @public (undocumented) -export type DefaultSettingsProps = 'id' | 'chartType' | 'specType' | 'rendering' | 'rotation' | 'resizeDebounce' | 'pointerUpdateDebounce' | 'pointerUpdateTrigger' | 'animateData' | 'debug' | 'tooltip' | 'theme' | 'brushAxis' | 'minBrushDelta' | 'externalPointerEvents' | 'showLegend' | 'showLegendExtra' | 'legendPosition' | 'legendMaxDepth' | 'ariaUseDefaultSummary' | 'ariaLabelHeadingLevel' | 'ariaTableCaption'; +export type DefaultSettingsProps = 'id' | 'chartType' | 'specType' | 'rendering' | 'rotation' | 'resizeDebounce' | 'pointerUpdateDebounce' | 'pointerUpdateTrigger' | 'animateData' | 'debug' | 'tooltip' | 'theme' | 'brushAxis' | 'minBrushDelta' | 'externalPointerEvents' | 'showLegend' | 'showLegendExtra' | 'legendPosition' | 'legendMaxDepth' | 'ariaUseDefaultSummary' | 'ariaLabelHeadingLevel' | 'ariaTableCaption' | 'allowBrushingLastHistogramBin'; // @public (undocumented) export const DEPTH_KEY = "depth"; @@ -1850,7 +1850,7 @@ export const Settings: React_2.FunctionComponent; // @public export interface SettingsSpec extends Spec, LegendSpec { - allowBrushingLastHistogramBucket?: boolean; + allowBrushingLastHistogramBin: boolean; // (undocumented) animateData: boolean; ariaDescribedBy?: string; diff --git a/packages/charts/src/chart_types/xy_chart/state/selectors/on_brush_end_caller.ts b/packages/charts/src/chart_types/xy_chart/state/selectors/on_brush_end_caller.ts index f8e1ebff15..dcd76bab02 100644 --- a/packages/charts/src/chart_types/xy_chart/state/selectors/on_brush_end_caller.ts +++ b/packages/charts/src/chart_types/xy_chart/state/selectors/on_brush_end_caller.ts @@ -10,7 +10,7 @@ import { Selector } from 'reselect'; import { ChartType } from '../../..'; import { Scale } from '../../../../scales'; -import { GroupBrushExtent, XYBrushEvent } from '../../../../specs'; +import { GroupBrushExtent, SeriesSpecs, XYBrushEvent } from '../../../../specs'; import { BrushAxis } from '../../../../specs/constants'; import { DragState, GlobalChartState } from '../../../../state/chart_state'; import { createCustomCachedSelector } from '../../../../state/create_selector'; @@ -19,11 +19,13 @@ import { clamp, Rotation } from '../../../../utils/common'; import { Dimensions } from '../../../../utils/dimensions'; import { hasDragged, DragCheckProps } from '../../../../utils/events'; import { GroupId } from '../../../../utils/ids'; +import { isHistogramEnabled } from '../../domains/y_domain'; import { isVerticalRotation } from '../utils/common'; import { computeChartDimensionsSelector } from './compute_chart_dimensions'; import { computeSmallMultipleScalesSelector, SmallMultipleScales } from './compute_small_multiple_scales'; import { getPlotAreaRestrictedPoint, getPointsConstraintToSinglePanel, PanelPoints } from './get_brush_area'; import { getComputedScalesSelector } from './get_computed_scales'; +import { getSeriesSpecsSelector } from './get_specs'; import { isBrushAvailableSelector } from './is_brush_available'; import { isHistogramModeEnabledSelector } from './is_histogram_mode_enabled'; @@ -53,21 +55,16 @@ export function createOnBrushEndCaller(): (state: GlobalChartState) => void { computeChartDimensionsSelector, isHistogramModeEnabledSelector, computeSmallMultipleScalesSelector, + getSeriesSpecsSelector, ], ( lastDrag, - { - onBrushEnd, - rotation, - brushAxis, - minBrushDelta, - roundHistogramBrushValues, - allowBrushingLastHistogramBucket, - }, + { onBrushEnd, rotation, brushAxis, minBrushDelta, roundHistogramBrushValues, allowBrushingLastHistogramBin }, computedScales, { chartDimensions }, histogramMode, smallMultipleScales, + seriesSpec, ): void => { const nextProps = { lastDrag, @@ -85,9 +82,10 @@ export function createOnBrushEndCaller(): (state: GlobalChartState) => void { histogramMode, xScale as Scale, smallMultipleScales, + allowBrushingLastHistogramBin, + seriesSpec, minBrushDelta, roundHistogramBrushValues, - allowBrushingLastHistogramBucket, ); } if (brushAxis === BrushAxis.Y || brushAxis === BrushAxis.Both) { @@ -136,9 +134,10 @@ function getXBrushExtent( histogramMode: boolean, xScale: Scale, smallMultipleScales: SmallMultipleScales, + allowBrushingLastHistogramBin: boolean, + seriesSpecs: SeriesSpecs, minBrushDelta?: number, roundHistogramBrushValues?: boolean, - allowBrushingLastHistogramBucket?: boolean, ): [number, number] | undefined { const isXHorizontal = !isVerticalRotation(rotation); // scale screen coordinates down to panel scale @@ -153,15 +152,16 @@ function getXBrushExtent( // if 0 size brush, avoid computing the value return; } - const offset = histogramMode ? 0 : -(xScale.bandwidth + xScale.bandwidthPadding) / 2; - const invertValue = roundHistogramBrushValues - ? (value: number) => xScale.invertWithStep(value, xScale.domain).value - : (value: number) => xScale.invert(value); + const histogramEnabled = isHistogramEnabled(seriesSpecs); + const invertValue = + histogramEnabled && roundHistogramBrushValues + ? (value: number) => xScale.invertWithStep(value, xScale.domain).value + : (value: number) => xScale.invert(value); const minPosScaled = invertValue(minPos + offset); const maxPosScaled = invertValue(maxPos + offset); - - const maxDomainValue = xScale.domain[1] + (allowBrushingLastHistogramBucket ? xScale.minInterval : 0); + const maxDomainValue = + xScale.domain[1] + (histogramEnabled && allowBrushingLastHistogramBin ? xScale.minInterval : 0); const minValue = clamp(minPosScaled, xScale.domain[0], maxPosScaled); const maxValue = clamp(minPosScaled, maxPosScaled, maxDomainValue); diff --git a/packages/charts/src/components/__snapshots__/chart.test.tsx.snap b/packages/charts/src/components/__snapshots__/chart.test.tsx.snap index 80974fa4b7..d0682a2ccf 100644 --- a/packages/charts/src/components/__snapshots__/chart.test.tsx.snap +++ b/packages/charts/src/components/__snapshots__/chart.test.tsx.snap @@ -56,7 +56,7 @@ exports[`Chart should render the legend name test 1`] = ` - + diff --git a/packages/charts/src/specs/constants.ts b/packages/charts/src/specs/constants.ts index 1cedd90613..39b39beeca 100644 --- a/packages/charts/src/specs/constants.ts +++ b/packages/charts/src/specs/constants.ts @@ -181,5 +181,6 @@ export const DEFAULT_SETTINGS_SPEC: SettingsSpec = { minBrushDelta: 2, ariaUseDefaultSummary: true, ariaLabelHeadingLevel: 'p', + allowBrushingLastHistogramBin: true, ...DEFAULT_LEGEND_CONFIG, }; diff --git a/packages/charts/src/specs/settings.tsx b/packages/charts/src/specs/settings.tsx index f2bd1ac208..a5be1c5cfa 100644 --- a/packages/charts/src/specs/settings.tsx +++ b/packages/charts/src/specs/settings.tsx @@ -582,16 +582,16 @@ export interface SettingsSpec extends Spec, LegendSpec { roundHistogramBrushValues?: boolean; /** * Boolean to allow brushing on last bucket even when outside domain or limit to end of domain. - * + * Should apply only for histogram charts * e.g. * A brush selection range of [1.23, 3.6] with a domain of [1, 2, 3] * * - when true returns [1.23, 3.6] * - when false returns [1.23, 3] * - * @defaultValue false + * @defaultValue true */ - allowBrushingLastHistogramBucket?: boolean; + allowBrushingLastHistogramBin: boolean; /** * Orders ordinal x values */ @@ -704,7 +704,8 @@ export type DefaultSettingsProps = | 'legendMaxDepth' | 'ariaUseDefaultSummary' | 'ariaLabelHeadingLevel' - | 'ariaTableCaption'; + | 'ariaTableCaption' + | 'allowBrushingLastHistogramBin'; /** @public */ export type SettingsSpecProps = Partial>; diff --git a/storybook/stories/interactions/10a_brush_selection_bar_hist.story.tsx b/storybook/stories/interactions/10a_brush_selection_bar_hist.story.tsx index 8b7285a50b..4be3d82f7c 100644 --- a/storybook/stories/interactions/10a_brush_selection_bar_hist.story.tsx +++ b/storybook/stories/interactions/10a_brush_selection_bar_hist.story.tsx @@ -22,7 +22,7 @@ export const Example = () => ( onBrushEnd={action('onBrushEnd')} rotation={getChartRotationKnob()} roundHistogramBrushValues={boolean('roundHistogramBrushValues', false)} - allowBrushingLastHistogramBucket={boolean('allowBrushingLastHistogramBucket', false)} + allowBrushingLastHistogramBin={boolean('allowBrushingLastHistogramBin', true)} /> Number(d).toFixed(2)} /> diff --git a/storybook/stories/interactions/12_brush_time_hist.story.tsx b/storybook/stories/interactions/12_brush_time_hist.story.tsx index dd6b865cb4..7c5cfd9d5a 100644 --- a/storybook/stories/interactions/12_brush_time_hist.story.tsx +++ b/storybook/stories/interactions/12_brush_time_hist.story.tsx @@ -48,7 +48,7 @@ export const Example = () => { onElementClick={action('onElementClick')} rotation={getChartRotationKnob()} roundHistogramBrushValues={boolean('roundHistogramBrushValues', false)} - allowBrushingLastHistogramBucket={boolean('allowBrushingLastHistogramBucket', false)} + allowBrushingLastHistogramBin={boolean('allowBrushingLastHistogramBin', true)} />