Skip to content

Conversation

@basbroek
Copy link
Contributor

@basbroek basbroek commented Jul 15, 2025

PR Description

This PR addresses long-standing issues (dating back to 2016) related to misalignment between the order of stacked marks and the domain in the color encoding. It potentially closes #1734, #6203, and #9496.

Proposed Solution

A new method has been added to the unit parser to check if a color domain is defined in the unit. If a domain is present and no custom order is set, additional encoding is injected to ensure that the color order of the mark matches the order in the legend.

Note

This is my first contribution to the project. If my code doesn't meet the project's standards or if the process I followed is incorrect, I apologise. I'm happy to refactor, feedback is very welcome!

Examples

Below are examples of specs rendered with the current code (left) and the same specs rendered with the proposed solution (right). All specs share this color encoding: "scale": {"domain": ["B", "A", "C"], "range": ["red", "blue", "green"]}

examples

@basbroek basbroek requested a review from a team as a code owner July 15, 2025 14:13
@basbroek basbroek changed the title fix/feat: align stack order with color domain fix: align stack order with color domain Jul 15, 2025
@nicolaskruchten
Copy link

(This is a very exciting PR, thank you for pushing on this!)

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.

Thank you.

offsetEncoding.sort = domain as [];
} else {
// align stacked bar and area order with color domain
const orderExpression = `indexof(${JSON.stringify(domain)}, datum.${field})`;
Copy link
Member

Choose a reason for hiding this comment

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

I think we can use stringValue from utils here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that makes sense, I have updated the code.

Copy link
Contributor Author

@basbroek basbroek Jul 19, 2025

Choose a reason for hiding this comment

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

Actually, I have a question regarding stringValue. If I understand correctly, its purpose is to escape problematic Unicode characters in strings, like explained here. So I changed my code to:

const orderExpression = `indexof(${stringValue(domain)}, datum['${stringValue(field)}'])`;

However, specs with problematic Unicode characters break the script anyway, as the following example shows: open it in the editor.

To avoid this, I think escaping or removing those characters could be handled earlier in the process. For example, this quick and dirty solution in the main compile function seems to work:

let spec = normalize(inputSpec, config);
spec = JSON.parse(
  JSON.stringify(spec)
    .replaceAll('\u2028', '')
    .replaceAll('\u2029', '')
);

Do you agree? If so, I would be happy to dig into this, though I assume that would be best handled in a separate PR?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, separate pull request. We don't really try to deal with bad characters in Vega-Lite except for a few cases that have come up.

@domoritz domoritz merged commit fad970f into vega:main Jul 22, 2025
8 checks passed
@domoritz
Copy link
Member

Thanks for the pull request. I thought the build already included all the changes but I missed a few critical issues. Can you fix them in a follow up pull request or should I revert the pull request for now?

  • In chore: build #9643 you can see that we include _year_sort_index in the accessibility description, which doesn't really make sense.
  • We seem to be sorting legends in examples where we have a color scale based on bins. We shouldn't really need to do that since in that case the color order is set and not dynamic. See a179516#diff-19db8933e9f1958a1a6b1b2279c1ba4351e32f8dba97bccf898d273eba0a3eb1 for example which doesn't really need to have the sort index. We should only add the sort index when it's needed.

@basbroek
Copy link
Contributor Author

@domoritz Thanks for your feedback. I have opened a new PR. I hope this will fix both issues.

domoritz added a commit that referenced this pull request Jul 22, 2025
## PR Description

Refines [PR: fix: align stack order with color
domain](#9641):

- Only for specs with nominal color encoding the stack order is aligned
with a custom color domain (if one is provided).
- The internal field that is use to order the stack is no longer added
to aria-labels in the SVG

---------

Co-authored-by: Bas Broekhuizen <bas.broekhuizen@gmail.com>
Co-authored-by: GitHub Actions Bot <vega-actions-bot@users.noreply.github.com>
yhoonkim added a commit that referenced this pull request Sep 11, 2025
yhoonkim added a commit that referenced this pull request Sep 11, 2025
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.

Allow specifying specific order of stack in stacked charts

3 participants