jsonchartsvisualizationvega-lite

Dynamically change color of vega-lite area plot based on result of linear regression


We have time series data with an overlay of the linear regression to indicate the trend
enter image description here

Now we would like to color it red if the trend is declining as shown here
enter image description here

See the example

We have tried various ways with parameters but did not manage to have the color dependent on the trend. Our approach was focused on getting the slope and check if it was positive or negative.


Solution

  • Here you go. I'll let you fix the gradient.

    enter image description here

    enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "params": [
        {
          "name": "slope",
          "expr": " (data('data_1')[1]['date']-data('data_1')[0]['date'])/(data('data_1')[1]['value']-data('data_1')[0]['value']) "
        },
        {
          "name": "red",
          "expr": "{gradient: 'linear', stops: [{offset: 0, color: 'red'}, {offset: 1, color: 'red'}]}"
        },
        {
          "name": "green",
          "expr": "{gradient: 'linear', stops: [{offset: 0, color: 'green'}, {offset: 1, color: 'green'}]}"
        }
      ],
      "data": {
        "values": [
          {"date": "2023-03-31", "value": 80},
          {"date": "2023-06-30", "value": 78},
          {"date": "2023-09-31", "value": 81},
          {"date": "2023-12-31", "value": 75},
          {"date": "2024-03-31", "value": 72},
          {"date": "2024-06-30", "value": 75},
          {"date": "2024-09-31", "value": 70}
        ]
      },
      "encoding": {
        "x": {"field": "date", "type": "temporal"},
        "y": {"field": "value", "type": "quantitative"}
      },
      "layer": [
        {
          "mark": {
            "type": "line",
            "color": "rgba(0,0,0,0.5)",
            "strokeWidth": 2,
            "clip": true
          },
          "transform": [{"regression": "value", "on": "date"}]
        },
        {
          "mark": {
            "type": "area",
            "clip": true,
            "line": {"color": {"expr": "slope>0?'red':'green'"}, "strokeWidth": 4},
            "color": {"expr": "slope>0?red:green"}
          }
        }
      ]
    }