Jump to content
 







Main menu
   


Navigation  



Main page
Contents
Current events
Random article
About Wikipedia
Contact us
Donate
 




Contribute  



Help
Learn to edit
Community portal
Recent changes
Upload file
 








Search  

































Create account

Log in
 









Create account
 Log in
 




Pages for logged out editors learn more  



Contributions
Talk
 



















Contents

   



(Top)
 


1 Usage  














Module:Climate chart






Qaraqalpaqsha
 

Edit links
 









Module
Talk
 

















Read
View source
View history
 








Tools
   


Actions  



Read
View source
View history
 




General  



What links here
Related changes
Upload file
Special pages
Permanent link
Page information
Get shortened URL
Download QR code
Wikidata item
 




Print/export  



Download as PDF
Printable version
 
















Appearance
   

 





Permanently protected module

From Wikipedia, the free encyclopedia
 


Implements {{climate chart}}. At some point.

Usage

{{#invoke:Climate chart|function_name}}

local p = {}
local cfg = mw.loadData('Module:Climate chart/configuration')

-- from https://lua-users.org/wiki/SimpleRound
local function round(num, decimal_places)
 local mult = 10^(decimal_places or 0)
 return math.floor(num * mult + 0.5) / mult
end

local function arg_or_default(args, from_arg, default)
 local arg = mw.text.trim(args[from_arg] or '')
 if arg ~= '' then
  return arg
 else
  return default
 end
end

-- we only draw using the metric numbers
local function compute_column_draw_data(metric_year, max_precipitation)
 local column_draw_data = {}
 -- so many magic constants
 local precipitation_scale = math.max(1, max_precipitation / 750) -- 750 mm is the maximum for height
 
 for _, month in ipairs(metric_year) do
  local precipitation_bar_height = month.precipitation / 50 / precipitation_scale -- 50 is a magic constant
  local temperature_bar_displacement = month.minimum / 5 + 8
  local temperature_bar_height = (month.maximum - month.minimum) / 5
  local temperature_high_displacement = month.maximum / 5 + 8
  local temperature_low_displacement = month.minimum / 5 + 6.5
  
  table.insert(column_draw_data, {
   precipitation_height = precipitation_bar_height,
   temperature_height = temperature_bar_height,
   temperature_displacement = temperature_bar_displacement,
   temperature_high_displacement = temperature_high_displacement,
   temperature_low_displacement = temperature_low_displacement
  })
 end
 
 return column_draw_data
end

local function present_monthly_temperature(temperature)
 local rounded_temp = round(temperature, 0)
 local temperature_sign = ''
 if rounded_temp < 0 then temperature_sign = '&minus;' end
 local abs_temp = math.abs(rounded_temp)
 
 return temperature_sign .. abs_temp
end

local function draw_column(month_draw_data, month_data)
 
 local precipitation = month_data.precipitation
 local precipitation_decimal_places = precipitation < 10 and 1 or 0
 local rounded_precipitation = round(precipitation, precipitation_decimal_places)
 
 local high_temp = present_monthly_temperature(month_data.maximum)
 local low_temp = present_monthly_temperature(month_data.minimum)
 
 local column = mw.html.create('div')
 column:addClass('climate-chart-column')
 :tag('div')
  :addClass('climate-chart-column-spacer')
  :wikitext('&nbsp;')
  :done()
 :tag('div')
  :addClass('climate-chart-column-precip-bar')
  :wikitext('&nbsp;')
  :css('height', month_draw_data.precipitation_height .. 'em')
  :css('print-color-adjust', 'exact') -- css sanitizer doesn't accept yet
  :done()
 :tag('div')
  :addClass('climate-chart-column-value climate-chart-column-precip')
  :tag('span')
   :wikitext(rounded_precipitation)
   :done()
  :done()
 :tag('div')
  :addClass('climate-chart-column-spacer2')
  :wikitext('&nbsp;')
  :done()
 :tag('div')
  :addClass('climate-chart-column-temp-bar')
  :wikitext('&nbsp;')
  :css('bottom', month_draw_data.temperature_displacement .. 'em' )
  :css('height', month_draw_data.temperature_height .. 'em')
  :css('print-color-adjust', 'exact') -- css sanitizer doesn't accept yet
  :done()
 :tag('div')
  :addClass('climate-chart-column-value climate-chart-column-high-temp')
  :css('bottom', month_draw_data.temperature_high_displacement .. 'em')
  :tag('span')
   :wikitext(high_temp)
   :done()
  :done()
 :tag('div')
  :addClass('climate-chart-column-value climate-chart-column-low-temp')
  :css('bottom', month_draw_data.temperature_low_displacement .. 'em')
  :tag('span')
   :wikitext(low_temp)
   :done()
  :done()
 :done()
 return column
end

local function header_row()
 local month_row = mw.html.create('tr')
 for _, month in ipairs(cfg.i18n.months) do
  month_row:tag('th')
   :attr('scope', 'col')
   :wikitext(month)
   :done()
 end
 
 return month_row:allDone()
end

local function fill_nice_tables(args)
 local primary_table = {}
 local secondary_table = {}
 for n = 2, 37, 3 do
  local minimum = tonumber(args[n])
  local maximum = tonumber(args[n+1])
  local precipitation = tonumber(args[n+2])
   -- we use the fact that `tonumber` returns nil if it gets not_a_string
   -- _OR_ the empty string later, since the defaults are unit-specific
  table.insert(primary_table, {
   minimum = minimum,
   maximum = maximum,
   precipitation = precipitation
  })
  table.insert(secondary_table, {
   minimum = minimum,
   maximum = maximum,
   precipitation = precipitation
  })
 end
 return primary_table, secondary_table
end

local function c_to_f(temperature_in_c)
 return temperature_in_c * 1.8 + 32
end

local function f_to_c(temperature_in_f)
 return (temperature_in_f - 32) * 5/9
end

local function mm_to_in(precipitation_in_mm)
 return precipitation_in_mm / 25.4 
end

local function in_to_mm(precipitation_in_in)
 return precipitation_in_in * 25.4
end

local function convert_inplace(t, convert_temperature, convert_precipitation)
 for _, month in ipairs(t) do
  month.minimum = convert_temperature(month.minimum)
  month.maximum = convert_temperature(month.maximum)
  month.precipitation = convert_precipitation(month.precipitation)
 end
end

local function fill_in_nils(year_t, default_t)
 for _, month in ipairs(year_t) do
  if not month.precipitation then month.precipitation = default_t.precipitation end
  if not month.maximum then month.maximum = default_t.temperature_high end
  if not month.minimum then month.minimum = default_t.temperature_low end
 end
end

local function chart_rows(args, imperial)
 local metric_t
 local imperial_t
 local maximum_precipitation = tonumber(args.maxprecip)
 local imperial_max_precipitation
 local metric_max_precipitation
 local default_max_precipitation = 1
 
 if imperial then
  imperial_t, metric_t = fill_nice_tables(args)
  fill_in_nils(metric_t, cfg.metric_default)
  fill_in_nils(imperial_t, cfg.imperial_default)
  convert_inplace(metric_t, f_to_c, in_to_mm, imperial)
  if maximum_precipitation then
   imperial_max_precipitation = maximum_precipitation
   metric_max_precipitation = in_to_mm(maximum_precipitation)
  else
   imperial_max_precipitation = default_max_precipitation
   metric_max_precipitation = default_max_precipitation
  end
 else
  metric_t, imperial_t = fill_nice_tables(args)
  fill_in_nils(metric_t, cfg.metric_default)
  fill_in_nils(imperial_t, cfg.imperial_default)
  convert_inplace(imperial_t, c_to_f, mm_to_in, imperial)
  if maximum_precipitation then
   metric_max_precipitation = maximum_precipitation
   imperial_max_precipitation = mm_to_in(maximum_precipitation)
  else
   metric_max_precipitation = default_max_precipitation
   imperial_max_precipitation = default_max_precipitation
  end
 end
 
 local column_draw_data = compute_column_draw_data(metric_t, metric_max_precipitation)
 
 local metric_row = mw.html.create('tr')
 local imperial_row = mw.html.create('tr')
 local function add_columns(row, year)
  for i = 1, 12 do
   row:tag('td')
    :node(draw_column(column_draw_data[i], year[i]))
    :done()
  end
 end
 
 add_columns(metric_row, metric_t)
 add_columns(imperial_row, imperial_t)
 
 return metric_row, imperial_row
 
end

local function present_chart_content(args, imperial)
 
 local primary_row, secondary_row
 if imperial then
  secondary_row, primary_row = chart_rows(args, imperial)
 else
  primary_row, secondary_row = chart_rows(args, imperial)
 end
 
 local primary = mw.html.create('table')
  :addClass('climate-chart-primary climate-chart-internal')
  :node(header_row())
  :node(primary_row)
  :done()
  
 local secondary_chart = mw.html.create('table')
  :addClass('climate-chart-secondary climate-chart-internal')
  :node(header_row())
  :node(secondary_row)
  :done()
 
 local secondary_title = imperial and cfg.i18n.secondary_title_metric or cfg.i18n.secondary_title_imperial
 -- primary has html_chart
 
 return primary, {
  title = secondary_title,
  chart = secondary_chart
 }
end

local function wrap_secondary_content(chart_content, temp_explanation, precip_explanation)
 local ret = mw.html.create('div')
 ret:addClass('climate-chart-secondary mw-collapsible mw-collapsed')
  :tag('div')
   :addClass('climate-chart-secondary-title')
   :wikitext(chart_content.title)
   :done()
  :tag('div')
   :addClass('mw-collapsible-content')
   :node(chart_content.chart)
   :node(temp_explanation)
   :node(precip_explanation)
   :done()
 return ret
end

local function explain_bar(bar_type, text)
 local ret = mw.html.create('p')
 ret:addClass('climate-change-explain-bar-' .. bar_type)
  :tag('span')
   :wikitext(cfg.i18n.explainer_key)
   :done()
  :wikitext(text)
  :done()
 return ret
end

local function explain(imperial, bar_type, imperial_explanation, metric_explanation)
 if imperial then
  return explain_bar(bar_type, imperial_explanation),
   explain_bar(bar_type, metric_explanation)
 else
  return explain_bar(bar_type, metric_explanation),
   explain_bar(bar_type, imperial_explanation)
 end
end

local function add_source(source)
 if not source then return end
 return mw.html.create('p'):wikitext(string.format(cfg.i18n.source, source))
end

local function add_title_content(title)
 local ret = mw.html.create()
 ret:tag('div')
  :addClass('climate-chart-title')
  :wikitext(title)
  :done()
 :tag('div')
  :addClass('climate-chart-explainer')
  :wikitext(cfg.i18n.explainer)
  :done()
 return ret
end

function p._main(args)
 
 local float = arg_or_default(args, cfg.arg.float, nil)
 local float_class = nil
 if float then
  if float == 'right' then
   float_class = 'climate-chart-right'
  elseif float == 'left' then
   float_class = 'climate-chart-left'
  end
 end
 
 local clear = arg_or_default(args, cfg.arg.clear, nil) or float
 local units = string.lower(arg_or_default(args, cfg.arg.units, ''))
 local is_imperial_primary = units == cfg.keyword.imperial
 local title = add_title_content(arg_or_default(args, cfg.arg.title, ''))
 local primary_chart, secondary_chart_content = present_chart_content(
  args,
  is_imperial_primary
 )
 local primary_temp_explanation, secondary_temp_explanation = explain(
  is_imperial_primary,
  'temp',
  cfg.i18n.explainer_fahrenheit,
  cfg.i18n.explainer_celsius
 )
 local primary_precip_explanation, secondary_precip_explanation = explain(
  is_imperial_primary,
  'precip',
  cfg.i18n.explainer_in,
  cfg.i18n.explainer_mm
 )
 
 local source = add_source(arg_or_default(args, 'source', nil))
 
 local secondary_content = wrap_secondary_content(
  secondary_chart_content,
  secondary_temp_explanation,
  secondary_precip_explanation
 )
 
 local climate_chart = mw.html.create('div')
 climate_chart:addClass('climate-chart')
  :addClass(float_class)
  :css('clear', clear)
 
 climate_chart:node(title)
  :node(primary_chart)
  :node(primary_temp_explanation)
  :node(primary_precip_explanation)
  :node(source)
  :node(secondary_content)
  :allDone()
 return mw.getCurrentFrame():extensionTag{
  name = 'templatestyles', args = { src = 'Module:Climate chart/styles.css' }
 } .. tostring(climate_chart)
end

function p.main(frame)
 return p._main(frame:getParent().args)
end

return p

Retrieved from "https://en.wikipedia.org/w/index.php?title=Module:Climate_chart&oldid=1211125245"

Categories: 
Modules subject to page protection
Templates using TemplateStyles
Hidden category: 
Wikipedia semi-protected modules
 



This page was last edited on 1 March 2024, at 00:07 (UTC).

Text is available under the Creative Commons Attribution-ShareAlike License 4.0; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization.



Privacy policy

About Wikipedia

Disclaimers

Contact Wikipedia

Code of Conduct

Developers

Statistics

Cookie statement

Mobile view



Wikimedia Foundation
Powered by MediaWiki