Skip to content

Instantly share code, notes, and snippets.

@tirnovar
Created August 12, 2023 06:25
Show Gist options
  • Select an option

  • Save tirnovar/96ce65ca6aa308cd4ac2db3f4bea2655 to your computer and use it in GitHub Desktop.

Select an option

Save tirnovar/96ce65ca6aa308cd4ac2db3f4bea2655 to your computer and use it in GitHub Desktop.
Water Fall Chart generated by DAX into SVG
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