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

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more

Reply
PbiwithPrasad
Helper I
Helper I

i need the deneb vega same clock need to take my measure and shoe date n time accordingly

i need the deneb vega same clock need to take my measure and shoe date n time accordingly , for examples utc + 5:00 hours  which is my desired time zone   time  and  how can i show it? pl help me urgent.

 

in Vega examples we have a templet for clock but it works for now(), but i want it need to work for my desired zone, may be it can use a measure from data set or can be done inside the vega code , but it need to work for may desired time zone time.

1 ACCEPTED SOLUTION
dm-p
Super User
Super User

Hi @PbiwithPrasad,

 

You can use utcOffset for this.

 

If using the default clock template, just update the init and update events for the currentDate signal.

 

In the template, this is using the now() expression, e.g.:

 

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

 

Update this to use the desired hour offset from UTC, e.g.:

 

    {
      "name": "currentDate",
      "init": "utcOffset('hours', now(), 5)",
      "on": [
        {
          "events": {
            "type": "timer",
            "throttle": 1000
          },
          "update": "utcOffset('hours', now(), 5)"
        }
      ]
    },

 

Here's the complete spec with the changes applied that you can copy/paste into your visual:

 

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "A circular clock visualization showing the current time.",
  "width": 400,
  "height": 400,
  "signals": [
    {
      "name": "centerX",
      "init": "width/2"
    },
    {
      "name": "centerY",
      "init": "height/2"
    },
    {
      "name": "radiusRef",
      "init": "min(width,height)*0.8"
    },
    {
      "name": "sizeFactor",
      "init": "radiusRef/400"
    },
    {
      "name": "outerRadius",
      "init": "radiusRef/2"
    },
    {
      "name": "innerRadius",
      "init": "radiusRef/2 - (10 * sizeFactor)"
    },
    {
      "name": "currentDate",
      "init": "utcOffset('hours', now(), 5)",
      "on": [
        {
          "events": {
            "type": "timer",
            "throttle": 1000
          },
          "update": "utcOffset('hours', now(), 5)"
        }
      ]
    },
    {
      "name": "currentHour",
      "init": "hours(currentDate)+minutes(currentDate)/60",
      "on": [
        {
          "events": {
            "signal": "currentDate"
          },
          "update": "hours(currentDate)+minutes(currentDate)/60"
        }
      ]
    },
    {
      "name": "currentMinute",
      "init": "minutes(currentDate)+seconds(currentDate)/60",
      "on": [
        {
          "events": {
            "signal": "currentDate"
          },
          "update": "minutes(currentDate)+seconds(currentDate)/60"
        }
      ]
    },
    {
      "name": "currentSecond",
      "init": "seconds(currentDate)",
      "on": [
        {
          "events": {
            "signal": "currentDate"
          },
          "update": "seconds(currentDate)"
        }
      ]
    }
  ],
  "data": [
    {
      "name": "hours",
      "transform": [
        {
          "type": "sequence",
          "start": 0,
          "stop": 12,
          "step": 1,
          "as": "hour"
        },
        {
          "type": "formula",
          "expr": "centerX - cos(PI/2 + (datum.hour * PI/6)) * (outerRadius - (outerRadius-innerRadius)/2)",
          "as": "x"
        },
        {
          "type": "formula",
          "expr": "centerY - sin(PI/2 + (datum.hour * PI/6)) * (outerRadius - (outerRadius-innerRadius)/2)",
          "as": "y"
        },
        {
          "type": "formula",
          "expr": "centerX - cos(PI/2 + (datum.hour * PI/6)) * (innerRadius - 25 * max(sizeFactor, 0.4))",
          "as": "xHour"
        },
        {
          "type": "formula",
          "expr": "centerY - sin(PI/2 + (datum.hour * PI/6)) * (innerRadius - 25 * max(sizeFactor, 0.4))",
          "as": "yHour"
        }
      ]
    },
    {
      "name": "minutes",
      "transform": [
        {
          "type": "sequence",
          "start": 0,
          "stop": 60,
          "step": 1,
          "as": "minute"
        },
        {
          "type": "formula",
          "expr": "centerX - cos(PI/2 + (datum.minute * PI/30)) * (outerRadius - (outerRadius-innerRadius)/3)",
          "as": "x"
        },
        {
          "type": "formula",
          "expr": "centerY - sin(PI/2 + (datum.minute * PI/30)) * (outerRadius - (outerRadius-innerRadius)/2)",
          "as": "y"
        }
      ]
    }
  ],
  "scales": [
    {
      "name": "hourScale",
      "domain": {
        "data": "hours",
        "field": "hour"
      },
      "range": [0, {"signal": "2*PI"}]
    },
    {
      "name": "minutesScale",
      "domain": {
        "data": "minutes",
        "field": "minute"
      },
      "range": [0, {"signal": "2*PI"}]
    }
  ],
  "marks": [
    {
      "type": "arc",
      "encode": {
        "enter": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "startAngle": {"value": 0},
          "endAngle": {
            "signal": "2*PI"
          },
          "outerRadius": {
            "signal": "outerRadius"
          },
          "fill": {
            "value": "transparent"
          },
          "stroke": {"value": "black"}
        }
      }
    },
    {
      "type": "arc",
      "encode": {
        "enter": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "startAngle": {"value": 0},
          "endAngle": {
            "signal": "2*PI"
          },
          "outerRadius": {
            "signal": "innerRadius"
          },
          "fill": {"value": "#FCFCFC"},
          "opacity": {"value": 0.6},
          "stroke": {"value": "black"}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "minutes"},
      "encode": {
        "enter": {
          "size": {
            "signal": "pow(2*sizeFactor, 2)"
          },
          "x": {"field": "x"},
          "y": {"field": "y"},
          "angle": {
            "signal": "datum.minute*6"
          },
          "shape": {
            "value": "m 0 -5 v 10"
          },
          "stroke": {"value": "black"}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "hours"},
      "encode": {
        "enter": {
          "size": {
            "signal": "pow(2*sizeFactor, 2)"
          },
          "angle": {
            "signal": "datum.hour*30"
          },
          "shape": {
            "value": "m -5 -5 h 10 l -5 10 l -5 -10 Z"
          },
          "x": {"field": "x"},
          "y": {"field": "y"},
          "fill": {"value": "black"}
        }
      }
    },
    {
      "type": "text",
      "from": {"data": "hours"},
      "encode": {
        "enter": {
          "x": {"field": "xHour"},
          "y": {"field": "yHour"},
          "align": {"value": "center"},
          "baseline": {
            "value": "middle"
          },
          "text": {
            "signal": "datum.hour === 0 ? 12 : datum.hour"
          },
          "fontSize": {
            "signal": "25*max(sizeFactor, 0.4)"
          }
        }
      }
    },
    {
      "type": "symbol",
      "encode": {
        "enter": {
          "size": {
            "signal": "pow(2*sizeFactor, 2)"
          },
          "shape": {
            "value": "M 0 0 h-1 l 1 -160 l 1 160 h-1"
          },
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "fill": {"value": "red"},
          "stroke": {"value": "red"},
          "strokeSize": {"value": 2},
          "strokeCap": {
            "value": "round"
          }
        },
        "update": {
          "angle": {
            "signal": "currentSecond*6"
          }
        }
      }
    },
    {
      "type": "symbol",
      "encode": {
        "enter": {
          "size": {
            "signal": "pow(2*sizeFactor, 2)"
          },
          "shape": {
            "value": "M 0 0 h -2 l -5 -30 l 7 -120 l 7 120 l -5 30 h -2 "
          },
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "fill": {"value": "black"},
          "stroke": {"value": "grey"},
          "strokeCap": {
            "value": "round"
          },
          "strokeWidth": {
            "signal": "2* min(sizeFactor, 1)"
          }
        },
        "update": {
          "angle": {
            "signal": "currentMinute*6"
          }
        }
      }
    },
    {
      "type": "symbol",
      "encode": {
        "enter": {
          "size": {
            "signal": "pow(2*sizeFactor, 2)"
          },
          "shape": {
            "value": "M 0 0 h-3 l -4 -30 l 7 -80 l 7 80 l -4 30 h -3"
          },
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "fill": {"value": "black"},
          "stroke": {"value": "grey"},
          "strokeCap": {
            "value": "round"
          },
          "strokeWidth": {
            "signal": "2* min(sizeFactor, 1)"
          },
          "zIndex": {"value": 1}
        },
        "update": {
          "angle": {
            "signal": "currentHour*30"
          }
        }
      }
    },
    {
      "type": "arc",
      "encode": {
        "enter": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "startAngle": {"value": 0},
          "endAngle": {
            "signal": "2*PI"
          },
          "outerRadius": {
            "signal": "6*sizeFactor"
          },
          "fill": {"value": "black"},
          "stroke": {"value": "grey"},
          "zIndex": {"value": 1}
        }
      }
    },
    {
      "type": "arc",
      "encode": {
        "enter": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "startAngle": {"value": 0},
          "endAngle": {
            "signal": "2*PI"
          },
          "innerRadius": {
            "signal": "outerRadius"
          },
          "outerRadius": {
            "signal": "outerRadius + 14 * sizeFactor"
          },
          "fill": {"value": "#333"},
          "stroke": {"value": "grey"}
        }
      }
    }
  ]
}

 

