Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Learn from the best! Meet the four finalists headed to the FINALS of the Power BI Dataviz World Championships! Register now

Reply
DGPBi
Helper I
Helper I

Power BI - Deneb/Vega 6.2.0: Filtering by Day Signal Causes Marks to Disappear

Hi everyone,
I am building a real-time schedule visual in Vega. I have a working visual that shows all data, but it breaks when I try to filter for the current day.
Data from provided from Power Bi to deneb:
- DST_ClockDiffBtwLocationAndLocalOffset:This is a measure. TimeZone Difference. provides the offset of this difference.

- From my Power BI table:
- ScheduleType

- day_num

- type

-startTime

-endTime

I have a query named AllSegments that creates a clean, flat table

Each day, for each scheduleType, we can have multiple rows. For example: 

Scheduletypeday_numtypestart_timeend_timestartTimeendTime
Production0No Production00:00:0022:00:00022
Production0Normal22:00:0023:59:002223.9833333
Production1Normal00:00:0023:59:00023:9833333
...      
SiteOpening0No Production00:00:0023:59:00023.9833333
SiteOpening1Normal08:30:0012:30:008.512.5
SiteOpening1Normal13:3017:00:0013.517
...      
Support0No Production00:00:0023:59:00023.9833333
Support1Normal08:30:0012:30:008.512.5
Support1Flexible13:30:0017:00:0013.517

 

       

The goal is one graph with a 24 hours
My working code:

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "A static visual for Monday with a dynamic real-time clock.",
  "background": "transparent",
  "width": 360,
  "height": 80,
  "autosize": {"type": "fit", "contains": "padding"},
  "signals": [
    {
      "name": "timer",
      "update": "now()",
      "on": [{"events": {"type": "timer", "throttle": 1000}, "update": "now()"}]
    },
    {
      "name": "adjustedTime",
      "update": "length(data('source')) > 0 ? utcOffset('seconds', timer, data('source')[0].DST_ClockDiffBtwLocationAndLocalOffset) : now()"
    },
    {
      "name": "currentTime",
      "update": "hours(adjustedTime) + minutes(adjustedTime) / 60"
    },
    {
      "name": "adjustedDate",
      "update": "timeFormat(adjustedTime, '%Y-%m-%d')"
    }
  ],
  "data": [
    {
      "name": "source"
    },
    {
      "name": "dataset",
      "source": "source",
      "transform": [
        {
          "type": "filter",
          "expr": "datum.ScheduleType == 'SiteOpening' && datum.type != 'No Production' && +datum.day_num == 1"
        }
      ]
    }
  ],
  "scales": [
    {
      "name": "xscale",
      "type": "linear",
      "domain": [0, 24],
      "range": "width"
    }
  ],
  "axes": [
    {
      "orient": "bottom",
      "scale": "xscale",
      "title": {"signal": "adjustedDate"},
      "tickCount": 24,
      "labelFontSize": 8,
      "offset": 5
    }
  ],
  "marks": [
    {
      "type": "rect",
      "from": {"data": "dataset"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "startTime"},
          "x2": {"scale": "xscale", "field": "endTime"},
          "y": {"value": 20},
          "height": {"value": 30},
          "fill": {"value": "lightgray"}
        }
      }
    },
    {
      "type": "rule",
      "from": {"data": "dataset"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "startTime"},
          "y": {"value": 15},
          "y2": {"value": 55},
          "stroke": {"value": "black"},
          "strokeWidth": {"value": 1}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "dataset"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "startTime"},
          "y": {"value": 15},
          "shape": {"value": "triangle-down"},
          "size": {"value": 40},
          "fill": {"value": "black"}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "dataset"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "endTime"},
          "y": {"value": 55},
          "shape": {"value": "triangle-up"},
          "size": {"value": 40},
          "fill": {"value": "black"}
        }
      }
    },
    {
      "type": "rule",
      "encode": {
        "update": {
          "x": {"scale": "xscale", "signal": "currentTime"},
          "y": {"value": 10},
          "y2": {"value": 60},
          "stroke": {"value": "red"},
          "strokeWidth": {"value": 2}
        }
      }
    },
    {
      "type": "text",
      "encode": {
        "update": {
          "x": {"scale": "xscale", "signal": "currentTime"},
          "y": {"value": 5},
          "text": {"signal": "timeFormat(adjustedTime, '%H:%M')"},
          "align": {"value": "center"},
          "fill": {"value": "red"},
          "fontSize": {"value": 10}
        }
      }
    }
  ]
}

