Skip to content
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: custom d3 number locale #20075

Merged
merged 1 commit into from
May 2, 2023
Merged

feat: custom d3 number locale #20075

merged 1 commit into from
May 2, 2023

Conversation

ebaratte
Copy link
Contributor

SUMMARY

This PR is an attempt to provide a way of customising the format of the numbers and currency displayed in superset frontend.
It is linked to (at least) issues #3972, #18938, #11328, #8913
Please also look at PR #17796, which provides a different approach to the same issue.

Design choice:

  • the user can change the following d3 number formatting parameters: decimal, thousands, grouping, currency, numerals, percent, minus and nan
  • this change does not include the time formatting parameters, since I believe it to be a different issue
  • unlike feat: Create D3NumberFormatters with active Locale #17796, it does not tie the format to the LANGUAGES config key: the user can use different parameters for the frontend language and number formatting

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Before
image

After:
image

TESTING INSTRUCTIONS

  • in config.py, add a D3_FORMAT dictionary with d3 locale settings
  • check the number formatting on any chart

ADDITIONAL INFORMATION

@codecov
Copy link

codecov bot commented May 16, 2022

Codecov Report

Merging #20075 (44ff829) into master (314987f) will increase coverage by 0.00%.
The diff coverage is 87.50%.

❗ Current head 44ff829 differs from pull request most recent head c28c849. Consider uploading reports for the commit c28c849 to get more accurate results

@@           Coverage Diff           @@
##           master   #20075   +/-   ##
=======================================
  Coverage   68.02%   68.03%           
=======================================
  Files        1936     1937    +1     
  Lines       74929    74943   +14     
  Branches     8141     8141           
=======================================
+ Hits        50974    50987   +13     
  Misses      21870    21870           
- Partials     2085     2086    +1     
Flag Coverage Δ
hive 53.01% <100.00%> (+<0.01%) ⬆️
javascript 54.30% <80.00%> (+<0.01%) ⬆️
mysql 78.80% <100.00%> (+<0.01%) ⬆️
postgres 78.88% <100.00%> (+<0.01%) ⬆️
presto 52.93% <100.00%> (+<0.01%) ⬆️
python 82.67% <100.00%> (+<0.01%) ⬆️
sqlite 77.39% <100.00%> (+<0.01%) ⬆️
unit 52.82% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...board/components/nativeFilters/FilterBar/index.tsx 50.53% <ø> (ø)
superset-frontend/src/preamble.ts 0.00% <0.00%> (ø)
superset-frontend/src/setup/setupFormatters.ts 0.00% <ø> (ø)
superset-frontend/src/types/bootstrapTypes.ts 100.00% <ø> (ø)
superset/views/base.py 76.87% <ø> (ø)
...d/components/DashboardBuilder/DashboardBuilder.tsx 73.26% <50.00%> (-0.74%) ⬇️
...perset-ui-chart-controls/src/utils/D3Formatting.ts 100.00% <100.00%> (ø)
...perset-ui-core/src/number-format/D3FormatConfig.ts 100.00% <100.00%> (ø)
...-core/src/number-format/NumberFormatterRegistry.ts 100.00% <100.00%> (ø)
.../number-format/NumberFormatterRegistrySingleton.ts 100.00% <100.00%> (ø)
... and 1 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@k7daniel
Copy link

This is very cool. Would be great to just set D3_FORMAT and pass that in to the docker image.

@SergeRomankevich
Copy link

Tables with different currencies are crying aside and waiting for the merge

@enryls
Copy link

enryls commented Jun 25, 2022

Great feature! Hope to see it merged soon

@pm-at
Copy link

pm-at commented Jul 5, 2022

Is there a way to bring this issue to the notice of reviewers?

@KarenWeis
Copy link

Are there plans to merge or include in 3.0 release?

@theYaro
Copy link

theYaro commented Oct 17, 2022

Waiting for this merge.

@pm-at
Copy link

pm-at commented Jan 12, 2023

I'm sorry for repeated nudge, but this is a really helpful feature. Waiting for this PR to be merged..

@MarkusBellmann
Copy link

Please, we really need this feature!

@lf-floriandin
Copy link

Would also love if this get reviewed and merged!

@villebro
Copy link
Member

@ebaratte would you be able to rebase this PR to fix the conflicts?

@ebaratte
Copy link
Contributor Author

I rebased the PR, we should be good to go.

@Pedrolrbr
Copy link

@justinpark @eschutho @kgabryje @villebro any updates?

Copy link
Member