Daniel





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

Proud to be a Super User!


On how to ask a technical question, if you really want an answer (courtesy of SQLBI)




View solution in original post

12 REPLIES 12
dm-p
Super User
Super User

Hi @PbiwithPrasad,

 

You can use utcOffset for this.

 

If using the default clock template, just update the init and update events for the currentDate signal.

 

In the template, this is using the now() expression, e.g.:

 

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

 

Update this to use the desired hour offset from UTC, e.g.:

 

    {
      "name": "currentDate",
      "init": "utcOffset('hours', now(), 5)",
      "on": [
        {
          "events": {
            "type": "timer",
            "throttle": 1000
          },
          "update": "utcOffset('hours', now(), 5)"
        }
      ]
    },

 

Here's the complete spec with the changes applied that you can copy/paste into your visual:

 

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "A circular clock visualization showing the current time.",
  "width": 400,
  "height": 400,
  "signals": [
    {
      "name": "centerX",
      "init": "width/2"
    },
    {
      "name": "centerY",
      "init": "height/2"
    },
    {
      "name": "radiusRef",
      "init": "min(width,height)*0.8"
    },
    {
      "name": "sizeFactor",
      "init": "radiusRef/400"
    },
    {
      "name": "outerRadius",
      "init": "radiusRef/2"
    },
    {
      "name": "innerRadius",
      "init": "radiusRef/2 - (10 * sizeFactor)"
    },
    {
      "name": "currentDate",
      "init": "utcOffset('hours', now(), 5)",
      "on": [
        {
          "events": {
            "type": "timer",
            "throttle": 1000
          },
          "update": "utcOffset('hours', now(), 5)"
        }
      ]
    },
    {
      "name": "currentHour",
      "init": "hours(currentDate)+minutes(currentDate)/60",
      "on": [
        {
          "events": {
            "signal": "currentDate"
          },
          "update": "hours(currentDate)+minutes(currentDate)/60"
        }
      ]
    },
    {
      "name": "currentMinute",
      "init": "minutes(currentDate)+seconds(currentDate)/60",
      "on": [
        {
          "events": {
            "signal": "currentDate"
          },
          "update": "minutes(currentDate)+seconds(currentDate)/60"
        }
      ]
    },
    {
      "name": "currentSecond",
      "init": "seconds(currentDate)",
      "on": [
        {
          "events": {
            "signal": "currentDate"
          },
          "update": "seconds(currentDate)"
        }
      ]
    }
  ],
  "data": [
    {
      "name": "hours",
      "transform": [
        {
          "type": "sequence",
          "start": 0,
          "stop": 12,
          "step": 1,
          "as": "hour"
        },
        {
          "type": "formula",
          "expr": "centerX - cos(PI/2 + (datum.hour * PI/6)) * (outerRadius - (outerRadius-innerRadius)/2)",
          "as": "x"
        },
        {
          "type": "formula",
          "expr": "centerY - sin(PI/2 + (datum.hour * PI/6)) * (outerRadius - (outerRadius-innerRadius)/2)",
          "as": "y"
        },
        {
          "type": "formula",
          "expr": "centerX - cos(PI/2 + (datum.hour * PI/6)) * (innerRadius - 25 * max(sizeFactor, 0.4))",
          "as": "xHour"
        },
        {
          "type": "formula",
          "expr": "centerY - sin(PI/2 + (datum.hour * PI/6)) * (innerRadius - 25 * max(sizeFactor, 0.4))",
          "as": "yHour"
        }
      ]
    },
    {
      "name": "minutes",
      "transform": [
        {
          "type": "sequence",
          "start": 0,
          "stop": 60,
          "step": 1,
          "as": "minute"
        },
        {
          "type": "formula",
          "expr": "centerX - cos(PI/2 + (datum.minute * PI/30)) * (outerRadius - (outerRadius-innerRadius)/3)",
          "as": "x"
        },
        {
          "type": "formula",
          "expr": "centerY - sin(PI/2 + (datum.minute * PI/30)) * (outerRadius - (outerRadius-innerRadius)/2)",
          "as": "y"
        }
      ]
    }
  ],
  "scales": [
    {
      "name": "hourScale",
      "domain": {
        "data": "hours",
        "field": "hour"
      },
      "range": [0, {"signal": "2*PI"}]
    },
    {
      "name": "minutesScale",
      "domain": {
        "data": "minutes",
        "field": "minute"
      },
      "range": [0, {"signal": "2*PI"}]
    }
  ],
  "marks": [
    {
      "type": "arc",
      "encode": {
        "enter": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "startAngle": {"value": 0},
          "endAngle": {
            "signal": "2*PI"
          },
          "outerRadius": {
            "signal": "outerRadius"
          },
          "fill": {
            "value": "transparent"
          },
          "stroke": {"value": "black"}
        }
      }
    },
    {
      "type": "arc",
      "encode": {
        "enter": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "startAngle": {"value": 0},
          "endAngle": {
            "signal": "2*PI"
          },
          "outerRadius": {
            "signal": "innerRadius"
          },
          "fill": {"value": "#FCFCFC"},
          "opacity": {"value": 0.6},
          "stroke": {"value": "black"}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "minutes"},
      "encode": {
        "enter": {
          "size": {
            "signal": "pow(2*sizeFactor, 2)"
          },
          "x": {"field": "x"},
          "y": {"field": "y"},
          "angle": {
            "signal": "datum.minute*6"
          },
          "shape": {
            "value": "m 0 -5 v 10"
          },
          "stroke": {"value": "black"}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "hours"},
      "encode": {
        "enter": {
          "size": {
            "signal": "pow(2*sizeFactor, 2)"
          },
          "angle": {
            "signal": "datum.hour*30"
          },
          "shape": {
            "value": "m -5 -5 h 10 l -5 10 l -5 -10 Z"
          },
          "x": {"field": "x"},
          "y": {"field": "y"},
          "fill": {"value": "black"}
        }
      }
    },
    {
      "type": "text",
      "from": {"data": "hours"},
      "encode": {
        "enter": {
          "x": {"field": "xHour"},
          "y": {"field": "yHour"},
          "align": {"value": "center"},
          "baseline": {
            "value": "middle"
          },
          "text": {
            "signal": "datum.hour === 0 ? 12 : datum.hour"
          },
          "fontSize": {
            "signal": "25*max(sizeFactor, 0.4)"
          }
        }
      }
    },
    {
      "type": "symbol",
      "encode": {
        "enter": {
          "size": {
            "signal": "pow(2*sizeFactor, 2)"
          },
          "shape": {
            "value": "M 0 0 h-1 l 1 -160 l 1 160 h-1"
          },
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "fill": {"value": "red"},
          "stroke": {"value": "red"},
          "strokeSize": {"value": 2},
          "strokeCap": {
            "value": "round"
          }
        },
        "update": {
          "angle": {
            "signal": "currentSecond*6"
          }
        }
      }
    },
    {
      "type": "symbol",
      "encode": {
        "enter": {
          "size": {
            "signal": "pow(2*sizeFactor, 2)"
          },
          "shape": {
            "value": "M 0 0 h -2 l -5 -30 l 7 -120 l 7 120 l -5 30 h -2 "
          },
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "fill": {"value": "black"},
          "stroke": {"value": "grey"},
          "strokeCap": {
            "value": "round"
          },
          "strokeWidth": {
            "signal": "2* min(sizeFactor, 1)"
          }
        },
        "update": {
          "angle": {
            "signal": "currentMinute*6"
          }
        }
      }
    },
    {
      "type": "symbol",
      "encode": {
        "enter": {
          "size": {
            "signal": "pow(2*sizeFactor, 2)"
          },
          "shape": {
            "value": "M 0 0 h-3 l -4 -30 l 7 -80 l 7 80 l -4 30 h -3"
          },
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "fill": {"value": "black"},
          "stroke": {"value": "grey"},
          "strokeCap": {
            "value": "round"
          },
          "strokeWidth": {
            "signal": "2* min(sizeFactor, 1)"
          },
          "zIndex": {"value": 1}
        },
        "update": {
          "angle": {
            "signal": "currentHour*30"
          }
        }
      }
    },
    {
      "type": "arc",
      "encode": {
        "enter": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "startAngle": {"value": 0},
          "endAngle": {
            "signal": "2*PI"
          },
          "outerRadius": {
            "signal": "6*sizeFactor"
          },
          "fill": {"value": "black"},
          "stroke": {"value": "grey"},
          "zIndex": {"value": 1}
        }
      }
    },
    {
      "type": "arc",
      "encode": {
        "enter": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "startAngle": {"value": 0},
          "endAngle": {
            "signal": "2*PI"
          },
          "innerRadius": {
            "signal": "outerRadius"
          },
          "outerRadius": {
            "signal": "outerRadius + 14 * sizeFactor"
          },
          "fill": {"value": "#333"},
          "stroke": {"value": "grey"}
        }
      }
    }
  ]
}

 

