Skip to content

Commit

Permalink
fix(crosshair): limit the width of the cursor band on edges (#353)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
markov00 authored Aug 27, 2019
1 parent 5e1446c commit 1177e59
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 9 deletions.
13 changes: 10 additions & 3 deletions .playground/playgroud.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
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 {
render() {
return (
<div className="chart">
<Chart>
<Settings showLegend={true} />
<Settings
showLegend={true}
xDomain={{
min: KIBANA_METRICS.metrics.kibana_os_load[0].data[0][0] - 10000,
max: KIBANA_METRICS.metrics.kibana_os_load[0].data[18][0] + 10000,
}}
rotation={0}
/>
<Axis id={getAxisId('y')} position={Position.Left} />
<Axis id={getAxisId('x')} position={Position.Bottom} />
<BarSeries
<HistogramBarSeries
id={getSpecId('bar')}
yScaleType={ScaleType.Linear}
xScaleType={ScaleType.Time}
Expand Down
132 changes: 132 additions & 0 deletions src/chart_types/xy_chart/crosshair/crosshair_utils.linear_snap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1472,4 +1472,136 @@ describe('Crosshair utils linear scale', () => {
});
});
});

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,
});
});
});
});
24 changes: 18 additions & 6 deletions src/chart_types/xy_chart/crosshair/crosshair_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
}
Expand Down

0 comments on commit 1177e59

Please sign in to comment.