Skip to content

Compound.Heatmap

Creates a KDE-based Heatmap compound SVG Visual using Kernel Density Estimation for smooth color gradients

Kernel Density Estimation (KDE)

KDE is a statistical method that estimates the probability density function of your data by placing a "kernel" (typically a normal distribution) at each data point. The heatmap visualizes data density across the range, creating smooth gradients that reveal patterns and concentrations in your dataset.

Key Parameters:

  • Samples: Controls the resolution of the density calculation (higher = smoother, but slower performance)

  • Bandwidth: Controls the smoothing level - smaller values create sharper peaks around data points, larger values create broader, smoother distributions

DaxLib.SVG.Compound.Heatmap( x, y, width, height, paddingX, paddingY, axisRef, measureRef, samples, bandwidth, color )
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
samples INT64 Number of density calculation points (default 50)
bandwidth NUMERIC Kernel bandwidth for smoothing (default auto-calculated)
color STRING The hex color for high density areas (e.g., "#01B8AA")

STRING SVG Heatmap

DaxLib.SVG.SVG(
    500,
    100,
    BLANK(),
    DaxLib.SVG.Compound.Heatmap(
        0,                  // x
        0,                  // y
        500,                // width
        100,                // height
        0.05,               // paddingX
        0.02,               // paddingY
        Dates[Date],        // axisRef
        [Total Cost],       // measureRef
        MAX( Samples[Samples] ), // samples
        MAX( Bandwidth[Bandwidth] ), // bandwidth
        "#EC008C"           // color
    ),
    BLANK()
)
function 'DaxLib.SVG.Compound.Heatmap' =
        (
            x: INT64,
            y: INT64,
            width: INT64,
            height: INT64,
            paddingX: DOUBLE,
            paddingY: DOUBLE,
            axisRef: ANYREF EXPR,
            measureRef: NUMERIC EXPR,
            samples: INT64,
            bandwidth: NUMERIC,
            color: 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 _NumValues =        COUNTROWS( _Data )
            VAR _Min =              MINX( _Data, [@Value] )
            VAR _Max =              MAXX( _Data, [@Value] )
            VAR _Range =            _Max - _Min
            VAR _RangePerSample =   _Range / samples

            // Calculate Kernel Density Estimation using Normal distribution
            VAR _KDE = 
                ADDCOLUMNS(
                    GENERATESERIES( 0, samples, 1 ),
                    "@InputX", _Min + _RangePerSample * [Value],
                    "@KDE", 
                        ( 1 / _NumValues ) * 
                        SUMX(
                            _Data, 
                            NORM.DIST( 
                                _Min + _RangePerSample * [Value], 
                                [@Value], 
                                bandwidth, 
                                FALSE() 
                            ) 
                        )
                )

            VAR _MaxKDE =       MAXX( _KDE, [@KDE] )

            // Create gradient stops from KDE points
            VAR _GradientStops = 
                CONCATENATEX(
                    _KDE,
                    VAR _Position = DaxLib.SVG.Scale.Normalize( [@InputX], _Min, _Max, 0, 100 )
                    VAR _Intensity = IF( _MaxKDE > 0, [@KDE] / _MaxKDE, 0 )
                    VAR _StopColor = 
                        DaxLib.SVG.Color.Hex.Interpolate(
                            "#FFFFFF",
                            color,
                            _Intensity
                        )
                    RETURN
                        "<stop offset='" & _Position & "%' stop-color='" & _StopColor & "' />",
                    "",
                    [Value],
                    ASC
                )

            // Create linear gradient definition
            VAR _GradientDef = 
                "<defs>" &
                    "<linearGradient id='kde-gradient' x1='0%' y1='0%' x2='100%' y2='0%'>" &
                        _GradientStops &
                    "</linearGradient>" &
                "</defs>"

            // Create rectangle with gradient fill
            VAR _HeatmapRect = 
                DaxLib.SVG.Element.Rect(
                    _X,                         // x
                    _Y,                         // y
                    _Width,                     // width
                    _Height,                    // height
                    0,                          // rx
                    0,                          // ry
                    DaxLib.SVG.Attr.Shapes(
                        "url(#kde-gradient)",   // fill
                        BLANK(),                // fillOpacity
                        BLANK(),                // fillRule
                        BLANK(),                // stroke
                        BLANK(),                // strokeWidth
                        BLANK(),                // strokeOpacity
                        BLANK()                 // opacity
                    ),
                    BLANK()                     // transforms
                )

            // Combined elements
            VAR _CombinedElements =
                _GradientDef & 
                _HeatmapRect

            RETURN

                IF( NOT ISEMPTY( _Data ), _CombinedElements )