Skip to content

Refactor Axes.doTicks and Axes.doTicksSingle #3254

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

Merged
merged 22 commits into from
Nov 20, 2018
Merged

Conversation

etpinard
Copy link
Contributor

@etpinard etpinard commented Nov 16, 2018

please review this PR commit-by-commit

Axes.doTicksSingle is currently used to compute and draw ticks, but also grid lines, tick labels, axis titles ... and a few more things. It is used by cartesian axes (via Axes.doTicks), colorbars, ternary axes and polar axes. Making that one single function work for all these cases turned Axes.doTicksSingle into hackcity 😨

In brief, this PR:

  • first breaks up Axes.doTicksSingle into drawTicks, drawGrid, drawZeroLine and drawLabels
  • wraps the cartesian ticks, grid, label, title sequence into a method called Axes.drawOne
  • renames Axes.doTicks -> Axes.draw, this one draws multiple (or all) cartesian axes
  • breaks up a few more reusable parts from Axes.drawOne
  • breaks up drawTitle, calcBoundingBox and doAutoMargin- which only get called by cartesian axes - from drawLabels
  • adapts colorbar, ternary and polar axis drawing code
  • removes a few hacks in ternary and polar subplots. I'm particularly 😄 about 944482c

Note: commit 5858067 is potentially dangenerous. No tests are failing because of it, but ignoring this comment:

// update the axis title
// (so it can move out of the way if needed)
// TODO: separate out scoot so we don't need to do
// a full redraw of the title (mostly relevant for MathJax)

makes me nervous.


A few things in axes.js could still be ironed out to make it even more "reusable":

  • a lot of things depend on ax._id.chaAt(0), this could made more general by adding a new opts flag e.g. orientation: 'h' | 'v'
  • tick sign logic is still a bit of a mess
  • clip-or-not-to-clip axis ticks logic is not great either
  • Axes.drawLabels could be made more d3-esque, but I worrying about potential performance losses.

but hopefully you'll find this PR a step in the right direction.

cc @plotly/plotly_js


TODO:

  • finish ✏️ jsDocs after initial 👍 -- done in: ea6e76f

- the companion Axes methods are:
  drawTicks, drawGrid, drawZeroLine, drawLabels, drawTitle
- axis-dependent params and functions are set as opts in drawOne
- stash tickLabels selection on ax._tickLabels to use it in drawTitle
  w/o having to query the DOM again
- some linting here and there.
... that uses Axes.drawOne, instead of Axes.doTicksSingle
... just like in the ternary case, but could potentially be
    used in elsewhere.
- say bye-bye to Axes.doTicks
- remove a few not obsolete '-' field on ternary subplot axis objects.
- call full updateRadialAxis on radial drag
  and call full updateAngularAxis on angular drag.
- no need to nest grid lines into extra <g> (that was an
  artifact from doTicksSingle.
- ... more cleanup to come.
... to turn off crispEdge SVG rendering.
@alexcjohnson
Copy link
Collaborator

@etpinard this is awesome. Huge step in the right direction!

Is all of this stuff sufficiently generalized that we could call most of it components/axes/ and leave in cartesian/axes.js only the stuff that's really specific to cartesian? Wouldn't have to do it now, but... is there going to be a better time?

commit 5858067 is potentially generous. No tests are failing because of it, but ignoring this comment...

Other than reading that comment I have no recollection of what's going on there... so I guess we just test what it seems to be worried about, which is dynamic title scoot. Do we have such tests? In the mathjax mock I see that both tick labels and axis title support mathjax, I guess in principle we should have 4 test cases: (regular/mathjax tick labels) * (regular/mathjax title), shifting back and forth between collision and no collision and verifying that the title moves to the right place.

a lot of things depend on ax._id.chaAt(0), this could made more general by adding a new opts flag e.g. orientation: 'h' | 'v'

Or even ax._orientation - you're moving away from that pattern in order to make the axis objects passed to the drawing routines require less mocking, but I feel like this one is meaningful enough as part of the axis' identity - does it ever want different values for the same axis in different contexts? Anyway it's used in some other places besides the drawing code - setConvert, scattered about the autotick & tick value/text code, and other places.

Anyway aside from ensuring we have tests for 5858067 I wouldn't consider any of my comments ^^ blocking, just opportunities to push this even farther, if you've got the appetite for it.

@@ -1805,7 +1805,7 @@ axes.drawTicks = function(gd, ax, opts) {
ticks.enter().append('path')
.classed(cls, 1)
.classed('ticks', 1)
.classed('crisp', 1)
.classed('crisp', !opts.noCrisp)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, that's cool! But I'm not a huge fan of negated option names - could we use:
opts.crisp !== false?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 016b8e4

... so that one can call it after dynamically adding MathJax
    <script> on page.
- so that one can include MathJax by adding a <script>
  for a given test.
- Removing MathJax from the page currently leads to errors
  in downstream tests.
@etpinard
Copy link
Contributor Author

I guess in principle we should have 4 test cases: (regular/mathjax tick labels) * (regular/mathjax title), shifting back and forth between collision and no collision and verifying that the title moves to the right place.

Looks like everything is ok: 6ccc457

... by the way ⤴️ are our first MathJax jasmine tests. About time.

@alexcjohnson
Copy link
Collaborator

Love it. 💃

@etpinard etpinard merged commit 695f311 into master Nov 20, 2018
@etpinard etpinard deleted the replace-axes-doTicks branch November 20, 2018 16:29
@etpinard
Copy link
Contributor Author

Is all of this stuff sufficiently generalized that we could call most of it components/axes/ and leave in cartesian/axes.js only the stuff that's really specific to cartesian?

I gave this a go this morning. I couldn't easily decide where to put a few things (e.g. cartesian/axis_ids.js and few methods in cartesian/axes.js), so I'll defer that for later.

Thinking about this, it might be nice to make a distinction between "registerable" (i.e optional) component modules (e.g. annotations/, shapes/) and component modules that are mostly intended to DRY things up (e.g. color/, colorscale/ ... and the soon-to-be axes/). Maybe the latter could be placed in different directory e.g. src/common/ and leave src/components/ for "registerable" modules?

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