Now, I want to filter these bars to show only the ones for the current day. I added a signals block for the current time and a filter to my data transform ...
Code doesn't work:

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "A dynamic, real-time visual for Site Opening Hours.",
  "background": "transparent",
  "width": 360,
  "height": 80,
  "autosize": {"type": "fit", "contains": "padding"},
  "signals": [
    {
      "name": "timer",
      "update": "now()",
      "on": [{"events": {"type": "timer", "throttle": 1000}, "update": "now()"}]
    },
    {
      "name": "adjustedTime",
      "update": "length(data('source')) > 0 ? utcOffset('seconds', timer, data('source')[0].DST_ClockDiffBtwLocationAndLocalOffset) : now()"
    },
    {
      "name": "currentTime",
      "update": "hours(adjustedTime) + minutes(adjustedTime) / 60"
    },
    {
      "name": "adjustedDate",
      "update": "timeFormat(adjustedTime, '%Y-%m-%d')"
    },
    {
      "name": "currentDayNum",
      "update": "day(adjustedTime)"
    }
  ],
  "data": [
    {
      "name": "source"
    },
    {
      "name": "opening_hours_today",
      "source": "source",
      "transform": [
        {
          "type": "filter",
          "expr": "datum.ScheduleType == 'SiteOpening' && datum.type != 'No Production' && +datum.day_num == currentDayNum"
        }
      ]
    }
  ],
  "scales": [
    {
      "name": "xscale",
      "type": "linear",
      "domain": [0, 24],
      "range": "width"
    }
  ],
  "axes": [
    {
      "orient": "bottom",
      "scale": "xscale",
      "title": {"signal": "adjustedDate"},
      "tickCount": 24,
      "labelFontSize": 8,
      "offset": 5
    }
  ],
  "marks": [
    {
      "type": "rect",
      "from": {"data": "opening_hours_today"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "startTime"},
          "x2": {"scale": "xscale", "field": "endTime"},
          "y": {"value": 20},
          "height": {"value": 30},
          "fill": {"value": "lightgray"}
        }
      }
    },
    {
      "type": "rule",
      "from": {"data": "opening_hours_today"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "startTime"},
          "y": {"value": 15},
          "y2": {"value": 55},
          "stroke": {"value": "black"},
          "strokeWidth": {"value": 1}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "opening_hours_today"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "startTime"},
          "y": {"value": 15},
          "shape": {"value": "triangle-down"},
          "size": {"value": 40},
          "fill": {"value": "black"}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "opening_hours_today"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "endTime"},
          "y": {"value": 55},
          "shape": {"value": "triangle-up"},
          "size": {"value": 40},
          "fill": {"value": "black"}
        }
      }
    },
    {
      "type": "rule",
      "encode": {
        "update": {
          "x": {"scale": "xscale", "signal": "currentTime"},
          "y": {"value": 10},
          "y2": {"value": 60},
          "stroke": {"value": "red"},
          "strokeWidth": {"value": 2}
        }
      }
    },
    {
      "type": "text",
      "encode": {
        "update": {
          "x": {"scale": "xscale", "signal": "currentTime"},
          "y": {"value": 5},
          "text": {"signal": "timeFormat(adjustedTime, '%H:%M')"},
          "align": {"value": "center"},
          "fill": {"value": "red"},
          "fontSize": {"value": 10}
        }
      }
    }
  ]
}

the final goal is:
- real time current clock (red bar + current hour text)
- real time current day. if it is a production day, a blue rect align on the 24 hours, if it is Flexible period, a dark blue rect. if No prod, a gray rect
- A second bar to provide info about when the location can have a support
- a legend with the different info


MyWish2.png

 

 

 


Thanks a lot for the support you will accept to provide 

1 ACCEPTED SOLUTION

