Module:SVG Chart/svg-axis

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Lua
CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules

Documentation for this module may be created at Module:SVG Chart/svg-axis/doc

Code

----  ----
local function svgAxisDefGrid (sID, dGridStep, dGridStartStretch, dGridStretch, dLengthRaw2, dX1, dX2, dY1, dY2, sDirection1, sDirection2, sComment)
    local sReturn

    if dGridStep and dGridStep ~= 'none' then
        sReturn = '\n' ..
            '  <!-- ' .. sComment .. ' -->\n' ..
            '  <pattern id="' .. sID .. '" ' .. sDirection2 .. '="' .. dLengthRaw2 * 2 ..
            '" ' .. sDirection1 .. '="' .. dGridStep * dGridStretch / 100 ..
            '" patternUnits="userSpaceOnUse">\n' ..
            '    <line x1="' .. dX1 .. '" x2="' .. dX2 .. '" y1="' .. dY1 .. '" y2="' .. dY2 .. '" class="gridline"/>\n' ..
            '  </pattern>\n'
    else
        sReturn = ''
    end
    
    return sReturn
end

---- svgAxisDefMark () ----
local function svgAxisDefMark (sID, sShow, dWidth, dHeight, dX0, dY0, dX1, dX2, dY1, dY2, sClass, sComment)
    local sXY0 = ''
    local sReturn
    
    if sShow then
        if dX0 then sXY0 = ' x="' .. dX0 .. '"' end
        if dY0 then sXY0 = ' y="' .. dY0 .. '"' end
     
        sReturn = '\n' ..
            '  &lt;!-- ' .. sComment .. ' -->\n' ..
            '  <pattern id="' .. sID .. '"' .. sXY0 ..
            ' width="'  .. dWidth .. '" height="' .. dHeight ..
            '" patternUnits="userSpaceOnUse">\n' ..
            '    <line x1="' .. dX1 .. '" y1="' .. dY1 .. '" x2="' .. dX2 .. '" y2="' .. dY2 .. '" class="' .. sClass .. '"/>\n' ..
            '  </pattern>\n'
    else
    	sReturn = ''
    end
    
    gsDebug = gsDebug .. 'svg-axis.svgAxisDefMark(): dX0: ' .. tostring(dX0) .. ', dY0: ' .. tostring(dY0) .. ', sXY0: ' .. sXY0 .. '\n'
    return sReturn
end

----  ----
local function svgAxisRect (sID, dX, dY, dWidth, dHeight, sFillURL)
    return 
        '  <rect id="' .. sID .. 
        '" x="' .. dX .. '" y="' .. dY .. '" width="' .. dWidth .. '" height="' .. dHeight .. '" fill="url(' .. sFillURL .. ')"/>\n'
end

----  ----
local function svgAxisLine (sID, dX1, dY1, dX2, dY2, sClass)
    return 
        '  <line id="' .. sID .. 
        '" x1="' .. dX1 .. '" y1="' .. dY1 .. '" x2="' .. dX2 .. '" y2="' .. dY2 .. '" class="' .. sClass .. '"/>\n'
end

---- global functions ----

---- only for test and debug, todo: may be removed sometime ----
function AxisMarkLengthT (dChartElementSize, dAxisMarkLengthFix)
	return AxisMarkLength (dChartElementSize, dAxisMarkLengthFix)
end

---- real in use, not to be removed: ----

-- Length of a axis mark: 
--[[
1: DiagramSize
2: default length
  ]]
function AxisMarkLength (dChartElementSize, dAxisMarkLengthFix)
    local dReturn
	
    if dAxisMarkLengthFix then
        dReturn = dAxisMarkLengthFix
    else
        dReturn = round (dChartElementSize * AXISMARKLENGTHREL / 100, 1)
    end

    return dReturn
end

--[[ space for the 2nd y-axis
factors should be aquivalent to /Left
1: ChartSize, px
2: YAxis2Text, text
3: alternate FontSize, %
  ]]
function YAxis2Width (dChartSize, sYAxis2Text, dFontSize)
    if sYAxis2Text then                 -- if YAxis2Text, then additional length
        return round (dChartSize * (
            0.04                        -- fixed width for axis mark
            + 0.15 * dFontSize / 100    -- width for numbers and text
            ), 1)
    else
    	return 0
    end
