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

Implement attributes base, offset and width in bar traces (issue 80) #1075

Merged

Conversation

n-riesco
Copy link
Contributor

This PR implements attributes base, offset and width as discussed in #80 .

This PR's review can be found here.

* Simplified algorithm to identify overlapping bars.

* Removed the closure setBarCenter.

* Checked that jasmine tests still pass.
* Converted the closure that groups vertical and horizontal bars into a
  function.

* This change will help split setPositions into functions for each
  barmode.
* Moved code to group bars from setGroupPositions to setPositions.
* Converted closure `barpositions` into function `setOffsetAndWidth`.

* This change will help split setPositions into functions for each
  barmode.
* Don't assume the position axis is `xa` in the calculation of
  `barDelta` in `bar/hover.js`.

* Updated `tests/bar_test.js` to account for the replacement of `t.bar`
  with `t.bargroupwidth`.

* Updated the group case in `tests/bar_test.js` to test the use of
  `layout.bargroupgap`.
* Refactored the code to set bar positions in overlay mode into function
  `setGroupPositionsInOverlayMode`.
* Refactored the code for setting bar positions into
  setGroupPositionsInOverlayMode,
  setGroupPositionsInGroupMode and
  setGroupPositionsInStackOrRelativeMode.

* Refactored code for stacking bars and computing minDiff into helper
  class Sieve.
* Renamed setBaseAndSize to stackBars.

* Refactor code to normalize bars into function normalizeBars.
* Allow minDtick update if barmode is group and bars overlap.
* Function sieveBars sieves all the bars without updating the bar bases.
  This step is required before calling normalizeBars.

* Function stackBars sieves all the bars and updates the bar bases and
  tops accordingly.
* Null defaults are used to denote optional properties.

* Note that null values are ignored by `Lib.nestedProperty(/**/).set()`,
  so that the pattern `fullTrace.base === undefined` still works.
* Added note to explain the reason why setGroupPositionsInOverlayMode
  handles the case barnorm is defined.
* Moved shared code between `setOffsetAndWidth` and
  `setOffsetAndWidthInGroupMode` to handle offset and width attributes
  into function `applyAttributes`.
* Test the use of the bar attributes: base, offset and width.
* Added mock images of bar plots using the attributes base, offset and
  width.
@etpinard etpinard added the feature something new label Oct 24, 2016
@etpinard etpinard added this to the v1.19.0 milestone Oct 24, 2016
@etpinard
Copy link
Contributor

@n-riesco great. I'll give this PR one last test drive tomorrow morning (UTC-4)

* This change is needed so that the attribute `base` in bar traces can
  accept `number` and `Date` values.
@n-riesco
Copy link
Contributor Author

@etpinard

plotschema_test.js fails because of attribute base. base can take a data value (valType: 'any') or a data array (valType: 'data_array').

I guess the easiest workaround would be to use valType: 'any' and remove arrayOk.

@etpinard
Copy link
Contributor

Can base be anything other than a number or an array of numbers?

If so, then it should be valType: 'number' with arrayOk: true.

@n-riesco
Copy link
Contributor Author

In principle, base could be any value taken by the corresponding axis. I can't think of any meaningful bar plot, where the size axis isn't a number, though.

@alexcjohnson How do you think? Did you have anything in mind in #80 that would require base to be any?

@alexcjohnson
Copy link
Collaborator

In general if there's no concept of zero on an axis then bar charts don't make sense. Though interestingly I guess with base we could relax that requirement and say distance must be meaningful (and the size data would be expressed as such a distance) but you don't need a zero. Date axes match that description, and the corresponding chart is a Gantt chart (cc @jackparmer ) so if we want to support that I guess base would need to be 'any' but size would still be a number (milliseconds)

@n-riesco
Copy link
Contributor Author

@etpinard @alexcjohnson Here's a crazy idea. At the moment, plotly classifies as valType: 'number' anything that isNumeric says it's a number. If isNumeric would consider Date values as numbers, then base declared as {valType: 'number', arrayOk: true} would also accept date values. Do you think this would work?

@etpinard
Copy link
Contributor

If isNumeric would consider Date values as numbers, then base declared as {valType: 'number', arrayOk: true} would also accept date values. Do you think this would work?

Hmm. I afraid that patching isNumeric will lead to some issues downstream. I'm thinking we should add a new valType called coordinate for attributes of the likes - in a future PR.

So, let's go with { valType: 'any', arrayOk: true } in this PR.

Thanks for the heads-up @n-riesco !

@n-riesco
Copy link
Contributor Author

@etpinard Do you want me to add arrayOk to

otherOpts: ['dflt', 'values'],
so that plotschema_test.js doesn't fail?

@alexcjohnson
Copy link
Collaborator

coordinate is an interesting idea... though you could say categories are coordinates too so it doesn't specify much. but yeah, dates and numbers are generally not interchangeable so we need to manage them separately.

I wonder if there would be value in valType unions, so you could specify number or date string, for example.

@etpinard
Copy link
Contributor

Do you want me to add arrayOk to

otherOpts: ['dflt', 'values'],
so that plotschema_test.js doesn't fail?

yes please.

@etpinard
Copy link
Contributor

Oh @n-riesco I forgot about something ... Plotly.restyle !

We (unfortunately - see #648) need to manually list which attributes require going through the calc / set-position on updates. That list is getting really ugly, but luckily the patch is easy to make:

image

should be all you need.

While doing so, maybe you can add one restyle test in bar_test.js. Requiring one test mock e.g require('@mocks/bar_attrs_relative'), together with a few Plotly.restyle calls and a few expect(gd.calcdata) should be all you need.

Sorry about the late notice.

* Fixed the bar tests that make use of the attribute offset. The values
  of the bar center in these tests were incorrect.
* Refactored `setWidthAndOffset` and `setWidthAndOffsetInGroupMode` so
  that the bar center is computed after applying the trace attributes
  offset and width.
@n-riesco
Copy link
Contributor Author

@etpinard While writing therestyle test, I noticed a bug in the calculation of the bar centers and the corresponding tests (bar centers have to be computed after applying offset and width). This is now fixed.

@etpinard
Copy link
Contributor

@n-riesco you win the PR of week 🏆

Thanks very much. This should make a bunch of people 😄

@etpinard etpinard merged commit 3cb7e7e into plotly:master Oct 25, 2016
@n-riesco n-riesco deleted the pr-20161017-issue-80-bar-base-offset-width branch October 27, 2016 16:18
@plotly plotly deleted a comment from AdnanBoota Aug 31, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants