From ac0202109474a2455c319084c645fe4fdc9cc3e6 Mon Sep 17 00:00:00 2001 From: Emma Cunningham Date: Thu, 6 Jun 2019 06:50:44 -0700 Subject: [PATCH] fix(crosshair): adjust band position for rotation (#220) --- src/state/chart_state.ts | 2 +- src/state/crosshair_utils.linear_snap.test.ts | 67 ++++++++++--------- src/state/crosshair_utils.ts | 25 +++++-- stories/bar_chart.tsx | 48 ++++++++++++- stories/line_chart.tsx | 15 ++++- 5 files changed, 116 insertions(+), 41 deletions(-) diff --git a/src/state/chart_state.ts b/src/state/chart_state.ts index 4fc4dd97db..03ffa94669 100644 --- a/src/state/chart_state.ts +++ b/src/state/chart_state.ts @@ -292,7 +292,7 @@ export class ChartStore { const updatedCursorBand = getCursorBandPosition( this.chartRotation, this.chartDimensions, - this.cursorPosition, + { x: xAxisCursorPosition, y: yAxisCursorPosition}, this.isTooltipSnapEnabled.get(), this.xScale, this.geometriesIndexKeys, diff --git a/src/state/crosshair_utils.linear_snap.test.ts b/src/state/crosshair_utils.linear_snap.test.ts index e3fc3dfbcf..656204cb85 100644 --- a/src/state/crosshair_utils.linear_snap.test.ts +++ b/src/state/crosshair_utils.linear_snap.test.ts @@ -453,8 +453,9 @@ describe('Crosshair utils linear scale', () => { [0, 1, 2], 1, ); + expect(bandPosition).toEqual({ - left: 0, + left: 120, top: 0, height: 100, width: 1, @@ -472,7 +473,7 @@ describe('Crosshair utils linear scale', () => { 1, ); expect(bandPosition).toEqual({ - left: 0, + left: 120, top: 0, height: 100, width: 1, @@ -490,7 +491,7 @@ describe('Crosshair utils linear scale', () => { 1, ); expect(bandPosition).toEqual({ - left: 40, + left: 80, top: 0, height: 100, width: 1, @@ -508,7 +509,7 @@ describe('Crosshair utils linear scale', () => { 1, ); expect(bandPosition).toEqual({ - left: 90, + left: 30, top: 0, height: 100, width: 1, @@ -544,7 +545,7 @@ describe('Crosshair utils linear scale', () => { 1, ); expect(bandPosition).toEqual({ - left: 0, + left: 120, top: 0, height: 100, width: 1, @@ -562,7 +563,7 @@ describe('Crosshair utils linear scale', () => { 1, ); expect(bandPosition).toEqual({ - left: 0, + left: 120, top: 0, height: 100, width: 1, @@ -580,7 +581,7 @@ describe('Crosshair utils linear scale', () => { 1, ); expect(bandPosition).toEqual({ - left: 0, + left: 120, top: 0, height: 100, width: 1, @@ -616,7 +617,7 @@ describe('Crosshair utils linear scale', () => { 1, ); expect(bandPosition).toEqual({ - left: 120, + left: 0, top: 0, height: 100, width: 1, @@ -671,7 +672,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 0, + top: 45, height: 1, width: 120, }); @@ -689,7 +690,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 40, + top: 0, height: 1, width: 120, }); @@ -707,7 +708,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 90, + top: 0, height: 1, width: 120, }); @@ -761,7 +762,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 0, + top: 60, height: 1, width: 120, }); @@ -797,7 +798,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 60, + top: 0, height: 1, width: 120, }); @@ -815,7 +816,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 120, + top: 0, height: 1, width: 120, }); @@ -851,7 +852,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 0, + top: 100, height: 1, width: 120, }); @@ -869,7 +870,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 0, + top: 55, height: 1, width: 120, }); @@ -887,7 +888,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 40, + top: 100, height: 1, width: 120, }); @@ -905,7 +906,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 90, + top: 100, height: 1, width: 120, }); @@ -941,7 +942,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 0, + top: 100, height: 1, width: 120, }); @@ -959,7 +960,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 0, + top: 40, height: 1, width: 120, }); @@ -977,7 +978,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 0, + top: 100, height: 1, width: 120, }); @@ -995,7 +996,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 60, + top: 100, height: 1, width: 120, }); @@ -1013,7 +1014,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 120, + top: 100, height: 1, width: 120, }); @@ -1156,7 +1157,7 @@ describe('Crosshair utils linear scale', () => { 1, ); expect(bandPosition).toEqual({ - left: 0, + left: 80, top: 0, height: 100, width: 40, @@ -1174,7 +1175,7 @@ describe('Crosshair utils linear scale', () => { 1, ); expect(bandPosition).toEqual({ - left: 0, + left: 80, top: 0, height: 100, width: 40, @@ -1210,7 +1211,7 @@ describe('Crosshair utils linear scale', () => { 1, ); expect(bandPosition).toEqual({ - left: 80, + left: 0, top: 0, height: 100, width: 40, @@ -1265,7 +1266,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 0, + top: 40, height: 40, width: 120, }); @@ -1283,7 +1284,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 40, + top: 0, height: 40, width: 120, }); @@ -1301,7 +1302,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 80, + top: 0, height: 40, width: 120, }); @@ -1337,7 +1338,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 0, + top: 60, height: 40, width: 120, }); @@ -1355,7 +1356,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 0, + top: 20, height: 40, width: 120, }); @@ -1373,7 +1374,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 40, + top: 60, height: 40, width: 120, }); @@ -1391,7 +1392,7 @@ describe('Crosshair utils linear scale', () => { ); expect(bandPosition).toEqual({ left: 0, - top: 80, + top: 60, height: 40, width: 120, }); diff --git a/src/state/crosshair_utils.ts b/src/state/crosshair_utils.ts index bee2b01e63..126c74d8ad 100644 --- a/src/state/crosshair_utils.ts +++ b/src/state/crosshair_utils.ts @@ -19,6 +19,7 @@ export function getSnapPosition( if (position === undefined) { return; } + if (scale.bandwidth > 0) { const band = scale.bandwidth / (1 - scale.barsPadding); const halfPadding = (band - scale.bandwidth) / 2; @@ -72,11 +73,16 @@ export function getCursorBandPosition( ): Dimensions | undefined { const { top, left, width, height } = chartDimensions; const { x, y } = cursorPosition; - if (x > width || y > height || x < 0 || y < 0) { + const isHorizontalRotated = isHorizontalRotation(chartRotation); + + const chartWidth = isHorizontalRotated ? width : height; + const chartHeight = isHorizontalRotated ? height : width; + if (x > chartWidth || y > chartHeight || x < 0 || y < 0) { return; } - const isHorizontalRotated = isHorizontalRotation(chartRotation); - const invertedValue = xScale.invertWithStep(isHorizontalRotated ? x : y, data); + + const invertedValue = xScale.invertWithStep(x, data); + if (invertedValue == null) { return; } @@ -84,17 +90,26 @@ export function getCursorBandPosition( if (!snappedPosition) { return; } + const { position, band } = snappedPosition; + const bandOffset = xScale.bandwidth > 0 ? band : 0; + if (isHorizontalRotated) { + const adjustedLeft = snapEnabled ? position : x; + const leftPosition = chartRotation === 0 ? left + adjustedLeft : left + width - adjustedLeft - bandOffset; + return { top, - left: left + (snapEnabled ? position : x), + left: leftPosition, width: band, height, }; } else { + const adjustedTop = snapEnabled ? position : x; + const topPosition = chartRotation === 90 ? top + adjustedTop : height + top - adjustedTop - bandOffset; + return { - top: top + (snapEnabled ? position : y), + top: topPosition, left, width, height: band, diff --git a/stories/bar_chart.tsx b/stories/bar_chart.tsx index a713aef00b..bf1a2996e8 100644 --- a/stories/bar_chart.tsx +++ b/stories/bar_chart.tsx @@ -238,8 +238,31 @@ storiesOf('Bar Chart', module) ); }) .add('with linear x axis', () => { + const chartRotation = select( + 'chartRotation', + { + '0 deg': 0, + '90 deg': 90, + '-90 deg': -90, + '180 deg': 180, + }, + 0, + ); + + const theme = { + ...LIGHT_THEME, + scales: { + barsPadding: number('bar padding', 0, { + range: true, + min: 0, + max: 1, + step: 0.01, + }), + }, + }; return ( + { + const chartRotation = select( + 'chartRotation', + { + '0 deg': 0, + '90 deg': 90, + '-90 deg': -90, + '180 deg': 180, + }, + 0, + ); + + const theme = { + ...LIGHT_THEME, + scales: { + barsPadding: number('bar padding', 0, { + range: true, + min: 0, + max: 1, + step: 0.01, + }), + }, + }; + return ( - + { + const chartRotation = select( + 'chartRotation', + { + '0 deg': 0, + '90 deg': 90, + '-90 deg': -90, + '180 deg': 180, + }, + 0, + ); + return ( +