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

[BUG] Floating point linear scale for text values #3723

Closed
USvER opened this issue Dec 20, 2016 · 16 comments · Fixed by #8053
Closed

[BUG] Floating point linear scale for text values #3723

USvER opened this issue Dec 20, 2016 · 16 comments · Fixed by #8053

Comments

@USvER
Copy link

USvER commented Dec 20, 2016

Current Behavior

Y scales show floating point linear scale from -1.0 to 1.0 and does not plot anything

Expected Behavior

When values are of type string, scales should be of type category and use values as ticks

Possible Solution

For values of type string change scales type to category and use distinct values as ticks

Steps to Reproduce (for bugs)

http://codepen.io/anon/pen/GNeZaJ

Environment

  • Chart.js version: 2.4.0
@etimberg
Copy link
Member

I can see how this is an issue, but I'm not sure it's right to automatically switch the axis type. cc @chartjs/maintainers thoughts?

@USvER
Copy link
Author

USvER commented Dec 20, 2016

If nothing ploted with 'good' data then it should be considered a bug.
For numbers it's safe to asume that scale would be linear with min/max from values.
But for strings this should be 'category', and use values as ticks. This is expected behaviour.

@USvER
Copy link
Author

USvER commented Dec 20, 2016

This problem is a direct consequence of chartjs not having notion of data types.
Beyond Numbers there is partial support for Category and Time but I can't see any overall picture on how this all fits together.
Should I add this as a feature request? Because i think this is a key to resolve this and other issues( #3725, #3193, #3305)

For example Google Charts distinguishes this data types string, number, boolean, date, datetime, and timeofday. This not only affects formating of the labels on Tooltips and Scales but also allows to use sensible defaults for scales. This is what chartjs lacks.

@etimberg
Copy link
Member

This is definitely a feature request. I was thinking about this a bit more and realized that there are also a lot of other things that need to be worked out at the same time. For instance, it's pretty common (judging by the number of times people have asked questions about it or opened issues) to pass in data that looks like
['10', '20', '30'] and expect it to be treated as numbers even though there are actually string values there.

Lets use this issue to brainstorm a proposal and then we can figure out what features need to get done to get there.

@etimberg
Copy link
Member

I should add that some of these changes might require a major version bump if we can't maintain backwards compatibility

@etimberg
Copy link
Member

Creating an ordinal scale shouldn't be too difficult. I think it could derive from the category scale and simply override getLabels https://github.com/chartjs/Chart.js/blob/master/src/scales/scale.category.js#L17

@USvER
Copy link
Author

USvER commented Dec 20, 2016

There is three steps in the process of visualizing chars:

  1. preparation (parsing, type conversion, etc)
  2. visualization (ploting charts)
  3. formating (date, currency, percent, etc)

Apart from visualization chartjs absolutely ignores preparation leaving this task for developers and has limited support for formating...

I think everyone should share their vision on how this parts should fit together.
Preparation and formating are related:

  • parsing date from the string and formating that date to string again (Moment.js)
  • parsing integer value from '100%' without percent sign and presenting it as '100%' back at scales and tooltips

Most of the time preparation is done on the server side thats why it actualy looks OK to ignore this step on client side, but there are cases where you don't have access to server-side and forced to do preparation on client side. Or because of known problems with dates in javascript, you want to prepare date as string and parse it using Moment.js on client-side.

Thats why i think preparation should be part of the BUNDLE but not necesarily be part of chartjs library.
I mean it would be cool to find good library for parsing/converting different types and integrate it with chartjs library seamlesly. This will allow lazy developers not to look for it and just use 10MB bundle :).

I think providing a standart set of formating options for tooltips and scales is a MUST and should be in the core (number formating, date formating). All custom formating should be done through common interface, not only user-defined function but some kind of pluggable 'formatter' classes/functions.

@USvER
Copy link
Author

USvER commented Dec 20, 2016

