Search code examples
powerbipowerbi-desktopvega-litevegadeneb

Task Names for Gantt Chart in Vega-lite


Hello I'm trying to create a Gantt Chart Visual in Vega Lite and i want to add the task names next the projekt name as extra column and that certain milestones with typ=4 are displayed with a different shape.

The data looks like the following:

USERPOS PROJEKT_NAME PLANSTART PLANENDE typ User_pos_ordering Project_pos_name
1 Projekt 1 24.06.2022 24.06.2023 1 1 Task 1
2 Projekt 1 13.02.2023 19.02.2023 2 2 Task 2
2.1 Projekt 1 15.02.2023 16.02.2023 3 2 Task 3
2.1.1 Projekt 1 16.02.2023 17.02.2023 3 2 Task 4
2.1.1.1 Projekt 1 16.02.2023 23.02.2023 4 2 Task 5

The json code i already have is:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {"name": "dataset"},
  "height": {"step": 15},
  "layer": [
    {
      "layer": [
        {
          "params": [
            {
              "name": "grid",
              "select": "interval",
              "bind": "scales"
            }
          ],
          "mark": {
            
            "type": "bar",
            "cornerRadius": 15

          },
          "encoding": {
            "color": {"field": "typ"}
          }
        },
        {
          "mark": {
            "type": "text",
            "align": "right"
          },
          "encoding": {
            "text": {
              "field": "USERPOS"
            },
            "color": {
              "value": "#000000"
            }
          }
        }
        
      ],
      "encoding": {
        "x": {
          "field": "PLANSTART",
          "type": "temporal",
          "axis": {
            "title": "Date",
            "grid": true,
            "gridColor": "black",
            "gridDash": [4, 4],
            "gridOpacity": {
              "condition": {
                "test": {
                  "field": "value",
                  "timeUnit": "month",
                  "equal": 1
                },
                "value": 1
              },
              "value": 0
            },
            "format": "%b%y"
          }
        },
        "y": {
          "field": "PROJEKT_Name",
          "type": "nominal",
          "axis": {
            "title": "Project Name",
            "grid": true,
            "tickBand": "extent"
          }
        },
        "x2": {"field": "PLANENDE"},
        "yOffset": {
          "field": "project_pos_name",
          "sort": {"field": "User_pos_ordering", "order":"ascending"}
        },
        "color": {"field": "typ"}
      }
    },
    {
      "transform": [
        {
          "calculate": "now()",
          "as": "now_field"
        }
      ],
      "mark": {
        "type": "rule",
        "color": "green",
        "size": 2
      },
      "encoding": {
        "x": {
          "sort": {"field": "PLANSTART"},
          "field": "now_field",
          "type": "temporal"
        }
      }
    }
  ]
}

With this specification it looks like this:

Current Version

And want i want to achieve is something like this:

Desired Version

I greatly appreciate any help!


Solution

  • EDIT

    New link

    EDIT END

    Add a new scale:

       {
      "name": "tFill",
      "type": "ordinal",
      "range": {"scheme":"category10"},
      "domain": {"data": "input", "field": "task"}
    }
    

    Use the new scale in these two places:

                  "fill": {
                    "signal": "item.mark.group.datum.task",
                    "scale": "tFill"
                  },
                  "stroke": {
                    "signal": "item.mark.group.datum.task",
                    "scale": "tFill"
                  },
    
    
              "fill": {"field": "task", "scale": "tFill"},
              "stroke": {"field": "task", "scale": "tFill"},
    

    Full spec (too big for SO so link only):

    enter image description here