end

   
function AxisGridStyles (tsGraphMarker, dChartElementSize, dXGrid, dYGrid)
    local sReturn 
    
    sReturn =
        '  .axisline {\n' ..
        '    stroke:          black;\n' ..
        '    stroke-width:    ' .. LineWidth (dChartElementSize, 50) .. ';\n' ..
        '    stroke-linecap:  round;\n' ..
        '  }\n' ..
        '  .axismark-main {\n' ..
        '    stroke:          black;\n' ..
        '    stroke-width:    ' .. LineWidth (dChartElementSize, 35) .. ';\n' ..
        '  }\n' ..
        '  .axismark-second {\n' ..
        '   stroke:           black;\n' ..
        '    stroke-width:    ' .. LineWidth (dChartElementSize, 35) .. ';\n' ..
        '  }\n'
        
    -- marker of graphs --
    if tsGraphMarker[1] or tsGraphMarker[2] then sReturn = sReturn ..
        '  .graphmarker {\n' ..
        '    stroke-width:    ' .. LineWidth (dChartElementSize, 50) .. ';\n' ..
        '    fill:            white;\n' ..
        '    stroke-linejoin: round;\n' ..
        '  }\n'
    end
    
    -- grid not on empty call or if not wished; default: WW-chart --
    if dXGrid ~= 'none' and dYGrid ~= 'none' then sReturn = sReturn ..
        '  .gridline {\n' ..
        '    stroke:          black;\n' ..
        '    stroke-width:    ' .. LineWidth (dChartElementSize, 25) .. ';\n' ..
        '  }\n'
    end

    return sReturn
end

---- svgAxisDefs () ----
function svgAxisDefs (dChartElementSize, dGraphStretchWidth, dGraphStretchHeight, dChartWidthRaw, dChartHeightRaw, dXMin, dYMin, dXGridStartT, dYGridStartT, dXGridStep, dYGridStep, dAxisMarkLength, dXAxisMarkStartT, dXAxisMarkStep, dXAxisMark2StartT, dXAxisMark2Step, dYAxisMarkStartT, dYAxisMarkStep, dYAxisMark2StartT, dYAxisMark2Step, dYAxis2MarkStartT, dYAxis2MarkStep)
	local dHeight, sReturn
    local dXGridStartStretch      = (dXGridStartT - dXMin)      * dGraphStretchWidth  / 100
    local dXAxisMarkStartStretch  = (dXAxisMarkStartT - dXMin)  * dGraphStretchWidth  / 100
    local dXAxisMarkStepStretch   = dXAxisMarkStep              * dGraphStretchWidth  / 100
    local dXAxisMark2StepStretch  = (dXAxisMark2Step or 5)      * dGraphStretchWidth  / 100  -- only avoid program error because values may be nil
    
    local dYGridStartStretch      = (dYGridStartT - dYMin)      * dGraphStretchHeight / 100
    local dYAxisMarkStartStretch  = (dYAxisMarkStartT - dYMin)  * dGraphStretchHeight / 100
    local dYAxisMarkStepStretch   = dYAxisMarkStep              * dGraphStretchHeight / 100
    local dYAxisMark2StepStretch  = (dYAxisMark2Step or 5)      * dGraphStretchHeight / 100
    
