plotly.js icon indicating copy to clipboard operation
plotly.js copied to clipboard

Add tickmode "proportional"

Open ayjayt opened this issue 1 year ago • 17 comments
trafficstars

For https://github.com/plotly/plotly.js/issues/6824:

The basic idea is that we create a mode called 'proportional' which is equivelent to 'array' but values are mapped from proportions before drawn. ~Then again, array doesn't need to have to be recalculated on zoom, so it's not quite so simple.~ [0, .5, 1] would be [left-most point, middle, right-most point].

nb: includes my other trivial pull request about meta-charset

TODO:

  • [x] Check if graph is reversed
  • [x] Find where ticks are redrawn on zoom (like in "auto") and make redraw proportional (will probably fix below)
  • [x] Figure out why ticks not redrawn on double click/home
  • [x] Add docs in layout
  • [x] Run tests (make new tests)
  • [x] Use simplemap, not array map
  • [x] Test all other types of cartesian maps:
    • [x] category (disable it, probably?)
    • [x] log
    • [x] date
    • [x] multicategory (disable it, probably?)
  • [ ] New task List

ayjayt avatar Dec 26 '23 02:12 ayjayt

Re: https://github.com/plotly/plotly.js/pull/6827/commits/6d48a3b87df9111ab7c7b7a98e1d726a799adb49 "Fix bug by which..." and "redrawing issue":

  • [x] Find where ticks are redrawn on zoom (like in "auto") and make redraw proportional (will probably fix below)
  • [x] Figure out why ticks not redrawn on double click/home

Issue was that replacing proportional values with actual values causes exponential tickval increase- each time actual values were to be calcuated, the proportional values used were equal to result of last calculation. This issue is a good argument for adding a whole new property other than tickvals (tickpropvals?)- but the relationship with array is nice for the end user experience.

ayjayt avatar Dec 26 '23 04:12 ayjayt

Alright that's pretty good. One more commit for whatever lint the bot picks up. I'll write tests after I get a response from devs.

Questions for devs:

  • Multicategories, should I even try to support it? It actually works kind of well for regular categories, it can help position the ticks.

Tomorrow, a youtube video with results.

Merry Christmas! image

ayjayt avatar Dec 26 '23 07:12 ayjayt

This strategy currently doesn't work if both major and minor ticks are proportional because plotly's array-mode conditions in calcTicks are broken. As of now, calcTicks cannot actually separate major and minor tick processing into separate loops (like it claims to do through comments and if (major)) instead processing major and minor ticks in the major loops, and then both again (duplicated) in the minor loops. There are other problems with that: Issue https://github.com/plotly/plotly.js/issues/6828, PR https://github.com/plotly/plotly.js/pull/6829

ayjayt avatar Dec 27 '23 04:12 ayjayt

Alright, the testing is parameterized and randomized:

It tests xaxis.tickmode:'proportional' xaxis.minor.tickmode:'proportional' yaxis.tickmode:'proportional' and yaxis.minor.tickmode:'proportional' in every permutation. Understandably, it's failling as a result of https://github.com/plotly/plotly.js/issues/6828.

All tickval are randomized, both length and values.

It runs for category linear log date type graphs and checks proportions against DOM object properties to verify geometry.

File would obviously be renamed or put into other more relevant location.

I don't understand how this concept would extend to multicategory especially since multicategory is TODO in arrayTicks.

Also, not sure how range padding is calculated but it might be convenient if the user were to know what proportion is added by padding so, eg., w/ autorange, maybe [.05, .95] would have the intended effect of [0, 1].

ayjayt avatar Dec 28 '23 23:12 ayjayt

Interesting PR. I merged your #6826 pull request. To simplify the diffs for the reviewers here, I suggest you fetch upstream/master then after git pull, merge master into this branch. Thank you!

archmoj avatar Jan 02 '24 14:01 archmoj

Two suggestions by Alex coming tonight:

  1. Change Name
  2. Additional mode to allow generation of ticks along domain w/o

