powerbivisualizationpowerbi-desktopvega-litedeneb

Snapping brush to dates for filtering


I have a text mark and two area marks concatenated vertically (related to my earlier question). The area marks each have a parameter brush and area 2 brush controls the domain of area 1. I'm using the brushed areas to filter the text mark and the issue is that as the x-axis is temporal, the brush seems to produce intervals in milliseconds whereas I want to brush in day units. I've changed the timeUnit to yearmonthdate however now the filtering does not work at all.

brushing individual days not working

How can the brush interval be snapped to individual dates and filter as before?

I've modified the previous code to change the timeUnit and also filtered on a single year to make it easier to brush individual days.

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {"url": "data/sp500.csv"},
  "transform": [
    {
      "filter": {"timeUnit": "year", "field": "date", "lte": "2000"}
    }
  ],
  "params": [
    {"name": "a", "expr": "brush1.date?true:false"},
    {"name": "b", "expr": "brush2.date?true:false"},
    
  ],
  "vconcat": [
    {
      "title": "text mark:",
      "width": 480,
      "mark": "text",
      "transform": [
         {"extent": "date", "param": "c"},
        {
          "joinaggregate": [
            {"op": "min", "field": "date", "as": "min_date"},
            {"op": "max", "field": "date", "as": "max_date"}
          ]
        },
        {
          "calculate": "a?brush1.date[0]:b?brush2.date[0]:datum.min_date",
          "as": "min_date"
        },
        {
          "calculate": "a?brush1.date[1]:b?brush2.date[1]:datum.max_date",
          "as": "max_date"
        },
        {
          "filter": "datum.date >= datum.min_date & datum.date <= datum.max_date"
        }
      ],
      "encoding": {
        "text": {
          "value": {
            "expr": "timeFormat(a?brush1.date[0]:b?brush2.date[0]:c[0], '%d %b %Y') + ' to ' + timeFormat(a?brush1.date[1]:b?brush2.date[1]:c[1], '%d %b %Y')"
          }
        }
      }
    },
    {
      "title": "area mark 1:",
      "width": 480,
      "mark": "area",
      "params": [
        {"name": "brush1", "select": {"type": "interval", "encodings": ["x"]}}
      ],
      "encoding": {
        "x": {
          "field": "date",
          "type": "temporal",
          "timeUnit": "yearmonthdate",
          "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", "timeUnit": "yearmonthdate"},
        "y": {
          "field": "price",
          "type": "quantitative",
          "axis": {"tickCount": 3, "grid": false}
        }
      }
    }
  ]
}

Solution

  • Change your references to yearmonthdate_date

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "data": {"url": "data/sp500.csv"},
      "transform": [
        {"filter": {"timeUnit": "year", "field": "date", "lte": "2000"}}
      ],
      "params": [
        {"name": "a", "expr": "brush1.yearmonthdate_date?true:false"},
        {"name": "b", "expr": "brush2.yearmonthdate_date?true:false"}
      ],
      "vconcat": [
        {
          "title": "text mark:",
          "width": 480,
          "mark": "text",
          "transform": [
            {"extent": "date", "param": "c"},
            {
              "joinaggregate": [
                {"op": "min", "field": "date", "as": "min_date"},
                {"op": "max", "field": "date", "as": "max_date"}
              ]
            },
            {
              "calculate": "a?brush1.yearmonthdate_date[0]:b?brush2.yearmonthdate_date[0]:datum.min_date",
              "as": "min_date"
            },
            {
              "calculate": "a?brush1.yearmonthdate_date[1]:b?brush2.yearmonthdate_date[1]:datum.max_date",
              "as": "max_date"
            },
            {
              "filter": "datum.date >= datum.min_date & datum.date <= datum.max_date"
            }
          ],
          "encoding": {
            "text": {
              "value": {
                "expr": "timeFormat(a?brush1.yearmonthdate_date[0]:b?brush2.yearmonthdate_date[0]:c[0], '%d %b %Y') + ' to ' + timeFormat(a?brush1.yearmonthdate_date[1]:b?brush2.yearmonthdate_date[1]:c[1], '%d %b %Y')"
              }
            }
          }
        },
        {
          "title": "area mark 1:",
          "width": 480,
          "mark": "area",
          "params": [
            {"name": "brush1", "select": {"type": "interval", "encodings": ["x"]}}
          ],
          "encoding": {
            "x": {
              "field": "date",
              "type": "temporal",
              "timeUnit": "yearmonthdate",
              "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", "timeUnit": "yearmonthdate"},
            "y": {
              "field": "price",
              "type": "quantitative",
              "axis": {"tickCount": 3, "grid": false}
            }
          }
        }
      ]
    }