Compound.Boxplot¶
Creates a Box Plot compound SVG Visual showing statistical distribution
DaxLib.SVG.Compound.Boxplot( x, y, width, height, paddingX, paddingY, axisRef, measureRef, fillColor, strokeColor, showOutliers, orientation )
| Parameter | Type | Required | Description |
|---|---|---|---|
| x | INT64 | The x position of the compound | |
| y | INT64 | The y position of the compound | |
| width | INT64 | The width of the compound | |
| height | INT64 | The height of the compound | |
| paddingX | DECIMAL | Optional: The horizontal padding percentage (0.0-1.0, e.g., 0.1 = 10% padding). Defaults to 0 | |
| paddingY | DECIMAL | Optional: The vertical padding percentage (0.0-1.0, e.g., 0.1 = 10% padding). Defaults to 0 | |
| axisRef | ANYREF EXPR | The column that the measure will be evaluated against | |
| measureRef | NUMERIC EXPR | The measure to evaluate | |
| fillColor | STRING | Color for the box fill | |
| strokeColor | STRING | Color for lines, whiskers, and median | |
| showOutliers | BOOLEAN | Whether to show outlier points beyond whiskers | |
| orientation | STRING | Optional: "Horizontal" (default) or "Vertical" |
STRING SVG Box Plot
DaxLib.SVG.SVG(
500,
100,
BLANK(),
DaxLib.SVG.Compound.Boxplot(
0, // x
0, // y
500, // width
100, // height
0.05, // paddingX
0.02, // paddingY
Dates[Date], // axisRef
[Total Cost], // measureRef
"#EC008C", // fillColor
"#605E5C", // strokeColor
TRUE, // showOutliers
"Horizontal" // orientation
),
BLANK()
)
function 'DaxLib.SVG.Compound.Boxplot' =
(
x: INT64,
y: INT64,
width: INT64,
height: INT64,
paddingX: DOUBLE,
paddingY: DOUBLE,
axisRef: ANYREF EXPR,
measureRef: NUMERIC EXPR,
fillColor: STRING,
strokeColor: STRING,
showOutliers: BOOLEAN,
orientation: STRING
) =>
// Apply padding to dimensions
VAR _X = x + (width * (IF(ISBLANK(paddingX), 0, paddingX) / 2))
VAR _Y = y + (height * (IF(ISBLANK(paddingY), 0, paddingY) / 2))
VAR _Width = width * (1 - IF(ISBLANK(paddingX), 0, paddingX))
VAR _Height = height * (1 - IF(ISBLANK(paddingY), 0, paddingY))
// Check if Axis is numeric
VAR axisSample = MAX( axisRef )
VAR axisIsNumeric = ISNUMERIC( axisSample ) || ISDATETIME( axisSample )
// For totals
VAR _Data =
ADDCOLUMNS(
FILTER(
VALUES( axisRef ),
NOT ISBLANK( measureRef )
),
"@AxisIndex",
IF(
axisIsNumeric,
axisRef,
RANK( DENSE, CALCULATETABLE( VALUES( axisRef ), ALLSELECTED() ) )
),
"@Value", measureRef
)
VAR _XMin = MINX( _Data, [@Value] )
VAR _XMax = MAXX( _Data, [@Value] )
VAR _Count = COUNTROWS( _Data )
VAR _Min = MINX( _Data, [@Value] )
VAR _Max = MAXX( _Data, [@Value] )
// Calculate quartiles using standard definitions
VAR _Q1 = PERCENTILEX.INC( _Data, [@Value], 0.25 )
VAR _Median = PERCENTILEX.INC( _Data, [@Value], 0.5 )
VAR _Q3 = PERCENTILEX.INC( _Data, [@Value], 0.75 )
// Calculate IQR and whisker boundaries (1.5 * IQR rule)
VAR _IQR = _Q3 - _Q1
VAR _LowerWhisker = MAX( _Min, _Q1 - 1.5 * _IQR )
VAR _UpperWhisker = MIN( _Max, _Q3 + 1.5 * _IQR )
VAR _Orientation = IF( orientation = "Vertical", "Vertical", "Horizontal" )
// Primary axis (data-mapped) and cross axis
VAR _PrimLow = IF( _Orientation = "Horizontal", _X, _Y + _Height )
VAR _PrimHigh = IF( _Orientation = "Horizontal", _X + _Width, _Y )
VAR _CrossStart = IF( _Orientation = "Horizontal", _Y, _X )
VAR _CrossLen = IF( _Orientation = "Horizontal", _Height, _Width )
// Scale statistical values to primary axis coordinates
VAR _Q1P = DaxLib.SVG.Scale.Normalize( _Q1, _XMin, _XMax, _PrimLow, _PrimHigh )
VAR _MedianP = DaxLib.SVG.Scale.Normalize( _Median, _XMin, _XMax, _PrimLow, _PrimHigh )
VAR _Q3P = DaxLib.SVG.Scale.Normalize( _Q3, _XMin, _XMax, _PrimLow, _PrimHigh )
VAR _LowerWhiskerP = DaxLib.SVG.Scale.Normalize( _LowerWhisker, _XMin, _XMax, _PrimLow, _PrimHigh )
VAR _UpperWhiskerP = DaxLib.SVG.Scale.Normalize( _UpperWhisker, _XMin, _XMax, _PrimLow, _PrimHigh )
// Cross-axis dimensions
VAR _BoxCross = _CrossStart + _CrossLen * 0.2
VAR _BoxCrossLen = _CrossLen * 0.6
VAR _CenterCross = _CrossStart + _CrossLen * 0.5
// Create outlier points beyond whiskers if enabled
VAR _Outliers =
IF(
showOutliers,
CONCATENATEX(
FILTER(
_Data,
[@Value] < _LowerWhisker || [@Value] > _UpperWhisker
),
DaxLib.SVG.Element.Circle(
IF( _Orientation = "Horizontal", DaxLib.SVG.Scale.Normalize( [@Value], _XMin, _XMax, _PrimLow, _PrimHigh ), _CenterCross ),
IF( _Orientation = "Horizontal", _CenterCross, DaxLib.SVG.Scale.Normalize( [@Value], _XMin, _XMax, _PrimLow, _PrimHigh ) ),
2,
DaxLib.SVG.Attr.Shapes( strokeColor, BLANK(), BLANK(), BLANK(), BLANK(), BLANK(), BLANK() ),
BLANK()
),
""
)
)
// Lower whisker line (along primary axis)
VAR _LowerWhiskerLine =
DaxLib.SVG.Element.Line(
IF( _Orientation = "Horizontal", _LowerWhiskerP, _CenterCross ),
IF( _Orientation = "Horizontal", _CenterCross, _LowerWhiskerP ),
IF( _Orientation = "Horizontal", _Q1P, _CenterCross ),
IF( _Orientation = "Horizontal", _CenterCross, _Q1P ),
DaxLib.SVG.Attr.Shapes( BLANK(), BLANK(), BLANK(), strokeColor, 1, BLANK(), BLANK() ),
BLANK()
)
// Upper whisker line (along primary axis)
VAR _UpperWhiskerLine =
DaxLib.SVG.Element.Line(
IF( _Orientation = "Horizontal", _Q3P, _CenterCross ),
IF( _Orientation = "Horizontal", _CenterCross, _Q3P ),
IF( _Orientation = "Horizontal", _UpperWhiskerP, _CenterCross ),
IF( _Orientation = "Horizontal", _CenterCross, _UpperWhiskerP ),
DaxLib.SVG.Attr.Shapes( BLANK(), BLANK(), BLANK(), strokeColor, 1, BLANK(), BLANK() ),
BLANK()
)
// Lower whisker cap (across cross axis)
VAR _LowerCap =
DaxLib.SVG.Element.Line(
IF( _Orientation = "Horizontal", _LowerWhiskerP, _BoxCross ),
IF( _Orientation = "Horizontal", _BoxCross, _LowerWhiskerP ),
IF( _Orientation = "Horizontal", _LowerWhiskerP, _BoxCross + _BoxCrossLen ),
IF( _Orientation = "Horizontal", _BoxCross + _BoxCrossLen, _LowerWhiskerP ),
DaxLib.SVG.Attr.Shapes( BLANK(), BLANK(), BLANK(), strokeColor, 1, BLANK(), BLANK() ),
BLANK()
)
// Upper whisker cap (across cross axis)
VAR _UpperCap =
DaxLib.SVG.Element.Line(
IF( _Orientation = "Horizontal", _UpperWhiskerP, _BoxCross ),
IF( _Orientation = "Horizontal", _BoxCross, _UpperWhiskerP ),
IF( _Orientation = "Horizontal", _UpperWhiskerP, _BoxCross + _BoxCrossLen ),
IF( _Orientation = "Horizontal", _BoxCross + _BoxCrossLen, _UpperWhiskerP ),
DaxLib.SVG.Attr.Shapes( BLANK(), BLANK(), BLANK(), strokeColor, 1, BLANK(), BLANK() ),
BLANK()
)
// Main box (Q1 to Q3)
VAR _Box =
DaxLib.SVG.Element.Rect(
IF( _Orientation = "Horizontal", MIN( _Q1P, _Q3P ), _BoxCross ),
IF( _Orientation = "Horizontal", _BoxCross, MIN( _Q1P, _Q3P ) ),
IF( _Orientation = "Horizontal", ABS( _Q3P - _Q1P ), _BoxCrossLen ),
IF( _Orientation = "Horizontal", _BoxCrossLen, ABS( _Q3P - _Q1P ) ),
2, 2,
DaxLib.SVG.Attr.Shapes( fillColor, 0.5, BLANK(), strokeColor, 1, BLANK(), BLANK() ),
BLANK()
)
// Median line (across cross axis)
VAR _MedianLine =
DaxLib.SVG.Element.Line(
IF( _Orientation = "Horizontal", _MedianP, _BoxCross ),
IF( _Orientation = "Horizontal", _BoxCross, _MedianP ),
IF( _Orientation = "Horizontal", _MedianP, _BoxCross + _BoxCrossLen ),
IF( _Orientation = "Horizontal", _BoxCross + _BoxCrossLen, _MedianP ),
DaxLib.SVG.Attr.Shapes( BLANK(), BLANK(), BLANK(), strokeColor, 2, BLANK(), BLANK() ),
BLANK()
)
// Combined elements
VAR _CombinedElements =
_LowerWhiskerLine &
_UpperWhiskerLine &
_LowerCap &
_UpperCap &
_Box &
_MedianLine &
_Outliers
RETURN
IF( NOT ISEMPTY( _Data ), _CombinedElements )