-
Notifications
You must be signed in to change notification settings - Fork 129
feat(tooltip): add custom headerFormatter #233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(tooltip): add custom headerFormatter #233
Conversation
Codecov Report
@@ Coverage Diff @@
## master #233 +/- ##
=========================================
Coverage ? 97.73%
=========================================
Files ? 36
Lines ? 2654
Branches ? 605
=========================================
Hits ? 2594
Misses ? 52
Partials ? 8
Continue to review full report at Codecov.
|
BREAKING CHANGE: Previously, you could define tooltipType and tooltipSnap props in a Settings component; now these and the header formatter configuration have been moved into tooltipProps such that you would define tooltipProps.type, tooltipProps.snap, and/or tooltipProps.headerFormatter.
nickofthyme
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Run storybook locally and verified feature. 👍
Only one suggestion in tests.
|
|
||
| function emptyFormatter(value: any): string { | ||
| return `${value}`; | ||
| function emptyFormatter<T>(value: T): T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
src/state/chart_state.test.ts
Outdated
| store.tooltipHeaderFormatter = undefined; | ||
| store.computeChart(); | ||
|
|
||
| // with no tooltipHeaderFormatter defined, should return value formatted using xAxis tickFormatter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it should be a test in a describe rather than in a comment. Then all the setup could be in a beforeEach to run both assertions you are making below the commented lines?
describe('can use a custom tooltip header formatter', () => {
beforeEach(() => {
const axisSpec: AxisSpec = {
id: AXIS_ID,
groupId: spec.groupId,
hide: true,
showOverlappingTicks: false,
showOverlappingLabels: false,
position: Position.Bottom,
tickSize: 30,
tickPadding: 10,
tickFormat: (value: any) => `foo ${value}`,
};
store.addAxisSpec(axisSpec);
store.addSeriesSpec(spec);
store.tooltipType.set(TooltipType.Crosshairs);
store.tooltipHeaderFormatter = undefined;
store.computeChart();
});
test('with no tooltipHeaderFormatter defined, should return value formatted using xAxis tickFormatter', () => {
store.setCursorPosition(10, 10);
expect(store.tooltipData[0].value).toBe('foo 1');
});
test('with tooltipHeaderFormatter defined, should return value formatted', () => {
store.tooltipHeaderFormatter = (value: TooltipValue) => `${value}`;
store.setCursorPosition(10, 10);
expect(store.tooltipData[0].value).toBe(1);
});
});Just a thought, maybe there are other implications to this test I don't see/know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Good catch and great suggestion!
markov00
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just take a look at the description and the code and I've few comments on that change:
- what do you think of change the tooltip props name from
tooltipPropsto onlytooltip? sounds much more simple and clean - what if the
tooltipprop accept two types: theTooltipTypeand theTooltipProps? this can simplify a bit the code for consumers that want only to specify the type of tooltip. - What are the use case where we want to change the full header (x value included) and what are the cases where we just want to add an additional test to the tooltip? I'm asking this because I just want to avoid consumers to go and implement their own header + add their own data formatter on the header if they want just to add a small text for specific cases.
- In the long run we can have the needs to:
- enable custom header text (as in this PR)
- enable custom X value formatter
- enable custom Y values formatter
- enable general tooltip formatter (all values + header)
what is your ideas behind that future?
|
@markov00 replies below inline:
Changed the name of
The type annotation for the headerFormatter is Another possibility could be to split up these configurations so that TooltipProps looks something like: (We need the element to have access to the raw data value or else we won't be able to do conditional displays if they come in as formatted strings.) In this case, then the user can:
I focussed just on the Where, if I think the implementation of the header customization doesn't commit us or block us from being able to address these other customizations, but also doesn't require that we tackle the entire question of what and how much the user should be able to customize these other things in order to get this one feature in which we know is needed for both TSVB and Discover replacements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@emmacunningham cool thanks for the explanation.
So for me it's good to merge. Just remember the breaking change footer :)
# [6.0.0](v5.2.0...v6.0.0) (2019-06-13) ### Features * **tooltip:** add custom headerFormatter ([#233](#233)) ([bd181b5](bd181b5)) ### BREAKING CHANGES * **tooltip:** Previously, you could define `tooltipType` and `tooltipSnap` props in a Settings component; this commit removes these from `SettingsSpecProps` and instead there is a single `tooltip` prop which can accept either a `TooltipType` or a full `TooltipProps` object which may include `type`, `snap`, and/or `headerFormattter` for formatting the header.
|
🎉 This PR is included in version 6.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
# [6.0.0](elastic/elastic-charts@v5.2.0...v6.0.0) (2019-06-13) ### Features * **tooltip:** add custom headerFormatter ([opensearch-project#233](elastic/elastic-charts#233)) ([bec476d](elastic/elastic-charts@bec476d)) ### BREAKING CHANGES * **tooltip:** Previously, you could define `tooltipType` and `tooltipSnap` props in a Settings component; this commit removes these from `SettingsSpecProps` and instead there is a single `tooltip` prop which can accept either a `TooltipType` or a full `TooltipProps` object which may include `type`, `snap`, and/or `headerFormattter` for formatting the header.
Summary
addresses #197 & #191
This PR introduces a SettingsSpec prop
headerFormatterwhich the user can use to define a custom header formatter for the tooltip headers.headerFormatterhas the type(data: TooltipValue) => JSX.Element | stringso that a user can either specify a simple value formatting function or a more complex one should they need to return a JSX element to be able to add additional text and/or styling that is not provided by the internal chart styles.We use this feature in Discover charts to show a custom message for the first and last bars in a series when they contain partial buckets:
Original Discover chart:

Version using elastic-charts with custom

headerFormatter:Notable implementation details:
emptyFormatterwas changed from always returning a string to returning the raw value; this was necessary because in Discover, we do a check to see if a value warrants the special header or notheaderFormatteris defined,emptyFormatteris used in place of the tick formatter from the relevant domain axis. This means that ifheaderFormatteris defined, the user must explicitly format the values themselves (in the Discover implementation, we re-use the axis formatter if the condition to display the special header is not met)<p>was changed to<div>to allow for nested elements (Kibana's DOM nesting validator throws a warning for nested elements in a<p>)tooltipType,tooltipSnap, andtooltipHeaderFormatter. Instead of three different props all with thetooltipnamespace, in this PR we create an interface for tooltip-related configuration to simplify things. This is a breaking change, but as far as I can tell, no one is usingtooltipTypeortooltipSnapright now, so it shouldn't impact anyone to change this now. Now, we defineTooltipPropsand in place of three individual props, exposetooltipProps:See discussion below for more on the new
tooltipprop onSettingSpecProps.Checklist
Use
strikethroughsto remove checklist items you don't feel are applicable to this PR.src/index.ts(and stories only import from../srcexcept for test data & storybook)