Tomrrow: 3) Test for #2 tomorrow

ayjayt avatar Jan 02 '24 23:01 ayjayt

Please pull upstream/master and merge it into this branch. Thank you!

archmoj avatar Jan 04 '24 02:01 archmoj

@archmoj alex is suggesting a different strategy for implementing this so i was thinking of letting this branch die?

edit: merged and done either way

ayjayt avatar Jan 04 '24 02:01 ayjayt

@archmoj alex is suggesting a different strategy for implementing this so i was thinking of letting this branch die?

Up to you. BTW you could possibly revert all the changes in one commit (or the ones that you don't need) and then keep going on this branch too. It's still easy to review this PR. That way you would also be rewarded all these valuable contributions on this list here: https://github.com/plotly/plotly.js/graphs/contributors Obviously that's just one measure.

archmoj avatar Jan 04 '24 03:01 archmoj

Sure, I can keep the history intact, it's a good idea. The end goal here is products for our customers so recognition means very little to me but I like the idea of having a clear history!

ayjayt avatar Jan 04 '24 03:01 ayjayt

Sure, I can keep the history intact, it's a good idea. The end goal here is products for our customers so recognition means very little to me but I like the idea of having a clear history!

It's still "clean history" if you continue IMHO. But I'll let you decide.

archmoj avatar Jan 04 '24 03:01 archmoj

Ok! There will be syntax and publish-dist to do after this- also replacing math.Random() w/ psuedoRandom()

Note One issue I have is that jasmine is not set up to parameterize tests, which I like a lot. I generally run tests on my features with every possible configuration, or as many as I can loop through.

The issue is that Jasmine tests are staged in a setup function() and an evaluate function(). Communicating the configuration between the setup (which needs it) and the evaluation (which needs it) requires either use of keyword let in the for loop, or the use of a closure function, which means

for (var i =0; i < N; i=++) {
   (function(i){
       // Test code here, several separate functions `then().then().then()` run with N different configurations.
    })(i);
}

It's ugly but the other solutions are using let or using a jasmine package that allows for parameterization, and that felt too involved for me, since it's more of a long-term testing-architecture decision.

ayjayt avatar Jan 04 '24 03:01 ayjayt

Thanks for the improvements. Are you going to add one or few mocks displaying new features? If so, please start your filename(s) with these letters: zz-... i.e. to avoid a CircleCI bug in our current image test system.

archmoj avatar Jan 12 '24 21:01 archmoj

Sure sure, whatever is needed.

ayjayt avatar Jan 12 '24 22:01 ayjayt

So, I'm happy to write logic + tests for the tick-mode combination but I need it spelled out (and what do we do if they try a combo that doesn't work?- edit: I'll just take a look at how layout_attribute.js violations handles bad values and probably add the logic in the same place)

To confirm:

Major Tickmode: Auto, Linear
  allow:
    Auto                # (within major ticks)
    Linear              # (absolute values)
    Array               # (absolute values)


Major Tickmode: Array
  allow:
    Linear              # (absolute values)
    Array               # (absolute values)

Major Tickmode: Sync
  allow:
    Sync                # automatic

Major Tickmode: Full Domain
  allow:
    Full Domain         # (within major ticks)
    Domain Array        # (within major ticks)

Major Tickmode: Domain Array
  allow:
    Domain Array        # (within major ticks)

ayjayt avatar Jan 24 '24 21:01 ayjayt

  • [x] Use a private property ax._something instead of overriding ax.tickvals
  • [x] Remove use of Lib.nestedProperty
  • [ ] Make some mocks
  • [ ] Rework math on minor ticks to be relative to major ticks (what do we do if major ticks is [])
  • [ ] Reinspect log math
  • [ ] Fail if using domain array/full domain in *category mode (how?)
  • [ ] Maybe take a look at sync while I'm here? (@archmoj if you don't mind)
  • [ ] Nail down the logic tree for proper major/minor tick combinations

ayjayt avatar Jan 25 '24 02:01 ayjayt