Created
August 12, 2023 06:25
-
-
Save tirnovar/96ce65ca6aa308cd4ac2db3f4bea2655 to your computer and use it in GitHub Desktop.
Water Fall Chart generated by DAX into SVG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| svgWaterFall = | |
| /* SETUP */ | |
| // ALL IN SETUP AND STYLES CAN BE UPDATED | |
| // BASE VALUE | |
| VAR _baseValue = 16 // WILL BE USED AS VALUE FOR BASE COLUMN | |
| // INPUT TABLE SETUP | |
| VAR _initTbl = | |
| ADDCOLUMNS ( | |
| SELECTCOLUMNS ( SUMMARIZE ( <TABLE>, <X-AXIS-CATEGORY> ), "@xAxisCategory", <X-AXIS-CATEGORY> ), | |
| "@vl", <MEASURE> | |
| ) | |
| // VISUAL SIZE SETUP | |
| VAR _heightCanvasSize = 350 // Height of the visual | |
| VAR _widthCanvasSize = 1260 // Width of the visual | |
| // PADDING SETUP | |
| VAR _paddingSpace = 20 // Padding space between the visual and the canvas | |
| VAR _requestedSpaceBetweenColumns = 20 // Space between columns | |
| /* STYLE DECLARTIONS */ | |
| VAR _styles = " | |
| <style> | |
| text { | |
| fill: #E2E2E2; | |
| font-family: 'Segoe UI'; | |
| font-size: 0.85em; | |
| dominant-baseline: hanging; | |
| text-anchor: middle; | |
| } | |
| .specialTexts{ | |
| fill: #CCCCCC | |
| } | |
| .supportLines { | |
| fill: none; | |
| stroke: #CCCCCC | |
| } | |
| .initialCol{ | |
| fill: #555555 | |
| } | |
| .neutralCol{ | |
| fill: #CCCCCC | |
| } | |
| .positiveCol { | |
| fill: #157558 | |
| } | |
| .negativeCol { | |
| fill: #A74764 | |
| } | |
| .textValuesBolder { | |
| font-weight: 600; | |
| font-size: 0.75em; | |
| } | |
| .darkerFiller{ | |
| fill: #999999 | |
| } | |
| .percentageChanges { | |
| font-weight: 400; | |
| font-size: 0.6em; | |
| } | |
| </style> | |
| " | |
| /* SVG DECLARTIONS */ | |
| VAR _svgDeclaration = "data:image/svg+xml;utf8," | |
| VAR _svgHeader = "<svg xmlns='http://www.w3.org/2000/svg' height='" & _heightCanvasSize & "' width='" & _widthCanvasSize & "' xmlns:space='perserve'>" | |
| VAR _svgEnd = "</svg>" | |
| /* CALCULATION */ | |
| VAR _counter = | |
| COUNTROWS ( _initTbl ) + 2 | |
| VAR _doublePadding = _paddingSpace * 2 | |
| VAR _usableWidth = ( _widthCanvasSize - _doublePadding ) | |
| VAR _usableHeight = ( _heightCanvasSize - ( _doublePadding * 2 ) - 25 ) | |
| VAR _xCanvasPoints = _usableWidth / 100 | |
| VAR _yCanvasPoints = _usableHeight / 100 | |
| VAR _maxValue = | |
| MAXX ( _initTbl, [@vl] ) | |
| VAR _resultSizeOfColumns = | |
| ABS ( | |
| ROUND ( | |
| DIVIDE ( | |
| _usableWidth - ( ( _counter + 1 ) * _requestedSpaceBetweenColumns ), | |
| _counter | |
| ), | |
| 1 | |
| ) | |
| ) | |
| VAR _content = | |
| VAR _endVl = | |
| MINX ( INDEX ( 1, _initTbl, ORDERBY ( [@xAxisCategory], DESC ) ), [@vl] ) | |
| VAR _firstVl = _baseValue /* START */ | |
| VAR _startYPosition = _usableHeight + _doublePadding + 25 | |
| VAR _startXPosition = _requestedSpaceBetweenColumns + _paddingSpace | |
| VAR _startPrevYPosition = | |
| _heightCanvasSize | |
| - ( | |
| ROUND ( DIVIDE ( _firstVl, _maxValue ) * 100, 1 ) * _yCanvasPoints | |
| ) - _paddingSpace * 2 | |
| VAR _startXMoving = _startXPosition + _resultSizeOfColumns | |
| VAR _startLowerYPosition = | |
| IF ( | |
| _startYPosition > _startPrevYPosition, | |
| _startPrevYPosition, | |
| _startYPosition | |
| ) | |
| VAR _startXPositionMoved = _startXPosition + ( _resultSizeOfColumns / 2 ) /* END */ | |
| VAR _endYPosition = _usableHeight + _doublePadding + 25 | |
| VAR _endXPosition = ( ( _counter - 1 ) * _resultSizeOfColumns ) + ( _requestedSpaceBetweenColumns * _counter ) + _paddingSpace | |
| VAR _endPrevYPosition = | |
| _heightCanvasSize | |
| - ( | |
| ROUND ( DIVIDE ( _endVl, _maxValue ) * 100, 1 ) * _yCanvasPoints | |
| ) - _paddingSpace * 2 | |
| VAR _endXMoving = _endXPosition + _resultSizeOfColumns | |
| VAR _endLowerYPosition = | |
| IF ( _endYPosition > _endPrevYPosition, _endPrevYPosition, _endYPosition ) | |
| VAR _endXPositionMoved = _endXPosition + ( _resultSizeOfColumns / 2 ) | |
| VAR _endColor = | |
| IF ( _endVl > _firstVl, "#C9EDE4", "#FFDBE4" ) | |
| VAR _endBarColor = | |
| IF ( | |
| _endVl > _firstVl, | |
| "#1A473C" /*"#153930"*/ | |
| , | |
| "#461924" /*"#39151E"*/ | |
| ) | |
| RETURN | |
| " | |
| <g stroke='none'> | |
| <path class='initialCol' d='M " & _startXPosition & " " & _startYPosition & " V " & _startPrevYPosition & " H " & _startXMoving & " V " & _startYPosition & " Z'/>" & "<text class='specialTexts' font-weight='600' x='" & _startXPositionMoved & "' y='" & _heightCanvasSize - _paddingSpace - ( _paddingSpace / 3 ) & "'> BASE </text> | |
| <text class='textValuesBolder darkerFiller' x='" & _startXPositionMoved & "' y='" & _startLowerYPosition - 15 & "'> " & _firstVl & " </text> | |
| " // -------------------------------------------------------------------- | |
| & CONCATENATEX ( | |
| _initTbl, | |
| VAR _row = | |
| ROWNUMBER ( _initTbl, ORDERBY ( [@xAxisCategory], ASC ), DEFAULT ) + 1 | |
| VAR _vl = [@vl] | |
| VAR _prevVl = | |
| VAR _prev = | |
| OFFSET ( -1, _initTbl ) | |
| RETURN | |
| IF ( _row = 2, _baseValue, CALCULATE ( MINX ( _prev, [@vl] ) ) ) | |
| VAR _yPosition = | |
| _heightCanvasSize | |
| - ( | |
| ROUND ( DIVIDE ( _vl, _maxValue ) * 100, 1 ) * _yCanvasPoints | |
| ) - _paddingSpace * 2 | |
| VAR _prevYPosition = | |
| _heightCanvasSize | |
| - ( | |
| ROUND ( DIVIDE ( _prevVl, _maxValue ) * 100, 1 ) * _yCanvasPoints | |
| ) - _paddingSpace * 2 | |
| VAR _xPosition = ( ( _row - 1 ) * _resultSizeOfColumns ) + ( _requestedSpaceBetweenColumns * _row ) + _paddingSpace | |
| VAR _xMoving = _xPosition + _resultSizeOfColumns | |
| VAR _lowerYPosition = | |
| IF ( _yPosition > _prevYPosition, _prevYPosition, _yPosition ) | |
| RETURN | |
| "<path class='" | |
| & SWITCH ( | |
| TRUE (), | |
| _vl > _prevVl, "positiveCol", | |
| _vl < _prevVl, "negativeCol", | |
| "neutralCol" | |
| ) & "' d='M " & _xPosition & " " & _yPosition & " V " & _prevYPosition & " H " & _xMoving & " V " & _yPosition & " Z'/>" & "<text class='specialTexts' x='" & _xPosition + ( _resultSizeOfColumns / 2 ) & "' y='" & _heightCanvasSize - _paddingSpace - ( _paddingSpace / 3 ) & "'> " & [@xAxisCategory] & " </text>" & "<text class='textValuesBolder' x='" & _xPosition + ( _resultSizeOfColumns / 2 ) & "' y='" | |
| & _lowerYPosition | |
| - IF ( _row = 1, 15, 32.5 ) & "'> " & _vl & " </text>" & "<text class='textValuesBolder percentageChanges " | |
| & SWITCH ( | |
| TRUE (), | |
| _vl > _prevVl, "positiveCol", | |
| _vl < _prevVl, "negativeCol", | |
| "neutralCol" | |
| ) & "' x='" & _xPosition + ( _resultSizeOfColumns / 2 ) & "' y='" & _lowerYPosition - 15 & "'> " | |
| & FORMAT ( DIVIDE ( _vl, _prevVl ) - 1, "▲ 0%;▼ 0%;--%" ) & " </text>", | |
| "", | |
| [@xAxisCategory], ASC | |
| ) // -------------------------------------------------------------------- | |
| & "<rect x='" & _endXPosition - ( _requestedSpaceBetweenColumns * 0.25 ) & "' width='" & _resultSizeOfColumns + ( _requestedSpaceBetweenColumns * 0.5 ) & "' y='" & _paddingSpace & "' height='" & _usableHeight + 25 + _paddingSpace & "' fill='" & _endColor & "' />" & "<path fill='" & _endBarColor & "' d='M " & _endXPosition & " " & _endYPosition & " V " & _endPrevYPosition & " H " & _endXMoving & " V " & _endYPosition & " Z'/>" & "<text class='specialTexts' font-weight='600' x='" & _endXPositionMoved & "' y='" & _heightCanvasSize - _paddingSpace - ( _paddingSpace / 3 ) & "'> TOTAL </text> | |
| <text class='textValuesBolder darkerFiller' x='" & _endXPositionMoved & "' y='" & _endLowerYPosition - 32.5 & "'> " & _endVl & " </text> | |
| <text class='textValuesBolder percentageChanges " | |
| & SWITCH ( | |
| TRUE (), | |
| _endVl > _firstVl, "positiveCol", | |
| _endVl < _firstVl, "negativeCol", | |
| "neutralCol" | |
| ) & "' x='" & _endXPositionMoved & "' y='" & _endLowerYPosition - 15 & "'> " | |
| & FORMAT ( DIVIDE ( _endVl, _firstVl ) - 1, "▲ 0%;▼ 0%;--%" ) & " </text> | |
| </g>" /* supportLines */ | |
| VAR _lines = | |
| VAR _endVl = | |
| MINX ( INDEX ( 1, _initTbl, ORDERBY ( [@xAxisCategory], DESC ) ), [@vl] ) | |
| VAR _endXPosition = ( ( _counter - 1 ) * _resultSizeOfColumns ) + ( _requestedSpaceBetweenColumns * _counter ) + _paddingSpace | |
| VAR _endPrevYPosition = | |
| _heightCanvasSize | |
| - ( | |
| ROUND ( DIVIDE ( _endVl, _maxValue ) * 100, 1 ) * _yCanvasPoints | |
| ) - _paddingSpace * 2 | |
| VAR _endXPrevPosition = ( ( _counter - 2 ) * _resultSizeOfColumns ) + ( _requestedSpaceBetweenColumns * ( _counter - 1 ) ) + _paddingSpace | |
| RETURN | |
| "<g class='supportLines'>" & "<path d='M " & _paddingSpace & " " & _heightCanvasSize - ( _paddingSpace * 2 ) & " H " & _widthCanvasSize - _paddingSpace & "' />" & "<path d='" | |
| & CONCATENATEX ( | |
| _initTbl, | |
| VAR _row = | |
| ROWNUMBER ( _initTbl, ORDERBY ( [@xAxisCategory], ASC ), DEFAULT ) + 1 | |
| VAR _prevVl = | |
| VAR _prev = | |
| OFFSET ( -1, _initTbl ) | |
| RETURN | |
| IF ( _row = 2, _baseValue, CALCULATE ( MINX ( _prev, [@vl] ) ) ) | |
| VAR _prevYPosition = | |
| _heightCanvasSize | |
| - ( | |
| ROUND ( DIVIDE ( _prevVl, _maxValue ) * 100, 1 ) * _yCanvasPoints | |
| ) - _paddingSpace * 2 | |
| VAR _xPosition = ( ( _row - 1 ) * _resultSizeOfColumns ) + ( _requestedSpaceBetweenColumns * _row ) + _paddingSpace | |
| VAR _xPrevPosition = ( ( _row - 2 ) * _resultSizeOfColumns ) + ( _requestedSpaceBetweenColumns * ( _row - 1 ) ) + _paddingSpace | |
| RETURN | |
| " M " & _xPrevPosition & " " & _prevYPosition & " H " & _xPosition + _resultSizeOfColumns | |
| ) & "' />" & "<path d=' M" & _endXPrevPosition & " " & _endPrevYPosition & " H " & _endXPosition + _resultSizeOfColumns & "' />" & "</g>" | |
| VAR _result = _svgDeclaration & _svgHeader & _styles & _content & _lines & _svgEnd | |
| RETURN | |
| _result |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment