Learn from the best! Meet the four finalists headed to the FINALS of the Power BI Dataviz World Championships! Register now
Hello Experts,
I would like to build a Custom Visual using HTML, but I do not have enough experience in this area. I would appreciate your support with the following requirements:
Create a Waterfall chart based on the following data:
| 1 | Budget NPAT | 4,261,532 |
| 2 | Gross Margin | 2,733,696 |
| 3 | Variable Costs | -280,573 |
| 4 | 3rd Party Cost Recovery | -435,951 |
| 5 | Other Income | 32,571 |
| 6 | Fixed Costs | 1,324,187 |
| 7 | Support Cost | 738,378 |
| 8 | Depreciation | -664,124 |
| 9 | Bad Debt Provision | 799,823 |
| 10 | Finance Exp & Inc | -1,537,797 |
| 11 | Income Tax | -637,201 |
| 12 | Actual NPAT | 6,334,541 |
The data must be sorted by Index in ascending order.
Index 1 should appear on the far left of the chart.
Index 12 should appear on the far right of the chart.
Colors:
Index 1 (Budget NPAT) must be in color: #389BBD
Index 12 (Actual NPAT) must be in color: #A4D233
The columns between them:
Green for positive values
Red for negative values
Starting Point (Very Important):
Index 1 and Index 12 must start from zero on the Y-axis.
I have attached an example to show the required layout.
Note: The attached example is not working correctly. It is only for illustration of the expected design.
If possible, please provide a Power BI (.pbix) file for this example.
Thank you in advance for your support.
Solved! Go to Solution.
Hi @majid154a,
I thought I'd give you a hand to get started with this.
I've managed to get a component working in HTML:
Here is the HTML for it, you may test it in your browser and play around with the scale, prev-value, and curr-movement/curr-label variables. Notice positive values will turn green, negative will turn red.
<style>
:root {
--scale: 5455;
--prev-value: 5000;
--curr-movement: -1505;
--curr-label: "-1505";
--movement: calc(var(--curr-movement) / abs(var(--curr-movement)));
--multiplier: calc((var(--movement) + 1) / 2);
--color: calc(var(--multiplier) * 122);
--height: calc(abs(var(--curr-movement)) / var(--scale) * 100%);
--top: calc((var(--scale) - var(--prev-value)) / var(--scale) * 100% - (var(--multiplier) * var(--height)));
.p-outer {
text-align: center;
padding-top: 1.5em;
}
.p-area {
height: 90vh;
width: 90vw;
margin-left: auto;
margin-right: auto;
}
.p-block::after {
content: var(--curr-label);
top: -1.5em;
position: relative;
color: black;
}
.p-block {
height: var(--height);
background-color: hsl(var(--color),70%,50%);
top: var(--top);
width: 100%;
position: relative;
}
.category {
text-align: center;
color: hsl(0,0%,50%);
}
body {
font-family: sans-serif;
}
</style>
<div>
<div class="p-outer">
<div class="p-area">
<div class="p-block"></div>
</div>
<div class="category">Category name</div>
</div>
</div>
We can then turn this into a parameterised DAX measure:
HTML Waterfall Bar =
VAR Scale = [Scale] // Replace with your max absolute value or dynamic max scale measure
VAR PrevValue = [Previous Cumulative Value] // Your measure for the running total BEFORE this step
VAR CurrMovement = [Variance / Delta] // Your measure for this step's change (positive or negative)
VAR CategoryName = SELECTEDVALUE('Category'[Category Name]) // or whatever your category field is
VAR CurrLabel = FORMAT(CurrMovement, "#,##0") // or use FIXED/ROUND as preferred
RETURN
"<html>
<head>
<style>
:root {
--scale: " & Scale & ";
--prev-value: " & PrevValue & ";
--curr-movement: " & CurrMovement & ";
--curr-label: """ & CurrLabel & """;
--movement: calc(var(--curr-movement) / abs(var(--curr-movement)));
--multiplier: calc((var(--movement) + 1) / 2);
--color: calc(var(--multiplier) * 122);
--height: calc(abs(var(--curr-movement)) / var(--scale) * 100%);
--top: calc((var(--scale) - var(--prev-value)) / var(--scale) * 100% - (var(--multiplier) * var(--height)));
}
.p-outer {
text-align: center;
padding-top: 1.5em;
}
.p-area {
height: 90vh;
width: 90vw;
margin-left: auto;
margin-right: auto;
}
.p-block::after {
content: var(--curr-label);
top: -1.5em;
position: relative;
color: black;
}
.p-block {
height: var(--height);
background-color: hsl(var(--color),70%,50%);
top: var(--top);
width: 100%;
position: relative;
}
.category {
text-align: center;
color: hsl(0,0%,50%);
}
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<div class='p-outer'>
<div class='p-area'>
<div class='p-block'></div>
</div>
<div class='category'>" & CategoryName & "</div>
</div>
</body>
</html>"
To get this working, you will need to create the following DAX measures:
You will also need to introduce logic for the Budget NPAT and Actual NPAT colors.
Granularity will need to be set to Category Name. Then sort by Category ID.
I hope this helps.
Hi @majid154a,
Thank you @Ashish_Mathur, for your insights.
With a sample dataset, I replicated your requirement in Power BI. On Page 1, I used the HTML Content visual to build the custom layout, and on Page 2, I utilized the standard Waterfall visual. I've attached the PBIX file for your review and included a Microsoft documentation link below for further details on the Waterfall visual.
Waterfall Charts in Power BI - Power BI | Microsoft Learn
Thank you.
Dear HTML Experts,
I need help for this question :
Waterfall by HTML Help - Microsoft Fabric Community
Hi @majid154a,
Could you review the solution that @NoosaInsight @Ashish_Mathur and I provided above? Please let us know if it helped resolve the issue, or if you notice any gaps, we would be happy to address them.
Thank you.
Hi @majid154a,
Thank you @NoosaInsight, for your insights,
Have you had a chance to review the solution we shared earlier? If the issue persists, feel free to reply so we can help further.
Thank you.
Hi @majid154a,
Thank you @Ashish_Mathur, for your insights.
With a sample dataset, I replicated your requirement in Power BI. On Page 1, I used the HTML Content visual to build the custom layout, and on Page 2, I utilized the standard Waterfall visual. I've attached the PBIX file for your review and included a Microsoft documentation link below for further details on the Waterfall visual.
Waterfall Charts in Power BI - Power BI | Microsoft Learn
Thank you.
Thank you,
itw worked.
Thank you again.
But how I can show data label, I tried in visual formate, I didnt fint option for that
Hi,
Why would you not want to use the built in waterfall chart visual?
Hi @majid154a,
I thought I'd give you a hand to get started with this.
I've managed to get a component working in HTML:
Here is the HTML for it, you may test it in your browser and play around with the scale, prev-value, and curr-movement/curr-label variables. Notice positive values will turn green, negative will turn red.
<style>
:root {
--scale: 5455;
--prev-value: 5000;
--curr-movement: -1505;
--curr-label: "-1505";
--movement: calc(var(--curr-movement) / abs(var(--curr-movement)));
--multiplier: calc((var(--movement) + 1) / 2);
--color: calc(var(--multiplier) * 122);
--height: calc(abs(var(--curr-movement)) / var(--scale) * 100%);
--top: calc((var(--scale) - var(--prev-value)) / var(--scale) * 100% - (var(--multiplier) * var(--height)));
.p-outer {
text-align: center;
padding-top: 1.5em;
}
.p-area {
height: 90vh;
width: 90vw;
margin-left: auto;
margin-right: auto;
}
.p-block::after {
content: var(--curr-label);
top: -1.5em;
position: relative;
color: black;
}
.p-block {
height: var(--height);
background-color: hsl(var(--color),70%,50%);
top: var(--top);
width: 100%;
position: relative;
}
.category {
text-align: center;
color: hsl(0,0%,50%);
}
body {
font-family: sans-serif;
}
</style>
<div>
<div class="p-outer">
<div class="p-area">
<div class="p-block"></div>
</div>
<div class="category">Category name</div>
</div>
</div>
We can then turn this into a parameterised DAX measure:
HTML Waterfall Bar =
VAR Scale = [Scale] // Replace with your max absolute value or dynamic max scale measure
VAR PrevValue = [Previous Cumulative Value] // Your measure for the running total BEFORE this step
VAR CurrMovement = [Variance / Delta] // Your measure for this step's change (positive or negative)
VAR CategoryName = SELECTEDVALUE('Category'[Category Name]) // or whatever your category field is
VAR CurrLabel = FORMAT(CurrMovement, "#,##0") // or use FIXED/ROUND as preferred
RETURN
"<html>
<head>
<style>
:root {
--scale: " & Scale & ";
--prev-value: " & PrevValue & ";
--curr-movement: " & CurrMovement & ";
--curr-label: """ & CurrLabel & """;
--movement: calc(var(--curr-movement) / abs(var(--curr-movement)));
--multiplier: calc((var(--movement) + 1) / 2);
--color: calc(var(--multiplier) * 122);
--height: calc(abs(var(--curr-movement)) / var(--scale) * 100%);
--top: calc((var(--scale) - var(--prev-value)) / var(--scale) * 100% - (var(--multiplier) * var(--height)));
}
.p-outer {
text-align: center;
padding-top: 1.5em;
}
.p-area {
height: 90vh;
width: 90vw;
margin-left: auto;
margin-right: auto;
}
.p-block::after {
content: var(--curr-label);
top: -1.5em;
position: relative;
color: black;
}
.p-block {
height: var(--height);
background-color: hsl(var(--color),70%,50%);
top: var(--top);
width: 100%;
position: relative;
}
.category {
text-align: center;
color: hsl(0,0%,50%);
}
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<div class='p-outer'>
<div class='p-area'>
<div class='p-block'></div>
</div>
<div class='category'>" & CategoryName & "</div>
</div>
</body>
</html>"
To get this working, you will need to create the following DAX measures:
You will also need to introduce logic for the Budget NPAT and Actual NPAT colors.
Granularity will need to be set to Category Name. Then sort by Category ID.
I hope this helps.
| User | Count |
|---|---|
| 59 | |
| 46 | |
| 31 | |
| 17 | |
| 16 |
| User | Count |
|---|---|
| 80 | |
| 68 | |
| 43 | |
| 26 | |
| 23 |