Skip to content

Axes.Render

Renders cartesian axis lines, ticks, and labels

DaxLib.SVG.Axes.Render( plotX, plotY, plotWidth, plotHeight, xAxisMin, xAxisMax, yAxisMin, yAxisMax, showAxis, axisFontSize, xAxisIsDate, yAxisIsDate, tickCountX, tickCountY )
Parameter Type Required Description
plotX NUMERIC VAL Plot area X origin
plotY NUMERIC VAL Plot area Y origin
plotWidth NUMERIC VAL Plot area width
plotHeight NUMERIC VAL Plot area height
xAxisMin NUMERIC VAL X-axis minimum value
xAxisMax NUMERIC VAL X-axis maximum value
yAxisMin NUMERIC VAL Y-axis minimum value
yAxisMax NUMERIC VAL Y-axis maximum value
showAxis BOOLEAN Optional: Whether axes are enabled. Defaults to FALSE
axisFontSize INT64 Optional: Axis label font size. Defaults to 10
xAxisIsDate BOOLEAN Optional: Whether X-axis values represent dates. Defaults to FALSE
yAxisIsDate BOOLEAN Optional: Whether Y-axis values represent dates. Defaults to FALSE
tickCountX INT64 Optional: Number of X-axis ticks. Defaults to 5
tickCountY INT64 Optional: Number of Y-axis ticks. Defaults to 4

STRING Axis SVG string or blank when axes are disabled