Daniel





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

Proud to be a Super User!


On how to ask a technical question, if you really want an answer (courtesy of SQLBI)




Hi, 

Thanks for your reply.

I am trying to find how to take utc time instead of the local time by using now().


Is there a simple way to do it?

 

Thanks a lot

Genarally when we publish a report it will show utc time only even we use now() also in power bi services, so no worries with utc, hope you understand, but if you want to show local time then you need to add the tome diff manually to now() so it will show a right time in services after publishing and sharing.

Hi,

 

Thanks for your reply.

However, it does not work that way. Even if you publish it, it still takes the local time of your machine. I just tested.
I was wondering if you can help me take the UTC time instead of now().
Even the function utcOffset('hours', now(), 0) does not work. This is because it still uses the now() function.

Could you please help me with it?

 

cant we make it in such a way that this excess time(+5:30) need to be taken from my measure.

Thank you @dm-p  got it how to add 5h 30 min thank you..

 

but can tou tell how to amke this to work with my measure .

lets suppose i have a measure whose result is 5:30, based on this i need my clock need to modified to new time (not utc)

if needed we can make two measures one with hours (eg:5) and other minuits (eg: 30) plz tell me the complete code for it.

 

Thank you so so much for your time and patience..

Hi @PbiwithPrasad,

 