OK, I solved all my problems so I post my code here if it can help someone else
I obtained my final visual like I show in my first post.

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "Final version with corrected 'ITSupport' string in the filter expression.",
  "width": 372,
  "height": 50,
  
  
  "signals": [
    {
      "name": "pbi_time_offset_seconds",
      "init": "isValid(data('pbi_summarize')[0]) ? data('pbi_summarize')[0].DST_ClockDiffBtwLocationAndLocalOffset : 0"
    },
    {
      "name": "utc_now",
      "init": "now()",
      "on": [
        {
          "events": {"type": "timer", "throttle": 1000},
          "update": "now()"
        }
      ]
    },
    {
      "name": "remote_now",
      "update": "utc_now + (pbi_time_offset_seconds * 1000)"
    },
    {
      "name": "remote_day",
      "update": "day(remote_now)"
    },
    {
      "name": "remote_hour_decimal",
      "update": "hours(remote_now) + (minutes(remote_now) / 60) + (seconds(remote_now) / 3600)"
    },
    {
      "name": "remote_time_label",
      "update": "timeFormat(remote_now, '%H:%M')"
    }
  ],

  "data": [
    {
      "name": "dataset"
    },
    {
      "name": "pbi_summarize"
    },
    {
      "name": "schedule_bands",
      "source": "dataset",
      "transform": [
        {
          "type": "filter",
          "expr": "datum.day_num != null && (datum.ScheduleType == 'Production' || datum.ScheduleType == 'ITSupport') && datum.day_num == remote_day"
        },
        {
          "type": "formula",
          "as": "display_type",
          "expr": "datum.type == 'Normal' ? (datum.ScheduleType == 'Production' ? 'Working hours' : 'Support hours') : datum.type == 'Flexible' ? 'Flexible hours' : 'No Working hours'"
        }
      ]
    },
    {
      "name": "site_opening_start",
      "source": "dataset",
      "transform": [
        {"type": "filter", "expr": "datum.day_num != null && datum.ScheduleType == 'SiteOpening' && datum.day_num == remote_day"},
        {"type": "project", "fields": ["startTime"], "as": ["time_value"]}
      ]
    },
    {
      "name": "site_opening_end",
      "source": "dataset",
      "transform": [
        {"type": "filter", "expr": "datum.day_num != null && datum.ScheduleType == 'SiteOpening' && datum.day_num == remote_day"},
        {"type": "project", "fields": ["endTime"], "as": ["time_value"]}
      ]
    }
  ],
  "scales": [
    {
      "name": "xscale",
      "type": "linear",
      "range": "width",
      "domain": [0, 24]
    },
    {
      "name": "yscale",
      "type": "band",
      "range": [1, 50],
      "domain": ["ITSupport", "Production"],
      "padding": 0.1
    },
    {
      "name": "color",
      "type": "ordinal",
      "domain": ["Working hours", "Support hours", "Flexible hours", "No Working hours"],
      "range": ["#a6cee3", "#b2df8a", "#1f78b4", "#d3d3d3"]
    }
  ],
  "axes": [
    {
      "orient": "bottom",
      "scale": "xscale",
      "tickCount": 25,
      "title": {
        "signal": "timeFormat(remote_now, 'Time & Day (%Y-%m-%d)')"
      },
      "labelFontSize": 9,
      "titleFontSize": 9
    }
  ],
  "marks": [
    {
      "type": "group",
      "name": "custom_legend",
      "encode": {"enter": {"x": {"value": 0}, "y": {"value": -40}}},
      "marks": [
        {"type": "rect", "encode": {"enter": {"x": {"value": 0}, "y": {"value": 0}, "width": {"value": 10}, "height": {"value": 10}, "fill": {"value": "#a6cee3"}}}},
        {"type": "text", "encode": {"enter": {"x": {"value": 15}, "y": {"value": 9}, "text": {"value": "Working hours"}, "fontSize": {"value": 10}, "align": {"value": "left"}}}},
        {"type": "rect", "encode": {"enter": {"x": {"value": 120}, "y": {"value": 0}, "width": {"value": 10}, "height": {"value": 10}, "fill": {"value": "#1f78b4"}}}},
        {"type": "text", "encode": {"enter": {"x": {"value": 135}, "y": {"value": 9}, "text": {"value": "Flexible hours"}, "fontSize": {"value": 10}, "align": {"value": "left"}}}},
        {"type": "rect", "encode": {"enter": {"x": {"value": 240}, "y": {"value": 0}, "width": {"value": 10}, "height": {"value": 10}, "fill": {"value": "#d3d3d3"}}}},
        {"type": "text", "encode": {"enter": {"x": {"value": 255}, "y": {"value": 9}, "text": {"value": "No Working hours"}, "fontSize": {"value": 10}, "align": {"value": "left"}}}},
        
        {"type": "rect", "encode": {"enter": {"x": {"value": 0}, "y": {"value": 15}, "width": {"value": 10}, "height": {"value": 10}, "fill": {"value": "#b2df8a"}}}},
        {"type": "text", "encode": {"enter": {"x": {"value": 15}, "y": {"value": 24}, "text": {"value": "Support hours"}, "fontSize": {"value": 10}, "align": {"value": "left"}}}},
        {"type": "rule", "encode": {"enter": {"x": {"value": 122}, "y": {"value": 13}, "x2": {"value": 122}, "y2": {"value": 23}, "stroke": {"value": "black"}}}},
        {"type": "symbol", "encode": {"enter": {"x": {"value": 122}, "y": {"value": 22}, "shape": {"value": "triangle-up"}, "size": {"value": 25}, "fill": {"value": "black"}}}},
        {"type": "rule", "encode": {"enter": {"x": {"value": 128}, "y": {"value": 15}, "x2": {"value": 128}, "y2": {"value": 24}, "stroke": {"value": "black"}}}},
        {"type": "symbol", "encode": {"enter": {"x": {"value": 128}, "y": {"value": 15}, "shape": {"value": "triangle-down"}, "size": {"value": 25}, "fill": {"value": "black"}}}},
        {"type": "text", "encode": {"enter": {"x": {"value": 135}, "y": {"value": 24}, "text": {"value": "Site Opening"}, "fontSize": {"value": 10}, "align": {"value": "left"}}}}
      ]
    },
    {
      "type": "rect",
      "from": {"data": "schedule_bands"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "startTime"},
          "x2": {"scale": "xscale", "field": "endTime"},
          "y": {"scale": "yscale", "field": "ScheduleType"},
          "height": {"scale": "yscale", "band": 1},
          "fill": {"scale": "color", "field": "display_type"}
        }
      }
    },
    {
      "type": "rule",
      "from": {"data": "site_opening_start"},
      "encode": {"enter": {"x": {"scale": "xscale", "field": "time_value"}, "y": {"value": 0}, "y2": {"value": 50}, "stroke": {"value": "black"}, "strokeWidth": {"value": 2}}}
    },
    {
      "type": "symbol",
      "from": {"data": "site_opening_start"},
      "encode": {"enter": {"x": {"scale": "xscale", "field": "time_value"}, "y": {"value": 50}, "shape": {"value": "triangle-up"}, "size": {"value": 50}, "fill": {"value": "black"}}}
    },
    {
      "type": "rule",
      "from": {"data": "site_opening_end"},
      "encode": {"enter": {"x": {"scale": "xscale", "field": "time_value"}, "y": {"value": 0}, "y2": {"value": 50}, "stroke": {"value": "black"}, "strokeWidth": {"value": 2}}}
    },
    {
      "type": "symbol",
      "from": {"data": "site_opening_end"},
      "encode": {"enter": {"x": {"scale": "xscale", "field": "time_value"}, "y": {"value": 3}, "shape": {"value": "triangle-down"}, "size": {"value": 50}, "fill": {"value": "black"}}}
    },
    {
      "type": "rule",
      "encode": {
        "update": {
          "x": {"scale": "xscale", "signal": "remote_hour_decimal"},
          "y": {"value": 2}, "y2": {"value": 50},
          "stroke": {"value": "red"},
          "strokeWidth": {"value": 2}
        }
      }
    },
    {
      "type": "text",
      "encode": {
        "update": {
          "x": {"scale": "xscale", "signal": "remote_hour_decimal"},
          "y": {"value": 3},
          "text": {"signal": "remote_time_label"},
          "baseline": {"value": "bottom"},
          "align": {"value": "center"},
          "fill": {"value": "red"}
        }
      }
    }
  ]
}

