From 7ab52116a71f9a389b06b996c5699274337a5e25 Mon Sep 17 00:00:00 2001 From: Marco Vettorello Date: Tue, 27 Aug 2019 19:15:35 +0200 Subject: [PATCH] fix(crosshair): limit the width of the cursor band on edges (#353) If the xDomain doesn't cover a full interval on the min or max edges, the crosshair is drawn outside the chart. This commit will fix that behaviour limiting the cursor band width and position to be always inside the chart fix #352 --- packages/osd-charts/.playground/playgroud.tsx | 13 +- .../crosshair_utils.linear_snap.test.ts | 132 ++++++++++++++++++ .../xy_chart/crosshair/crosshair_utils.ts | 24 +++- 3 files changed, 160 insertions(+), 9 deletions(-) diff --git a/packages/osd-charts/.playground/playgroud.tsx b/packages/osd-charts/.playground/playgroud.tsx index 733a395b048d..ac4abd1f26c7 100644 --- a/packages/osd-charts/.playground/playgroud.tsx +++ b/packages/osd-charts/.playground/playgroud.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Axis, Chart, getAxisId, getSpecId, Position, ScaleType, Settings, BarSeries } from '../src'; +import { Axis, Chart, getAxisId, getSpecId, Position, ScaleType, Settings, HistogramBarSeries } from '../src'; import { KIBANA_METRICS } from '../src/utils/data_samples/test_dataset_kibana'; export class Playground extends React.Component { @@ -7,10 +7,17 @@ export class Playground extends React.Component { return (
- + - { }); }); }); + + describe('BandPosition bar chart wwith limited edges', () => { + const chartDimensions: Dimensions = { top: 0, left: 0, width: 120, height: 120 }; + test('cursor at begin of domain', () => { + const barSeriesScaleLimited = computeXScale({ + xDomain: { + domain: [0.5, 3.5], + isBandScale: true, + minInterval: 1, + scaleType: ScaleType.Linear, + type: 'xDomain', + }, + totalBarsInCluster: 1, + range: [0, 120], + }); + const bandPosition = getCursorBandPosition( + 0, + chartDimensions, + { x: 0, y: 0 }, + { + value: 0, + withinBandwidth: true, + }, + true, + barSeriesScaleLimited, + 1, + ); + expect(bandPosition).toEqual({ + left: 0, + top: 0, + height: 120, + width: 15, + visible: true, + }); + }); + test('cursor at end of domain', () => { + const barSeriesScaleLimited = computeXScale({ + xDomain: { + domain: [-0.5, 2.5], + isBandScale: true, + minInterval: 1, + scaleType: ScaleType.Linear, + type: 'xDomain', + }, + totalBarsInCluster: barSeriesMap.size, + range: [0, 120], + }); + const bandPosition = getCursorBandPosition( + 0, + chartDimensions, + { x: 119, y: 0 }, + { + value: 3, + withinBandwidth: true, + }, + true, + barSeriesScaleLimited, + 1, + ); + expect(bandPosition).toEqual({ + left: 105, + top: 0, + height: 120, + width: 15, + visible: true, + }); + }); + test('cursor at top begin of domain', () => { + const barSeriesScaleLimited = computeXScale({ + xDomain: { + domain: [0.5, 3.5], + isBandScale: true, + minInterval: 1, + scaleType: ScaleType.Linear, + type: 'xDomain', + }, + totalBarsInCluster: 1, + range: [0, 120], + }); + const bandPosition = getCursorBandPosition( + 90, + chartDimensions, + { x: 0, y: 0 }, + { + value: 0, + withinBandwidth: true, + }, + true, + barSeriesScaleLimited, + 1, + ); + expect(bandPosition).toEqual({ + left: 0, + top: 0, + height: 15, + width: 120, + visible: true, + }); + }); + test('cursor at top end of domain', () => { + const barSeriesScaleLimited = computeXScale({ + xDomain: { + domain: [-0.5, 2.5], + isBandScale: true, + minInterval: 1, + scaleType: ScaleType.Linear, + type: 'xDomain', + }, + totalBarsInCluster: barSeriesMap.size, + range: [0, 120], + }); + const bandPosition = getCursorBandPosition( + 90, + chartDimensions, + { x: 0, y: 119 }, + { + value: 3, + withinBandwidth: true, + }, + true, + barSeriesScaleLimited, + 1, + ); + expect(bandPosition).toEqual({ + left: 0, + top: 105, + height: 15, + width: 120, + visible: true, + }); + }); + }); }); diff --git a/packages/osd-charts/src/chart_types/xy_chart/crosshair/crosshair_utils.ts b/packages/osd-charts/src/chart_types/xy_chart/crosshair/crosshair_utils.ts index d1e3b6657b57..0d72484abbe4 100644 --- a/packages/osd-charts/src/chart_types/xy_chart/crosshair/crosshair_utils.ts +++ b/packages/osd-charts/src/chart_types/xy_chart/crosshair/crosshair_utils.ts @@ -107,24 +107,36 @@ export function getCursorBandPosition( if (isHorizontalRotated) { const adjustedLeft = snapEnabled ? position : cursorPosition.x; - const leftPosition = chartRotation === 0 ? left + adjustedLeft : left + width - adjustedLeft - bandOffset; - + let leftPosition = chartRotation === 0 ? left + adjustedLeft : left + width - adjustedLeft - bandOffset; + let adjustedWidth = band; + if (band > 1 && leftPosition + band > left + width) { + adjustedWidth = left + width - leftPosition; + } else if (band > 1 && leftPosition < left) { + adjustedWidth = band - (left - leftPosition); + leftPosition = left; + } return { top, left: leftPosition, - width: band, + width: adjustedWidth, height, visible: true, }; } else { const adjustedTop = snapEnabled ? position : cursorPosition.x; - const topPosition = chartRotation === 90 ? top + adjustedTop : height + top - adjustedTop - bandOffset; - + let topPosition = chartRotation === 90 ? top + adjustedTop : height + top - adjustedTop - bandOffset; + let adjustedHeight = band; + if (band > 1 && topPosition + band > top + height) { + adjustedHeight = band - (topPosition + band - (top + height)); + } else if (band > 1 && topPosition < top) { + adjustedHeight = band - (top - topPosition); + topPosition = top; + } return { top: topPosition, left, width, - height: band, + height: adjustedHeight, visible: true, }; }