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 layout.legend.orientation (closes #53) #535

Merged
merged 19 commits into from
May 17, 2016

Conversation

n-riesco
Copy link
Contributor

@etpinard @mdtusz @jackparmer

Here is a PR ready for review that closes #53 (horizontal legends).

* Removed unused `i`.

* Passed `legendItem` directly.
* Checked that all jasmine and image tests still pass.
* Set tspan.line's x in the callback to convertToSpans, otherwise they
  won't be set in the first render.

* Checked all jasmine and image tests still pass.
* Ensure the position of the `tspan.line`s is set before computing the
  legend dimensions and expanding the margins.

* The baseline image for `pseudo_html.json` needed updating because it
  has a multi-line legend.
* This change not only improves drawing performance, but it will also
  allows for `drawTexts` to be moved to `styles.js`.

* Checked all jasmine and image tests still pass.
* Moved the placing of legend groups to `computeLegendDimensions` so
  that they are handled along with the placing of legend traces.

* This change is a preliminary step to implement horizontal legends.

* Checked all jasmine and image tests still pass.
* Added `legend_horizontal.json` (a mock with a horizontal legend
  without groups).

* Added `legend_horizontal_groups.json` (a mock with a grouped
  horizontal legend).
@jackparmer
Copy link
Contributor

@n-riesco Wow, awesome! Psyched about this. Do you have a few screenshots that you could drop here?

@n-riesco
Copy link
Contributor Author

n-riesco commented May 14, 2016

@jackparmer Not the prettiest shots, but here are the mocks I used for testing:

  • with legend groups
    legend_horizontal_groups
  • without legend groups
    legend_horizontal

@@ -35,6 +35,13 @@ module.exports = {
font: extendFlat({}, fontAttrs, {
description: 'Sets the font used to text the legend items.'
}),
orientation: {
valType: 'enumerated',
values: ['v', 'h'],
Copy link
Contributor

Choose a reason for hiding this comment

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

@etpinard @cldougl @chriddyp

Do we want v/h or vertical/horizontal?

Copy link
Contributor

Choose a reason for hiding this comment

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

'v' / 'h' gets my vote - for parity with bar orientation.

@etpinard
Copy link
Contributor

@n-riesco This PR is looking great. Solid work. 🍻

Not handling looooong horizontal legend like:

image

is ok. I don't think we should make horizontal legends horizontally scrollable ( @mdtusz agrees).

This means that we'll probably have to add some sort legend item grid attribute at some point, to allow users to make grid-like legends. But, that will be for a future PR.

@jackparmer
Copy link
Contributor

ggplot2 users rejoice! cc @cpsievert

@n-riesco
Copy link
Contributor Author

@etpinard I wouldn't mind to implement a horizontal scrollbar in another PR.
For this PR, I'll make sure that horizontal legends don't extend beyond the plotting area.

* Used `selection.call()` to invoke drawTexts, setupTraceToggle and
  computeTextDimentions.
* Removed legendItem from the function signatures of drawTexts,
  setupTraceToggle and computeTextDimensions.
@etpinard
Copy link
Contributor

I wouldn't mind to implement a horizontal scrollbar in another PR

Actually, I don't think we should allow horizontal scrollbar ever. But yeah, not in this PR for sure.

I'll make sure that horizontal legends don't extend beyond the plotting area.

How exactly are you thinking about doing this? By truncating the legend? By making long horizontal legends span two (or more) rows? Something else?

@mdtusz
Copy link
Contributor

mdtusz commented May 17, 2016

Agreed on no horizontal scroll - I think it always feels very unnatural even at the best of times.

A grid layout of items when they overflow probably makes the most sense, but will be a bit of a pain to calculate with the varying text widths. If we go this route though, it will be a good opportunity to make a generalised method for "tabling" svg elements into a given width (or height too I suppose).

* Position horizontal legends on the bottom left, unless a range slider
  is present.

* If a range slider is present, position the horizontal legend on the
  top left.
@n-riesco
Copy link
Contributor Author

@etpinard I hadn't thought of spanning into multiple rows. I've truncated the legend width.

I can try the idea of spanning into multiple rows, but I think it won't be a small change.
Shall I leave it for a separate PR?

@etpinard
Copy link
Contributor

I've truncated the legend width.

Yep. That's fine

Shall I leave it for a separate PR?

Absolutely. That will give us the time to think about a future grid layout.

coerce('orientation');
if(containerOut.orientation === 'h') {
var xaxis = layoutIn.xaxis;
if(xaxis && xaxis.rangeslider && xaxis.rangeslider.visible) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Yep, that works. layout.xaxis is coerced before layout.legend. 👍

var mockLayoutIn = Lib.extendDeep({}, layoutInForHorizontalLegends);
mockLayoutIn.xaxis.rangeslider.visible = true;

supplyLayoutDefaults(mockLayoutIn, layoutOut, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

Great tests. Thanks

@etpinard
Copy link
Contributor

Great PR. It doesn't solve all our legend issues, but it certainly puts us in a good place to iterate on.

Brilliant work @n-riesco 🍻

@etpinard etpinard merged commit 5c91b8f into plotly:master May 17, 2016
@n-riesco n-riesco deleted the legend-orientation branch May 17, 2016 20:03
@ronakvala
Copy link

How can I use this feature of Legend Orientation in my code?

@n-riesco
Copy link
Contributor Author

@ronakvala The two simple examples I posted above can be found here:

@Nathan219
Copy link

@etpinard I hadn't thought of spanning into multiple rows. I've truncated the legend width.

I can try the idea of spanning into multiple rows, but I think it won't be a small change.
Shall I leave it for a separate PR?

What was your reasoning for truncating it? A legend isn't useful if it's cutting off things that are supposed to be listed.

Currently, I can't use vertical legends because of the negative anchor bug, and I can't use horizontal because it cuts stuff off. I don't want to group because I want people to be able to show/hide individual items.

At this point, my only choice is to implement my own legend :(.

@n-riesco
Copy link
Contributor Author

@Nathan219 I'm not sure I understand. I thought that after #786 horizontal legend traces wrap to new lines.

@Nathan219
Copy link

Looks like it does it when I don't use grouping. Grouped is still affected by the truncation. Looks like the anchoring issue is my main issue now, since both orientations are covering up the graph.

Thanks for the super quick response, by the way. Definitely appreciate it.

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.

Horizontal Legend below the chart
6 participants