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

Setting bar bandPosition to 0 with timeUnit on complex chart breaks bars #9228

Open
1 task done
nicolaskruchten opened this issue Jan 17, 2024 · 0 comments
Open
1 task done
Labels

Comments

@nicolaskruchten
Copy link

nicolaskruchten commented Jan 17, 2024

Bug Description

This bug appears only in a narrow condition which happens to be fairly important to us, and which was enabled by this PR (cc @kanitw!). A very stripped-down example is as follows (link to editor). Setting encoding.x.bandPosition: 0 causes the bars to disappear, possibly because the resulting Vega spec has data entries that refer to each other out of order. Certainly VegaFusion rejects the resulting Vega spec because of this issue.

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "layer": [
    {
      "data": {"url": "data/stocks.csv"},
      "encoding": {
        "x": {"field": "date", "timeUnit": "year", "bandPosition": 0.5},
        "y": {"field": "price", "aggregate": "sum"}
      },
      "layer": [
        {
          "transform": [{"filter": "isValid(datum[\"date\"])"}],
          "layer": [{"mark": "bar"}, {"mark": "point"}]
        },
        {
          "transform": [{"filter": "isValid(datum[\"date\"])"}],
          "layer": [{"mark": "line"}]
        }
      ]
    }
  ]
}

This doesn't happen with a single layer or a single mark per layer, or if the two layers have different transform values 🤪 or if the transforms are hoisted up to the top level.

The actual spec we're working contains more repetition, like this, but the bug is the same.

Here is the offending Vega code that gets generated when bandPosition is set to 0. It looks like data_0 refers to source_0 which doesn't contain year_date or the other date-derived fields, which are in data_1:

"data": [
    {
      "name": "source_0",
      "url": "data/stocks.csv",
      "format": {"type": "csv", "parse": {"date": "date"}, "delimiter": ","},
      "transform": [{"type": "filter", "expr": "isValid(datum[\"date\"])"}]
    },
    {
      "name": "data_0",
      "source": "source_0",
      "transform": [
        {
          "type": "aggregate",
          "groupby": [
            "year_date",
            "year_date_end",
            "year_date_offsetted_rect_start",
            "year_date_offsetted_rect_end"
          ],
          "ops": ["sum"],
          "fields": ["price"],
          "as": ["sum_price"]
        },
        {
          "type": "filter",
          "expr": "(isDate(datum[\"year_date\"]) || (isValid(datum[\"year_date\"]) && isFinite(+datum[\"year_date\"]))) && isValid(datum[\"sum_price\"]) && isFinite(+datum[\"sum_price\"])"
        }
      ]
    },
    {
      "name": "data_1",
      "source": "source_0",
      "transform": [
        {
          "field": "date",
          "type": "timeunit",
          "units": ["year"],
          "as": ["year_date", "year_date_end"]
        },
        {
          "field": "date",
          "type": "timeunit",
          "units": ["year"],
          "as": ["year_date", "year_date_end"]
        },
        {
          "type": "formula",
          "expr": "0.5 * timeOffset('year', datum['year_date'], -1) + 0.5 * datum['year_date']",
          "as": "year_date_offsetted_rect_start"
        },
        {
          "type": "formula",
          "expr": "0.5 * datum['year_date'] + 0.5 * datum['year_date_end']",
          "as": "year_date_offsetted_rect_end"
        },
        {
          "type": "aggregate",
          "groupby": ["year_date", "year_date_end"],
          "ops": ["sum"],
          "fields": ["price"],
          "as": ["sum_price"]
        }
      ]
    },
    {
      "name": "data_2",
      "source": "data_1",
      "transform": [
        {
          "type": "filter",
          "expr": "(isDate(datum[\"year_date\"]) || (isValid(datum[\"year_date\"]) && isFinite(+datum[\"year_date\"]))) && isValid(datum[\"sum_price\"]) && isFinite(+datum[\"sum_price\"])"
        }
      ]
    }
  ],

Checklist

  • I checked for duplicate issues.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant