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

feat: support offset channel for grouped bar chart and jittering #7684

Merged
merged 26 commits into from
Oct 8, 2021

Conversation

kanitw
Copy link
Member

@kanitw kanitw commented Sep 6, 2021

  • Unit test coverage

  • Add to example gallery

    • grouped bar
    • jittering
  • update docs

    • bar + facet independent scale
    • point
    • step
  • test examples / corner cases

    • better default step bar_grouped.vl.json
    • top-down sizing bar_grouped_fixed_width.vl.json
    • step for offset bar_grouped_step_for_offset.vl.json
    • step for position bar_grouped_step_for_position.vl.json
    • smooth transition from grouped bar to point / ticks point_grouped
    • layering bar_grouped_label, layer_bar_circle_grouped
    • jittering point_offset_random
    • grouped bar with non-grouped line ayer_bar_grouped_line_ungrouped.vl.json
    • offset only bar_x_offset_without_x_broken.vl.json
    • x = Q/T (continuous), disallow xOffset
      • Note that x=Q, xOffset=Q should be valid in the future and behave like offsetting the data in data domain before applying scale. However, that use case isn't that important to support in this PR.
    • datum def -- bar_grouped_repeated.vl.json

@kanitw kanitw force-pushed the kw/new-offset branch 4 times, most recently from 1e68335 to f544a4f Compare September 7, 2021 02:13
@kanitw kanitw mentioned this pull request Sep 7, 2021
@kanitw kanitw force-pushed the kw/new-offset branch 7 times, most recently from d60c72f to ee0d03a Compare September 13, 2021 04:28
kanitw added a commit that referenced this pull request Sep 13, 2021
…order

This is required for #7684 as xOffset must be normalized after x (same for y)
kanitw added a commit that referenced this pull request Sep 13, 2021
…order

This is required for #7684 as xOffset must be normalized after x (same for y)
// otherwise use the position
return [0, {signal: `bandwidth('${positionScaleName}')`}];
} else { // continuous scale
throw new Error(`Cannot use ${channel} scale if ${positionChannel} scale is not discrete.`)
Copy link
Member Author

Choose a reason for hiding this comment

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

We should never reach this line because we won't even generate the scale in the first place.

src/scale.ts Outdated
* @minimum 0
* @maximum 1
*/
nestedOffsetPaddingInner?: number | ES;
Copy link
Member Author

Choose a reason for hiding this comment

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

Any opinion about this config name?

Copy link
Member

Choose a reason for hiding this comment

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

Why is it nested and not just offset padding?

Copy link
Member Author

Choose a reason for hiding this comment

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

renamed to bandWithNestedOffsetPadding --> This is padding of the x/y scale, when they have x/yOffset nested, but the padding is for x/y scales, not x/yOffset scales. (offsetPaddingInner/Outer is then for x/yOffset scales)

/**
* Whether to apply the step to position scale or offset scale when there are both `x` and `xOffset` or both `y` and `yOffset` encodings.
*/
for?: StepFor;
Copy link
Member Author

Choose a reason for hiding this comment

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

Any opinion about this property name?

Copy link
Member

Choose a reason for hiding this comment

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

forScale or applyTo or along maybe?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think

{step: 20, for: "position"}

reads better than

{step: 20, forScale/applyTo/along: "position"}?

Copy link
Member

Choose a reason for hiding this comment

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

Full examples

{
  width: {step: 23, for: 'position'},
  mark: 'bar',
  encoding: {
    x: {field: 'x', type: 'nominal'},
    xOffset: {field: 'subx', type: 'nominal'}
  }
}
{
  width: {step: 23, for: 'offset'},
  mark: 'bar',
  encoding: {
    x: {field: 'x', type: 'nominal'},
    xOffset: {field: 'subx', type: 'nominal'}
  }
}

Another option may be forChannel. I am okay with for.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think for is also better than forChannel because it's for position (which is a category of channel). "for channel position" is swapping the order of the words anyway.

If it's unclear if a longer word is clearer, I generally prefer brevity

Copy link
Member

Choose a reason for hiding this comment

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

Agreed.

@kanitw kanitw force-pushed the kw/new-offset branch 2 times, most recently from f7064cb to 7ae3ea5 Compare September 18, 2021 08:19
Copy link
Member

@domoritz domoritz left a comment

Choose a reason for hiding this comment

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

  • Offset doesn't support title. Should we remove it from the schema?
  • Shouldn't the grouped bar chart have some padding between the bars? It looks pretty tight right now. Also, how do you add padding and still make sure that bars are centered?

Other than that, this is awesome!

src/stack.ts Outdated
let dimensionDef = encoding[dimensionChannel];
const dimensionChannel: 'x' | 'y' | 'theta' | 'radius' = getDimensionChannel(fieldChannel);
const groupbyChannels: StackProperties['groupbyChannels'] = [];
const groupbyFields: FieldName[] = [];
Copy link
Member

Choose a reason for hiding this comment

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

Could we make this a Set<FieldName>?

/**
* Whether to apply the step to position scale or offset scale when there are both `x` and `xOffset` or both `y` and `yOffset` encodings.
*/
for?: StepFor;
Copy link
Member

Choose a reason for hiding this comment

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

forScale or applyTo or along maybe?

@kanitw
Copy link
Member Author

kanitw commented Sep 29, 2021

Offset doesn't support title. Should we remove it from the schema?

There is no guide, but the field itself still has title, which can be used for tooltip.

@kanitw
Copy link
Member Author

kanitw commented Oct 2, 2021

Shouldn't the grouped bar chart have some padding between the bars? It looks pretty tight right now.

That's sort of intentional. If you google "grouped bar", even for D3, it seems like the norm is to have near-zero padding.
Plus, given padding in the underlying D3 scales is a ratio, not absolute pixel, trying to do padding for both x and xOffset can be pretty messy, esp. as a default behavior.

If you strongly think we should change this, let me know. Otherwise, I think we can merge this.

In any case, I also added config.scale.offsetBandPaddingInner/Outer just in case someone doesn't like the zero default.

Also, how do you add padding and still make sure that bars are centered?

Good question. You can add padding to x/yOffset scale. (Good that you ask because I then noticed a bug for this padding. It's now fixed.)

@domoritz
Copy link
Member

domoritz commented Oct 7, 2021

That's sort of intentional. If you google "grouped bar", even for D3, it seems like the norm is to have near-zero padding.
Plus, given padding in the underlying D3 scales is a ratio, not absolute pixel, trying to do padding for both x and xOffset can be pretty messy, esp. as a default behavior.

Wow, that's surprising. I feel some padding is better since the bars show different categories. But I guess not padding makes the grouping clearer. I don't feel strongly about it so we can leave as it is as long as it's easy to add padding.

@domoritz
Copy link
Member

domoritz commented Oct 7, 2021

I tested a couple specs locally and padding works like expected now. This is awesome.

@kanitw kanitw changed the title Support offset channel for grouped bar / jittering feat: support offset channel for grouped bar chart and jittering Oct 8, 2021
@kanitw kanitw enabled auto-merge (squash) October 8, 2021 03:11
@kanitw kanitw merged commit c84e581 into master Oct 8, 2021
@kanitw kanitw deleted the kw/new-offset branch October 8, 2021 03:13
@wylieconlon
Copy link

I'm not sure how the release cycle works on vega-lite, but it would be great if you could publish a release with this included!

@kanitw
Copy link
Member Author

kanitw commented Nov 16, 2021

Yes, I'm fixing one more bug that's relevant to this and then we'll release soon.

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.

3 participants