Skip to content

Fix/category scale wrong tooltip#12106

Open
mbehr1 wants to merge 2 commits intochartjs:masterfrom
mbehr1:fix/category_scale_wrong_tooltip
Open

Fix/category scale wrong tooltip#12106
mbehr1 wants to merge 2 commits intochartjs:masterfrom
mbehr1:fix/category_scale_wrong_tooltip

Conversation

@mbehr1
Copy link
Copy Markdown

@mbehr1 mbehr1 commented Aug 2, 2025

No description provided.

mbehr1 added 2 commits August 2, 2025 10:39
showing the problem/issue if a label is a string
but converts to a number within the labels range.
If labels are used that convert to numbers between 0..labels.length
a wrong value is returned.
Changed getLabelForValue to use value as an index only if typeof value is number.
@mbehr1
Copy link
Copy Markdown
Author

mbehr1 commented Aug 2, 2025

I stumbled upon this problem while analyzing mbehr1/dlt-logs#268.

const labels = this.getLabels();

if (value >= 0 && value < labels.length) {
if (typeof value === 'number' && value >= 0 && value < labels.length) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The function should be used to use the internal values of the category scale and convert them to the string values.
The internal values are numbers. This feels like a wrong implementation of this function.

The type definition also specifies the input as a number and not a string
https://www.chartjs.org/docs/latest/api/classes/Scale.html#getlabelforvalue

I would find it more logical that there would be a guard against number inputs but that would possible be too breaking since inputting a number as a string will be seen as a number.

So the current implementation is the most correct in my eyes and this is not a bug.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@LeeLenaleee but then the issue is here:

value: vScale ? '' + vScale.getLabelForValue(parsed[vScale.axis]) : ''

  getLabelAndValue(index) {
    const meta = this._cachedMeta;
    const iScale = meta.iScale;
    const vScale = meta.vScale;
    const parsed = this.getParsed(index);
    return {
      label: iScale ? '' + iScale.getLabelForValue(parsed[iScale.axis]) : '',
      value: vScale ? '' + vScale.getLabelForValue(parsed[vScale.axis]) : ''
    };
  }

?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do you have a reproducible sample of the issue. Because I don't see the issue.
When I add a label with a number in it it just shows the label on the correct spot, even though indexed it would have picked something else.

https://jsfiddle.net/Lrkc75ao/

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Will add one. Currently I see this in my vscode extension but a small example doesn't show the issue. Will keep on analyzing.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@LeeLenaleee
see a minimal example here (was struggling as the code I tried to repro with had my change already.... ;-)
https://jsfiddle.net/9xefs4g1/1/

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

image

here a pic of the example. Example code:

var options = {
  type: 'line',
  data: {
    labels: ["Jan", "2", "Mar", "Apr", "May", "Jun", "Jul"],
    datasets: [
			{
        type: 'line',
				data: [{x: 0, y: 'ON'},
        {x: 1, y: 'OFF'},
        {x: 2, y: '0'},
        {x: 3, y: 0},
        {x: 4, y: '1'}],
				borderWidth: 1,
        parsing: false
			}
		]
  },
  options: {
    scales: {
      y: {
        type: 'category',
        indexAxis: 'x',
        labels: ['ON', 'OFF', '1', '0'],
      },
    },
  }
}

var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);

Copy link
Copy Markdown
Collaborator

@LeeLenaleee LeeLenaleee Sep 14, 2025

Choose a reason for hiding this comment

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

I gave this another look and the current implementation seems correct to me.
The reason your code does not work is because you have set the parsing option to false.

In the documentation it is noted that if you do this, you will need to provide the data sorted and in the format that is the internal format. For category scales this is the index of the label.

Either not disabling parsing and use the labels for the Y key or using the index of the label and keep parsing dissabled will give the correct result.
Parsing true (default) and labels for Y keys: https://jsfiddle.net/gd2an916/
Using internal data structure: https://jsfiddle.net/q9mev3fd/

image

@mbehr1
Copy link
Copy Markdown
Author

mbehr1 commented Aug 21, 2025

@LeeLenaleee any update? Do you need more info?

@mbehr1
Copy link
Copy Markdown
Author

mbehr1 commented Sep 6, 2025

@LeeLenaleee any update?

@LeeLenaleee
Copy link
Copy Markdown
Collaborator

I had little time lately, i will look at it this weekend

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants