Module:yo-dial-map

local export = {}

local m_links = require("Module:links") local m_lang = require("Module:languages") local yo = m_lang.getByCode("yo") local dial_data = mw.loadData("Module:yo-dial-map/data")

local radius = 0.001

local colors = { "d2502e", "6941c7", "9fdd42", "e7ff79", "b66063", "30bcff", "c6ceff", "02f291", "2e1200", "a4ff46", "ffcccf", "63001e", "c124de", "00ae2d", "ff4ce4", "6fff8b", "b900b1", "bfff6b", "0035b6", "fffe8d", "61008c", "adff9e", "d463ff", "3c8a00", "db0098", "00c97f", "a20090", "01a145", "ff5ec8", "59ffc6", "e50025", "01c0cc", "a60003", "02b9db", "d37200", "0151c6", "949900", "00156f", "ffa938", "290062", "b69700", "6d87ff", "c88100", "014592", "ff823e", "000f36", "bdffc4", "1e003b", "ffce7a", "320029", "d5ffea", "6a0050", "009267", "ff4c61", "019282", "fd98ff", "094300", "ad96ff", "965a00", "8eb0ff", "761f00", "9bd8ff", "490d00", "fbffe9", "1d000f", "feecff", "00141e", "ffddad", "001b14", "ff93ce", "004f23", "9d0050", "005e5e", "ffa291", "003e33", "ff9cac", "00536c", "ffc594", "0079b1", "5a3600", }

local function delink(text) text = text:gsub("%[%^|%[%+|([^|%[%]]+)%]%]","%1") :gsub("%[%[([^|%[%]]+)%]%]","%1") return text end

function export.make_list(data) return "" .. table.concat(data,"") .. "" end

function export.map_header(text) return tostring(		mw.html.create("h2")			:wikitext(text)		:done	) end

function export.get_coords(lat,long,i,n) if n > 1 then return {long+radius*math.cos(2*math.pi*i/n),lat+radius*math.sin(2*math.pi*i/n)} else return {long,lat} end end

function export.make_point(lat,long,color,text,i,n) return { type = "Feature", properties = { title = text, ["marker-color"] = color, ["marker-size"] = "small", },		geometry = { type = "Point", coordinates = export.get_coords(lat,long,i,n) }	} end

function export.make_polygon(text,color,points) local coords = {} for _,pt in ipairs(points) do		table.insert(coords,{pt.long,pt.lat}) end table.insert(coords,{points[1].long,points[1].lat}) return { type = "Feature", properties = { title = text, ["stroke-width"] = 0, ["fill"] = color, ["fill-opacity"] = 0.2, },		geometry = { type = "Polygon", coordinates = {coords}, }	} end

function export.legend(colour, show, cat, hide) return tostring(		mw.html.create("div")			:addClass("yo-dial-map__legend-row")			:addClass((colour == grey and "yo-dial-map__legend-row-other" or nil))			:tag("div")				:addClass("vsSwitcher")				:attr("data-toggle-category", cat)				:attr("data-vs-showtext", "lects ▼")				:attr("data-vs-hidetext", "lects ▲")

:addClass("yo-dial-map__legend-row-dot") :css("background-color", "#" .. colour) :wikitext("") :done :tag("span") :addClass("vsToggleElement") :wikitext("") :done :wikitext(show) :tag("div") :addClass("vsHide") :wikitext(hide) :allDone ) end

function export.make_legends(legend) -- divide into five columns manually -- DO NOT replace with css column-count local r = #legend%5 local q = math.floor(#legend/5) local d1 = q+(r>0 and 1 or 0) local d2 = d1+q+(r>1 and 1 or 0) local d3 = d2+q+(r>2 and 1 or 0) local d4 = d3+q+(r>3 and 1 or 0) local l1 = table.concat(legend,"",1,d1) local l2 = table.concat(legend,"",d1+1,d2) local l3 = table.concat(legend,"",d2+1,d3) local l4 = table.concat(legend,"",d3+1,d4) local l5 = table.concat(legend,"",d4+1,#legend) local cell = {width="20%",["vertical-align"]="top"} return tostring(		mw.html.create("table"):css("width","100%"):tag("tr")			:tag("td"):css(cell):wikitext(l1):done			:tag("td"):css(cell):wikitext(l2):done			:tag("td"):css(cell):wikitext(l3):done			:tag("td"):css(cell):wikitext(l4):done			:tag("td"):css(cell):wikitext(l5):done		:allDone	) end

function export.make_map(frame,geojson,legend) return tostring(		mw.html.create("div")			:addClass("thumb")			:addClass("yo-dial-map__container")			:wikitext(frame:extensionTag("mapframe",mw.text.jsonEncode(geojson),{				class = "yo-dial-map__map",				mapstyle = "osm-intl",				width = 1200,				height = 600,				latitude = 7.38298,				longitude = 3.94703,				zoom = 7			}))			:done

:wikitext(legend) :done :done ) end

function export.show(frame) local geojson = {} local legend = {} local dial = mw.loadData("Module:dialect synonyms/yo").varieties local syn = mw.loadData("Module:dialect synonyms/yo/"..frame.args[1]) -- recurse through dial to find all the lects local lects = {} local layer = {dial} while layer[1] do		local children = {} for _,node in ipairs(layer) do			if node[1] then -- node is a subfamily for _,child in ipairs(node) do					table.insert(children,child) end elseif node.long and syn.syns[node.name] and syn.syns[node.name][1] ~= "" then table.insert(lects,node) end end layer = children end local locs = {} -- loc[form] = {lect1, lect2, ...} local n = {} for _,lect in ipairs(lects) do		local syn_lect = syn.syns[lect.name] n[lect.name] = 0 -- `#` doesn't work with mw.loadData local i = 0 for _,form in ipairs(syn_lect) do			i = i + 1 n[lect.name] = n[lect.name] + 1 locs[form] = locs[form] or {} table.insert(locs[form],{lect,i}) end end local forms = {} for form,lects in pairs(locs) do		table.insert(forms,form) end table.sort(forms, function(a,b) return #locs[a] > #locs[b]		or (#locs[a] == #locs[b] and a > b) end) for idx,form in ipairs(forms) do		local color = colors[idx] local legend_lects = {} local link = m_links.full_link({			lang = yo,			term = form,		}) for _,lect_i in ipairs(locs[form]) do			local lect,i = lect_i[1],lect_i[2] local link_ = link if lect.code then link_ = m_links.full_link({					lang = m_lang.getByCode(lect.code),					term = form,				}) end local display = lect.text_display .. ": " .. link_ table.insert(geojson,export.make_point(lect.lat,lect.long,color,display,i,n[lect.name])) table.insert(legend_lects, lect.text_display) end table.insert(legend, export.legend(color, link .. " (" .. #locs[form] .. ")", form, export.make_list(legend_lects))) end local title = syn.title and syn.title ~= "" and syn.title or frame.args[1] title = title:gsub("[0-9%-]", "") local map_header = export.map_header(		"Map of Yoruba varieties and languages for " .. m_links.full_link( {				lang = yo, term = title, gloss = syn.meaning, }		)	)	-- draw the families for _,fam in ipairs(dial_data.groups) do		table.insert(geojson,export.make_polygon(fam.name,fam.color,fam.points)) end local legends = export.make_legends(legend) local map = export.make_map(frame, geojson, legends) return map_header .. map end

return export