View solution in original post

4 REPLIES 4
BeaBF
Super User
Super User

@DGPBi Hi! Try with this adjusted code:

 

{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "Real-time schedule visual (Site Opening) with correct day filtering.",
"background": "transparent",
"width": 360,
"height": 80,
"autosize": {"type": "fit", "contains": "padding"},

"signals": [
{
"name": "timer",
"update": "now()",
"on": [
{
"events": {"type": "timer", "throttle": 1000},
"update": "now()"
}
]
},

{
"name": "adjustedTime",
"update": "length(data('source')) > 0 ? utcOffset('seconds', timer, data('source')[0].DST_ClockDiffBtwLocationAndLocalOffset) : now()"
},

{
"name": "currentTime",
"update": "hours(adjustedTime) + minutes(adjustedTime) / 60"
},

{
"name": "adjustedDate",
"update": "timeFormat(adjustedTime, '%Y-%m-%d')"
},

{
"name": "currentDayNum",
"update": "(day(adjustedTime) + 6) % 7"
}
],

"data": [
{ "name": "source" },

{
"name": "opening_hours_today",
"source": "source",
"transform": [
{
"type": "filter",
"expr":
"datum.ScheduleType == 'SiteOpening' && datum.type != 'No Production' && +datum.day_num == currentDayNum"
}
]
}
],

"scales": [
{
"name": "xscale",
"type": "linear",
"domain": [0, 24],
"range": "width"
}
],

"axes": [
{
"orient": "bottom",
"scale": "xscale",
"title": {"signal": "adjustedDate"},
"tickCount": 24,
"labelFontSize": 8,
"offset": 5
}
],

"marks": [
{
"type": "rect",
"from": {"data": "opening_hours_today"},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "startTime"},
"x2": {"scale": "xscale", "field": "endTime"},
"y": {"value": 20},
"height": {"value": 30},
"fill": {"value": "lightgray"}
}
}
},