You can access the dataset using the data function, which allows you to pass in the name of a dataset.

 

  • Deneb's dataset is named 'dataset'.
  • Passing in a single measure will result in a single row in the visual dataset.
  • As Vega is built in JavaScript it uses zero-based indexes for arrays. Therefore you can access this single row with the [0] index.
  • Once you have this row, you can use a similar accessor to get the name of your field, which I assume would be your measure.
  • This can be assigned to a signal, and passed into the downstream work we did in my last post.

 

As utcOffset doesn't work well with decimal values, and you'd prefer to use hours with a decimal value to allow finer-grained offsets of half-hour or more, then we can do the calculation inside the visual. For this example, I'll use a decimal measure and convert to minutes in the utcOffset function to show how flexible you can be in-visual.

 

You could change this approach to use multiple measures using a similar process to create additional signals for minutes and making multiple calls to the utcOffset function accordingly.

 

For this example my measure is called [Offset Value]. and it's currently set to 5.5 (which would be 5:30 in hours and minutes).

 

Above the currentDate signal, I'll create a new signal called offset, and use the approach outlined above to access the first row of my dataset's Offset Value field and multiply this by 60 to get the minutes, e.g.:

 

{
  ...
  "signals": [
    ...
    {
      "name": "offset",
      "init": "data('dataset')[0]['Offset Value'] * 60"
    },
    ...
  ]
  ...
}

 