@villebro villebro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that Superset is badly lacking in this space, but the main issue I have with this approach is the fact that it assumes the deployment as a whole speaks one single locale. As we start to prepare for making Superset more localizable (see e.g. a WIP PR of mine that adds timezone support to the chart data API: #23511), it would be nice if we could start making gradual progress towards having user or chart specific locales. Let's say we want to have one chart that shows euros, and another that shows US dollars. This would not be possible with this setting.

Having said that, I think this approach is good to cover use cases where the entire deployment wants to "speak" only one specific locale, as long as we leave open the door for making this overridable per user/chart. And based on my review this doesn't paint us into any corner, so I think this looks good. Thoughts @ebaratte @Pedrolrbr @kgabryje @rusackas ?

# "currency": ["$", ""] # - currency prefix/suffix strings (e.g., ["$", ""])
# }
# https://github.com/d3/d3-format/blob/main/README.md#formatLocale
D3_FORMAT: Dict[str, Any] = {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: as TypedDict is now a default thing in our currently supported Python versions, I'd prefer to create a D3Format(TypedDict) for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I updated the type definition

@@ -150,6 +151,7 @@ export interface CommonBootstrapData {
extra_sequential_color_schemes: SequentialSchemeConfig[];
theme_overrides: JsonObject;
menu_data: MenuData;
d3_format: Partial<FormatLocaleDefinition>;
Copy link
Member

@villebro villebro Apr 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need Partial here? It appears that the added dict in config.py defines all properties of FormatLocaleDefinition. If not, let's make sure the type in config.py reflects the partialness (this could be done by adding total=False to the Python class that's extending TypedDict).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we do; the way the code is set up, a user can specify a subset of the formatting options in config.py (total=False in the type definition).
The default values are set in the front (D3FormatConfig.ts, and setD3Format() in NumberFormatterRegistry.ts:52)

@ebaratte ebaratte force-pushed the master branch 2 times, most recently from 0446aea to 606bbf1 Compare April 25, 2023 10:00
@ebaratte
Copy link
Contributor Author

I know that Superset is badly lacking in this space, but the main issue I have with this approach is the fact that it assumes the deployment as a whole speaks one single locale. As we start to prepare for making Superset more localizable (see e.g. a WIP PR of mine that adds timezone support to the chart data API: #23511), it would be nice if we could start making gradual progress towards having user or chart specific locales. Let's say we want to have one chart that shows euros, and another that shows US dollars. This would not be possible with this setting.

Having said that, I think this approach is good to cover use cases where the entire deployment wants to "speak" only one specific locale, as long as we leave open the door for making this overridable per user/chart. And based on my review this doesn't paint us into any corner, so I think this looks good. Thoughts @ebaratte @Pedrolrbr @kgabryje @rusackas ?

This is indeed the general idea of this PR: set default values for the whole instance. This is especially relevant for the currency, since there is no proper way at the moment to change the default currency, and displaying an incorrect currency makes the charts incorrect - whereas number formatting is more of a cosmetic issue. Obviously, it assumes that all the data is in a single currency.

It shouldn't prevent local overrides, like:

@villebro
Copy link
Member

This is indeed the general idea of this PR: set default values for the whole instance. This is especially relevant for the currency, since there is no proper way at the moment to change the default currency, and displaying an incorrect currency makes the charts incorrect - whereas number formatting is more of a cosmetic issue. Obviously, it assumes that all the data is in a single currency.

It shouldn't prevent local overrides, like:

Ok you don't need to convince me more @ebaratte 🙂 Looks good to go to me, but there appears to be some frontend UTs that are failing. Please take a look so we can get this in 👍

Copy link
Member

@villebro villebro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM once the tests are passing.

@ebaratte
Copy link
Contributor Author

Rebased to fix the tests (#23805)

@k7daniel
Copy link

Yay! Can't wait to test this out!!

@rusackas
Copy link
Member

Hoping to test this on an ephemeral build, but then I can't wait to click the Merge button on this!!!! 🚀

@apache apache deleted a comment from github-actions bot Apr 27, 2023
@apache apache deleted a comment from github-actions bot Apr 27, 2023
@apache apache deleted a comment from github-actions bot Apr 27, 2023
@apache apache deleted a comment from github-actions bot Apr 27, 2023
@rusackas
Copy link
Member

/testenv up

@rusackas
Copy link
Member

Sorry for all the noise on the thread, folks! I'm trying to troubleshoot the ephemeral environment builds, so it needs a little kicking ;)

@github-actions
Copy link
Contributor

@rusackas Ephemeral environment spinning up at http://54.200.4.245:8080. Credentials are admin/admin. Please allow several minutes for bootstrapping and startup.

@rusackas
Copy link
Member

rusackas commented May 2, 2023

Had a nice long chat with @mistercrunch about this approach and a couple other approaches to improving currency handling in Superset. At the end of the day, I think all three have their place. Expect some more proposals and/or PRs in the future. In the meantime, this looks ready to go. Thanks for the PR!!!! Hitting the merge button!

@rusackas rusackas merged commit a170ae4 into apache:master May 2, 2023
@github-actions
Copy link
Contributor

github-actions bot commented May 2, 2023

Ephemeral environment shutdown and build artifacts deleted.

@cwegener
Copy link
Contributor

cwegener commented May 3, 2023

Just cross-linking the alternative designs for future reference (somehow Github doesn't place links from Discussion threads for issue mentions into the issue log automatically ...)
#23684

@phifa
Copy link

phifa commented Jun 12, 2023

So I am not familiar with D3_FORMAT. Can someone tell me what I need to add to config.py? I want this number to be displayed in a european format, like this: 579 781 or like this 579.781,000. Thanks a ton!

@cwegener
Copy link
Contributor

@phifa
According to the documentation, this config should be what is needed:

D3_FORMAT = {
    "decimal": ".",
    "thousands": ",",
    "grouping": [3],
    "currency": ["€", ""]
}

@dab21rus
Copy link

@phifa According to the documentation, this config should be what is needed:

D3_FORMAT = {
    "decimal": ".",
    "thousands": ",",
    "grouping": [3],
    "currency": ["€", ""]
}

Does it work on version 2.1.0 ? Nothing changes for me.

@cwegener
Copy link
Contributor

Does it work on version 2.1.0 ? Nothing changes for me.

No. This PR is not part of 2.1

This PR is only available in the master branch.

mostafa-k-m pushed a commit to sylndr/superset that referenced this pull request Dec 6, 2023
@mistercrunch mistercrunch added 🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels 🚢 3.0.0 labels Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels size/L 🚢 3.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.