{
"type": "rule",
"from": {"data": "opening_hours_today"},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "startTime"},
"y": {"value": 15},
"y2": {"value": 55},
"stroke": {"value": "black"},
"strokeWidth": {"value": 1}
}
}
},

{
"type": "symbol",
"from": {"data": "opening_hours_today"},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "startTime"},
"y": {"value": 15},
"shape": {"value": "triangle-down"},
"size": {"value": 40},
"fill": {"value": "black"}
}
}
},

{
"type": "symbol",
"from": {"data": "opening_hours_today"},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "endTime"},
"y": {"value": 55},
"shape": {"value": "triangle-up"},
"size": {"value": 40},
"fill": {"value": "black"}
}
}
},

{
"type": "rule",
"encode": {
"update": {
"x": {"scale": "xscale", "signal": "currentTime"},
"y": {"value": 10},
"y2": {"value": 60},
"stroke": {"value": "red"},
"strokeWidth": {"value": 2}
}
}
},

{
"type": "text",
"encode": {
"update": {
"x": {"scale": "xscale", "signal": "currentTime"},
"y": {"value": 5},
"text": {"signal": "timeFormat(adjustedTime, '%H:%M')"},
"align": {"value": "center"},
"fill": {"value": "red"},
"fontSize": {"value": 10}
}
}
}
]
}

 

BBF


💡 Did I answer your question? Mark my post as a solution!

👍 Kudos are appreciated

🔥 Proud to be a Super User!

Community News image 1920X1080.png

Hi BeaBF,
Thank you so much for your answer.
I tested your code but I only have the 24 hours scale and the current time bar + text. No rect on the graph
And the filter on the day seems not working. 
In my example, The difference between Local and destination is the same time zone it is why you 0 for his offset
result15.png

Please find an example of data. I will ertainely help you to play with them.

