powerbilinear-gradientsvega-lite

line gradient based on dynamic inputs


I am wondering if it is possible to create a custom gradient coloring for a line chart based on a field or parameter value. Based on my research, it does not seem to be possible, as I couldn’t find any documentation supporting this functionality.

Although this post includes exactly the output I am looking for, it achieves the result using manually inputted values, which does not suit my needs --> LINK

My goal is to achieve something similar dynamically. For example, if the completion field is at 25%, the gradient would start at the x-position of 0, and for the first 25% of the line length, the color would match the value from the color field. The remaining portion of the line would use the same color but with an opacity of 0.3.

I suspect this might not be possible in Vega-Lite, but I would be happy to hear if someone has a workaround or a solution for this.

Thank you!

Sample:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {
    "values": [
      {"startDate": "2024-01-15", "category": "a", "value": 1, "color": "red", "completion": 0.25},
      {"startDate": "2024-01-17", "category": "a", "value": 1.5, "color": "red", "completion": 0.25},
      {"startDate": "2024-01-18", "category": "a", "value": 1.5, "color": "red", "completion": 0.25},
      {"startDate": "2024-01-19", "category": "a", "value": 1.5, "color": "red", "completion": 0.25},
      {"startDate": "2024-01-22", "category": "a", "value": 2, "color": "red", "completion": 0.25},
      {"startDate": "2024-02-15", "category": "b", "value": 2, "color": "blue", "completion": 0.45},
      {"startDate": "2024-02-17", "category": "b", "value": 2.5, "color": "blue", "completion": 0.45},
      {"startDate": "2024-02-18", "category": "b", "value": 2.5, "color": "blue", "completion": 0.45},
      {"startDate": "2024-02-19", "category": "b", "value": 2.5, "color": "blue", "completion": 0.45},
      {"startDate": "2024-02-22", "category": "b", "value": 3, "color": "blue", "completion": 0.45}
    ]
  },
  "mark": "line",
  "encoding": {
    "x": {
      "field": "startDate",
      "type": "temporal",
      "title": "Date"
    },
    "y": {
      "field": "value",
      "type": "quantitative",
      "title": "Value"
    },
    "detail": {
      "field": "category"
    }
  }
}

Solution

  • Instead of a line that has a gradient, consider adding a second layer where you visualize the completed vs target for each day. Or of course a gantt chart would be a good option here also. Here is a basic example:

    enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "width": 400,
      "data": {
        "values": [
          {
            "startDate": "2024-01-15",
            "category": "a",
            "value": 1,
            "color": "red",
            "completion": 0.25
          },
          {
            "startDate": "2024-01-17",
            "category": "a",
            "value": 1.5,
            "color": "red",
            "completion": 0.25
          },
          {
            "startDate": "2024-01-18",
            "category": "a",
            "value": 1.5,
            "color": "red",
            "completion": 0.25
          },
          {
            "startDate": "2024-01-19",
            "category": "a",
            "value": 1.5,
            "color": "red",
            "completion": 0.25
          },
          {
            "startDate": "2024-01-22",
            "category": "a",
            "value": 2,
            "color": "red",
            "completion": 0.25
          },
          {
            "startDate": "2024-02-15",
            "category": "b",
            "value": 2,
            "color": "blue",
            "completion": 0.45
          },
          {
            "startDate": "2024-02-17",
            "category": "b",
            "value": 2.5,
            "color": "blue",
            "completion": 0.45
          },
          {
            "startDate": "2024-02-18",
            "category": "b",
            "value": 2.5,
            "color": "blue",
            "completion": 0.45
          },
          {
            "startDate": "2024-02-19",
            "category": "b",
            "value": 2.5,
            "color": "blue",
            "completion": 0.45
          },
          {
            "startDate": "2024-02-22",
            "category": "b",
            "value": 3,
            "color": "blue",
            "completion": 0.45
          }
        ]
      },
      "transform": [
        {
          "calculate": "datum.value * (datum.completion > 0 ? datum.completion : 0)",
          "as": "completed"
        }
      ],
      "layer": [
        {
          "mark": {"type": "area", "interpolate": "monotone"},
          "encoding": {
            "x": {"field": "startDate", "type": "temporal", "title": "Date"},
            "y": {"field": "value", "type": "quantitative", "title": "Value"}
          }
        },
        {
          "mark": {"stroke": "white", "type": "area", "interpolate": "monotone"},
          "encoding": {
            "color": {"value": "#85C5A6"},
            "x": {"field": "startDate", "type": "temporal", "title": "Date"},
            "y": {"field": "completed", "type": "quantitative", "title": "Value"}
          }
        }
      ]
    }
    

    This could be a starting point for you:

    enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "data": {
        "values": [
          {
            "startDate": "2024-01-15",
            "category": "a",
            "value": 1,
            "color": "red",
            "completion": 0.25
          },
          {
            "startDate": "2024-01-17",
            "category": "a",
            "value": 1.5,
            "color": "red",
            "completion": 0.25
          },
          {
            "startDate": "2024-01-18",
            "category": "a",
            "value": 1.5,
            "color": "red",
            "completion": 0.25
          },
          {
            "startDate": "2024-01-19",
            "category": "a",
            "value": 1.5,
            "color": "red",
            "completion": 0.25
          },
          {
            "startDate": "2024-01-22",
            "category": "a",
            "value": 2,
            "color": "red",
            "completion": 0.25
          },
          {
            "startDate": "2024-02-15",
            "category": "b",
            "value": 2,
            "color": "blue",
            "completion": 0.45
          },
          {
            "startDate": "2024-02-17",
            "category": "b",
            "value": 2.5,
            "color": "blue",
            "completion": 0.45
          },
          {
            "startDate": "2024-02-18",
            "category": "b",
            "value": 2.5,
            "color": "blue",
            "completion": 0.45
          },
          {
            "startDate": "2024-02-19",
            "category": "b",
            "value": 2.5,
            "color": "blue",
            "completion": 0.45
          },
          {
            "startDate": "2024-02-22",
            "category": "b",
            "value": 3,
            "color": "blue",
            "completion": 0.8
          }
        ]
      },
      "transform": [{"calculate": "datum.value-0.2", "as": "lineWidth"}],
      "spacing": 0,
      "facet": {"field": "startDate", "type": "ordinal"},
      "spec": {
        "width": 70,
        "mark": {
          "type": "bar",
          "color": {
            "expr": "{'x1': 0,'y1': 1,'x2': 1,'y2': 1,gradient: 'linear', stops: [{offset: 0, color: datum.color},  {offset: datum.completion, color: 'white'}]}"
          }
        },
        "encoding": {
          "y": {"field": "value", "type": "quantitative", "title": "Value"},
          "y2": {"field": "lineWidth"}
        }
      }
    }