--    local dAxisMarkLength         = AxisMarkLength (dChartElementSize, dAxisMarkLengthFix)
    dAxisMarkLength = dAxisMarkLength * 1.2    -- a little bit bigger
   
    sReturn =
        '  &lt;!--== axis dashes definitions ==-->\n' ..
        svgAxisDefGrid ('x-gridline', dXGridStep, dXGridStartStretch, dGraphStretchWidth,  dChartHeightRaw, dXGridStartStretch, dXGridStartStretch, 0, dChartHeightRaw * 2, 'width',  'height', 'x-axis gridline vertical, modify "width"') ..
        svgAxisDefGrid ('y-gridline', dYGridStep, dYGridStartStretch, dGraphStretchHeight, dChartWidthRaw,  0, dChartWidthRaw * 2, dYGridStartStretch, dYGridStartStretch,  'height', 'width',  'y-axis gridline horizontal, modify "height"') ..
        
        svgAxisDefMark     ('x-axismark-main',   true,            dXAxisMarkStepStretch,  dAxisMarkLength,    dXAxisMarkStartStretch,  nil,                                  0, 0, -1, dAxisMarkLength, 'axismark-main',   'x-axis mark, modify "height"')
        if dXAxisMark2StartT ~= nil then sReturn = sReturn ..
            svgAxisDefMark ('x-axismark-second', dXAxisMark2Step, dXAxisMark2StepStretch, dAxisMarkLength,    (dXAxisMark2StartT - dXMin) * dGraphStretchWidth / 100, nil,   0, 0, -1, dAxisMarkLength, 'axismark-second', 'x-axis 2nd mark, modify "width" and "x1"')
        end

        -- svgAxisDefMark (sID, sShow, dWidth, dHeight, dX0, dY0, dX1, dX2, dY1, dY2, sClass, sComment)
        sReturn = sReturn ..
            svgAxisDefMark ('y-axismark-main',   true,            dAxisMarkLength, dYAxisMarkStepStretch,  nil, dYAxisMarkStartStretch,                                                     -1, dAxisMarkLength, 0, 0,  'axismark-main',   'y-axis mark, modify "width"')
        if dYAxisMark2StartT ~= nil then sReturn = sReturn ..
            svgAxisDefMark ('y-axismark-second', dYAxisMark2Step, dAxisMarkLength, dYAxisMark2StepStretch, nil, (dYAxisMark2StartT - dYMin) * dGraphStretchHeight / 100, -1, dAxisMarkLength, 0, 0,  'axismark-second', 'y-axis 2nd mark, modify "height" and "y1"') -- todo: not congruent to ymark o ymark2
        end
            
        if dYAxis2MarkStartT ~= nil then 
        	dHeight = (dYAxis2MarkStep or 5) * dGraphStretchHeight / 100
        	sReturn = sReturn ..
            svgAxisDefMark ('y-axis2mark-main',  dYAxis2MarkStep, dAxisMarkLength,    dHeight,                nil, (dYAxis2MarkStartT - dYMin) * dGraphStretchHeight / 100, -1, dAxisMarkLength, 0, 0,  'axismark-main',   'y-axis2 mark, modify "width"')   -- todo = yaxis1 ?; y2 = dAxisMarkLength * 4 ?; dAxisMarkLength * 2?
        end
    
    gsDebug = gsDebug .. 'svg-axis.svgAxisDefs(): dXGridStartT: ' .. dXGridStartT .. ', dYGridStartT: ' .. dYGridStartT .. ', dXGridStartStretch: ' .. dXGridStartStretch .. ', dYGridStartStretch: ' .. dYGridStartStretch .. '\n'
    return sReturn
end

---- svgAxisGrid (), generate axis with marks, grid and background ----
function svgBackground2 (sBackground, bDefaultWWChart, dChartWidthStretch, dChartHeightStretch, dXMin, dYMin, dXGrid, dYGrid, dAxisMarkLength, dXAxisMarkStart, dXAxisMark2Start, dXAxisMark2Step, dYAxisMark2Step, sYAxis2Text, dYAxis2MarkStep)
    local sReturn
    
    -- background --
    if sBackground then     -- todo: does it works, allready implemented on other place?
        sReturn =
            '&lt;!-- axes and grids -->\n' ..
            '<g transform="scale(1, -1)">'

        sReturn = sReturn .. '\n' ..
            '  &lt;!-- background, modify "width" and "height" --&gt;' ..
            svgAxisRect ('background', 0, 0, round (dChartWidthStretch * 1.003, 1), round (dChartHeightStretch * 1.003, 1), '#background-fill') ..
        '</g>\n'
    else
    	sReturn = ''
    end
        
    return sReturn
end