I'll now get a signal named offset, which can be inspected in the Signals pane, e.g.:

 

dmp_1-1690321780902.png

 

As we can see, this has extracted the measure from the dataset's first row and has converted that value of 5.5 hours into 330 minutes.

 

Now, we change the logic for our downstream currentDate signal to use this and offset by minutes rather than a hard-coded value:

 

{
  ...
  "signals": [
    ...
    {
      "name": "currentDate",
      "init": "utcOffset('minutes', now(), offset)",
      "on": [
        {
          "events": {
            "type": "timer",
            "throttle": 1000
          },
          "update": "utcOffset('minutes', now(), offset)"
        }
      ]
    },
    ...
  ]
  ...
}

 

Our visual will now be assigned to the measure value, e.g.:

 

deneb-vega-dynamic-clock.gif

 

I've attached a sample workbook with both clocks in there for you to play with.

 

Good luck!

 

Daniel





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

Proud to be a Super User!


On how to ask a technical question, if you really want an answer (courtesy of SQLBI)




what if i want to have now + 5 hours and 30 minuits

Thank you @dm-p  got it how to add 5h 30 min thank you..

 

but can tou tell how to amke this to work with my measure .

lets suppose i have a measure whose result is 5:30, based on this i need my clock need to modified to new time (not utc)

if needed we can make two measures one with hours (eg:5) and other minuits (eg: 30) plz tell me the complete code for it.

 

Thank you so so much for your time and patience..

Thank you @dm-p  got it how to add 5h 30 min thank you..

 

but can tou tell how to amke this to work with my measure .

lets suppose i have a measure whose result is 5:30, based on this i need my clock need to modified to new time (not utc)

if needed we can make two measures one with hours (eg:5) and other minuits (eg: 30) plz tell me the complete code for it.

 

Thank you so so much for your time and patience..

what if i want to have now + 5 hours and 30 minuits

Anonymous
Not applicable

HI @PbiwithPrasad,

I check the common visualization but not found the similar effect. Perhaps you can try use script-based visuals(R, Python) to manually plot this effect based on custom scripts and graph libraries.

Create Power BI visuals using R - Power BI | Microsoft Learn

Create Power BI visuals using Python in Power BI Desktop - Power BI | Microsoft Learn
Regards,

Xiaoxin Sheng

Helpful resources

Announcements
Power BI DataViz World Championships

Power BI Dataviz World Championships

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now!

November Power BI Update Carousel

Power BI Monthly Update - November 2025

Check out the November 2025 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.