Join us for an expert-led overview of the tools and concepts you'll need to pass exam PL-300. The first session starts on June 11th. See you there!
Get registeredPower BI is turning 10! Let’s celebrate together with dataviz contests, interactive sessions, and giveaways. Register now.
Hello All,
I am brand new to using Deneb, but with the help of copilot and some edits, I was able to produce the visual I needed, a matrix with banded rows, a total row that is bolded, red text for negatives in change columns, black for category columns (2024 Act, 2025 PL, etc.), and 5 change buckets with a header of 'Cost' with a outline around and 'Cost' shaded blue with white font. The visual is responsive and seems to work.
My issue... There are multiple warnings including using bandPosition values of less than 0 and greater than 1, to position some strokes and shading at the precise location I want. I also have a warning saying that the "field" property isn't allowed in my "x2" sections. I'm getting the result I desire, but I'm afraid the visual may break in future updates of vega-lite. I am providing the code as well as a sample screenshot of the output. I've made the output use multiple RAND() DAX functions, so if you see weird values, including the Total line not tying, that's why. Data and the total are working fine when not randomizing the numbers. Could someone please help me fix the warnings? Also, if there are more efficient ways to do what my example picture shows, please let me know.
Here is the vega-lite coding. I've put //WARNING: at the end of the code lines that have a warning, followed by what the warning says.
{
"data": {"name": "dataset"},
"transform": [
{
"calculate": "(datum.Quarter === '1Q' || datum.Quarter === '3Q') ? 'lightgrey' : 'white'",
"as": "RowColor"
},
{
"calculate": "isNumber(datum['MBR PVC']) && datum['MBR PVC'] < 0 && !(datum.MBRPVCTableSort < 60 || (datum.MBRPVCTableSort >= 69 && datum.MBRPVCTableSort <= 899)) ? 'red' : (indexof(datum['MBR PVC__formatted'], '-') >= 0 && !(datum.MBRPVCTableSort < 60 || (datum.MBRPVCTableSort >= 69 && datum.MBRPVCTableSort <= 899)) ? 'red' : 'black')",
"as": "TextColor"
}
],
"encoding": {
"y": {
"field": "Quarter",
"title": null,
"axis": {
"ticks": false,
"labelPadding": 5,
"labelFontWeight": {
"condition": {"test": "datum.value === 'Total'", "value": "bold"},
"value": "normal"
},
"labelFontSize": 12
}
},
"x": {
"field": "MBRPVCTable",
"title": null,
"sort": {"field": "MBRPVCTableSort", "order": "ascending"},
"axis": {
"orient": "top",
"labelAngle": 0,
"ticks": false,
"labelFontSize": 12
}
}
},
"layer": [
{
"mark": {
"type": "rect",
"tooltip": true,
"opacity": 0.5
},
"encoding": {
"color": {
"field": "RowColor",
"type": "nominal",
"scale": null
}
}
},
{
"transform": [
{"filter": "datum.Quarter !== 'Total'"}
],
"mark": {
"type": "text",
"tooltip": true,
"fontSize": 12
},
"encoding": {
"text": {
"field": "MBR PVC__formatted"
},
"color": {
"field": "TextColor",
"type": "nominal",
"scale": null
}
}
},
{
"transform": [
{"filter": "datum.Quarter === 'Total'"}
],
"mark": {
"type": "text",
"tooltip": true,
"fontSize": 12,
"fontWeight": "bold"
},
"encoding": {
"text": {
"field": "MBR PVC__formatted"
},
"color": {
"field": "TextColor",
"type": "nominal",
"scale": null
},
"y": {"field": "Quarter"},
"x": {"field": "MBRPVCTable"}
}
},
{
"transform": [
{"filter": "datum.Quarter === 'Total'"}
],
"mark": {
"type": "rule",
"tooltip": true,
"strokeWidth": 2
},
"encoding": {
"y": {
"field": "Quarter",
"type": "nominal",
"aggregate": "min",
"bandPosition": 0
},
"x": {
"value": 0
},
"x2": {
"value": {"expr": "width"}
}
}
},
{
"transform": [
{"filter": "datum.MBRPVCTable === 'SGA' && datum.MBRPVCTable2 === 'Cost'"}
],
"layer": [
{
"mark": {
"type": "rect",
"tooltip": true,
"color": "#004ABF",
"opacity": 0.5
},
"encoding": {
"x": {
"field": "MBRPVCTable",
"type": "nominal",
"bandPosition": -2 //WARNING: Value is below the minimum of 0.
},
"x2": {
"field": "MBRPVCTable", //WARNING: Property field is not allowed.
"type": "nominal",
"bandPosition": 3 //WARNING: Value is above the maximum of 1.
},
"y": {
"value": -35 // Position the rectangle above the x-axis
},
"y2": {
"value": -16 // Extend the rectangle to the x-axis
}
}
},
{
"mark": {
"type": "text",
"tooltip": true,
"fontSize": 12,
"color": "white",
"dy": -25
},
"encoding": {
"text": {
"field": "MBRPVCTable2"
},
"x": {
"field": "MBRPVCTable",
"type": "nominal"
},
"y": {
"value": 0 // Position the text above the x-axis
}
}
}
]
},
{
"transform": [
{"filter": "datum.MBRPVCTable === 'COR'"}
],
"mark": {
"type": "rule",
"tooltip": true,
"strokeWidth": 1,
"color": "black"
},
"encoding": {
"x": {
"field": "MBRPVCTable",
"type": "nominal",
"bandPosition": 0
},
"y": {
"value": -35 // Adjust this value to extend the line to the top
},
"y2": {
"value": {"expr": "height"}
}
}
},
{
"transform": [
{"filter": "datum.MBRPVCTable === 'Other'"}
],
"mark": {
"type": "rule",
"tooltip": true,
"strokeWidth": 1,
"color": "black"
},
"encoding": {
"x": {
"field": "MBRPVCTable",
"type": "nominal",
"bandPosition": 1
},
"y": {
"value": -35 // Adjust this value to extend the line to the top
},
"y2": {
"value": {"expr": "height"}
}
}
},
{
"transform": [
{"filter": "datum.MBRPVCTable === 'COR'"}
],
"mark": {
"type": "rule",
"tooltip": true,
"strokeWidth": 1,
"color": "black"
},
"encoding": {
"x": {
"field": "MBRPVCTable",
"type": "nominal",
"bandPosition": 0
},
"x2": {
"field": "MBRPVCTable", //WARNING: Property field is not allowed.
"type": "nominal",
"bandPosition": 5 //WARNING: Value is above the maximum of 1.
},
"y": {
"value": -35 // Position the top horizontal line
},
"y2": {
"value": -35 // Ensure the line is horizontal
}
}
},
{
"transform": [
{"filter": "datum.MBRPVCTable === 'Other'"}
],
"mark": {
"type": "rule",
"tooltip": true,
"strokeWidth": 1,
"color": "black"
},
"encoding": {
"x": {
"field": "MBRPVCTable",
"type": "nominal",
"bandPosition": -4 //WARNING: Value is below the minimum of 0.
},
"x2": {
"field": "MBRPVCTable", //WARNING: Property field is not allowed.
"type": "nominal",
"bandPosition": 1
},
"y": {
"value": {"expr": "height"} // Position the bottom horizontal line
},
"y2": {
"value": {"expr": "height"} // Ensure the line is horizontal
}
}
}
]
}
Thanks ahead of time for your help!!
Solved! Go to Solution.
Adding type to x2 is unnecessary and does nothing, as these share the same scale as x. The type in x dictates how x2 is scaled. Remove type from the channel and the warning should go away. (EDIT: example of using offset channels on a StackOverflow post from the other day that may help clarify)
bandPosition only spans from 0 to 1 and dictates percentage of the band to use for a mark's position (0.5 being the centre). Use xOffset or x2Offset if you want to adjust by a specific amount relative to encoded position.
Proud to be a Super User!
On how to ask a technical question, if you really want an answer (courtesy of SQLBI)
Adding type to x2 is unnecessary and does nothing, as these share the same scale as x. The type in x dictates how x2 is scaled. Remove type from the channel and the warning should go away. (EDIT: example of using offset channels on a StackOverflow post from the other day that may help clarify)
bandPosition only spans from 0 to 1 and dictates percentage of the band to use for a mark's position (0.5 being the centre). Use xOffset or x2Offset if you want to adjust by a specific amount relative to encoded position.
Proud to be a Super User!
On how to ask a technical question, if you really want an answer (courtesy of SQLBI)
Thanks so much for responding Daniel and thanks @lbendlin for tagging him!
I was able to get rid of the type error by using your solution and also finagle the xOffset and x2Offset to work. My issue now with the Offset solution is if one of the columns goes away in my 'matrix', the shading of blue or the horizontal lines will be too short as the columns change size. When I was using the bandPosition without xOffset, the lines and shading would continue to expand to the correct position. The vertical lines work fine as the bandPosition isn't going outside of the 0-1 bounds.
Is there a way to calculate how many pixels to change the offset if I always want the starting x to be the start of the 'COR' column within MBRPVCTable and the ending x2 to be the end of the 'Other' column within MBRPVCTable like my image above shows?
Thanks again for both of your time! I have to admit I was kind of star struck when I got a reply from the DMP!
You're too kind! I get pretty giddy each time I see someone using Deneb to solve a challenge 🙂
These properties have expression support, so you could calculate the x-axis's bandwidth and offset by half of that.
I'd need to see any revised code (and possibly get a sample of data to set up and try to confirm 100%, as it depends on where you're using xOffset, etc., in your spec (whether via mark properties or encoding channels).
If using via mark properties, something like the following could be a starting point which should offset by a quarter of the derived bandwidth in each direction:
// Assuming you want to go left (negative)
"xOffset": {
"expr": "-bandwidth('x') * 0.25"
}
// Assuming you want to go right (positive)
"x2Offset": {
"expr": "bandwidth('x') * 0.25"
}
Hoepfully that may get you on the right path, but if you're still stuck then any contextual info like a revised spec and sample data would be a great help to get you where you need to be.
Good luck!
Daniel
Proud to be a Super User!
On how to ask a technical question, if you really want an answer (courtesy of SQLBI)
Thanks for all of the help Daniel. Sorry for the lateness in my reply. My initial attempts were unsuccessful and several work priorities have kept me away. I will mark your original post as the solution for my question but will eventually post a sample workbook for my latest question to you.
Thanks again!
Bob
One of the x2 sections is creating a shaded rectangle in color #004ABF where x describes the beginning x position and x2 describes the ending point to draw the rectangle:
"mark": {
"type": "rect",
"tooltip": true,
"color": "#004ABF",
"opacity": 0.5
},
"encoding": {
"x": {
"field": "MBRPVCTable",
"type": "nominal",
"bandPosition": -2 //WARNING: Value is below the minimum of 0.
},
"x2": {
"field": "MBRPVCTable", //WARNING: Property field is not allowed.
"type": "nominal",
"bandPosition": 3 //WARNING: Value is above the maximum of 1.
The other x2 sections where I have warnings are creating two different horizontal lines at specific points in the table. The below code section does the horizontal line that shows above 'Cost' in my sample image and "x" is the starting x position whereas "x2" is the ending position for the line/stroke.
"transform": [
{"filter": "datum.MBRPVCTable === 'COR'"}
],
"mark": {
"type": "rule",
"tooltip": true,
"strokeWidth": 1,
"color": "black"
},
"encoding": {
"x": {
"field": "MBRPVCTable",
"type": "nominal",
"bandPosition": 0
},
"x2": {
"field": "MBRPVCTable", //WARNING: Property field is not allowed.
"type": "nominal",
"bandPosition": 5 //WARNING: Value is above the maximum of 1.
},
"y": {
"value": -35 // Position the top horizontal line
},
"y2": {
"value": -35 // Ensure the line is horizontal
The code below here is the 2nd horizontal line that shows at the bottom of the visual in my sample picture.
"transform": [ {"filter": "datum.MBRPVCTable === 'Other'"} ], "mark": { "type": "rule", "tooltip": true, "strokeWidth": 1, "color": "black" }, "encoding": { "x": { "field": "MBRPVCTable", "type": "nominal", "bandPosition": -4 //WARNING: Value is below the minimum of 0. }, "x2": { "field": "MBRPVCTable", //WARNING: Property field is not allowed. "type": "nominal", "bandPosition": 1 }, "y": { "value": {"expr": "height"} // Position the bottom horizontal line }, "y2": { "value": {"expr": "height"} // Ensure the line is horizontal
I guess the line has the same x for both horizontal lines, I'm just using a different starting point and hence why one has a negative bandPosition of -4 going to 1 whereas the other goes from 0 to 5. Again, I am brand new to Deneb, so the different starting points for the lines comes from Copilot, but it worked so I didn't analyze and question why to not use the same starting x position 'COR'.
This is your chance to engage directly with the engineering team behind Fabric and Power BI. Share your experiences and shape the future.
Check out the June 2025 Power BI update to learn about new features.