---- svgGrid (), generate axis with marks, grid and background ----
function svgGrid (bDefaultWWChart, dChartWidthStretch, dChartHeightStretch, dXGrid, dYGrid)
    local sReturn
    local sReturnGrid = ''
    
    if bDefaultWWChart or dXGrid ~= 'none' then
        sReturnGrid = sReturnGrid ..
            svgAxisRect ('x-gridline-area', 0.3, 0, round (dChartWidthStretch * 1.01, 1), round (dChartHeightStretch, 1), '#x-gridline')
    end

    if bDefaultWWChart or dYGrid ~= 'none' then
        sReturnGrid = sReturnGrid ..
            svgAxisRect ('y-gridline-area', 0, 0.3, round (dChartWidthStretch, 1), round (dChartHeightStretch * 1.01, 1), '#y-gridline')
    end

    if sReturnGrid ~= '' then
        sReturn = '\n' ..
        '<g transform="scale(1, -1)">' .. '\n' ..
            '  &lt;!-- grids --&gt;\n' ..
            sReturnGrid ..
        '</g>\n'
    else 
    	sReturn = ''
    end
    
    return sReturn 
end

---- svgAxis (), generate axis with marks, grid and background ----
function svgAxis (bDefaultWWChart, dChartWidthStretch, dChartHeightStretch, dXMin, dYMin, dAxisMarkLength, dXAxisMarkStart, dXAxisMark2Start, dXAxisMark2Step, dYAxisMark2Step, sYAxis2Text, dYAxis2MarkStep)
--    local sReturn, dAxisMarkLength
    local sReturn
    
    dAxisMarkLength = round (dAxisMarkLength, 1)
    
    sReturn = '\n' ..
        '&lt;!-- axes with marks -->\n' ..
        '<g transform="scale(1, -1)">'

    -- x-axis --
    sReturn = sReturn .. '\n' ..
        '  &lt;!-- x axis, modify "x2" and "width" -->\n'
            
    if dXAxisMark2Step then sReturn = sReturn ..
        svgAxisRect ('x-axismark2', dXAxisMark2Start - dXMin - dAxisMarkLength, -1 * dAxisMarkLength * AXISMARKLENGTH2REL, round (dChartWidthStretch        - dXAxisMark2Start + dXMin, 1), dAxisMarkLength * AXISMARKLENGTH2REL, '#x-axismark-second') 
    end
    sReturn = sReturn ..
--        svgAxisRect ('x-axismark',  dXAxisMarkStart  - dXMin - dAxisMarkLength, round (dAxisMarkLength * -3.5, 1), round (dChartWidthStretch * 1.02 - dXAxisMarkStart  + dXMin, 1), dAxisMarkLength * 3.5, '#x-axismark-main') ..
        svgAxisRect ('x-axismark',  dXAxisMarkStart  - dXMin - dAxisMarkLength, -1 * dAxisMarkLength, round (dChartWidthStretch * 1.02 - dXAxisMarkStart  + dXMin, 1), dAxisMarkLength, '#x-axismark-main') ..
        svgAxisLine ('x-axis', 0, 0, round (dChartWidthStretch, 0), 0, 'axisline')
 
    -- y-axis --
    sReturn = sReturn .. '\n' ..
        '  &lt;!-- y axis, modify "height" -->\n'
            
    if dYAxisMark2Step then sReturn = sReturn .. 
        svgAxisRect ('y-axismark2', -1 * dAxisMarkLength * AXISMARKLENGTH2REL, -1 * dAxisMarkLength, dAxisMarkLength * AXISMARKLENGTH2REL, round (dChartHeightStretch + 1, 1), '#y-axismark-second') 
    end
    sReturn = sReturn ..
        svgAxisRect ('y-axismark',  -1 * dAxisMarkLength, -1 * dAxisMarkLength, dAxisMarkLength, round (dChartHeightStretch + 2, 1), '#y-axismark-main') ..  -- dChartHeightStretch + x: x additional height
        svgAxisLine ('y-axis', 0, 0, 0, round (dChartHeightStretch, 1), 'axisline')

    -- 2nd y-axis on right side --
    if sYAxis2Text then
        sReturn = sReturn .. '\n' ..
            '  &lt;!-- 2nd y-axis on right side -->\n' ..
            svgAxisRect ('y-axis2mark', dChartWidthStretch, -1 * dAxisMarkLength, dAxisMarkLength, round (dChartHeightStretch + 2, 1), '#y-axis2mark-main') ..
            svgAxisLine ('y-axis2', round (dChartWidthStretch,  0), 0, round (dChartWidthStretch,  0), round (dChartHeightStretch, 1), 'axisline')
    end
        
    return sReturn ..
        '</g>\n'
end