DaxLib.SVG.Axes.Render(
    40,             // plotX
    5,              // plotY
    460,            // plotWidth
    270,            // plotHeight
    0,              // xAxisMin
    100,            // xAxisMax
    0,              // yAxisMin
    500,            // yAxisMax
    TRUE,           // showAxis
    10,             // axisFontSize
    FALSE,          // xAxisIsDate
    FALSE,          // yAxisIsDate
    5,              // tickCountX
    4               // tickCountY
)
// Returns SVG string with axis lines, ticks, and labels
// Returns BLANK when showAxis = FALSE
function 'DaxLib.SVG.Axes.Render' =
        (
            plotX: NUMERIC VAL,
            plotY: NUMERIC VAL,
            plotWidth: NUMERIC VAL,
            plotHeight: NUMERIC VAL,
            xAxisMin: NUMERIC VAL,
            xAxisMax: NUMERIC VAL,
            yAxisMin: NUMERIC VAL,
            yAxisMax: NUMERIC VAL,
            showAxis: BOOLEAN,
            axisFontSize: INT64,
            xAxisIsDate: BOOLEAN,
            yAxisIsDate: BOOLEAN,
            tickCountX: INT64,
            tickCountY: INT64
        ) =>

            VAR _ShowAxis = IF( ISBLANK( showAxis ), FALSE(), showAxis )
            VAR _AxisFontSize = IF( ISBLANK( axisFontSize ), 10, axisFontSize )
            VAR _AxisFontFamily = "Segoe UI"
            VAR _AxisColor = "#605E5C"
            VAR _AxisLineStrokeWidth = 1
            VAR _TickLength = 3
            VAR _TickPadding = 4
            VAR _TickCountX = IF( ISBLANK( tickCountX ) || tickCountX < 1, 5, tickCountX )
            VAR _TickCountY = IF( ISBLANK( tickCountY ) || tickCountY < 1, 4, tickCountY )
            VAR _XAxisIsDate = IF( ISBLANK( xAxisIsDate ), FALSE(), xAxisIsDate )
            VAR _YAxisIsDate = IF( ISBLANK( yAxisIsDate ), FALSE(), yAxisIsDate )
            VAR _XAxisSpan = ABS( xAxisMax - xAxisMin )
            VAR _YAxisSpan = ABS( yAxisMax - yAxisMin )
            VAR _XAxisDecimals = IF( _XAxisSpan >= 100, 0, IF( _XAxisSpan >= 10, 1, 2 ) )
            VAR _YAxisDecimals = IF( _YAxisSpan >= 100, 0, IF( _YAxisSpan >= 10, 1, 2 ) )

            VAR _XTickBase =
                ADDCOLUMNS(
                    GENERATESERIES( 0, _TickCountX - 1, 1 ),
                    "@TickValue",
                        IF(
                            _TickCountX = 1,
                            xAxisMin,
                            xAxisMin + DIVIDE( [Value], _TickCountX - 1, 0 ) * ( xAxisMax - xAxisMin )
                        ),
                    "@TickIndex", [Value]
                )

            VAR _XTickTable =
                ADDCOLUMNS(
                    _XTickBase,
                    "@Pos",
                        IF(
                            xAxisMax = xAxisMin,
                            plotX + plotWidth / 2,
                            DaxLib.SVG.Scale.Normalize( [@TickValue], xAxisMin, xAxisMax, plotX, plotX + plotWidth )
                        ),
                    "@Label",
                        FORMAT(
                            IF(
                                _XAxisIsDate,
                                [@TickValue],
                                ROUND( [@TickValue], _XAxisDecimals )
                            ),
                            IF( _XAxisIsDate, "dd-mmm-yy", "General Number" )
                        ),
                    "@Anchor",
                        IF(
                            [@TickIndex] = 0, "start",
                            IF( [@TickIndex] = _TickCountX - 1, "end", "middle" )
                        )
                )

            // Detect X-axis label overlap and filter to first/last when needed
            VAR _XLabelWidthFactor = 0.56
            VAR _MaxXLabelLen = MAXX( _XTickTable, LEN( [@Label] ) )
            VAR _EstXLabelWidth = _MaxXLabelLen * _AxisFontSize * _XLabelWidthFactor
            VAR _XLabelsOverlap = _EstXLabelWidth * _TickCountX > plotWidth * 0.9

            VAR _XTickRendered =
                FILTER(
                    _XTickTable,
                    NOT _XLabelsOverlap || [@TickIndex] = 0 || [@TickIndex] = _TickCountX - 1
                )

            VAR _YTickBase =
                ADDCOLUMNS(
                    GENERATESERIES( 0, _TickCountY - 1, 1 ),
                    "@TickValue",
                        IF(
                            _TickCountY = 1,
                            yAxisMin,
                            yAxisMin + DIVIDE( [Value], _TickCountY - 1, 0 ) * ( yAxisMax - yAxisMin )
                        )
                )

            VAR _YTickTable =
                ADDCOLUMNS(
                    _YTickBase,
                    "@Pos",
                        IF(
                            yAxisMax = yAxisMin,
                            plotY + plotHeight / 2,
                            DaxLib.SVG.Scale.Normalize( [@TickValue], yAxisMin, yAxisMax, plotY + plotHeight, plotY )
                        ),
                    "@Label",
                        FORMAT(
                            IF(
                                _YAxisIsDate,
                                [@TickValue],
                                ROUND( [@TickValue], _YAxisDecimals )
                            ),
                            IF( _YAxisIsDate, "dd-mmm-yy", "General Number" )
                        )
                )

            // Detect Y-axis label overlap and filter to first/last when needed
            VAR _EstYLabelHeight = _AxisFontSize * 1.5
            VAR _YLabelsOverlap = _EstYLabelHeight * _TickCountY > plotHeight * 0.9

            VAR _YTickRendered =
                FILTER(
                    _YTickTable,
                    NOT _YLabelsOverlap || [Value] = 0 || [Value] = _TickCountY - 1
                )

            VAR _XAxisLine =
                DaxLib.SVG.Element.Line(
                    plotX,
                    plotY + plotHeight,
                    plotX + plotWidth,
                    plotY + plotHeight,
                    DaxLib.SVG.Attr.Shapes( BLANK(), BLANK(), BLANK(), _AxisColor, _AxisLineStrokeWidth, BLANK(), BLANK() ),
                    BLANK()
                )

            VAR _YAxisLine =
                DaxLib.SVG.Element.Line(
                    plotX,
                    plotY,
                    plotX,
                    plotY + plotHeight,
                    DaxLib.SVG.Attr.Shapes( BLANK(), BLANK(), BLANK(), _AxisColor, _AxisLineStrokeWidth, BLANK(), BLANK() ),
                    BLANK()
                )

            VAR _XTicks =
                CONCATENATEX(
                    _XTickRendered,
                    DaxLib.SVG.Element.Line(
                        [@Pos],
                        plotY + plotHeight,
                        [@Pos],
                        plotY + plotHeight + _TickLength,
                        DaxLib.SVG.Attr.Shapes( BLANK(), BLANK(), BLANK(), _AxisColor, 1, BLANK(), BLANK() ),
                        BLANK()
                    )
                    &
                    DaxLib.SVG.Element.Txt(
                        [@Pos],
                        plotY + plotHeight + _TickLength + _TickPadding,
                        [@Label],
                        BLANK(),
                        BLANK(),
                        DaxLib.SVG.Attr.Shapes( _AxisColor, BLANK(), BLANK(), BLANK(), BLANK(), BLANK(), BLANK() )
                        & DaxLib.SVG.Attr.Txt( _AxisFontFamily, _AxisFontSize, BLANK(), BLANK(), [@Anchor], "hanging", BLANK(), BLANK(), BLANK() ),
                        BLANK()
                    ),
                    ""
                )

            VAR _YTicks =
                CONCATENATEX(
                    _YTickRendered,
                    DaxLib.SVG.Element.Line(
                        plotX - _TickLength,
                        [@Pos],
                        plotX,
                        [@Pos],
                        DaxLib.SVG.Attr.Shapes( BLANK(), BLANK(), BLANK(), _AxisColor, 1, BLANK(), BLANK() ),
                        BLANK()
                    )
                    &
                    DaxLib.SVG.Element.Txt(
                        plotX - _TickLength - _TickPadding,
                        [@Pos],
                        [@Label],
                        BLANK(),
                        BLANK(),
                        DaxLib.SVG.Attr.Shapes( _AxisColor, BLANK(), BLANK(), BLANK(), BLANK(), BLANK(), BLANK() )
                        & DaxLib.SVG.Attr.Txt( _AxisFontFamily, _AxisFontSize, BLANK(), BLANK(), "end", "middle", BLANK(), BLANK(), BLANK() ),
                        BLANK()
                    ),
                    ""
                )

            RETURN
                IF( _ShowAxis, _XAxisLine & _YAxisLine & _XTicks & _YTicks )