Module:SVG Chart/svg-legend

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-legend/doc

Code

----  ----
local function LegendHead (sLegendType, dChartWidthStretch, dChartHeightStretch, bLegendX, dLegendX, dLegendY, dChartSize, dYAxis2Width, sYAxis2Text, dYAxisFontSize)
    local sReturn = ''
    local d1, d2
    local dx, dy = 9999, 9999
    
    if sLegendType ~= 'none' then
        sReturn = sReturn ..
            '<g id="legend" class="legendtext" transform="translate('       -- x, y, position of the legend
            
        if sLegendType == 'line' then                   -- line legend
            if bLegendX then
                d1 = dLegendX / 100
            else
--                d1 = 0.1
                d1 = dYAxis2Width
            end
            
            if dLegendY then
                d2 = dLegendY / -100
            else
                d2 = 0.25
            end
            
            dx = round (dChartWidthStretch  * d1, 1)
            dy = round (dChartHeightStretch * d2, 1)
        else                                              -- box legend
            if bLegendX then
                d1 = dChartWidthStretch * dLegendX / 100
            else
                d1 = dChartWidthStretch
                 	+ LegendBoxDX (dChartSize)
                    + dYAxis2Width
            end
       
            dx = round (d1, 1)
            dy = round (-1 * dChartHeightStretch * dLegendY / 100, 1)     -- y, LegendY is distance top of legend to bottom of chart - ToDo: may be an other default value
        end
            
        sReturn = sReturn .. dx .. ', ' .. dy .. ')">'            
    end
    
    gsDebug = gsDebug .. 'svg-legend.LegendHead (, sLegendType, dChartWidthStretch, dChartHeightStretch, dLegendX, dLegendY, dChartSize, sYAxis2Text, dYAxisFontSize) = \n' ..
        '     LegendHead (, ' .. sLegendType .. ', ' .. dChartWidthStretch .. ', ' .. dChartHeightStretch .. ', ' .. tostring (dLegendX) .. ', ' .. tostring(dLegendY) .. ', ' .. dChartSize .. ', ' .. tostring (sYAxis2Text) .. ', ' .. dYAxisFontSize .. ') \n' ..
        '     LegendBoxDX (dChartSize) = LegendBoxDX (' .. dChartSize .. ') = ' .. LegendBoxDX (dChartSize) ..', YAxis2Width (dChartSize, sYAxis2Text, dYAxisFontSize) = YAxis2Width (' .. dChartSize .. ', ' .. tostring (sYAxis2Text) .. ', ' .. dYAxisFontSize .. ') = ' .. YAxis2Width (dChartSize, sYAxis2Text, dYAxisFontSize) .. '\n' ..
        '     dx: ' .. dx .. ', dy: ' .. dy .. '\n' ..
        'svg-legend.LegendHead(): dYAxis2Width: ' .. dYAxis2Width .. '\n'
    return sReturn
end


---- LegendeElement (), line and text entry for legend ----
--[[
 1:  number of graph
 2:  ChartSize, Px
 3:  Legend FontSize, Px, alternate: 6
 4:  text, required, check whether legend entry is shown
 5:  if marker, normally the ID of the marker
 6:  form: "box" (default) or "line"
 7:  LegendWidth, % of standard value, currently required for line legend
  ]]
  
local function LegendElement (iNumber, dChartSizePx, dFontSizePx, sText, iMarkerID, sLegendType, dLegendWidth)
    local sReturn, sReturnMarker = '', ''

	if sText ~= nil then
        sReturn = ' \n'
         
        -- line type legend; graph 1 may have a own special class: therefore "graph1" or "graph" --
        if sLegendType == 'line' then
            if iMarkerID ~= nil then                                                                 -- for marker
                sReturnMarker = 
                    '      <path id="legend-marker' .. iNumber .. '" transform="scale(1 -1)" stroke-width="0.00001" d="M ' ..
                    round (dChartSizePx * ((iNumber-1) * 0.23 * dLegendWidth/100 + 0.045), 2) .. ' ' ..    -- x2, y2
                    round (-1.05 * dFontSizePx, 2) .. ' h 0" marker-start="url(#graph' .. iNumbermarker .. ')" marker-end="none"/>\n'
            end
            
            sReturn = sReturn ..
                '  <g class="graphgeneral"><g class="graph' .. iNumber .. 'line">\n' ..
                '    <polyline id="legend-line' .. iNumber .. '" points="' ..
                round (dChartSizePx * ((iNumber-1) * 0.23 * dLegendWidth/100 + 0.020), 2) .. ' ' ..  -- x1
                round (1.05 * dFontSizePx, 2) .. ' ' ..                                              -- y1; 1.4: text line height
                round (dChartSizePx * ((iNumber-1) * 0.23 * dLegendWidth/100 + 0.070), 2) .. ' ' ..  -- x3
                round (1.05 * dFontSizePx, 2) ..                                                     -- y3
                '" marker-start="none" marker-end="none"/>\n' ..
                sReturnMarker ..                 
                '  </g></g>\n' ..
                '  <text id="legend-text' .. iNumber .. '" x="' ..
                round (dChartSizePx * ((iNumber-1) * 0.23 * dLegendWidth/100 + 0.090), 1) .. '" y="' ..
                round (dFontSizePx * 1.2, 2) .. '">' ..
                svgText (dFontSizePx, sText) .. '</text>'
             
        -- box type legend; graph 1 may have a own special class: therefore "graph1" or "graph" --
        else
            if iMarkerID ~= nil then                                                                 -- for marker
                sReturnMarker = 
                    '      <path id="legend-marker' .. iNumber .. '" transform="scale(1 -1)" stroke-width="0.00001" d="M ' ..
                    round (dChartSizePx * 0.045, 2) .. ' ' ..                                        -- x2
                    round (dFontSizePx * -1.1 * (iNumber - 0.3), 2) ..                               -- y2
                    ' h 0" marker-start="url(#graph' .. iNumber .. 'marker)" marker-end="none"/>\n'
            end
            
            sReturn = sReturn ..
                '  <g class="graphgeneral"><g class="graph' .. iNumber .. 'line">\n' ..
                '    <polyline id="legend-line' .. iNumber .. '" points="' ..                            -- 1.xx: text line height
                round (dChartSizePx * 0.020, 2) .. ' ' ..                                            -- x1
                round (dFontSizePx * 1.1 * (iNumber - 0.3), 2) .. ' ' ..                             -- y1
                round (dChartSizePx * 0.070, 2) .. ' ' ..                                            -- x3
                round (dFontSizePx * 1.1 * (iNumber - 0.3), 2) ..                                    -- y3
                '" marker-start="none" marker-end="none"/>\n' ..
                sReturnMarker ..                 
                '  </g></g>\n' ..
                '  <text id="legend-text' .. iNumber .. '" x="' ..
                round (dChartSizePx * 0.090, 1) .. '" y="' ..
                round (dFontSizePx * 1.1 * (iNumber - 0.03), 2) .. '">' ..                         -- >1.x: more on top
                svgText (dFontSizePx, sText) .. '</text>\n'
        end
    end
     
    return sReturn       
end

---- global functions ----

--[[ dx position of a box type legend in addition to x axis length:
1: GeneralSize, Px
  ]]
function LegendBoxDX (dGeneralSize)
  	return 0.05 * dGeneralSize
end

---- LegendBoxWidth (), width of a box type legend ----
--[[
1: dChartSize, Px
2: dFontSize, %, should be: {{{LegendFontSize|{{{FontSize|100}}}}}}
3: dLegendWidth, % of standard value
]]
function LegendBoxWidth (dChartSizePx, dFontSize100, dLegendWidth100)
	return 
	    round (dChartSizePx * dLegendWidth100 / 10000 * (
	    	10 +                     -- length of line sample
		    30 * dFontSize100 / 100     -- standard length of text
		    ), 1)
end

---- Legend (), legend of the graphs ----
--[[
1:  form: "box" (default) or "line"
2:  ChartSize, Px
3:  Fontsize, Px
4:  Fontsize, %
5:  LegendWidth, % of standard value
6:  alternate border color
7:  text of graph 1
    ...
12: text of graph 6
13: if marker of graph 1
    ...
18: if marker of graph 6
/xx values are the distance from the left side of the box
-xx values are the distance from top of the box
  ]]

function svgLegend (sLegendType, dChartSizePx, dLegendFontSizePx, dLegendFontSize100, dLegendBoxWidth, dLegendWidth100, sBorderColor, tsText, tMarker, sLegendSVG, dChartWidthStretch, dChartHeightStretch, bLegendX, dLegendX, dLegendY, dChartSize, dYAxis2Width, sYAxis2Text, dYAxisFontSize)
    local i, iElements, dx, dy
    local sReturn, sElements, sDebug = '', '', ''
	
    if sLegendType ~= 'none' or sLegendSVG then
        sReturn = sReturn .. '\n' ..
            '&lt;!-- legend -->\n'
	
        if sLegendSVG then      -- replacement of standard legend by own svg instructions
            sReturn = sReturn ..
                sLegendSVG
        else                    -- sLegendType ~= none
            sReturn = sReturn .. ' \n' ..
                LegendHead (sLegendType, dChartWidthStretch, dChartHeightStretch, bLegendX, dLegendX, dLegendY, dChartSize, dYAxis2Width, sYAxis2Text, dYAxisFontSize)
		
            sReturn = sReturn .. ' \n' ..
                '  <g id="legend-background" class="axismark-main">\n' ..
                '    <rect x="0" y="0" fill="white"'
            if sBorderColor ~= nil then
                sReturn = sReturn .. ' stroke="' .. sBorderColor .. '"'
            end

            -- all graph lines and descriptions --
            iElements = 0
            for i = 1, MAXCHARTNUMBER do
                sElements = sElements ..
                    LegendElement (i, dChartSizePx, dLegendFontSizePx, tsText [i], tMarker [i], sType, dLegendWidth100)
                if tsText [i] ~= nil then iElements = iElements + 1 end
            end

            if sLegendType == 'line' then             -- line type legend
                    dx = round (dChartSizePx * (0.23 * iElements) * dLegendWidth100/100 + 0.05, 1)   -- width of the border; first factor the same in LegendElement function 
                    dy = round (dLegendFontSizePx * 2.1, 1)   -- height of the border
            else                                      -- box type legend
                    dx = dLegendBoxWidth              -- width of the border; /x: copy x to viewBox width
                    dy = round (dLegendFontSizePx * (1.1 * iElements + 0.5), 1)              -- height of the border, 1.x same factor as in LegendElement
            end
            sDebug  = 'iElements: ' .. iElements
            sReturn = sReturn .. ' width="' .. dx .. '" height="' .. dy .. '"/>\n' ..
                '  </g>\n' ..
                sElements ..
                '</g>\n'
        end
    end

    gsDebug = gsDebug .. 'svg-legend.Legend(): sLegendType: ' .. tostring(sLegendType) .. ', sLegendSVG: ' .. tostring(sLegendSVG) .. ', ' .. sDebug .. '\n'
    return sReturn
end