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

Line chart render yAxes error with number "0.6" #4928

Closed
longpham162 opened this issue Nov 6, 2017 · 3 comments · Fixed by #4943
Closed

Line chart render yAxes error with number "0.6" #4928

longpham162 opened this issue Nov 6, 2017 · 3 comments · Fixed by #4943

Comments

@longpham162
Copy link

longpham162 commented Nov 6, 2017

I have to use chart.js version 2.7.1 and get the bug look like the title.
Some thing wrong when library render label on y-axis with number "0.6". With that number he's always return me 0.6000000000000001 LOL.
But i have a temporary bad solution for fix that.

yAxes: [{
	ticks: {
        fontColor: "white",
	fontSize: 13,
	beginAtZero: true,
	callback: function(value, index, values) {
		//TODO: need to remove check condition in future because bug of library.
		//Chart js library render value on y-axis error with number 0.6, that always return 0.6000000000000001 for 0.6 "LOL"
		if (value === 0.6000000000000001) {
			return 0.6;
		}
	        return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
	}
}]

I hope u will fix that. Many thanks!

@etimberg
Copy link
Member

etimberg commented Nov 7, 2017

@longpham162 do you have a fiddle that reproduces this?

@engelby
Copy link

engelby commented Nov 8, 2017

I discovered this yesterday when adding metric scaling to the vertical axes. My temp solution was to copy the tick formatting callback code from core.ticks.js and put in the added code in my version of the callback. It seems like when adding the tick callback, the chart code skips formatting the tickValue, but I haven't followed the code with the debugger yet. I'll try and make a fiddle later when I get some time.

yAxes: [{
    gridLines: { display: true, drawBorder: false, tickMarkLength: 5, },
    ticks: {
        suggestedMin: 0,
        suggestedMax: 2,
        maxTicksLimit: 11,

        callback: function(tickValue, index, ticks) {
            // If we have lots of ticks, don't use the ones
            var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];

            // If we have a number like 2.5 as the delta, figure out how many decimal places we need
            if (Math.abs(delta) > 1) {
                if (tickValue !== Math.floor(tickValue)) {
                    // not an integer
                    delta = tickValue - Math.floor(tickValue);
                }
            }

            var logDelta = Chart.helpers.log10(Math.abs(delta));
            var tickString = '';

            if (tickValue !== 0) {
                var numDecimal = -1 * Math.floor(logDelta);
                numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
                tickString = tickValue.toFixed(numDecimal);
            } else {
                tickString = '0'; // never show decimal places for 0
            }

            // scale the linear tick value to metric suffixes
            if (tickValue >= 1000000) {
                tickString = (tickValue/1000000).toString()+'m';
            }
            else if (tickValue >= 1000) {
                tickString = (tickValue/1000).toString()+'k';
            }
            return tickString;
        }
    },
    scaleLabel: { display: true, labelString: 'Pounds' }
}]

@jcopperfield
Copy link
Contributor

Test case: https://codepen.io/anon/pen/LOLxvL
v2.7
issue_tick_rounding_error_4928
Proposed fix
fix-issue_tick_rounding_error_4928

diff --git a/src/core/core.ticks.js b/src/core/core.ticks.js
index 2dbc274..2924885 100644
--- a/src/core/core.ticks.js
+++ b/src/core/core.ticks.js
@@ -80,10 +80,15 @@ module.exports = {
 				numSpaces = Math.ceil(numSpaces);
 			}
 
-			// Put the values into the ticks array
+			var precision = 1;
+			if (spacing < 1) {
+				precision = Math.pow(10, spacing.toPrecision().length - 2);
+				niceMin = Math.round(niceMin * precision) / precision;
+				niceMax = Math.round(niceMax * precision) / precision;
+			}
 			ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);
 			for (var j = 1; j < numSpaces; ++j) {
-				ticks.push(niceMin + (j * spacing));
+				ticks.push(niceMin + Math.round(j * spacing * precision) / precision);
 			}
 			ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);

etimberg pushed a commit that referenced this issue Dec 2, 2017
… precision. (#4943)

* Fix issue 4928
 - linear tick generator doesn't round values to needed precision.

* Improve: replace toPrecision() in toString() to improve readability.

* Fix: logarithmic tick generator doesn't round values to needed precision.

* Fix: rounding tick values didn't work for negative values.

* Add: Core ticks tests
@etimberg etimberg added this to the Version 2.8 milestone Dec 2, 2017
yofreke pushed a commit to yofreke/Chart.js that referenced this issue Dec 30, 2017
… needed precision. (chartjs#4943)

* Fix issue 4928
 - linear tick generator doesn't round values to needed precision.

* Improve: replace toPrecision() in toString() to improve readability.

* Fix: logarithmic tick generator doesn't round values to needed precision.

* Fix: rounding tick values didn't work for negative values.

* Add: Core ticks tests
exwm pushed a commit to exwm/Chart.js that referenced this issue Apr 30, 2021
… needed precision. (chartjs#4943)

* Fix issue 4928
 - linear tick generator doesn't round values to needed precision.

* Improve: replace toPrecision() in toString() to improve readability.

* Fix: logarithmic tick generator doesn't round values to needed precision.

* Fix: rounding tick values didn't work for negative values.

* Add: Core ticks tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants