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
d3.scale.log tickFormat returns empty labels with ticks() length too large #655
Comments
Can you provide an example of what you're trying to do? |
I have posted the code at https://gist.github.com/2817050 which can be viewed at http://bl.ocks.org/2817050 Note how when using log scale the tick values are all blank. You can flip to linear and power to see values show up for those. Basically what I'm trying to do is allow the display of any set of metrics for various timelines and allow switching between linear, power and log scales and resizing the graphs to fit whatever browser window they have. The example I've provided only has a single axis on the left but I'm working on some dual-axis use cases as well. The data ranges can be from 0 to 4 or 0 to 10s of millions so the max value of the axes are calculated using d3.max whenever the data is loaded. It all has been working very well with the exception of this small glitch for log scale tick labels. Line 286 of line-graph.js can be modified from this:
to the following to make the log ticks show up:
That is not an ideal thing to have to change though, as it then requires different values depending on what data is being passed in, what scale (log/linear/power) is being used and the vertical size of the chart. I have chosen to set the desired tick count to fit the vertical size I'm targeting and expected each of the axes to generate ticks accordingly and it was working well until one of my graphs didn't work with its dataset. After debugging I found it was because the data values caused a large number of ticks to be calculated which resulted in the conditional logic from my first comment preventing any tick labels to be created. Also, if my use of the d3.js library or my javascript isn't correct, please let me know as I don't consider myself an expert at Javascript (and if that's the source of this issue I apologize for wasting your time). Thank you for taking the time to look at this for me. |
Thank you for the fix and the library. |
I've tried using the d3.v2.js and d3.v2.min.js from the branch where this fix was committed and they do not appear to resolve the problem. https://github.com/mbostock/d3/blob/fix-log-ticks/d3.v2.js I updated the example gist to use this source and demonstrate it is still not resolved. |
As best I can tell, you're using your own tick format for that example anyway—you're not using the log scale's tickFormat, so my fix doesn't change anything in your code. |
Ah, wait, sorry. I misread. That's the inner format that's passed through the log scale's format. This seems to reproduce the problem if you want to debug it: var y = d3.scale.log().domain([1e-1, 1e7]);
y.ticks(6).map(y.tickFormat(6)); |
Here is a version using default tick formatting and https://github.com/mbostock/d3/blob/fix-log-ticks/d3.v2.js and ticks do not show up: http://bl.ocks.org/2876258 Issue 655 Example Without Custom Formatting Here is a fork of my example that includes my patched version of d3.js that makes the ticks show: http://bl.ocks.org/2876215 Issue 655 Example (Patch) Here is the same example with default tick formatting using my patched d3.js file so ticks show up: http://bl.ocks.org/2876239 Issue 655 Example (Patch) Without Custom Formatting In the patched examples, line 2825 of d3.v2.patched.js is the location of the patch that makes the ticks correctly show. |
I'm looking at the code example you sent ... my previous comment was sent before I saw your second comment. The examples I provide do however show the functionality without custom formatting being involved. |
Yes, that code replicates it. Debugging now and will post what I find. Thanks |
I think the only change that needs to occur is this: return d / pow(f(log(d) + e)) < k ? format(d) : ""; to return d / pow(f(log(d) + e)) <= k ? format(d) : ""; Your previous change made it so the smallest value of k is 0.1, but the tick value (d / pow(f(log(d) + e))) ends up being 0.1 and thus never less than 0.1 in scenarios where k is 0.1 Thus, it just needs to be <= as opposed to just < k. I've posted my test and with the fixed version at http://bl.ocks.org/2876507 The diff can be seen here: https://github.com/benjchristensen/d3/commit/8dcd8fe8d5ce128468774f8db06b73482b45e25a#d3.v2.js I'm not sure what other files I should be changing so I'm not doing a pull request as your previous commit seemed to have also touched unit tests and triggered a build of the minified version. |
Thanks Mike. |
The following code returns empty labels when the desiredTickCount/ticks().length < 0.1.
Changing the code to explicitly check for == 0.1 seems to fix it in the use cases I've got, but I am sure there are scenarios I'm missing that necessitated the use of the k variable.
The other way to work around it is to configure the desiredTickCount to be higher, but that doesn't work well for dynamic charts. For example, if 6 is generally the appropriate desiredTickCount but then a certain dataset requires 10 for the log scale to display it's awkward to determine that and would be preferable for the above scale.tickFormat function to correctly handle it.
The text was updated successfully, but these errors were encountered: