Skip to content

Commit

Permalink
fix: align line and rect annotation on continuous scales
Browse files Browse the repository at this point in the history
  • Loading branch information
markov00 committed Feb 7, 2024
1 parent f9c11fc commit 2433121
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ import { Colors } from '../../../../common/colors';
import { SmallMultipleScales, getPanelSize } from '../../../../common/panel_utils';
import { Line } from '../../../../geoms/types';
import { ScaleBand, ScaleContinuous } from '../../../../scales';
import { isBandScale, isContinuousScale } from '../../../../scales/types';
import { Position, Rotation } from '../../../../utils/common';
import { Dimensions, Size } from '../../../../utils/dimensions';
import { GroupId } from '../../../../utils/ids';
import { mergeWithDefaultAnnotationLine } from '../../../../utils/themes/merge_utils';
import { isHorizontalRotation, isVerticalRotation } from '../../state/utils/common';
import { computeXScaleOffset } from '../../state/utils/utils';
import { AnnotationDomainType, LineAnnotationDatum, LineAnnotationSpec } from '../../utils/specs';
import { getAnnotationXScaledValue } from '../scale_utils';

function computeYDomainLineAnnotationDimensions(
annotationSpec: LineAnnotationSpec,
Expand Down Expand Up @@ -137,36 +136,7 @@ function computeXDomainLineAnnotationDimensions(

dataValues.forEach((datum: LineAnnotationDatum, i) => {
const { dataValue } = datum;
let annotationValueXPosition = xScale.scale(dataValue);
if (Number.isNaN(annotationValueXPosition)) {
return;
}
if (isContinuousScale(xScale) && typeof dataValue === 'number') {
const [minDomain, scaleMaxDomain] = xScale.domain;
const maxDomain = isHistogramMode ? scaleMaxDomain + xScale.minInterval : scaleMaxDomain;
if (dataValue < minDomain || dataValue > maxDomain) {
return;
}
if (isHistogramMode) {
const offset = computeXScaleOffset(xScale, true);
const pureScaledValue = xScale.pureScale(dataValue);
if (!Number.isNaN(pureScaledValue)) {
// Number.isFinite is regrettably not a type guard yet https://github.com/microsoft/TypeScript/issues/10038#issuecomment-924115831
annotationValueXPosition = pureScaledValue - offset;
}
} else {
annotationValueXPosition += (xScale.bandwidth * xScale.totalBarsInCluster) / 2;
}
} else if (isBandScale(xScale)) {
annotationValueXPosition += isHistogramMode
? -(xScale.step - xScale.originalBandwidth) / 2
: xScale.originalBandwidth / 2;
} else {
return;
}
if (!isFinite(annotationValueXPosition)) {
return;
}
const annotationValueXPosition = getAnnotationXScaledValue(xScale, dataValue, isHistogramMode);

vertical.domain.forEach((verticalValue) => {
horizontal.domain.forEach((horizontalValue) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { PrimitiveValue } from '../../../partition_chart/layout/utils/group_by_r
import { isHorizontalRotation, isVerticalRotation } from '../../state/utils/common';
import { getAxesSpecForSpecId } from '../../state/utils/spec';
import { AxisSpec, RectAnnotationDatum, RectAnnotationSpec } from '../../utils/specs';
import { getAnnotationXScaledValue } from '../scale_utils';
import { Bounds } from '../types';

/** @internal */
Expand Down Expand Up @@ -199,14 +200,10 @@ function scaleXonContinuousScale(
if (typeof x1 !== 'number' || typeof x0 !== 'number') {
return null;
}
const scaledX0 = xScale.scale(x0);
const scaledX1 =
xScale.totalBarsInCluster > 0 && !isHistogramModeEnabled ? xScale.scale(x1 + xScale.minInterval) : xScale.scale(x1);
// the width needs to be computed before adjusting the x anchor
const scaledX0 = getAnnotationXScaledValue(xScale, x0, isHistogramModeEnabled) ?? NaN;
const scaledX1 = getAnnotationXScaledValue(xScale, x1, isHistogramModeEnabled) ?? NaN;
const width = Math.abs(scaledX1 - scaledX0);
return Number.isNaN(width)
? null
: { width, x: scaledX0 - (xScale.bandwidthPadding / 2) * xScale.totalBarsInCluster };
return Number.isNaN(width) ? null : { width, x: scaledX0 };
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { ScaleBand, ScaleContinuous } from '../../../scales';
import { isBandScale, isContinuousScale } from '../../../scales/types';
import { computeXScaleOffset } from '../state/utils/utils';

/** @internal */
export function getAnnotationXScaledValue(
xScale: ScaleBand | ScaleContinuous,
dataValue: string | number,
isHistogramMode: boolean,
): number {
let annotationValueXPosition = xScale.scale(dataValue);
if (Number.isNaN(annotationValueXPosition)) {
return NaN;
}
if (isContinuousScale(xScale) && typeof dataValue === 'number') {
const [minDomain, scaleMaxDomain] = xScale.domain;
const maxDomain = isHistogramMode ? scaleMaxDomain + xScale.minInterval : scaleMaxDomain;
if (dataValue < minDomain || dataValue > maxDomain) {
return NaN;
}
if (isHistogramMode) {
const offset = computeXScaleOffset(xScale, true);
const pureScaledValue = xScale.pureScale(dataValue);
if (!Number.isNaN(pureScaledValue)) {
// Number.isFinite is regrettably not a type guard yet https://github.com/microsoft/TypeScript/issues/10038#issuecomment-924115831
annotationValueXPosition = pureScaledValue - offset;
}
} else {
annotationValueXPosition += (xScale.bandwidth * xScale.totalBarsInCluster) / 2;
}
} else if (isBandScale(xScale)) {
annotationValueXPosition += isHistogramMode
? -(xScale.step - xScale.originalBandwidth) / 2
: xScale.originalBandwidth / 2;
} else {
return NaN;
}
if (!isFinite(annotationValueXPosition)) {
return NaN;
}
return annotationValueXPosition;
}
71 changes: 65 additions & 6 deletions storybook/stories/bar/1_basic.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@
*/

import { boolean } from '@storybook/addon-knobs';
import moment from 'moment-timezone';
import React from 'react';

import { BarSeries, Chart, ScaleType, Settings } from '@elastic/charts';
import { Axis, BarSeries, Chart, LineAnnotation, Position, RectAnnotation, ScaleType, Settings } from '@elastic/charts';

import { ChartsStory } from '../../types';
import { useBaseTheme } from '../../use_base_theme';

export const Example: ChartsStory = (_, { title, description }) => {
const toggleSpec = boolean('toggle bar spec', true);
const now = Date.now();
const data1 = [
{ x: 0, y: 2 },
{ x: 1, y: 7 },
{ x: 2, y: 3 },
{ x: 3, y: 6 },
{ x: now, y: 2 },
{ x: now + 1000 * 60 * 60 * 1, y: 1 },
{ x: now + 1000 * 60 * 60 * 2, y: 3 },
{ x: now + 1000 * 60 * 60 * 3, y: 6 },
];
const data2 = data1.map((datum) => ({ ...datum, y: datum.y - 1 }));
const data = toggleSpec ? data1 : data2;
Expand All @@ -31,12 +33,69 @@ export const Example: ChartsStory = (_, { title, description }) => {
<BarSeries
id={specId}
name="Simple bar series"
xScaleType={ScaleType.Linear}
xScaleType={ScaleType.Time}
yScaleType={ScaleType.Linear}
enableHistogramMode
xAccessor="x"
yAccessors={['y']}
stackAccessors={['x']}
data={data}
/>
<BarSeries
id="bars 2"
name="Simple bar series"
xScaleType={ScaleType.Time}
yScaleType={ScaleType.Linear}
enableHistogramMode
stackAccessors={['x']}
xAccessor="x"
yAccessors={['y']}
data={data}
/>
<Axis id="y" position={Position.Left} domain={{ min: 0, max: 10 }} />
<Axis
id="bottom"
position={Position.Bottom}
timeAxisLayerCount={2}
style={{
tickLabel: {
alignment: { horizontal: 'left' },
},
}}
/>
<LineAnnotation
id="line1"
domainType="xDomain"
style={{
line: {
opacity: 1,
stroke: 'red',
strokeWidth: 2,
},
}}
marker={<div style={{ width: 50, height: 50, background: 'rgba(122,40,112,0.5)' }}></div>}
dataValues={[
{
dataValue: now + 1000 * 60 * 60 * 1,
details: `1.5`,
},
]}
/>
<RectAnnotation
id="rect1"
style={{
fill: 'red',
}}
dataValues={[
{
coordinates: {
x0: now + 1000 * 60 * 60 * 1,
x1: now + 1000 * 60 * 60 * 3,
},
details: `1.5 - 2.5`,
},
]}
/>
</Chart>
);
};

0 comments on commit 2433121

Please sign in to comment.