Module:Sandbox/User:Keplare/Fetch RTP: Difference between revisions

From Illerai
Jump to navigation Jump to search
illerai>Keplare
No edit summary
 
m 1 revision imported
 
(No difference)

Latest revision as of 21:59, 4 November 2024

Documentation for this module may be created at Module:Sandbox/User:Keplare/Fetch RTP/doc

local p = {}

local geprice = require('Module:Exchange')._price
local coins = require('Module:Coins')._amount
local chart = require('Module:Chart data')
local rgba = require('Module:Rgba')

local rune_order = {
    "Soul", "Blood", "Death", "Law", "Nature", "Astral", "Chaos", "Cosmic", 
    "Body", "Fire", "Earth", "Water", "Mind", "Air"
}

local rune_colors = {
    Air = rgba.new(248, 245, 245),
    Mind = rgba.new(215, 109, 0),
    Water = rgba.new(43, 132, 234),
    Earth = rgba.new(109, 73, 13),
    Fire = rgba.new(255, 50, 30),
    Body = rgba.new(23, 26, 130),
    Cosmic = rgba.new(224, 222, 26),
    Chaos = rgba.new(224, 168, 26),
    Astral = rgba.new(207, 182, 207),
    Nature = rgba.new(17, 139, 21),
    Law = rgba.new(26, 34, 224),
    Death = rgba.new(21, 17, 17),
    Blood = rgba.new(139, 29, 17),
    Soul = rgba.new(150, 151, 218)
}

local thresholds = {
    -- (Thresholds table remains unchanged)
}

local total_range = 10001 -- +1 as range is 0-indexed 

-- Helper function to convert rgba object to CSS string with error handling
local function rgba_to_css(color)
    if not color then
        return "rgba(0, 0, 0, 1)" -- Default to black if color is undefined
    end
    return string.format("rgba(%d, %d, %d, %.2f)", color.red, color.green, color.blue, color.alpha)
end

function calculate_chances(thresholds, total_range)
    local chances = {}
    for level_range, level_thresholds in pairs(thresholds) do
        chances[level_range] = {}
        local last_threshold = -1 -- Start from -1 because the range is 0-indexed
        for _, element in ipairs(rune_order) do
            local threshold = level_thresholds[element]
            local range = threshold - last_threshold
            local percentage = (range / total_range) * 100
            chances[level_range][element] = percentage
            last_threshold = threshold
        end
    end
    return chances
end

-- New function to merge adjacent rune colors
function merge_adjacent_colors(chances)
    local merged_chances = {}
    
    for level_range, level_thresholds in pairs(chances) do
        merged_chances[level_range] = {}
        local last_rune = nil
        local last_percentage = 0

        for _, rune in ipairs(rune_order) do
            local percentage = level_thresholds[rune]
            
            if last_rune == rune then
                -- Merge with the previous segment
                last_percentage = last_percentage + percentage
            else
                -- Save the previous segment if it exists
                if last_rune then
                    merged_chances[level_range][last_rune] = last_percentage
                end
                -- Update to the new rune
                last_rune = rune
                last_percentage = percentage
            end
        end

        -- Save the last segment
        if last_rune then
            merged_chances[level_range][last_rune] = last_percentage
        end
    end
    
    return merged_chances
end

function stacked_bar()
    local chances = calculate_chances(thresholds, total_range)
    local merged_chances = merge_adjacent_colors(chances)

    -- Create a new chart of type 'bar'
    local plot = chart.newChart{ type = 'bar' }

    -- Add the labels (x-axis labels)
    local sorted_ranges = {}
    for level_range, _ in pairs(merged_chances) do
        table.insert(sorted_ranges, level_range)
    end
    table.sort(sorted_ranges, function(a, b)
        return tonumber(string.match(a, "%d+")) < tonumber(string.match(b, "%d+"))
    end)
    plot:addDataLabels(sorted_ranges)

    -- Add datasets for each rune
    for _, rune in ipairs(rune_order) do
        local data_points = {}
        local has_data = false
        for _, level_range in ipairs(sorted_ranges) do
            local percentage = merged_chances[level_range][rune] or 0
            table.insert(data_points, percentage)
            if percentage > 0 then
                has_data = true
            end
        end

        -- Only add datasets that have actual data
        if has_data then
            plot:newDataSet{
                label = rune .. " rune",
                data = data_points,
                backgroundColor = rgba_to_css(rune_colors[rune]), -- Converts rgba object to CSS string
                borderColor = rgba_to_css(rune_colors[rune]),
                borderWidth = 3,
                barPercentage = 0.975,
                categoryPercentage = 1.05,
                borderSkipped = 'bottom'
            }
        end
    end

    -- Set chart options
    plot:setOptions{
        responsive = true,
        maintainAspectRatio = false,
        plugins = {
            legend = { position = 'top' },
            tooltip = { mode = 'index', intersect = false }
        },
        scales = {
            x = {
                stacked = true,
            },
            y = { 
                stacked = true, 
                beginAtZero = true,
                max = 100,
                ticks = {
                    callback = function(value)
                        return value .. '%'
                    end
                }
            }
        }
    }

    -- Finalize and return the chart
    return tostring(plot:finish())  -- Convert chart object to a string
end

function p.chart(frame)
    return stacked_bar()
end

return p