Skip to content

Compound.Jitter

Creates a Jitter Plot compound SVG Visual showing values as points with x-position based on value and y-position jittered around center

DaxLib.SVG.Compound.Jitter( x, y, width, height, axisRef, measureRef, pointColor, jitterAmount, paddingX, paddingY )
Parameter Type Required Default 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
axisRef ANYREF EXPR The column that the measure will be evaluated against
measureRef NUMERIC EXPR The measure to evaluate
pointColor STRING BLANK() Optional: The hex color of the points (e.g., "#01B8AA")
jitterAmount DECIMAL 0.3 Optional: The amount of jitter as a percentage of height (0.0-1.0). Defaults to 0.3
paddingX DECIMAL 0.05 Optional: The horizontal padding percentage (0.0-1.0, e.g., 0.1 = 10% padding). Defaults to 0.05
paddingY DECIMAL 0.02 Optional: The vertical padding percentage (0.0-1.0, e.g., 0.1 = 10% padding). Defaults to 0.02

STRING SVG Jitter Plot

DaxLib.SVG.SVG(
    500,
    100,
    BLANK(),
    DaxLib.SVG.Compound.Jitter(
        0,                  // x
        0,                  // y
        500,                // width
        100,                // height
        Dates[Date],        // axisRef
        [Total Cost],       // measureRef
        "#EC008C",          // pointColor
        0.5,                // jitterAmount
        0.05,               // paddingX
        0.02                // paddingY
    ),
    BLANK()
)
function 'DaxLib.SVG.Compound.Jitter' =
        (
            x: INT64,
            y: INT64,
            width: INT64,
            height: INT64,
            axisRef: ANYREF EXPR,
            measureRef: NUMERIC EXPR,
            pointColor: STRING = BLANK(),
            jitterAmount: DOUBLE = 0.3,
            paddingX: DOUBLE = 0.05,
            paddingY: DOUBLE = 0.02
        ) =>

            // 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))

            VAR _PointColor = IF( NOT ISBLANK( pointColor ), pointColor, "#01B8AA" )

            // 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 _RawXMin =  MINX( _Data, [@Value] )
            VAR _XMin =     IF( _RawXMin > 0, 0, _RawXMin )
            VAR _XMax =     MAXX( _Data, [@Value] )

            // Points
            VAR _CenterY =      _Y + _Height * 0.5
            VAR _JitterRange =  _Height * IF( ISBLANK( jitterAmount ), 0.3, jitterAmount )
            VAR _CircleElements = 
                CONCATENATEX(
                    _Data,
                    IF( 
                        NOT ISBLANK( [@Value] ),
                        VAR _Seed =         ABS( [@Value] * 12345 ) + ABS( [@AxisIndex] * 67890 ) + ABS( LEN( FORMAT( [@Value], "0.000000" ) ) * 9876 )
                        VAR _PseudoRandom = MOD( _Seed, 10000 ) / 10000
                        VAR _JitterOffset = ( _PseudoRandom - 0.5 ) * _JitterRange
                        VAR _CX = DaxLib.SVG.Scale.Normalize( [@Value], _XMin, _XMax, _X, _X + _Width )
                        VAR _CY = _CenterY + _JitterOffset
                        VAR _ClampedCX = MAX( _X, MIN( _X + _Width, _CX ) )
                        VAR _ClampedCY = MAX( _Y, MIN( _Y + _Height, _CY ) )
                        RETURN
                            DaxLib.SVG.Element.Circle(
                                _ClampedCX,
                                _ClampedCY,
                                2,
                                DaxLib.SVG.Attr.Shapes(
                                    _PointColor,
                                    0.5,
                                    BLANK(),
                                    _PointColor,
                                    1,
                                    0.9
                                )
                            )
                    ),
                    " ",
                    [@AxisIndex],
                    ASC
                )

            RETURN

                IF( NOT ISEMPTY( _Data ), _CircleElements )