"data": [
		{
			"name": "dataset",
			"values": [
				{"ScheduleType": "Production", "day_num": 0, "type": "No Production", "startTime": 0, "endTime": 22},
				{"ScheduleType": "Production", "day_num": 0, "type": "Normal", "startTime": 22, "endTime": 23.9833333333333},
				{"ScheduleType": "Production", "day_num": 1, "type": "Normal", "startTime": 0, "endTime": 23.9833333333333},
				{"ScheduleType": "Production", "day_num": 2, "type": "Normal", "startTime": 0, "endTime": 23.9833333333333},
				{"ScheduleType": "Production", "day_num": 3, "type": "Normal", "startTime": 0, "endTime": 23.9833333333333},
				{"ScheduleType": "Production", "day_num": 4, "type": "Normal", "startTime": 0, "endTime": 23.9833333333333},
				{"ScheduleType": "Production", "day_num": 5, "type": "Normal", "startTime": 0, "endTime": 22},
				{"ScheduleType": "Production", "day_num": 5, "type": "Flexible", "startTime": 22, "endTime": 23.9833333333333},
				{"ScheduleType": "Production", "day_num": 6, "type": "Flexible", "startTime": 0, "endTime": 6},
				{"ScheduleType": "Production", "day_num": 6, "type": "No Production", "startTime": 6, "endTime": 23.9833333333333},
				{"ScheduleType": "SiteOpening", "day_num": 0, "type": "No Production", "startTime": 0, "endTime": 23.9833333333333},
				{"ScheduleType": "SiteOpening", "day_num": 1, "type": "Normal", "startTime": 8.5, "endTime": 12.5},
				{"ScheduleType": "SiteOpening", "day_num": 1, "type": "Normal", "startTime": 13.5, "endTime": 16.5},
				{"ScheduleType": "SiteOpening", "day_num": 2, "type": "Normal", "startTime": 8.5, "endTime": 12.5},
				{"ScheduleType": "SiteOpening", "day_num": 2, "type": "Normal", "startTime": 13.5, "endTime": 16.5},
				{"ScheduleType": "SiteOpening", "day_num": 3, "type": "Normal", "startTime": 8.5, "endTime": 12.5},
				{"ScheduleType": "SiteOpening", "day_num": 3, "type": "Normal", "startTime": 13.5, "endTime": 16.5},
				{"ScheduleType": "SiteOpening", "day_num": 4, "type": "Normal", "startTime": 8.5, "endTime": 12.5},
				{"ScheduleType": "SiteOpening", "day_num": 4, "type": "Normal", "startTime": 13.5, "endTime": 16.5},
				{"ScheduleType": "SiteOpening", "day_num": 5, "type": "Normal", "startTime": 8.5, "endTime": 12.5},
				{"ScheduleType": "SiteOpening", "day_num": 5, "type": "Normal", "startTime": 13.5, "endTime": 16.5},
				{"ScheduleType": "SiteOpening", "day_num": 6, "type": "No Production", "startTime": 0, "endTime": 23.9833333333333},
				{"ScheduleType": "ITSupport", "day_num": 0, "type": "No Production", "startTime": 0, "endTime": 23.9833333333333},
				{"ScheduleType": "ITSupport", "day_num": 1, "type": "Normal", "startTime": 8.5, "endTime": 12.5},
				{"ScheduleType": "ITSupport", "day_num": 1, "type": "Normal", "startTime": 13.5, "endTime": 16.5},
				{"ScheduleType": "ITSupport", "day_num": 2, "type": "Normal", "startTime": 8.5, "endTime": 12.5},
				{"ScheduleType": "ITSupport", "day_num": 2, "type": "Normal", "startTime": 13.5, "endTime": 16.5},
				{"ScheduleType": "ITSupport", "day_num": 3, "type": "Normal", "startTime": 8.5, "endTime": 12.5},
				{"ScheduleType": "ITSupport", "day_num": 3, "type": "Normal", "startTime": 13.5, "endTime": 16.5},
				{"ScheduleType": "ITSupport", "day_num": 4, "type": "Normal", "startTime": 8.5, "endTime": 12.5},
				{"ScheduleType": "ITSupport", "day_num": 4, "type": "Normal", "startTime": 13.5, "endTime": 16.5},
				{"ScheduleType": "ITSupport", "day_num": 5, "type": "Normal", "startTime": 8.5, "endTime": 12.5},
				{"ScheduleType": "ITSupport", "day_num": 5, "type": "Normal", "startTime": 13.5, "endTime": 16.5},
				{"ScheduleType": "ITSupport", "day_num": 6, "type": "No Production", "startTime": 0, "endTime": 23.9833333333333}
			]
		},

OK, I solved all my problems so I post my code here if it can help someone else
I obtained my final visual like I show in my first post.

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "Final version with corrected 'ITSupport' string in the filter expression.",
  "width": 372,
  "height": 50,
  
  
  "signals": [
    {
      "name": "pbi_time_offset_seconds",
      "init": "isValid(data('pbi_summarize')[0]) ? data('pbi_summarize')[0].DST_ClockDiffBtwLocationAndLocalOffset : 0"
    },
    {
      "name": "utc_now",
      "init": "now()",
      "on": [
        {
          "events": {"type": "timer", "throttle": 1000},
          "update": "now()"
        }
      ]
    },
    {
      "name": "remote_now",
      "update": "utc_now + (pbi_time_offset_seconds * 1000)"
    },
    {
      "name": "remote_day",
      "update": "day(remote_now)"
    },
    {
      "name": "remote_hour_decimal",
      "update": "hours(remote_now) + (minutes(remote_now) / 60) + (seconds(remote_now) / 3600)"
    },
    {
      "name": "remote_time_label",
      "update": "timeFormat(remote_now, '%H:%M')"
    }
  ],

  "data": [
    {
      "name": "dataset"
    },
    {
      "name": "pbi_summarize"
    },
    {
      "name": "schedule_bands",
      "source": "dataset",
      "transform": [
        {
          "type": "filter",
          "expr": "datum.day_num != null && (datum.ScheduleType == 'Production' || datum.ScheduleType == 'ITSupport') && datum.day_num == remote_day"
        },
        {
          "type": "formula",
          "as": "display_type",
          "expr": "datum.type == 'Normal' ? (datum.ScheduleType == 'Production' ? 'Working hours' : 'Support hours') : datum.type == 'Flexible' ? 'Flexible hours' : 'No Working hours'"
        }
      ]
    },
    {
      "name": "site_opening_start",
      "source": "dataset",
      "transform": [
        {"type": "filter", "expr": "datum.day_num != null && datum.ScheduleType == 'SiteOpening' && datum.day_num == remote_day"},
        {"type": "project", "fields": ["startTime"], "as": ["time_value"]}
      ]
    },
    {
      "name": "site_opening_end",
      "source": "dataset",
      "transform": [
        {"type": "filter", "expr": "datum.day_num != null && datum.ScheduleType == 'SiteOpening' && datum.day_num == remote_day"},
        {"type": "project", "fields": ["endTime"], "as": ["time_value"]}
      ]
    }
  ],
  "scales": [
    {
      "name": "xscale",
      "type": "linear",
      "range": "width",
      "domain": [0, 24]
    },
    {
      "name": "yscale",
      "type": "band",
      "range": [1, 50],
      "domain": ["ITSupport", "Production"],
      "padding": 0.1
    },
    {
      "name": "color",
      "type": "ordinal",
      "domain": ["Working hours", "Support hours", "Flexible hours", "No Working hours"],
      "range": ["#a6cee3", "#b2df8a", "#1f78b4", "#d3d3d3"]
    }
  ],
  "axes": [
    {
      "orient": "bottom",
      "scale": "xscale",
      "tickCount": 25,
      "title": {
        "signal": "timeFormat(remote_now, 'Time & Day (%Y-%m-%d)')"
      },
      "labelFontSize": 9,
      "titleFontSize": 9
    }
  ],
  "marks": [
    {
      "type": "group",
      "name": "custom_legend",
      "encode": {"enter": {"x": {"value": 0}, "y": {"value": -40}}},
      "marks": [
        {"type": "rect", "encode": {"enter": {"x": {"value": 0}, "y": {"value": 0}, "width": {"value": 10}, "height": {"value": 10}, "fill": {"value": "#a6cee3"}}}},
        {"type": "text", "encode": {"enter": {"x": {"value": 15}, "y": {"value": 9}, "text": {"value": "Working hours"}, "fontSize": {"value": 10}, "align": {"value": "left"}}}},
        {"type": "rect", "encode": {"enter": {"x": {"value": 120}, "y": {"value": 0}, "width": {"value": 10}, "height": {"value": 10}, "fill": {"value": "#1f78b4"}}}},
        {"type": "text", "encode": {"enter": {"x": {"value": 135}, "y": {"value": 9}, "text": {"value": "Flexible hours"}, "fontSize": {"value": 10}, "align": {"value": "left"}}}},
        {"type": "rect", "encode": {"enter": {"x": {"value": 240}, "y": {"value": 0}, "width": {"value": 10}, "height": {"value": 10}, "fill": {"value": "#d3d3d3"}}}},
        {"type": "text", "encode": {"enter": {"x": {"value": 255}, "y": {"value": 9}, "text": {"value": "No Working hours"}, "fontSize": {"value": 10}, "align": {"value": "left"}}}},
        
        {"type": "rect", "encode": {"enter": {"x": {"value": 0}, "y": {"value": 15}, "width": {"value": 10}, "height": {"value": 10}, "fill": {"value": "#b2df8a"}}}},
        {"type": "text", "encode": {"enter": {"x": {"value": 15}, "y": {"value": 24}, "text": {"value": "Support hours"}, "fontSize": {"value": 10}, "align": {"value": "left"}}}},
        {"type": "rule", "encode": {"enter": {"x": {"value": 122}, "y": {"value": 13}, "x2": {"value": 122}, "y2": {"value": 23}, "stroke": {"value": "black"}}}},
        {"type": "symbol", "encode": {"enter": {"x": {"value": 122}, "y": {"value": 22}, "shape": {"value": "triangle-up"}, "size": {"value": 25}, "fill": {"value": "black"}}}},
        {"type": "rule", "encode": {"enter": {"x": {"value": 128}, "y": {"value": 15}, "x2": {"value": 128}, "y2": {"value": 24}, "stroke": {"value": "black"}}}},
        {"type": "symbol", "encode": {"enter": {"x": {"value": 128}, "y": {"value": 15}, "shape": {"value": "triangle-down"}, "size": {"value": 25}, "fill": {"value": "black"}}}},
        {"type": "text", "encode": {"enter": {"x": {"value": 135}, "y": {"value": 24}, "text": {"value": "Site Opening"}, "fontSize": {"value": 10}, "align": {"value": "left"}}}}
      ]
    },
    {
      "type": "rect",
      "from": {"data": "schedule_bands"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "startTime"},
          "x2": {"scale": "xscale", "field": "endTime"},
          "y": {"scale": "yscale", "field": "ScheduleType"},
          "height": {"scale": "yscale", "band": 1},
          "fill": {"scale": "color", "field": "display_type"}
        }
      }
    },
    {
      "type": "rule",
      "from": {"data": "site_opening_start"},
      "encode": {"enter": {"x": {"scale": "xscale", "field": "time_value"}, "y": {"value": 0}, "y2": {"value": 50}, "stroke": {"value": "black"}, "strokeWidth": {"value": 2}}}
    },
    {
      "type": "symbol",
      "from": {"data": "site_opening_start"},
      "encode": {"enter": {"x": {"scale": "xscale", "field": "time_value"}, "y": {"value": 50}, "shape": {"value": "triangle-up"}, "size": {"value": 50}, "fill": {"value": "black"}}}
    },
    {
      "type": "rule",
      "from": {"data": "site_opening_end"},
      "encode": {"enter": {"x": {"scale": "xscale", "field": "time_value"}, "y": {"value": 0}, "y2": {"value": 50}, "stroke": {"value": "black"}, "strokeWidth": {"value": 2}}}
    },
    {
      "type": "symbol",
      "from": {"data": "site_opening_end"},
      "encode": {"enter": {"x": {"scale": "xscale", "field": "time_value"}, "y": {"value": 3}, "shape": {"value": "triangle-down"}, "size": {"value": 50}, "fill": {"value": "black"}}}
    },
    {
      "type": "rule",
      "encode": {
        "update": {
          "x": {"scale": "xscale", "signal": "remote_hour_decimal"},
          "y": {"value": 2}, "y2": {"value": 50},
          "stroke": {"value": "red"},
          "strokeWidth": {"value": 2}
        }
      }
    },
    {
      "type": "text",
      "encode": {
        "update": {
          "x": {"scale": "xscale", "signal": "remote_hour_decimal"},
          "y": {"value": 3},
          "text": {"signal": "remote_time_label"},
          "baseline": {"value": "bottom"},
          "align": {"value": "center"},
          "fill": {"value": "red"}
        }
      }
    }
  ]
}

Helpful resources

Announcements
Join our Fabric User Panel

Join our Fabric User Panel

Share feedback directly with Fabric product managers, participate in targeted research studies and influence the Fabric roadmap.

February Power BI Update Carousel

Power BI Monthly Update - February 2026

Check out the February 2026 Power BI update to learn about new features.

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.

Top Solution Authors
Top Kudoed Authors