Module:AspectCodesTagCloud
From semantic-mediawiki.org
Documentation for this module may be created at Module:AspectCodesTagCloud/doc
-- DEVELOPMENT!!!
local p = {}
function p.show(frame)
if not mw.smw then
return "mw.smw module not found"
end
local conferenceContributionsQuery = mw.smw.getQueryResult(" \
[[HasConferenceContributionAspectCode::+]] \
|?HasConferenceContributionAspectCode \
|?HasConferenceContributionType \
|?HasConferenceContributionStatus \
|?HasConferenceContributionAuthorName \
|?HasConferenceContributionScheduleDay \
|?HasConferenceContributionStartTime \
|?HasEntityTitle \
|?HasEntityBlurb \
|?HasEntityKeyword \
")
if conferenceContributionsQuery == nil then
return "(no values)"
end
if type( conferenceContributionsQuery ) == "table" then
local conferenceContributions = {}
for k,v in pairs( conferenceContributionsQuery.results ) do
table.insert(conferenceContributions, {
conferenceContribution = v.fulltext,
properties = v.printouts
} )
end
-- Sort by AspectCode
conferenceContributionsByAspectCode = {}
keywords = {}
contributionTypes = {}
scheduleDays = {}
for k,v in pairs(conferenceContributions) do
page = mw.title.new(v.conferenceContribution)
if tableHasKey(conferenceContributionsByAspectCode, v.properties.HasConferenceContributionAspectCode[1].fulltext) then
table.insert(conferenceContributionsByAspectCode[v.properties.HasConferenceContributionAspectCode[1].fulltext], {
conferenceContribution = v.conferenceContribution,
properties = v.properties,
content = page:getContent()
})
else
conferenceContributionsByAspectCode[v.properties.HasConferenceContributionAspectCode[1].fulltext] = {{
conferenceContribution = v.conferenceContribution,
properties = v.properties,
content = page:getContent()
}}
end
-- KEYWORDS
for kwk, kwv in pairs(v.properties.HasEntityKeyword) do
if tableHasKey(keywords, kwv) then
keywords[kwv]["vol"] = keywords[kwv]["vol"] + 1
else
keywords[kwv] = { vol = 1 }
end
end
-- CONTRIBUTION TYPES
if tableHasKey(contributionTypes, v.properties.HasConferenceContributionType[1]) then
contributionTypes[v.properties.HasConferenceContributionType[1]]["vol"] = contributionTypes[v.properties.HasConferenceContributionType[1]]["vol"] + 1
else
contributionTypes[v.properties.HasConferenceContributionType[1]] = { vol = 1 }
end
-- SCHEDULE DAYS
if v.properties.HasConferenceContributionScheduleDay[1] then
if tableHasKey(scheduleDays, v.properties.HasConferenceContributionScheduleDay[1].raw) then
scheduleDays[string.sub(v.properties.HasConferenceContributionScheduleDay[1].raw, 3)]["vol"] = scheduleDays[string.sub(v.properties.HasConferenceContributionScheduleDay[1].raw, 3)]["vol"] + 1
else
scheduleDays[string.sub(v.properties.HasConferenceContributionScheduleDay[1].raw, 3)] = { vol = 1 }
end
end
end
aspectCodesData = getAspectCodesData()
-- Assemble tag cloud
tagCloud = {}
maxContributions = getMaxContributions(conferenceContributionsByAspectCode)
minContributions = getMinContributions(conferenceContributionsByAspectCode)
maxFontSize = 60
minFontSize = 20
for k,v in pairs(conferenceContributionsByAspectCode) do
contributionTitlesList = getContributionTitlesList(v)
if aspectCodesData[k] then
aspectCodeGroup = aspectCodesData[k][1].properties.HasAspectCodeGroup[1]
aspectCodeTitle = aspectCodesData[k][1].properties.HasEntityTitle[1]
if aspectCodesData[k][1].properties.HasEntityBlurb[1] then
aspectCodeBlurb = aspectCodesData[k][1].properties.HasEntityBlurb[1]
else
aspectCodeBlurb = ""
end
else
aspectCodeGroup = ""
aspectCodeTitle = ""
aspectCodeBlurb = ""
end
tooltip = mw.getCurrentFrame():preprocess( "{{#info: " .. aspectCodeBlurb .. " |note }}" )
fontSize = minFontSize + ((table.getn(v) - minContributions) / (maxContributions - minContributions) * (maxFontSize - minFontSize))
table.insert(tagCloud, "<div style=' \
background-color:" .. getBackgroundColorForAspectCodeGroup(aspectCodeGroup) .. "; \
margin:3px; \
padding:3px; \
display:inline; \
float:left; \
border-radius:5px; \
border:1px solid gray;'> \
<div style='font-size:14px;'>" .. aspectCodeGroup .. "</div> \
<div style='font-size:" .. fontSize .. "px;'>[[" .. k .. "|" .. aspectCodeTitle .. "]]" .. tooltip .. "</div> \
<div style='font-size:14px;'>" .. contributionTitlesList .. "</div> \
</div>")
end
legend = "<div style=''><span style='background-color:#BDE4A7;'>PROMOTE/USE/MONITOR</span> | <span style='background-color:#B5C8F6;'>CONFIGURE/INTEGRATE</span> | <span style='background-color:#FFD57C;'>SETUP/DEVELOP/MAINTAIN</span> | <span style='border:1px solid gray;'>COMMUNITY</span></div>"
if frame.args[1] == "cloud" then
return "<div style='float:left;clear:right;border:1px solid gray;border-radius:2px;'>" .. legend .. "<hr>" .. table.concat(tagCloud, ' ') .. "</div>"
else
-- return table_print(aspectCodesData)
-- return table_print(contributionTypes)
-- return table_print(conferenceContributionsByAspectCode)
return aspectsMap(conferenceContributionsByAspectCode)
end
end
return conferenceContributionsQuery
end
-- HELPER FUNCTIONS
function aspectsMap(conferenceContributionsByAspectCode)
-- KEYWORDS
keywordNounList = {}
keywordVerbList = {}
for kwk, kwv in pairsByKeys(keywords) do
fontSize = 13 + ( kwv["vol"] * 2 )
firstCharIsUppercase = string.match(kwk, '^%u')
if firstCharIsUppercase == nil then
table.insert(keywordVerbList, "<span class='keywordCheckbox' title='" .. kwk .. "'>❏</span> <i><span class='keyword' style='font-size:" .. fontSize .. "px;'>" .. kwk .. "</span></i><sup>" .. kwv["vol"] .. "</sup>")
else
table.insert(keywordNounList, "<span class='keywordCheckbox' title='" .. kwk .. "'>❏</span> <span class='keyword' style='font-size:" .. fontSize .. "px;'>" .. kwk .. "</span><sup>" .. kwv["vol"] .. "</sup>")
end
end
-- CONTRIBUTION TYPES
contributionTypeList = {}
for ctk, ctv in pairsByKeys(contributionTypes) do
table.insert(contributionTypeList, "<span class='contributionTypeCheckbox' title='" .. ctk .. "'>❏</span> <span class='contributionType'>" ..
ctk .. "</span><sup>" .. ctv["vol"] .. "</sup>")
end
-- SCHEDULE DAYS
scheduleDayList = {}
for ctk, ctv in pairsByKeys(scheduleDays) do
table.insert(scheduleDayList, "<span class='scheduleDayCheckbox' title='" .. ctk .. "'>❏</span> <span class='scheduleDay'>" ..
ctk .. "</span><sup>" .. ctv["vol"] .. "</sup>")
end
mytable = {
"<table class='aspectMapMainTable'>",
"<tr><td colspan='3'><b>NOUN KEYWORDS:</b> " .. table.concat(keywordNounList, ", ") .. "</td></tr>",
"<tr><td colspan='3'><b>VERB KEYWORDS:</b> " .. table.concat(keywordVerbList, ", ") .. "</td></tr>",
"<tr><td colspan='3'><b>TYPES:</b> " .. table.concat(contributionTypeList, ", ") .. "</td></tr>",
"<tr><td colspan='3'><b>DAYS:</b> " .. table.concat(scheduleDayList, ", ") .. "</td></tr>",
"<tr class='groups'>",
"<td style='width:33%;'><b>TOGGLE ALL:</b> <span class='toggleAll'>❏</span></td>",
"<td style='width:33%;'>",
"<div class='aspectCodeGroupTitle'>COMMUNITY</div>",
getAspectCodeHTML("COM-0"),
getAspectCodeHTML("COM-1"),
getAspectCodeHTML("COM-2"),
"</td>",
"<td>",
"<div class='aspectCodeGroupTitle'>COMMUNITY</div>",
getAspectCodeHTML("COM-3"),
getAspectCodeHTML("COM-4"),
getAspectCodeHTML("COM-5"),
"</td>",
"</tr>",
"<tr style='background-color:#bde4a7;'>",
"<td><div class='aspectCodeGroupTitle'>Operations: PROMOTE</div>",
getAspectCodeHTML("PR-0"),
getAspectCodeHTML("PR-1"),
"</td>",
"<td><div class='aspectCodeGroupTitle'>Operations: USE</div>",
getAspectCodeHTML("US-0"),
getAspectCodeHTML("US-1"),
getAspectCodeHTML("US-2"),
"</td>",
"<td><div class='aspectCodeGroupTitle'>Operations: MONITOR</div>",
getAspectCodeHTML("MO-0"),
getAspectCodeHTML("MO-1"),
"</td>",
"</tr>",
"<tr>",
"<td colspan=3>",
"<table class='aspectMapSubTable'>",
"<tr style='background-color:#b5c8f6;'>",
"<td style='width:50%;'><div class='aspectCodeGroupTitle'>Customization: CONFIGURE</div>",
getAspectCodeHTML("CONF-0"),
getAspectCodeHTML("CONF-1"),
getAspectCodeHTML("CONF-2"),
"</td>",
"<td style='width:50%;'><div class='aspectCodeGroupTitle'>Customization: INTEGRATE</div>",
getAspectCodeHTML("IN-0"),
getAspectCodeHTML("IN-1"),
"</td>",
"</tr>",
"</table>",
"</td></tr>",
"<tr style='background-color:#ffd57c;'>",
"<td><div class='aspectCodeGroupTitle'>Infrastructure: SETUP</div>",
getAspectCodeHTML("SE-0"),
getAspectCodeHTML("SE-1"),
getAspectCodeHTML("SE-2"),
"</td><td><div class='aspectCodeGroupTitle'>Infrastructure: MAINTAIN</div>",
getAspectCodeHTML("MA-0"),
getAspectCodeHTML("MA-1"),
getAspectCodeHTML("MA-2"),
"</td><td><div class='aspectCodeGroupTitle'>Infrastructure: DEVELOP</div>",
getAspectCodeHTML("DE-0"),
getAspectCodeHTML("DE-1"),
getAspectCodeHTML("DE-2"),
"</td>",
"</tr></table>"
}
return table.concat(mytable, '')
end
function getAspectCodeHTML(ac)
if aspectCodesData[ac] then
t = {
"<div>",
"<h4 class='aspectCodeCode'>" .. ac .. " <span class='aspectCodeTitle'>",
aspectCodesData[ac][1].properties.HasEntityTitle[1] .. "</span> " .. getAspectCodeTooltip(ac) .. "</h4>",
getContributionTitlesList(conferenceContributionsByAspectCode[ac]),
"</div>"
}
else
t = {}
end
return table.concat(t, '')
end
function table_print (tt, indent, done)
done = done or {}
indent = indent or 0
if type(tt) == "table" then
local sb = {}
for key, value in pairs (tt) do
table.insert(sb, string.rep (" ", indent)) -- indent it
if type (value) == "table" and not done [value] then
done [value] = true
table.insert(sb, key .. " = {\n");
table.insert(sb, table_print (value, indent + 2, done))
table.insert(sb, string.rep (" ", indent)) -- indent it
table.insert(sb, "}\n");
elseif "number" == type(key) then
table.insert(sb, string.format("\"%s\"\n", tostring(value)))
else
table.insert(sb, string.format(
"%s = \"%s\"\n", tostring (key), tostring(value)))
end
end
return table.concat(sb)
else
return tt .. "\n"
end
end
function pairsByKeys(t, f)
local a = {}
for n in pairs(t) do a[#a + 1] = n end
table.sort(a, f)
local i = 0
return function ()
i = i + 1
return a[i], t[a[i]]
end
end
function to_string( tbl )
if "nil" == type( tbl ) then
return tostring(nil)
elseif "table" == type( tbl ) then
return table_print(tbl)
elseif "string" == type( tbl ) then
return tbl
else
return tostring(tbl)
end
end
function tableHasKey(table,key)
return table[key] ~= nil
end
function getMaxContributions(conferenceContributionsByAspectCode)
-- Get max amount of contributions per aspect code
max = 0
for k,v in pairs(conferenceContributionsByAspectCode) do
if table.getn(v) > max then
max = table.getn(v)
end
end
return max
end
function getMinContributions(aspectCodes)
-- Get min amount of contributions per aspect code
min = 0
for k,v in pairs(aspectCodes) do
if table.getn(v) < min then
min = table.getn(v)
elseif min == 0 then
min = table.getn(v)
end
end
return min
end
function getAspectCodesData()
local aspectCodesDataQuery = mw.smw.getQueryResult(" \
[[HasAspectCodeGroup::+]] \
|?HasAspectCodeGroup \
|?HasEntityTitle \
|?HasEntityBlurb \
|limit=50 \
")
if aspectCodesDataQuery == nil then
return "(no values)"
end
if type( aspectCodesDataQuery ) == "table" then
aspectCodesData = {}
for k,v in pairs( aspectCodesDataQuery.results ) do
table.insert(aspectCodesData, {
aspectCode = v.fulltext,
properties = v.printouts
} )
end
end
-- Sort by AspectCode
aspectCodes = {}
for k,v in pairs(aspectCodesData) do
if tableHasKey(aspectCodesData, v.aspectCode) then
table.insert(aspectCodes[v.aspectCode], {
properties = v.properties
})
else
aspectCodes[v.aspectCode] = {{
properties = v.properties
}}
end
end
return aspectCodes
end
function getBackgroundColorForAspectCodeGroup(aspectCode)
green = { PROMOTE=true, USE=true, MONITOR=true }
blue = { CONFIGURE=true, INTEGRATE=true }
red = { SETUP=true, DEVELOP=true, MAINTAIN=true }
if green[aspectCode] then
return "#BDE4A7"
elseif blue[aspectCode] then
return "#B5C8F6"
elseif red[aspectCode] then
return "#FFD57C"
else
return "#E3EBEB"
end
end
function getContributionTitlesList(conferenceContributions)
if conferenceContributions == nil then
return ""
end
ctl = {}
for k,v in pairs(conferenceContributions) do
if v.properties.HasEntityBlurb[1] then
hasEntityBlurb = v.properties.HasEntityBlurb[1]
else
hasEntityBlurb = ""
end
if v.content[1] then
volOfUpvotes = getVolOfUpvotes(v.content)
else
volOfUpvotes = 0
end
-- KEYWORDS
theKeywords = {}
if v.properties.HasEntityKeyword[1] then
for kwk, kwv in pairs(v.properties.HasEntityKeyword) do
table.insert(theKeywords, "<span class='keyword'>" .. kwv .. "</span>")
end
end
-- AUTHORS
theAuthors = {}
if v.properties.HasConferenceContributionAuthorName[1] then
for ak, av in pairs(v.properties.HasConferenceContributionAuthorName) do
table.insert(theAuthors, "<span class='author'>[[" .. av.fulltext .. "]]</span>")
end
end
-- DAYS
if v.properties.HasConferenceContributionScheduleDay[1] then
scheduleDay = string.sub(v.properties.HasConferenceContributionScheduleDay[1].raw, 3)
else
scheduleDay = ""
end
-- START TIME
if v.properties.HasConferenceContributionStartTime[1] then
startTime = v.properties.HasConferenceContributionStartTime[1]
else
startTime = ""
end
tooltip = mw.getCurrentFrame():preprocess( "{{#info: " .. hasEntityBlurb .. " |note }}" )
table.insert(ctl, "<span class='contributionTitle'>[[" .. v.conferenceContribution .. "|" .. v.properties.HasEntityTitle[1] .. "]]</span> " .. tooltip .. " (<span class='contributionType'>" .. v.properties.HasConferenceContributionType[1] .. "</span>, " .. volOfUpvotes .. " upvotes)<br/>by " .. table.concat(theAuthors, "/") .. "<br/>" .. table.concat(theKeywords, " - ") .. "<br/><span class='scheduleDay'>" .. scheduleDay .. "</span> at " .. startTime)
end
return "<ul class='contributionTitlesList'><li class='contribution'>" .. table.concat(ctl, "</li><li class='contribution'>") .. "</li></ul>"
end
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
function getVolOfUpvotes(content)
allUpvotes = split(content, "Upvotes")[2]
if allUpvotes then
volUpvotes = #split(allUpvotes, "*")
else
volUpvotes = 1
end
return volUpvotes - 1
end
function getAspectCodeTooltip(k)
if aspectCodesData[k][1].properties.HasEntityBlurb[1] then
aspectCodeBlurb = aspectCodesData[k][1].properties.HasEntityBlurb[1]
else
aspectCodeBlurb = ""
end
return mw.getCurrentFrame():preprocess( "{{#info: " .. aspectCodeBlurb .. " |note }}" )
end
return p