In d3.js, linear scale/axis with ticks at intervals of 2^(10*c) instead of 10^c?
-
06-06-2021 - |
سؤال
I'm using d3.js to show information about network traffic to great effect. At a certain point in the visualization, a y-axis is being used to show a count of bytes.
I am currently using the d3.svg.axis().ticks() system, which results in nice round numbers like 20000. When converting to kB/MB/etc, however the result is awkward numbers like 19.5, and 9.8. Is there a way to get ticks back on multiples of (2^(10*c)), like 1024, 1048576, etc, instead of multiples of (10^c)?
Other information/thoughts:
- I appreciate that svg.axis handles the nuts and bolts of painting for me, and would like to find a solution that does not displace this functionality.
- I'm open to modifying d3 and submitting a pull request, so long as it would jive with @mbostock and company.
- I've checked out the repos, focusing on the code in and around d3_scale_linearTickRange(), but don't see a simple way to accomplish my goals without changing the default functionality, which I need for other axis.
- There is one potential work-around posted below that could be considered, but it borders on dishonest.
المحلول
You could handle the tick values manually, as documented here: https://github.com/mbostock/d3/wiki/SVG-Axes#wiki-tickValues
var xAxis = d3.svg.axis()
.scale(x)
.tickValues([1, 2, 3, 5, 8, 13, 21]);
And you can use tickFormat for help with formatting, i.e. for fix precision and SI prefixes. https://github.com/mbostock/d3/wiki/Formatting#wiki-d3_format
نصائح أخرى
One work-around is to use the labels kilo- and mega- in an incorrect way, dividing by 1000 instead of 1024 to achieve the end result.
Instead of:
20000 B / 1024 = 19.5 kB :(
Stretch the truth with:
20000 B / 1000 = 20 kB :)
This seems unacceptable on its face, in that it willfully introduces error, but if I can convince myself that it's "only a few pixels" off, I might go for it in the interests of not performing surgery on d3 itself.
I'm sure there's a better method.