Module:Chart absolute to relative

Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules


This module provides utility functions for transforming tabular data sets in chart renderings.

See mw:Extension:Chart/Transforms for more documentation on this transform feature of the Charts system.

See similar module: Module:ChartPercentage

UsageUsage

convert_to_percentage: convert the data to percentages, relative to a base value column

To use as a chart transform:

"transform": {
        "module": "Chart absolute to relative",
        "function": "convert_to_percentage",
        "args": {
            "sum_column": "2",
            "units": "percent",
            "decimals": "2"
        }
    },

Arguments:

ExampleExample

Code

local p = {}

local function toNumber(x)
	if x == nil then return nil end
	if type(x) == "number" then return x end
	if type(x) ~= "string" then return nil end
	local s = x:gsub("%s+", ""):gsub(",", "")
	return tonumber(s)
end

local function roundTo(n, decimals)
	if n == nil then return nil end
	decimals = tonumber(decimals)
	if not decimals or decimals < 0 then return n end
	local m = 10 ^ decimals
	return math.floor(n * m + 0.5) / m
end

local function unitsIsPercent(u)
	return u == "percent" or u == "%" or u == "percentage"
end

function p.convert_to_percentage(tab, args)
	args = args or {}
	if type(tab) ~= "table" or not unitsIsPercent(args.units) then
		return tab
	end

	local N = tonumber(args.sum_column) or tonumber(args.sumcol) or tonumber(args.sum) or 2
	local decimals = args.decimals

	-- Tabular Data rows
	local rows = tab.data
	if type(rows) ~= "table" then
		rows = tab -- fallback for raw matrix
	end

	-- Determine column count robustly (prefer schema)
	local colCount
	if type(tab.schema) == "table" and type(tab.schema.fields) == "table" then
		colCount = #tab.schema.fields
	else
		-- fallback: use first row length (best-effort)
		colCount = (type(rows[1]) == "table") and #rows[1] or 0
	end

	local outData = {}

	for r = 1, #rows do
		local row = rows[r]
		if type(row) == "table" then
			local newRow = {}
			newRow[1] = row[1] -- year

			local sum = toNumber(row[N])

			local newCol = 2
			for c = 2, colCount do
				if c ~= N then
					local v = toNumber(row[c])
					if v ~= nil and sum ~= nil and sum ~= 0 then
						newRow[newCol] = roundTo((v / sum) * 100, decimals)
					else
						newRow[newCol] = nil
					end
					newCol = newCol + 1
				end
			end

			outData[#outData + 1] = newRow
		else
			outData[#outData + 1] = row
		end
	end

	-- Copy original object and replace data
	local result = {}
	for k, v in pairs(tab) do
		result[k] = v
	end
	result.data = outData

	-- Adjust schema.fields (remove column N)
	if type(tab.schema) == "table" and type(tab.schema.fields) == "table" then
		local oldFields = tab.schema.fields
		local newFields = {}

		for i = 1, #oldFields do
			if i ~= N then
				newFields[#newFields + 1] = oldFields[i]
			end
		end

		local newSchema = {}
		for k, v in pairs(tab.schema) do
			newSchema[k] = v
		end
		newSchema.fields = newFields

		result.schema = newSchema
	end

	return result
end

return p
Category:Chart transform modules Category:Charts extension documentation Category:Modules in pre-alpha development