Last active
August 18, 2023 13:38
-
-
Save tirnovar/30a502c01235f0e6fd1a676e215393f9 to your computer and use it in GitHub Desktop.
Hills and Falls - DAX SVG Generator
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
| /* SETUP */ | |
| VAR _initTbl = | |
| ADDCOLUMNS( | |
| SELECTCOLUMNS( | |
| SUMMARIZE( <TABLE>, <X-AXIS-COLUMN> ), | |
| "@yAxisCategory", <X-AXIS-COLUMN> | |
| ), | |
| "@firstLine", <MEASURE-1>, | |
| "@secondLine", <MEASURE-2> | |
| ) | |
| VAR _squareCanvasSize = 400 | |
| VAR _paddingSpace = 15 | |
| //SERIES LABELS | |
| VAR _firstLineText = "Exports" | |
| VAR _secondLineText = "Imports" | |
| /* COLORS DECLARTIONS */ | |
| VAR _firstLineColor = "#12239E" | |
| VAR _secondLineColor = "#118DFF" | |
| VAR _green = "#7EC8B8" | |
| VAR _red = "#722838" | |
| VAR _grey = "#CCCCCC" | |
| /* SVG DECLARTIONS */ | |
| VAR _svgDeclaration = "data:image/svg+xml;utf8," | |
| VAR _svgHeader = | |
| "<svg xmlns='http://www.w3.org/2000/svg' height='" | |
| & _squareCanvasSize | |
| & "' width='" | |
| & _squareCanvasSize + 50 | |
| & "'>" | |
| VAR _svgEnd = "</svg>" | |
| /* CALCULATION */ | |
| VAR _tblPrecalculation = | |
| ADDCOLUMNS( | |
| _initTbl, | |
| "@positionChanged", | |
| VAR _rowNumber = | |
| ROWNUMBER( _initTbl, ORDERBY( [@yAxisCategory], ASC ) ) | |
| RETURN | |
| IF( | |
| IF( [@firstLine] >= [@secondLine], 1, 0 ) | |
| = MINX( | |
| OFFSET( -1, _initTbl ), | |
| IF( [@firstLine] >= [@secondLine], 1, 0 ) | |
| ) | |
| || _rowNumber = 1, | |
| BLANK( ), | |
| 1 | |
| ), | |
| "@clrSetter", IF( [@firstLine] >= [@secondLine], 1, 0 ), | |
| "@rowNum", | |
| ROWNUMBER( _initTbl, ORDERBY( [@yAxisCategory], ASC ) ) | |
| ) | |
| VAR _precountOfSegments = | |
| COUNTAX( _tblPrecalculation, [@positionChanged] ) + 1 | |
| VAR _generateSpaceForSegments = | |
| GENERATESERIES( 1, _precountOfSegments, 1 ) | |
| VAR _usableCanvasSpace = _squareCanvasSize - ( _paddingSpace * 2 ) | |
| VAR _usableCanvasPoints = _usableCanvasSpace / 100 | |
| VAR _rowsCounter = COUNTROWS( _tblPrecalculation ) | |
| VAR _paddingSpaceBetweenPoitns = | |
| _usableCanvasSpace / _rowsCounter | |
| VAR _highestValueOfMeasures = | |
| MAXX( | |
| _tblPrecalculation, | |
| MAX( [@firstLine], [@secondLine] ) | |
| ) | |
| * 1.05 | |
| VAR _lowestValueOfMeasures = | |
| MINX( | |
| _tblPrecalculation, | |
| MIN( [@firstLine], [@secondLine] ) | |
| ) | |
| * 0.95 | |
| VAR _differenceBetweenPositions = | |
| _highestValueOfMeasures - _lowestValueOfMeasures | |
| VAR _percentModificator = 100 / _highestValueOfMeasures | |
| VAR _tblCoordinatesPreCalculation = | |
| ADDCOLUMNS( | |
| _tblPrecalculation, | |
| "@xCoordinates", | |
| VAR _perc = | |
| ( [@firstLine] * _percentModificator ) * _usableCanvasPoints | |
| RETURN | |
| _paddingSpace + [@rowNum] * _paddingSpaceBetweenPoitns | |
| - _paddingSpaceBetweenPoitns * ( 1 / 2 ), | |
| "@yCoordinatesForFirstLine", | |
| ( 1 | |
| - DIVIDE( | |
| [@firstLine] - _lowestValueOfMeasures, | |
| _differenceBetweenPositions | |
| ) ) | |
| * _usableCanvasSpace, | |
| "@yCoordinatesForSecondLine", | |
| ( 1 | |
| - DIVIDE( | |
| [@secondLine] - _lowestValueOfMeasures, | |
| _differenceBetweenPositions | |
| ) ) | |
| * _usableCanvasSpace | |
| ) | |
| VAR _tblConnectionPoints = | |
| ADDCOLUMNS( | |
| _tblCoordinatesPreCalculation, | |
| "@LinesConnection", | |
| IF( | |
| NOT ISBLANK( [@positionChanged] ), | |
| VAR _offset = OFFSET( -1, _tblCoordinatesPreCalculation ) | |
| // X Shared Positions | |
| VAR _x1 = [@xCoordinates] | |
| VAR _xMoved = CALCULATE( MINX( _offset, [@xCoordinates] ) ) | |
| // FIRST LINE Y Position | |
| VAR _y1 = [@yCoordinatesForFirstLine] | |
| VAR _y2 = | |
| CALCULATE( MINX( _offset, [@yCoordinatesForFirstLine] ) ) | |
| // SECOND LINE Y Position | |
| VAR _y3 = [@yCoordinatesForSecondLine] | |
| VAR _y4 = | |
| CALCULATE( MINX( _offset, [@yCoordinatesForSecondLine] ) ) | |
| // NEW POSITIONS | |
| VAR _x = | |
| DIVIDE( | |
| ( ( _y2 - _y1 ) * ( _xMoved - _x1 ) * _x1 ) | |
| + ( ( _xMoved - _x1 ) * ( _xMoved - _x1 ) * ( _y3 - _y1 ) ) | |
| - ( ( _y4 - _y3 ) * ( _xMoved - _x1 ) * _x1 ), | |
| ( ( _y2 - _y1 ) * ( _xMoved - _x1 ) ) - ( ( _xMoved - _x1 ) * ( _y4 - _y3 ) ) | |
| ) | |
| VAR _y = | |
| DIVIDE( | |
| ( _x * ( _y2 - _y1 ) ) + ( _y1 * ( _xMoved - _x1 ) ) - ( _x1 * ( _y2 - _y1 ) ), | |
| _xMoved - _x1 | |
| ) | |
| RETURN | |
| _x & " " & _y, | |
| BLANK( ) | |
| ) | |
| ) | |
| VAR _line = | |
| "<g stroke-width='3' fill='none'>" & "<path stroke='" | |
| & _firstLineColor | |
| & "' d='" | |
| & CONCATENATEX( | |
| _tblCoordinatesPreCalculation, | |
| IF( [@rowNum] = 1, "M", " L " ) & [@xCoordinates] & " " | |
| & [@yCoordinatesForFirstLine] | |
| ) | |
| & "' />" | |
| & "<path stroke='" | |
| & _secondLineColor | |
| & "' d='" | |
| & CONCATENATEX( | |
| _tblCoordinatesPreCalculation, | |
| IF( [@rowNum] = 1, "M", " L " ) & [@xCoordinates] & " " | |
| & [@yCoordinatesForSecondLine] | |
| ) | |
| & "' />" | |
| & "</g>" | |
| VAR _segmentsFirstLine = | |
| CONCATENATEX( | |
| _tblConnectionPoints, | |
| " " | |
| & IF( | |
| ISBLANK( [@positionChanged] ), | |
| [@xCoordinates] & " " & [@yCoordinatesForFirstLine], | |
| [@LinesConnection] & " | " & [@LinesConnection] & " L " | |
| & [@xCoordinates] | |
| & " " | |
| & [@yCoordinatesForFirstLine] | |
| ), | |
| "", | |
| [@yAxisCategory], ASC | |
| ) | |
| VAR _segmentsSecondLine = | |
| CONCATENATEX( | |
| _tblConnectionPoints, | |
| " " | |
| & IF( | |
| ISBLANK( [@positionChanged] ), | |
| " " & [@xCoordinates] & " " & [@yCoordinatesForSecondLine], | |
| " " & [@xCoordinates] & " " & [@yCoordinatesForSecondLine] | |
| & " | " | |
| ), | |
| "", | |
| [@yAxisCategory], DESC | |
| ) | |
| VAR _segments = | |
| "<g stroke='none'>" | |
| & CONCATENATEX( | |
| _generateSpaceForSegments, | |
| VAR _rowValue = | |
| IF( | |
| [Value] = 1, | |
| SELECTCOLUMNS( | |
| TOPN( 1, _tblConnectionPoints, [@yAxisCategory], ASC ), | |
| "@forInternalPurpose", [@clrSetter] | |
| ), | |
| SELECTCOLUMNS( | |
| TOPN( | |
| 1, | |
| TOPN( | |
| [Value] - 1, | |
| FILTER( | |
| _tblConnectionPoints, | |
| NOT ISBLANK( [@positionChanged] ) | |
| ), | |
| [@yAxisCategory], ASC | |
| ), | |
| [@yAxisCategory], DESC | |
| ), | |
| "@forInternalPurpose", [@clrSetter] | |
| ) | |
| ) | |
| VAR _colorSelector = IF( _rowValue = 1, _green, _red ) | |
| RETURN | |
| "<path fill='" & _colorSelector & "' d='M" | |
| & PATHITEM( _segmentsFirstLine, [Value] ) | |
| & " " | |
| & PATHITEM( | |
| _segmentsSecondLine, | |
| _precountOfSegments - ( [Value] - 1 ) | |
| ) | |
| & "Z" | |
| & "' />", | |
| "", | |
| [Value], ASC | |
| ) | |
| & "</g>" | |
| VAR _supportLines = | |
| "<g stroke='" & _grey & "' stroke-dasharray='5 5'>" | |
| & CONCATENATEX( | |
| _tblConnectionPoints, | |
| "<line x1='" & [@xCoordinates] & "' x2='" & [@xCoordinates] | |
| & "' y1='" | |
| & _paddingSpace + 5 | |
| & "' y2='" | |
| & _squareCanvasSize - _paddingSpace - 5 | |
| & "'/>" | |
| ) | |
| & "</g>" | |
| VAR _texts = | |
| VAR _lastIndexedYAxisPoint = | |
| INDEX( | |
| 1, | |
| _tblConnectionPoints, | |
| ORDERBY( [@yAxisCategory], DESC ) | |
| ) | |
| VAR _yPositionsFirstLine = | |
| MAXX( _lastIndexedYAxisPoint, [@yCoordinatesForFirstLine] ) | |
| VAR _yPositionsSecondLine = | |
| MAXX( _lastIndexedYAxisPoint, [@yCoordinatesForSecondLine] ) | |
| VAR _xPosition = | |
| MAXX( _lastIndexedYAxisPoint, [@xCoordinates] ) | |
| RETURN | |
| "<g font-size='80%' font-family='Segoe UI' dominant-baseline='middle'> | |
| <g text-anchor='start' font-weight='bold'>" | |
| & "<text fill='" | |
| & _firstLineColor | |
| & "' x='" | |
| & _xPosition + _paddingSpace - 5 | |
| & "' y='" | |
| & _yPositionsFirstLine | |
| & "'>" | |
| & _firstLineText | |
| & "</text>" | |
| & "<text fill='" | |
| & _secondLineColor | |
| & "' x='" | |
| & _xPosition + _paddingSpace - 5 | |
| & "' y='" | |
| & _yPositionsSecondLine | |
| & "'>" | |
| & _secondLineText | |
| & "</text>" | |
| & "</g> | |
| <g text-anchor='middle' fill='" | |
| & _grey | |
| & "'>" | |
| & CONCATENATEX( | |
| _tblConnectionPoints, | |
| "<text x='" & [@xCoordinates] & "' y='" | |
| & _squareCanvasSize - _paddingSpace + 5 | |
| & "'>" | |
| & [@yAxisCategory] | |
| & "</text>" | |
| ) | |
| & "</g> | |
| </g>" | |
| VAR _result = | |
| _svgDeclaration & _svgHeader & _supportLines & _texts | |
| & _segments | |
| & _line | |
| & _svgEnd | |
| RETURN | |
| _result |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment