-
Notifications
You must be signed in to change notification settings - Fork 122
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
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.
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.
@@ -52,6 +52,6 @@ export function formatTooltip( | |||
}; | |||
} | |||
|
|||
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!
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
tooltipProps
to onlytooltip
? sounds much more simple and clean - what if the
tooltip
prop accept two types: theTooltipType
and 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
headerFormatter
which the user can use to define a custom header formatter for the tooltip headers.headerFormatter
has the type(data: TooltipValue) => JSX.Element | string
so 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:
emptyFormatter
was 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 notheaderFormatter
is defined,emptyFormatter
is used in place of the tick formatter from the relevant domain axis. This means that ifheaderFormatter
is 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 thetooltip
namespace, 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 usingtooltipType
ortooltipSnap
right now, so it shouldn't impact anyone to change this now. Now, we defineTooltipProps
and in place of three individual props, exposetooltipProps
:See discussion below for more on the new
tooltip
prop onSettingSpecProps
.Checklist
Use
strikethroughsto remove checklist items you don't feel are applicable to this PR.src/index.ts
(and stories only import from../src
except for test data & storybook)