Search code examples
powerbivisualizationpowerbi-desktopvega-litedeneb

Filter mark by brush parameter conditionally


I have a text mark and two area marks concatenated vertically (based on example here). The area marks each have a parameter brush and area 2 brush controls the domain of area 1.

text and area marks

With the text mark, I want to show the date range that is filtered in this way:

  if area 1 is brushed use it as the only filter
    else if area 2 is brushed use it as the only filter
     else show full date range with no filter

Right now it shows the entire date range (in milliseconds).

As it is a text mark, the approach with using "scale": {"domain": {"param": "brush2"}}, doesn't work as with area mark 1. I guess setting up a filter in some way?

Here's the code without the text mark filter:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {"url": "data/sp500.csv"},
  "vconcat": [
    {
    "title": "text mark:",
    "width": 480,
    "mark": "text",
    "transform": [
      {
        "joinaggregate": [
          {
            "op": "min",
            "field": "date",
            "as": "min_date"
          },
          {
            "op": "max",
            "field": "date",
            "as": "max_date"
          }
        ]
      },
      {
        "calculate": "datum.min_date + ' to ' + datum.max_date",
        "as": "date_range"
      }
    ],
    "encoding": {
      "text": {
        "field": "date_range",
        "type": "nominal"
        }
    }
    },
    {
    "title": "area mark 1:",
    "width": 480,
    "mark": "area",
    "params": [{
      "name": "brush1",
      "select": {"type": "interval", "encodings": ["x"]}
    }],
    "encoding": {
      "x": {
        "field": "date",
        "type": "temporal",
        "scale": {"domain": {"param": "brush2"}},
        "axis": {"title": ""}
      },
      "y": {"field": "price", "type": "quantitative"}
    }
  }, {
    "title": "area mark 2:",
    "width": 480,
    "height": 60,
    "mark": "area",
    "params": [{
      "name": "brush2",
      "select": {"type": "interval", "encodings": ["x"]}
    }],
    "encoding": {
      "x": {
        "field": "date",
        "type": "temporal"
      },
      "y": {
        "field": "price",
        "type": "quantitative",
        "axis": {"tickCount": 3, "grid": false}
      }
    }
  }]
}

I've not changed date format from milliseconds to simplify the code - if there's an easy way to format it that would be appreciated but is not the key part of the question.


Solution

  • {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "data": {"url": "data/sp500.csv"},
      "vconcat": [
        {
          "title": "text mark:",
          "width": 480,
          "mark": "text",
          "transform": [
            {
              "joinaggregate": [
                {"op": "min", "field": "date", "as": "min_date"},
                {"op": "max", "field": "date", "as": "max_date"}
              ]
            },
            {
              "calculate": "datum.min_date + ' to ' + datum.max_date",
              "as": "date_range"
            }
          ],
          "encoding": {
            "text": {
       "value":{"expr": "brush1.date?brush1.date[0] + ' to ' + brush1.date[0]:brush2.date?brush2.date[0] + ' to ' + brush2.date[0]:datum.date_range"}
            }
          }
        },
        {
          "title": "area mark 1:",
          "width": 480,
          "mark": "area",
          "params": [
            {"name": "brush1", "select": {"type": "interval", "encodings": ["x"]}}
          ],
          "encoding": {
            "x": {
              "field": "date",
              "type": "temporal",
              "scale": {"domain": {"param": "brush2"}},
              "axis": {"title": ""}
            },
            "y": {"field": "price", "type": "quantitative"}
          }
        },
        {
          "title": "area mark 2:",
          "width": 480,
          "height": 60,
          "mark": "area",
          "params": [
            {"name": "brush2", "select": {"type": "interval", "encodings": ["x"]}}
          ],
          "encoding": {
            "x": {"field": "date", "type": "temporal"},
            "y": {
              "field": "price",
              "type": "quantitative",
              "axis": {"tickCount": 3, "grid": false}
            }
          }
        }
      ]
    }