Dynamic Step Size for X-Axis in Vega Specification

First of all, please note that I’m using Vega–not Vega-Lite. However, if there is a way to do this in Vega-Lite, I wouldn’t mind learning that also.

I’m trying to create a column chart that uses step size as the column width because there will be situations in which there will be so many columns that I want the chart to scroll horizontally rather than have tiny columns that get squished into the chart area. However, there will also be times when the data is filtered so that only a few columns are present. In these situations, I want the step size to adjust to the available space like the native Power BI column chart object does.

My thought process was to create a signal that would dynamically calculate the step size based on the number of rows present in the dataset. However, I have yet been able to get it to work. Below is what the relevant portion of the specification looks like. The exact formula I’ve used probably doesn’t make any sense at this stage since I’m just trying to get the chart to render for now. I’ll refine the formula once I can actually see a chart.

I’ve also attached the PBIX file. Any help would be greatly appreciated!

{
  "signals": [
    {
      "name": "stepSize",
      "update": "datum._rowcount > 10 ? 20 : 20 * (10 - datum._rowcount)"
    }
  ],
  "data": [
    {
      "name": "dataset",
      "transform": [
        {
          "type": "joinaggregate",
          "ops": ["count"],
          "fields": ["Letters"],
          "as": ["_rowcount"]
        }
      ]
    }
  ],
  "scales": [
    {
      "name": "xscale",
      "type": "band",
      "domain": {
        "data": "dataset",
        "field": "Letters"
      },
      "range": {
        "step": {"signal": "stepSize"}
      },
      "paddingInner": 0.1,
      "paddingOuter": 0.5,
      "round": true
    },
    {
      "name": "yscale",
      "domain": {
        "data": "dataset",
        "field": "Numbers"
      },
      "nice": true,
      "range": "height"
    }
  ],

Width Signal.pbix (1.6 MB)

Hi @DaveC. Unfortunately, no luck. I barely know Vega, so don’t have any insight there. I tried in Vega-Lite, but can only make the step size static (I haven’t tried this before and wasn’t able to find any examples to make the width/step dynamic). Nevertheless, I’ve uploaded what I have in Vega-Lite.

Hope this helps.
Greg
eDNA Forum - Deneb Vega-Lite Dynamic Step Size.pbix (1.6 MB)

Thanks for trying, @Greg. Anyone else want to give it a shot?

@dm-p, Sorry to tag you, but we don’t seem to have much experience with Vega as a group, so I was hoping you might be able to chime in. I’ve searched for a few hours on Google, and the only thing I can find where anyone is dynamically adjusting sizes using signals is to resize the entire visual based on browser window size using by hijacking the “width” and “height” signals. I can’t find any examples of dynamically setting the step size.

I know you’re on leave right now, so no rush. But I’d love your input at some point. Thanks!

As far as I can tell, you’re attempting to access a datum from the top-level signals array. The problem here is that multiple datasets exist, so Vega doesn’t know where you want to look. There is no global object called datum in this scope.

Instead, you can modify the signal as follows, to get the number of rows from the dataset directly by name rather than doing the joinaggregate against the dataset. Because this returns a JavaScript array, you can use the length property to get the number of rows:

  "signals": [
    {
      "name": "rowCount",
      "update": "data('dataset').length"
    },
    {
      "name": "stepSize",
      "update": "rowCount > 10 ? 20 : 20 * (10 - rowCount)"
    }
  ],

This will evaluate to zero if all rows get filtered out also, so you should be able to use it as a jumping-off point for the rest of your logic.

I’ve done this is 2 signals, just to avoid getting the dataset twice in the stepSize signal logic, but yu could do it all in one if you like.

Source: data function.

You could also wrap the expression with a length function to achieve similar results.

I’ve also re-attached your workbook with my changes in situ.

Width Signal.pbix (1.6 MB)

2 Likes

Thank you so much for taking the time to look at this! I will work through it tonight and try to get my head around it.

I don’t want to combine multiple issues into one topic, but I do have one other issue I’ve run into that seems to apply only when using Vega instead of Vega-Lite. I will describe it in another post.

Thanks again!