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

Y Axes alignment option #985

Closed
wants to merge 9 commits into from
Closed

Conversation

gazal-k
Copy link
Contributor

@gazal-k gazal-k commented Aug 13, 2015

When there are two y axes and at least one of them has values in the negative range, the 0 level on both axes don't line up.
Having an option to line them up seemed like a nice to have in my opinion.

Example:

Without Setting alignAxes option:

screenshot from 2015-08-13 10 01 59

Setting alignAxes option:

chart.alignAxes(true);

screenshot from 2015-08-13 10 03 40

Pending

  • tests
  • docs (couldn't find how to generate the docs)

@gordonwoodhull
Copy link
Contributor

I agree this is a good feature. However, I find the implementation excessively complicated.

  • I think you can implement this with much simpler, much less code by adapting the two places where yAxisMin, rightYAxisMin, yAxisMax, rightYAxisMax are used, rather than changing how they are defined.
  • You have made yAxisMin and rightYAxisMin mutually recursive, each one calling the other with the alignment flag implicitly false. This is inefficient, because all the data will be evaluated twice. I also find this implementation confusing.
  • At least to me, it seems more intuitive to leave the meaning of these functions alone, to let them still return the actual minimum and maximum for each axis. Then, after each has been calculated, adjust all four values and set the ranges for both left and right axes. Of course this means combining prepareLeftYAxis and prepareRightYAxis, which is fine, because they are only ever called at the same time, from _prepareYAxis. The combined function could be prepareYAxes(left, right), where left and right are boolean parameters.

Also, this definitely needs tests in spec/composite-chart-spec.js, showing that the axes are not aligned with alignedAxes false, and are aligned with alignedAxes true. IMO the flag should also be called alignYAxes.

@gazal-k
Copy link
Contributor Author

gazal-k commented Sep 15, 2015

@gordonwoodhull sorry about that. I'd been using the composite chart in an application we're developing. Originally this axes alignment feature was developed outside composite-chart's source which actually was more optimal. I kinda messed it up when I tried to put that into composite-chart code.
So, now I've used the original implementation and introduced it into composite-chart as per your recommendations.
Just a minor difference though, because of cyclomatic complexity, I'd to refactor it again. There's no unified prepareYAxes function. Instead the calculation for axes alignment is done in a separate function and its result fed to prepareLeftYAxis and prepareRightYAxis.

I haven't added tests in spec/composite-chart-spec.js yet. Before that, please let me know if the refactor is ok.

if (leftYAxisChildren().length !== 0) { prepareLeftYAxis(); }
if (rightYAxisChildren().length !== 0) { prepareRightYAxis(); }
var left = (leftYAxisChildren().length !== 0), right = (rightYAxisChildren().length !== 0),
ranges = calculateYAxesRanges(left, right);
Copy link
Contributor

Choose a reason for hiding this comment

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

Needs var otherwise ranges will end up in the global scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gordonwoodhull looks like I mislead you with the indentation. I'll just change the multivar declare for better readability.

@gordonwoodhull
Copy link
Contributor

Ah, this looks much more clear! And now I understand why you took the prior approach, modifying these classes from outside is indeed tricky. I like that the new approach doesn't change existing interfaces.

This can go into the 2.0 branch, once you add tests. Thanks!

@gordonwoodhull gordonwoodhull added this to the v2.0 milestone Oct 6, 2015
Conflicts:
	dc.js.map
	dc.min.js
	dc.min.js.map
	web/js/dc.js.map
	web/js/dc.min.js
	web/js/dc.min.js.map
@gordonwoodhull
Copy link
Contributor

Duh, right, fooled by the indent. Thanks!

@gordonwoodhull
Copy link
Contributor

Hi @gazal-k.

Thanks again! I'm currently merging this. The design and code structure is very good, but I'm not sure about the actual calculation. It can cause one of the axes actually to flip over, in the simple Jasmine test case I built where one of the charts is all negative.

Could you explain the rationale behind taking the ratio of minimum and maximum on one axis, and then applying this ratio to the other axis? It seems like it does cause the zero lines to match up, but might not always keep both plots with the chart boundaries or properly oriented.

gordonwoodhull added a commit that referenced this pull request Oct 31, 2015
add tests
force resize when changing alignYAxes
rename calculateYAxisRanges
add author
@gordonwoodhull
Copy link
Contributor

Merged in 2.0.0 beta 20

@gazal-k
Copy link
Contributor Author

gazal-k commented Oct 31, 2015

@gordonwoodhull sorry for the delayed reply. I don't remember exactly how I applied the math for it. Let me try the test you mentioned.

@gazal-k
Copy link
Contributor Author

gazal-k commented Oct 31, 2015

@gordonwoodhull thanks for that. I had totally missed that case. And sorry that I made you write the tests 😢
#1033 should fix the issue. Please check and let me know

@gazal-k gazal-k deleted the composite-chart-enh branch October 31, 2015 14:20
@gordonwoodhull
Copy link
Contributor

Note: I think it was implied that elasticY must be true to enable this feature. In the first pass we didn't account for this, but that caused breakage in #1056. I'm enforcing that now.

In other words, you can't manually apply the Y domains and use this feature, because this feature expects to set the Y domains for you.

gordonwoodhull added a commit that referenced this pull request Dec 4, 2015
@gazal-k
Copy link
Contributor Author

gazal-k commented Dec 5, 2015

@gordonwoodhull sorry about that. so alignYAxes should have no effect when elasticY is false, correct?

Shall make the change here: #1033

@gordonwoodhull
Copy link
Contributor

You agree this is correct, right? I think I have fixed it in the commit referenced above.

It may have been me who broke this in the first place, since I made some additional changes after testing your code.

Please review the fix and then document this requirement in #1033. Thanks!

@gazal-k
Copy link
Contributor Author

gazal-k commented Dec 5, 2015

Hadn't noticed 3d13e68.
But that only changes the spec, right? I didn't see any change in https://github.com/dc-js/dc.js/blob/develop/src/composite-chart.js that limits alignYAxes from being applied when elasticY is false.

And yes, I do agree that alignYAxes need only be applied when elasticY is true.

@gordonwoodhull
Copy link
Contributor

Whoops I linked one commit but not the other. Here is the fix: d1c087d

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

Successfully merging this pull request may close these issues.

2 participants