Skip to content

Commit

Permalink
feat(series): add simple mark formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
nickofthyme committed Sep 10, 2020
1 parent 8afce43 commit 770f56a
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ module.exports = {
'jsx-a11y/click-events-have-key-events': 1,
'@typescript-eslint/member-ordering': 1,
eqeqeq: 1,
'unicorn/no-nested-ternary': 0,

/**
* Standard rules
Expand Down Expand Up @@ -249,7 +250,6 @@ module.exports = {
'unicorn/no-fn-reference-in-iterator': 0,
'unicorn/prefer-query-selector': 0,
'unicorn/no-for-loop': 0,
'unicorn/no-nested-ternary': 1,
'unicorn/no-reduce': 0,
'unicorn/no-useless-undefined': 0,
'unicorn/prefer-spread': 0,
Expand Down
7 changes: 5 additions & 2 deletions api/charts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,9 @@ export interface BasePointerEvent {
export type BasicListener = () => undefined | void;

// @public (undocumented)
export type BasicSeriesSpec = SeriesSpec & SeriesAccessors & SeriesScales;
export type BasicSeriesSpec = SeriesSpec & SeriesAccessors & SeriesScales & {
markFormat?: TickFormatter;
};

// Warning: (ae-missing-release-tag) "BrushAxis" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
Expand Down Expand Up @@ -1543,11 +1545,12 @@ export type TooltipType = $Values<typeof TooltipType>;
// @public
export interface TooltipValue {
color: Color;
formattedMarkValue?: string | null;
formattedValue: string;
isHighlighted: boolean;
isVisible: boolean;
label: string;
markValue?: any;
markValue?: number | null;
seriesIdentifier: SeriesIdentifier;
value: any;
valueAccessor?: Accessor;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions integration/tests/interactions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,12 @@ describe('Interactions', () => {
{ left: 280, top: 80 },
);
});

it('should use custom mark formatters', async () => {
await common.expectChartWithMouseAtUrlToMatchScreenshot(
'http://localhost:9001/?path=/story/mixed-charts--mark-size-accessor',
{ left: 400, top: 80 },
);
});
});
});
39 changes: 39 additions & 0 deletions src/chart_types/xy_chart/tooltip/tooltip.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,4 +339,43 @@ describe('Tooltip formatting', () => {
expect(tooltipValue.value).toBe(1);
expect(tooltipValue.formattedValue).toBe('1');
});

describe('markFormat', () => {
const markFormat = jest.fn((d) => `${d} number`);
const markIndexedGeometry: BarGeometry = {
...indexedGeometry,
value: {
x: 1,
y: 10,
accessor: 'y1',
mark: 10,
},
};

it('should format mark value with markFormat', () => {
const tooltipValue = formatTooltip(
markIndexedGeometry,
{
...SPEC_1,
markFormat,
},
false,
false,
false,
YAXIS_SPEC,
);
expect(tooltipValue).toBeDefined();
expect(tooltipValue.markValue).toBe(10);
expect(tooltipValue.formattedMarkValue).toBe('10 number');
expect(markFormat).toBeCalledWith(10, undefined);
});

it('should format mark value with defaultTickFormatter', () => {
const tooltipValue = formatTooltip(markIndexedGeometry, SPEC_1, false, false, false, YAXIS_SPEC);
expect(tooltipValue).toBeDefined();
expect(tooltipValue.markValue).toBe(10);
expect(tooltipValue.formattedMarkValue).toBe('10');
expect(markFormat).not.toBeCalled();
});
});
});
9 changes: 8 additions & 1 deletion src/chart_types/xy_chart/tooltip/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { LegendItemExtraValues } from '../../../commons/legend';
import { SeriesKey } from '../../../commons/series_id';
import { TooltipValue } from '../../../specs';
import { getAccessorFormatLabel } from '../../../utils/accessor';
import { isDefined } from '../../../utils/commons';
import { IndexedGeometry, BandedAccessorType } from '../../../utils/geometry';
import { defaultTickFormatter } from '../utils/axis_utils';
import { getSeriesName } from '../utils/series';
Expand Down Expand Up @@ -83,6 +84,7 @@ export function formatTooltip(
const isVisible = label === '' ? false : isFiltered;

const value = isHeader ? x : y;
const markValue = isHeader || mark === null ? null : mark;
const tickFormatOptions: TickFormatterOptions | undefined = spec.timeZone ? { timeZone: spec.timeZone } : undefined;
const tickFormatter =
(isHeader ? axisSpec?.tickFormat : spec.tickFormat ?? axisSpec?.tickFormat) ?? defaultTickFormatter;
Expand All @@ -93,7 +95,12 @@ export function formatTooltip(
label,
value,
formattedValue: tickFormatter(value, tickFormatOptions),
markValue: isHeader || mark === null ? null : mark,
markValue,
...(isDefined(markValue) && {
formattedMarkValue: spec.markFormat
? spec.markFormat(markValue, tickFormatOptions)
: defaultTickFormatter(markValue),
}),
color,
isHighlighted: isHeader ? false : isHighlighted,
isVisible,
Expand Down
19 changes: 16 additions & 3 deletions src/chart_types/xy_chart/utils/specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,11 @@ export interface SeriesAccessors {
splitSeriesAccessors?: Accessor[];
/** An array of fields thats indicates the stack membership */
stackAccessors?: Accessor[];
/** Field name of mark size metric on `Datum` */
/**
* Field name of mark size metric on `Datum`
*
* Only used with line/area series
*/
markSizeAccessor?: Accessor | AccessorFn;
}