@etimberg changing getLabels will work for now... but there is much more bigger picture for this issue.

@USvER
Copy link
Author

USvER commented Dec 20, 2016

I like the Google Charts approach where preparation and formatting is done before visualization and stored as pair of raw value and formatted value. This has a cost of additional memory for storing formatted value but allows to show this value efficiently in multiple places(tooltip, scale) and simplifies the processing, because you can make both preparation and formatting in one path... Also this allows to make formatting server-side... This does not negates requirement for client-side formatting classes.

@USvER
Copy link
Author

USvER commented Dec 20, 2016

http://numeraljs.com/ is the library we looking for!?

@etimberg
Copy link
Member

NumeralJS looks interesting and could solve a lot of the parsing and formatting problems.

In terms of storing both the raw and formatted values, are you thinking something like:

datasets: [{
  data: [10, 20, 30, 40],
  formatted: ['$10', '$20', '$30', '$40']
}]

I'm guessing the user would supply the data and we would build the formatted property. Would formatting be tied to the axis the dataset is displayed on? or would it be customizable per dataset?

One thing to think about with that example is that the formatting needs to also apply to the tick marks. Presumably if the axis is using '$' we want the tooltip to show the same thing.

In terms of implementing this, I'm wondering if we can ship it as a plugin. As you noted, not everyone wants to download a huge library and we've already got complaints about the current size being too large.

What I was envisioning the plugin would do would be

  1. Format the data for each dataset and attach appropriate format functions to each axis
  2. Ensure the tooltip correctly finds the formatted data

@USvER
Copy link
Author

USvER commented Dec 20, 2016

Storing formatted values is not a panacea, but looks good and easy to implement. One of the issues you mentioned is that it will only work for 'category' scales...
This technique is just a complement to pluggable parsers/formatters, most used (Number, Date) should be in core.

What is interesting in NumeralJS is that they have this idea of format/unformat, so you can transform in each way... If you think about it, all this 'number as string' issues happening because data come preformated and you want it to be 'unformated' to raw values wich can be used by chartjs library and then you want it to be formated again. So format/unformat feature is interesting. Also it's already have alot of formats and allow easy integration of custom formatters.
I'm not pushing it, i'm googled this library just today...
From the bottom of NumeralJS website: "Numeral.js, while less complex, was inspired by and heavily borrowed from Moment.js"

@USvER
Copy link
Author

USvER commented Dec 20, 2016

Interesting question about formating in a situation where same dataset having multiple scales. Is it possible? Any usecases?
I think, currently, this is not possible and the only usecase for this is to look at the same data with different ticks. Let's say from the left would be linear scale and from the right would be 'category' with custom ticks that should match linear ticks. Too complex scenario... Linear vs Logarithmic scale comparision???

@USvER
Copy link
Author

USvER commented Dec 20, 2016

Would formatting be tied to the axis the dataset is displayed on? or would it be customizable per dataset?

For tooltip, formatting will be something like this:

  1. Use suplied formatting function if exist
  2. Use formatter class if defined
  3. Use formatted value if exist
  4. Use raw value

For scale use array of user-defined ticks or autogenerated ticks and follow the same steps to get formatted value.

It's expected behaviour to use same formatting for scale and tooltip, but it shouldn't be a hard restiction... So if scale does not have any formatting it can use formatting from dataset... Looks ok to me... Also this requires option to disable formatting or opposite...

@etimberg
Copy link
Member

same dataset having multiple scales

The case of the same dataset having multiple scales shouldn't happen and isn't supported.

If you think about it, all this 'number as string' issues happening because data come preformated and you want it to be 'unformated' to raw values wich can be used by chartjs library and then you want it to be formated again.

That's a very good way to think about it. Something like numeral (doesn't have to be this) will definitely solve problems.

For tooltip, formatting will be something like this:

That sounds like a good idea to me. It would maintain backwards compatibility for anyone using custom functions already.

@BrazhnykYuriy
Copy link

❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants