powerbivisualizationpowerbi-desktopvega-litedeneb

Joining consecutive values in rule mark


This is a followup to this question, modified for dynamic x-axis range. The idea is to have line segments at the bottom of the chart based on a boolean value, in this example when the price goes over 400.

Is there a way to have the rule mark (or any other mark) so that it joins on consecutive values? I could increase the stroke width however when I dynamically filter the date range it would break. Alternatively some formula to calculate the stroke width based on extents, but that seems overkill.

This is the example (based on the code below)

disjoint rule marks

I'd like it to look something like this, i.e. the marks are joined no matter how much the x-axis is zoomed in or out:

joint rule marks

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "description": "Google's stock price over time.",
  "data": {"url": "data/stocks.csv"},
  "transform": [
    {"filter": "datum.symbol==='GOOG'"},
    {"filter": {"timeUnit": "year", "field": "date", "lte": "2007"}},
    {"filter": {"timeUnit": "year", "field": "date", "gte": "2005"}},
    ],
  "encoding": {"x": {"field": "date", "type": "temporal"}},
  "layer": [
    {
      "mark": "area",
      "encoding": {"y": {"field": "price", "type": "quantitative"}}
    },
    {
      "transform": [
        {"calculate": "datum.price > 400 ? 1 : 0", "as": "high_price"}
      ],
      "mark": {"type": "rule", "strokeWidth": 4},
      "encoding": {
        "y": {"value": 201}, "y2":{"value":195},
        "opacity": {"field": "high_price", "type": "quantitative", "scale":{"rangeMin":0}, "legend":null},
        "color": {"value": "red"}
      }
    }
  ]
}

Followup 12 Aug 24:

Responding to @davidebacci - this is what I mean by patchy - this is a direct copy of your answer into https://vega.github.io/editor/ Please observe the discontinuities of the red line on the right. Your suggestion is what I used at the start when asking the question to get the smoother line - set stroke width a bit wider. This works on a static chart but fails when changing zoom level dynamically.

patchy


Solution

  • This should work at any size.

    enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "description": "Google's stock price over  time.",
      "data": {"url": "data/stocks.csv"},
    
      "transform": [
        {"filter": "datum.symbol==='GOOG'"},
        {"filter": {"timeUnit": "year", "field": "date", "lte": "2007"}},
        {"filter": {"timeUnit": "year", "field": "date", "gte": "2005"}},
        {
          "sort": [
            {"field": "date", "order": "ascending"}
    
          ],
          "window": [{"op": "lead", "as": "nextDate", "field": "date"}]
        }
      ],
      "encoding": {"x": {"field": "date", "type": "temporal"}},
      "layer": [
        {
          "mark": "area",
          "encoding": {"y": {"field": "price", "type": "quantitative"}}
        },
        {
          "transform": [
            {"calculate": "datum.price > 400 ? 1 : 0", "as": "high_price"}
          ],
          "mark": {"type": "rect"},
          "encoding": {
            "x": {"field": "date"},
           "x2": {"field": "nextDate"},
           
            "y": {"value": 201},
            "y2": {"value": 196},
            "opacity": {
              "field": "high_price",
              "type": "quantitative",
              "scale": {"rangeMin": 0},
              "legend": null
            },
            "color": {"value": "red"}
          }
        }
      ]
    }