-
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: nice ticks everywhere #1087
feat: nice ticks everywhere #1087
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1087 +/- ##
==========================================
+ Coverage 71.55% 71.70% +0.14%
==========================================
Files 381 402 +21
Lines 11914 11527 -387
Branches 2588 2205 -383
==========================================
- Hits 8525 8265 -260
+ Misses 3358 3131 -227
- Partials 31 131 +100
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
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.
Code changes LGTM. Tested locally on storybook and functions as expected.
Can we add a nice
example for time scales?
src/chart_types/xy_chart/state/selectors/compute_axes_geometries.ts
Outdated
Show resolved
Hide resolved
…0/elastic-charts into 2021_03_23-nice_ticks_everywhere
api/charts.api.md
Outdated
@@ -71,6 +71,14 @@ export const AnnotationType: Readonly<{ | |||
// @public (undocumented) | |||
export type AnnotationType = $Values<typeof AnnotationType>; | |||
|
|||
// @public (undocumented) | |||
export interface APIScale<T extends ScaleType> { |
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.
Not sure of the pros/cons of putting the word API
in an element of the API, all things being equal, would prefer a simple, expressive, semantic name. I'd probably not call it Scale
because it's currently just a tuple of {type: 'linear' | ..., nice: boolean}
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.
Right, any suggestion? what if we don't expose the interface externally on our API, and we reserve the APIScale
type for internal purposes?
The external will look like this:
export interface SeriesScales {
...
xScaleType: XScaleType | { nice: boolean; type: XScaleType };
yScaleType: ScaleContinuousType | { nice: boolean; type: ScaleContinuousType };
}
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 think, even for internal use the word "API" in it is a good question, maybe it has a bunch of benefits, eg. knowing which "boundary layer" we talk about, eg. external API, internal API or implementation detail (the latter of which is clear from @internal
).
Could namespaces / modules achieve this without resorting to Hungarian notation?
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.
Is this inception or recursion?
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.
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.
Epic PR 🎉
Some of my comments might be discoursive, and for consideration of future refactoring and API changes. Those that directly relate to new structures esp. in the API, eg. trying to avoid a union type in xScaleType
or some public namings pertain to this PR more closely. These could be discussed if necessary, as ideally we don't add to the API to then soon revise it
@@ -1669,10 +1677,10 @@ export type SeriesNameFn = (series: XYChartSeriesIdentifier, isTooltip: boolean) | |||
// @public (undocumented) | |||
export interface SeriesScales { |
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.
Unrelated to the PR:
- instead of
SeriesScales
, we might eventually consider a more specific term, eg.ProjectionPair
orCartesianPlaneProjections
(or a shorter version), to express that it's not some set or array of scales, but it defines the Cartesian plane, with the orthogonal projection pair - also, "projection" might work better here, and also in a lot of places where we use
scale
at the moment;Projection
captures the linearity (or how it's non-linear) of a dimension, eg. currentScaleType
; whileScale
adds the multiplier and usually offset, for example, by using the data domain and the screen pixel range
api/charts.api.md
Outdated
@@ -71,6 +71,14 @@ export const AnnotationType: Readonly<{ | |||
// @public (undocumented) | |||
export type AnnotationType = $Values<typeof AnnotationType>; | |||
|
|||
// @public (undocumented) | |||
export interface APIScale<T extends ScaleType> { |
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 think, even for internal use the word "API" in it is a good question, maybe it has a bunch of benefits, eg. knowing which "boundary layer" we talk about, eg. external API, internal API or implementation detail (the latter of which is clear from @internal
).
Could namespaces / modules achieve this without resorting to Hungarian notation?
@@ -110,12 +110,13 @@ export function shapeViewModel( | |||
let xValues = xDomain.domain as any[]; | |||
|
|||
const timeScale = | |||
xDomain.scaleType === ScaleType.Time | |||
xDomain.type === ScaleType.Time |
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.
The word domain covers, or maybe in our case, characterizes the set of values that a variable can assume, and is only very loosely connected to the projection type which is what we mean here, eg. linear, logarithmic. Not just in math, but also in geography and eg. D3, domain and projection are quite independent.
This has practical use too. For example, it'll be eventually useful to describe/configure the domain as a first class entity (and codomain, which we can call yDomain), and share it among multiple visualizations, some of which may use linear projection, some, logarithmic projection, and some, square root projection (eg. for varying size heatmap squares).
Domains compose nicely, eg. the discussed operators, like
- unioning (not just enlarging the domain if the user wants, but also, projecting multiple series on the same cartesian dimesion, we need to compute the union of the domains of all the series)
- mandatory inclusion of a certain obligatevalue, eg. zero—which is of course just a special case of unioning (unioning with a set that has a singluar value)
- intersection of the domain, eg. crop outliers (maybe shown or listed separately or on an overview chart) etc
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.
we can clean this up in a different PR.
We should change not only the variable name, but also the enum
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.
Yes that's good, do you have a list of items on which this can be put, to eventually circle back if deemed useful?
? new ScaleContinuous( | ||
{ | ||
type: ScaleType.Time, | ||
domain: xDomain.domain, | ||
range: [0, chartDimensions.width], | ||
nice: false, |
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.
Yes, the nice
flag forms high cohesion with the domain of the data and the pixel range onto which we project, as these are equally needed to compute the ticks. Also, the proposed tick count, or tick density (eg. via max font height and padding, avoiding overlap or too many/too few ticks)
} | ||
|
||
/** @internal */ | ||
export const getAPIScaleConfigsSelector = createCachedSelector( |
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.
Maybe both the get
prefix and the Selector
postfix could be removed as they're Hungarian notation
return acc; | ||
}, {}); | ||
|
||
const customDomainByGroupId = mergeYCustomDomainsByGroupId(axisSpecs, settingsSpec.rotation); |
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.
merge
in mergeYCustomDomainsByGroupId
is a verb, while functions stand in place of the equivalent expression or value, so a noun eg. unionYCustomDomainsByGroupId
would be a better fit in this otherwise very nice, descriptive function name (OK union
can be either a word or a noun, but at least, it is possibly a noun)
src/chart_types/xy_chart/state/selectors/get_api_scale_configs.ts
Outdated
Show resolved
Hide resolved
…0/elastic-charts into 2021_03_23-nice_ticks_everywhere
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.
Thanks for the changes, it looks great 🎉 Tested with negative numbers, maybe useful to add some negatives to the Custom Domains story if you need to touch this story in a future PR, and separate nicing toggle per series (ie. everything bar would be on the bar knob page etc)
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.
Changes per @monfera comments look good to me.
api/charts.api.md
Outdated
xNice?: boolean; | ||
xScaleType: XScaleType; | ||
yNice?: boolean; | ||
// @deprecated | ||
yScaleToDataExtent?: boolean; | ||
yScaleType: ScaleContinuousType | APIScale<ScaleContinuousType>; | ||
yScaleType: ScaleContinuousType; | ||
} |
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.
👍🏼
# [28.1.0](v28.0.1...v28.1.0) (2021-04-13) ### Bug Fixes * **legend:** sizing for short labels with scrollbar ([#1115](#1115)) ([6e1f223](6e1f223)) * **xy:** negative bar highlight and click ([#1109](#1109)) ([ec17cb2](ec17cb2)), closes [#1100](#1100) ### Features * **a11y:** improve chart figure ([#1104](#1104)) ([815cf39](815cf39)) * **partition:** order slices and sectors ([#1112](#1112)) ([74df29b](74df29b)) * **partitions:** small multipies events pass on smAccessorValue ([#1106](#1106)) ([a3234fe](a3234fe)) * **xy:** optionally rounds the domain to nice values ([#1087](#1087)) ([f644cc4](f644cc4)) * **xy:** specify pixel and ratio width for bars ([#1114](#1114)) ([58de413](58de413)) * mosaic ([#1113](#1113)) ([64bdd88](64bdd88))
🎉 This PR is included in version 28.1.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
the elastic#1087 PR introduced a regression where the useDefaultGroupDomain was not considered when computing the scale configs.
The #1087 PR introduced a regression where the useDefaultGroupDomain was not considered when computing the scale configs.
# [28.2.0](v28.1.0...v28.2.0) (2021-04-15) ### Bug Fixes * **xy:** consider `useDefaultGroupDomain` on scale config ([#1119](#1119)) ([c1b59f2](c1b59f2)), closes [#1087](#1087) ### Features * **a11y:** allow user to pass custom description for screen readers ([#1111](#1111)) ([2ee1b91](2ee1b91)), closes [#1097](#1097) * **partition:** add debuggable state ([#1117](#1117)) ([d7fc206](d7fc206)), closes [#917](#917)
# [28.1.0](elastic/elastic-charts@v28.0.1...v28.1.0) (2021-04-13) ### Bug Fixes * **legend:** sizing for short labels with scrollbar ([opensearch-project#1115](elastic/elastic-charts#1115)) ([ebf2552](elastic/elastic-charts@ebf2552)) * **xy:** negative bar highlight and click ([opensearch-project#1109](elastic/elastic-charts#1109)) ([065673c](elastic/elastic-charts@065673c)), closes [opensearch-project#1100](elastic/elastic-charts#1100) ### Features * **a11y:** improve chart figure ([opensearch-project#1104](elastic/elastic-charts#1104)) ([373ea72](elastic/elastic-charts@373ea72)) * **partition:** order slices and sectors ([opensearch-project#1112](elastic/elastic-charts#1112)) ([72c0d1b](elastic/elastic-charts@72c0d1b)) * **partitions:** small multipies events pass on smAccessorValue ([opensearch-project#1106](elastic/elastic-charts#1106)) ([0e1f7de](elastic/elastic-charts@0e1f7de)) * **xy:** optionally rounds the domain to nice values ([opensearch-project#1087](elastic/elastic-charts#1087)) ([9c2eefc](elastic/elastic-charts@9c2eefc)) * **xy:** specify pixel and ratio width for bars ([opensearch-project#1114](elastic/elastic-charts#1114)) ([6294d5f](elastic/elastic-charts@6294d5f)) * mosaic ([opensearch-project#1113](elastic/elastic-charts#1113)) ([15c0d78](elastic/elastic-charts@15c0d78))
# [28.2.0](elastic/elastic-charts@v28.1.0...v28.2.0) (2021-04-15) ### Bug Fixes * **xy:** consider `useDefaultGroupDomain` on scale config ([opensearch-project#1119](elastic/elastic-charts#1119)) ([269ff1a](elastic/elastic-charts@269ff1a)), closes [opensearch-project#1087](elastic/elastic-charts#1087) ### Features * **a11y:** allow user to pass custom description for screen readers ([opensearch-project#1111](elastic/elastic-charts#1111)) ([a0020ba](elastic/elastic-charts@a0020ba)), closes [#1097](elastic/elastic-charts#1097) * **partition:** add debuggable state ([opensearch-project#1117](elastic/elastic-charts#1117)) ([08f8baf](elastic/elastic-charts@08f8baf)), closes [opensearch-project#917](elastic/elastic-charts#917)
Summary
This PR adds the nicing to the scales domain.
As the first step, I've just introduced an optional
nice
prop per axis, off by default to avoid breaking change now.The following improvements and refactoring are implemented:
scale_defaults.ts
.SettingsSpec
,AxisSpec
,SeriesSpec
and the all relative default values).This is the first step toward refactoring the scale-related configuration into its own component.
fix #397