Skip to content

Compound.Area

Creates an Area compound SVG Visual for a numeric x-axis

01-Aug-2516-Aug-2531-Aug-2515-Sep-2501-Oct-25020000400006000080000100000

DaxLib.SVG.Compound.Area( x, y, width, height, axisRef, measureRef, fillColor, strokeColor, fillOpacity, minMarkColor, maxMarkColor, showAxis, axisFontSize, 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
fillColor STRING BLANK() Optional: The color of the area fill, e.g., "#01B8AA". Defaults to "#01B8AA"
strokeColor STRING BLANK() Optional: The color of the stroke line. Defaults to fillColor
fillOpacity NUMERIC 0.3 Optional: The opacity of the fill (0-1). Defaults to 0.3
minMarkColor STRING BLANK() Optional: The hex color for the minimum value marker. Omitted if not specified
maxMarkColor STRING BLANK() Optional: The hex color for the maximum value marker. Omitted if not specified
showAxis BOOLEAN FALSE() Optional: Show axes when TRUE. Defaults to FALSE
axisFontSize INT64 10 Optional: Axis label font size. Defaults to 10
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 Area Chart

 DaxLib.SVG.SVG(
    500,
    100,
    BLANK(),
    DaxLib.SVG.Compound.Area(
        0,                  // x
        0,                  // y
        100,                // width
        20,                 // height
        Dates[Date],        // axisRef
        [Total Cost],       // measureRef
        "#EC008C",          // fillColor
        "#EC008C",          // strokeColor
        0.2,                // fillOpacity
        "#D04848",          // minMarkColor
        "#2E8B57",          // maxMarkColor
        TRUE,               // showAxis
        8,                  // axisFontSize
        0.05,               // paddingX
        0.02                // paddingY
    ),
    BLANK()
)
function 'DaxLib.SVG.Compound.Area' =
        (
            x: INT64,
            y: INT64,
            width: INT64,
            height: INT64,
            axisRef: ANYREF EXPR,
            measureRef: NUMERIC EXPR,
            fillColor: STRING = BLANK(),
            strokeColor: STRING = BLANK(),
            fillOpacity: NUMERIC = 0.3,
            minMarkColor: STRING = BLANK(),
            maxMarkColor: STRING = BLANK(),
            showAxis: BOOLEAN = FALSE(),
            axisFontSize: INT64 = 10,
            paddingX: DOUBLE = 0.05,
            paddingY: DOUBLE = 0.02
        ) =>

            // Apply padding to dimensions
            VAR _X =            x + (width * (paddingX / 2))
            VAR _Y =            y + (height * (paddingY / 2))
            VAR _Width =        width * (1 - paddingX)
            VAR _Height =       height * (1 - paddingY)

            VAR _FillColor = IF( NOT ISBLANK( fillColor ), fillColor, "#01B8AA" )
            VAR _StrokeColor = IF( NOT ISBLANK( strokeColor ), strokeColor, _FillColor )
            VAR _AxisIsDate = ISDATETIME( MAX( axisRef ) )

            VAR _Data = DaxLib.SVG.Data.AxisMeasure( axisRef, measureRef, "Auto" )
            VAR _DataNonBlank = FILTER( _Data, NOT ISBLANK( [@Value] ) )
            VAR _RawYMin = MINX( _DataNonBlank, [@Value] )
            VAR _RawYMax = MAXX( _DataNonBlank, [@Value] )
            VAR _Range = DaxLib.SVG.Data.Range( _RawYMin, _RawYMax, TRUE() )

            VAR _XMin =     MINX( _DataNonBlank, [@AxisIndex] )
            VAR _XMax =     MAXX( _DataNonBlank, [@AxisIndex] )
            VAR _RawYMin2 = MINX( _Range, [@Baseline] )
            VAR _RawYMax2 = MAXX( _Range, [@Max] )

            // Compute nice range for value axis
            VAR _NiceY = DaxLib.SVG.Scale.NiceRange( _RawYMin2, _RawYMax2, 5, TRUE() )
            VAR _YMin = MINX( _NiceY, [@NiceMin] )
            VAR _YMax = MINX( _NiceY, [@NiceMax] )
            VAR _YTickCount = MINX( _NiceY, [@NiceTickCount] )

            // Axis layout
            VAR _MaxTickLabelWidth = DaxLib.SVG.Axes.MaxTickLabelWidth( _YMin, _YMax, _YTickCount, axisFontSize )
            VAR _Layout = DaxLib.SVG.Axes.Layout( _X, _Y, _Width, _Height, _MaxTickLabelWidth, showAxis, axisFontSize )
            VAR _PlotX = MINX( _Layout, [@PlotX] )
            VAR _PlotY = MINX( _Layout, [@PlotY] )
            VAR _PlotWidth = MINX( _Layout, [@PlotWidth] )
            VAR _PlotHeight = MINX( _Layout, [@PlotHeight] )

            VAR _Baseline = DaxLib.SVG.Axes.Baseline( "Vertical", _YMin, _YMax, _PlotX, _PlotY, _PlotWidth, _PlotHeight )
            VAR _BaselineX = MINX( _Baseline, [@BaseX] )
            VAR _BaselineY = MINX( _Baseline, [@BaseY] )
            VAR _FirstDatum = TOPN( 1, _DataNonBlank, [@AxisIndex], ASC )
            VAR _LastDatum = TOPN( 1, _DataNonBlank, [@AxisIndex], DESC )

            // Get first and last X positions
            VAR _FirstX = 
                MAXX(
                    _FirstDatum,
                    MINX( DaxLib.SVG.Axes.Point( "Vertical", [@AxisIndex], [@Value], _XMin, _XMax, _YMin, _YMax, _PlotX, _PlotY, _PlotWidth, _PlotHeight ), [@X] )
                )

            VAR _FirstY =
                MAXX(
                    _FirstDatum,
                    MINX( DaxLib.SVG.Axes.Point( "Vertical", [@AxisIndex], [@Value], _XMin, _XMax, _YMin, _YMax, _PlotX, _PlotY, _PlotWidth, _PlotHeight ), [@Y] )
                )

            VAR _LastX = 
                MAXX(
                    _LastDatum,
                    MINX( DaxLib.SVG.Axes.Point( "Vertical", [@AxisIndex], [@Value], _XMin, _XMax, _YMin, _YMax, _PlotX, _PlotY, _PlotWidth, _PlotHeight ), [@X] )
                )

            VAR _LastY =
                MAXX(
                    _LastDatum,
                    MINX( DaxLib.SVG.Axes.Point( "Vertical", [@AxisIndex], [@Value], _XMin, _XMax, _YMin, _YMax, _PlotX, _PlotY, _PlotWidth, _PlotHeight ), [@Y] )
                )

            // Generate points for the area polygon
            // Start at baseline (bottom left), go up the data line, then back down to baseline
            VAR _PolygonPoints = 
                _FirstX & "," & _BaselineY
                & " " & 
                CONCATENATEX(
                    _DataNonBlank,
                    IF( 
                        NOT ISBLANK( [@Value] ), 
                        VAR _Point = DaxLib.SVG.Axes.Point( "Vertical", [@AxisIndex], [@Value], _XMin, _XMax, _YMin, _YMax, _PlotX, _PlotY, _PlotWidth, _PlotHeight )
                        RETURN COMBINEVALUES( ",", MINX( _Point, [@X] ), MINX( _Point, [@Y] ) )
                    ),
                    " ",
                    [@AxisIndex],
                    ASC
                )
                & " " & _LastX & "," & _BaselineY

            // Generate points for just the top line (for optional stroke)
            VAR _TopPoints = 
                CONCATENATEX(
                    _DataNonBlank,
                    IF( 
                        NOT ISBLANK( [@Value] ), 
                        VAR _Point = DaxLib.SVG.Axes.Point( "Vertical", [@AxisIndex], [@Value], _XMin, _XMax, _YMin, _YMax, _PlotX, _PlotY, _PlotWidth, _PlotHeight )
                        RETURN COMBINEVALUES( ",", MINX( _Point, [@X] ), MINX( _Point, [@Y] ) )
                    ),
                    " ",
                    [@AxisIndex],
                    ASC
                )

            // Area Element (using polygon for filled area)
            VAR _AreaElement =
                DaxLib.SVG.Element.Polygon(
                    _PolygonPoints,
                    DaxLib.SVG.Attr.Shapes(
                        _FillColor,
                        IF( NOT ISBLANK( fillOpacity ), fillOpacity, 0.3 ),
                        BLANK(),
                        "none",
                        0
                    )
                )

            // stroke line on top of the area
            VAR _StrokeElement = 
                DaxLib.SVG.Element.Polyline(
                    _TopPoints,
                    DaxLib.SVG.Attr.Shapes(
                        "none",
                        BLANK(),
                        BLANK(),
                        _StrokeColor,
                        1
                    )
                )

            // Circle if only one point
            VAR _SinglePoint = DaxLib.SVG.Axes.Point( "Vertical", MAXX( _DataNonBlank, [@AxisIndex] ), MAXX( _DataNonBlank, [@Value] ), _XMin, _XMax, _YMin, _YMax, _PlotX, _PlotY, _PlotWidth, _PlotHeight )
            VAR _SinglePointElement =
                DaxLib.SVG.Element.Circle(
                        MINX( _SinglePoint, [@X] ),
                        MINX( _SinglePoint, [@Y] ),
                        2,
                        DaxLib.SVG.Attr.Shapes( _FillColor )
                    )

            // Combine elements
            VAR _CombinedElements = 
                IF(
                    COUNTROWS( _DataNonBlank ) = 1,
                    _SinglePointElement,
                    _AreaElement &
                    _StrokeElement
                )

            // Min and Max value markers
            VAR _MinValueRow = TOPN( 1, _DataNonBlank, [@Value], ASC )
            VAR _MinValueAxisIdx = MINX( _MinValueRow, [@AxisIndex] )
            VAR _MinValueVal = MINX( _MinValueRow, [@Value] )
            VAR _MinPointData = DaxLib.SVG.Axes.Point( "Vertical", _MinValueAxisIdx, _MinValueVal, _XMin, _XMax, _YMin, _YMax, _PlotX, _PlotY, _PlotWidth, _PlotHeight )
            VAR _MaxValueRow = TOPN( 1, _DataNonBlank, [@Value], DESC )
            VAR _MaxValueAxisIdx = MINX( _MaxValueRow, [@AxisIndex] )
            VAR _MaxValueVal = MAXX( _MaxValueRow, [@Value] )
            VAR _MaxPointData = DaxLib.SVG.Axes.Point( "Vertical", _MaxValueAxisIdx, _MaxValueVal, _XMin, _XMax, _YMin, _YMax, _PlotX, _PlotY, _PlotWidth, _PlotHeight )
            VAR _MinMarkColor = IF( NOT ISBLANK( minMarkColor ), minMarkColor, _FillColor )
            VAR _MaxMarkColor = IF( NOT ISBLANK( maxMarkColor ), maxMarkColor, _FillColor )
            VAR _MinMarkHalo =
                DaxLib.SVG.Element.Circle(
                    MINX( _MinPointData, [@X] ),
                    MINX( _MinPointData, [@Y] ),
                    3.5,
                    DaxLib.SVG.Attr.Shapes( "white", 0.7 )
                )
            VAR _MinMark =
                DaxLib.SVG.Element.Circle(
                    MINX( _MinPointData, [@X] ),
                    MINX( _MinPointData, [@Y] ),
                    2.5,
                    DaxLib.SVG.Attr.Shapes( _MinMarkColor )
                )
            VAR _MaxMarkHalo =
                DaxLib.SVG.Element.Circle(
                    MINX( _MaxPointData, [@X] ),
                    MINX( _MaxPointData, [@Y] ),
                    3.5,
                    DaxLib.SVG.Attr.Shapes( "white", 0.7 )
                )
            VAR _MaxMark =
                DaxLib.SVG.Element.Circle(
                    MINX( _MaxPointData, [@X] ),
                    MINX( _MaxPointData, [@Y] ),
                    2.5,
                    DaxLib.SVG.Attr.Shapes( _MaxMarkColor )
                )
            VAR _MinMaxMarks =
                IF(
                    COUNTROWS( _DataNonBlank ) > 2,
                    IF( NOT ISBLANK( minMarkColor ), _MinMarkHalo & _MinMark )
                        & IF( NOT ISBLANK( maxMarkColor ), _MaxMarkHalo & _MaxMark )
                )

            VAR _AxisElements = DaxLib.SVG.Axes.Render( _PlotX, _PlotY, _PlotWidth, _PlotHeight, _XMin, _XMax, _YMin, _YMax, showAxis, axisFontSize, _AxisIsDate, FALSE(), 5, _YTickCount )

            RETURN

                IF( NOT ISEMPTY( _DataNonBlank ) && _PlotWidth > 0 && _PlotHeight > 0, _CombinedElements & _MinMaxMarks & _AxisElements )