Module:USASpending-spending-over-time
From Defense Knowledge
Documentation for this module may be created at Module:USASpending-spending-over-time/doc
local p = {}
-- Function to create a tab button dynamically
local function createTabButton(id, label, isActive)
local activeClass = isActive and 'active' or ''
local selected = isActive and 'true' or 'false'
return string.format(
'<li class="nav-item" role="presentation">' ..
'<div class="nav-link rounded-0 %s" id="%s-tab" data-bs-toggle="tab" data-bs-target="#%s" type="button" role="tab" aria-controls="%s" aria-selected="%s">%s</div>' ..
'</li>',
activeClass, id, id, id, selected, label
)
end
-- Helper function to generate graph data (comma-separated values)
local function generateSpendingGraph(data, field)
local values = {}
for _, entry in ipairs(data) do
local value
if field == 'quarter' then
local year = entry['fiscal_year']
local period = entry[field]
if year and period then
value = "'" .. year .. " Q" .. period .. "'"
end
else
value = entry[field]
end
-- Insert the value into the list if it exists
if value then
table.insert(values, value)
end
end
return table.concat(values, ',')
end
-- Main function to fetch data and generate output
function p.aggregatedByYear(uei, queryUrl)
-- Define API URLs
local baseUrl = 'https://api.usaspending.gov'
local queryUrl = queryUrl or '/api/v2/search/spending_over_time/'
local apiUrl = baseUrl .. queryUrl
-- Helper function to fetch data
local function fetchData(postData)
return mw.ext.externalData.getWebData {
url = apiUrl,
format = 'JSON',
['use jsonpath'] = true,
['post data'] = postData,
data = { aggregated_amount = '$..aggregated_amount', quarter = '$..quarter', fiscal_year = '$..fiscal_year' },
['cache seconds'] = 86400
} or {}
end
-- Prepare output
local output = {}
local frame = mw.getCurrentFrame()
-- Generate the tab buttons
table.insert(output, '<ul class="nav nav-tabs m-0 mt-3 pb-0" id="transactionGraphs" role="tablist">')
table.insert(output, createTabButton('quarter', 'By Quarter', true))
table.insert(output, createTabButton('year', 'By Year', false))
table.insert(output, '</ul>')
table.insert(output, '<div class="tab-content" id="transactionGraphsContent">')
-- Generate "Quarters" tab content
local quartersData = fetchData(string.format('{"group":"quarter","filters":{"recipient_search_text":["%s"]}}', uei))
table.insert(output, '<div class="tab-pane active pt-3" id="quarter" role="tabpanel" aria-labelledby="quarter-tab">')
table.insert(output, '<div id="quarter-graph" style="width:100%;height:280px;max-width:900px"></div>') -- Graph wrapper
local x = generateSpendingGraph(quartersData, 'quarter') -- X-axis data
local y = generateSpendingGraph(quartersData, 'aggregated_amount') -- Y-axis data
-- Build the graph using the #widget parser function
local graphQuarter = frame:callParserFunction(
'#widget',
'SpendingOverTimeGraph',
'xAxis=' .. x,
'yAxis=' .. y,
'target=quarter-graph',
'name=Obligations'
)
-- Return the graph output
table.insert(output, '<div>' .. graphQuarter .. '</div>')
table.insert(output, '</div>')
-- Generate "Years" tab content
local yearsData = fetchData(string.format('{"group":"fiscal_year","filters":{"recipient_search_text":["%s"]}}', uei))
table.insert(output, '<div class="tab-pane active pt-3" id="year" role="tabpanel" aria-labelledby="year-tab">')
table.insert(output, '<div id="year-graph" style="width:100%;height:280px;max-width:900px"></div>') -- Graph wrapper
local x = generateSpendingGraph(yearsData, 'fiscal_year') -- X-axis data
local y = generateSpendingGraph(yearsData, 'aggregated_amount') -- Y-axis data
-- Build the graph using the #widget parser function
local graphYear = frame:callParserFunction(
'#widget',
'SpendingOverTimeGraph',
'xAxis=' .. x,
'yAxis=' .. y,
'target=year-graph',
'name=Obligations'
)
-- Return the graph output
table.insert(output, '<div>' .. graphYear .. '</div>')
table.insert(output, '</div>')
table.insert(output, '</div>')
return table.concat(output, "\n")
end
return p