Expand Down Expand Up @@ -453,7 +457,16 @@ export interface SeriesScales {
}

/** @public */
export type BasicSeriesSpec = SeriesSpec & SeriesAccessors & SeriesScales;
export type BasicSeriesSpec = SeriesSpec &
SeriesAccessors &
SeriesScales & {
/**
* A function called to format every single mark value
*
* Only used with line/area series
*/
markFormat?: TickFormatter<number>;
};

export type SeriesSpecs<S extends BasicSeriesSpec = BasicSeriesSpec> = Array<S>;

Expand Down Expand Up @@ -661,7 +674,7 @@ export type TickFormatterOptions = {
};

/** @public */
export type TickFormatter = (value: any, options?: TickFormatterOptions) => string;
export type TickFormatter<V = any> = (value: V, options?: TickFormatterOptions) => string;

export const AnnotationTypes = Object.freeze({
Line: 'line' as const,
Expand Down
17 changes: 14 additions & 3 deletions src/components/tooltip/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { getInternalTooltipAnchorPositionSelector } from '../../state/selectors/
import { getInternalTooltipInfoSelector } from '../../state/selectors/get_internal_tooltip_info';
import { getSettingsSpecSelector } from '../../state/selectors/get_settings_specs';
import { getTooltipHeaderFormatterSelector } from '../../state/selectors/get_tooltip_header_formatter';
import { Rotation } from '../../utils/commons';
import { Rotation, isDefined } from '../../utils/commons';
import { TooltipPortal, TooltipPortalSettings, AnchorPosition, Placement } from '../portal';
import { getTooltipSettings } from './get_tooltip_settings';
import { TooltipInfo, TooltipAnchorPosition } from './types';
Expand Down Expand Up @@ -102,12 +102,23 @@ const TooltipComponent = ({
<div className="echTooltip__list">
{values.map(
(
{ seriesIdentifier, valueAccessor, label, formattedValue, markValue, color, isHighlighted, isVisible },
{
seriesIdentifier,
valueAccessor,
label,
markValue,
formattedValue,
formattedMarkValue,
color,
isHighlighted,
isVisible,
},
index,
) => {
if (!isVisible) {
return null;
}

const classes = classNames('echTooltip__item', {
echTooltip__rowHighlighted: isHighlighted,
});
Expand All @@ -129,7 +140,7 @@ const TooltipComponent = ({
<div className="echTooltip__item--container">
<span className="echTooltip__label">{label}</span>
<span className="echTooltip__value">{formattedValue}</span>
{markValue && <span className="echTooltip__markValue">&nbsp;({markValue})</span>}
{isDefined(markValue) && <span className="echTooltip__markValue">&nbsp;({formattedMarkValue})</span>}
</div>
</div>
);
Expand Down
6 changes: 5 additions & 1 deletion src/specs/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@ export interface TooltipValue {
/**
* The mark value
*/
markValue?: any;
markValue?: number | null;
/**
* The mark value to display
*/
formattedMarkValue?: string | null;
/**
* The color of the graphic mark (by default the color of the series)
*/
Expand Down
8 changes: 6 additions & 2 deletions stories/mixed/7_marks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
*/

import { action } from '@storybook/addon-actions';
import { number, boolean } from '@storybook/addon-knobs';
import { number, boolean, text } from '@storybook/addon-knobs';
import numeral from 'numeral';
import React from 'react';

import { AreaSeries, Axis, Chart, LineSeries, Position, ScaleType, Settings } from '../../src';
Expand All @@ -33,7 +34,7 @@ const data1 = new Array(100).fill(0).map((_, x) => ({
const data2 = new Array(100).fill(0).map((_, x) => ({
x,
y: getRandomNumber(0, 100),
z: getRandomNumber(0, 50),
z: getRandomNumber(0, 50, 4),
}));

export const Example = () => {
Expand All @@ -54,6 +55,7 @@ export const Example = () => {
max: 100,
step: 10,
});
const markFormat = text('markFormat', '0.0');

return (
<Chart className="story-chart">
Expand Down Expand Up @@ -81,6 +83,7 @@ export const Example = () => {
yAccessors={['y']}
markSizeAccessor="z"
data={data1.slice(0, size)}
markFormat={(d) => `${numeral(d).format(markFormat)}%`}
/>
<LineSeries
id="line"
Expand All @@ -90,6 +93,7 @@ export const Example = () => {
yAccessors={['y']}
markSizeAccessor="z"
data={data2.slice(0, size)}
markFormat={(d) => `${numeral(d).format(markFormat)}%`}
/>
</Chart>
);
Expand Down

0 comments on commit 770f56a

Please sign in to comment.