Selasa, 27 Oktober 2026
16:17 WIB
TERKINI
Bandar Lampung Harga Singkong Lampung Meroket, Petani Nikmati Keuntungan Rp45 Juta per Hektare Bandar Lampung BSU 2026 Segera Disalurkan: Rp900 Ribu dan Analisis Pakar Terkait Tantangan Pekerja Bandar Lampung Optimisme Harga Singkong Lampung 2027: Bibit dan Pupuk Kunci Utama Bandar Lampung Krisis Asap dan Ribuan Titik Panas: WALHI Desak Audit Ekologis TNWK Bandar Lampung Polda Lampung Luncurkan Operasi Patuh Krakatau 2026: 702 Personel Siap Tingkatkan Disiplin Lalu Lintas Bandar Lampung Pembakaran Sampah Diduga Picu Kebakaran Lahan di Panjang Bandar Lampung Bandar Lampung Waspada Hujan Ringan: Prakiraan Cuaca Lampung Sepanjang 24 Oktober 2026 Bandar Lampung Penundaan Pembahasan APBD Lampung 2027: Berkas dan Data Terkini Jadi Kunci Bandar Lampung Fokus Pendidikan dan Ekonomi Desa, Lampung Matangkan APBD 2027 Bandar Lampung Polisi Hadir di Jalanan: Ratusan Makan Siang Gratis Eratkan Hubungan Warga Bandar Lampung Bandar Lampung Harga Singkong Lampung Meroket, Petani Nikmati Keuntungan Rp45 Juta per Hektare Bandar Lampung BSU 2026 Segera Disalurkan: Rp900 Ribu dan Analisis Pakar Terkait Tantangan Pekerja Bandar Lampung Optimisme Harga Singkong Lampung 2027: Bibit dan Pupuk Kunci Utama Bandar Lampung Krisis Asap dan Ribuan Titik Panas: WALHI Desak Audit Ekologis TNWK Bandar Lampung Polda Lampung Luncurkan Operasi Patuh Krakatau 2026: 702 Personel Siap Tingkatkan Disiplin Lalu Lintas Bandar Lampung Pembakaran Sampah Diduga Picu Kebakaran Lahan di Panjang Bandar Lampung Bandar Lampung Waspada Hujan Ringan: Prakiraan Cuaca Lampung Sepanjang 24 Oktober 2026 Bandar Lampung Penundaan Pembahasan APBD Lampung 2027: Berkas dan Data Terkini Jadi Kunci Bandar Lampung Fokus Pendidikan dan Ekonomi Desa, Lampung Matangkan APBD 2027 Bandar Lampung Polisi Hadir di Jalanan: Ratusan Makan Siang Gratis Eratkan Hubungan Warga Bandar Lampung

Modul:Chart

Wikimedia module

Bagikan:
Dokumentasi modulbuatsegarkan
Anda dapat membuat halaman dokumentasi untuk buat pada modul Scribunto ini.
Penyunting dapat melakukan uji coba pada halaman bak pasir (buat | cermin) dan kasus uji (buat) modul ini.
Subhalaman modul ini.
--[[
	keywords are used for languages: they are the names of the actual
	parameters of the template
]]
localkeywords={
barChart='bar chart',
pieChart='pie chart',
width='width',
height='height',
stack='stack',
colors='colors',
group='group',
xlegend='x legends',
yticks='y tick marks',
tooltip='tooltip',
accumulateTooltip='tooltip value accumulation',
links='links',
defcolor='default color',
scalePerGroup='scale per group',
unitsPrefix='units prefix',
unitsSuffix='units suffix',
groupNames='group names',
hideGroupLegends='hide group legends',
slices='slices',
slice='slice',
radius='radius',
percent='percent',
}-- here is what you want to translate
localdefColors=mw.loadData("Module:Chart/Default colors")
localhideGroupLegends
localfunctionnulOrWhitespace(s)
returnnotsormw.text.trim(s)==''
end
localfunctioncreateGroupList(tab,legends,cols)
if#legends>1andnothideGroupLegendsthen
table.insert(tab,mw.text.tag('div'))
locallist={}
localspanStyle="padding:0 1em;color:inherit;background-color:%s;border:1px solid %s;margin-right:1em;-webkit-print-color-adjust:exact;"
forgi=1,#legendsdo
localspan=mw.text.tag('span',{style=string.format(spanStyle,cols[gi],cols[gi])},' ')..' '..legends[gi]
table.insert(list,mw.text.tag('li',{},span))
end
table.insert(tab,
mw.text.tag('ul',
{style="list-style:none;column-width:12em;"},
table.concat(list,'\n')
)
)
table.insert(tab,'</div>')
end
end
localfunctionpieChart(frame)
localres,imslices,args={},{},frame.args
localradius
localvalues,colors,names,legends,links={},{},{},{},{}
localdelimiter=args.delimiteror':'
locallang=mw.getContentLanguage()
localfunctiongetArg(s,def,subst,with)
localresult=args[keywords[s]]ordefor''
ifsubstandwiththenresult=string.gsub(result,subst,with)end
returnresult
end
localfunctionanalyzeParams()
localfunctionaddSlice(i,slice)
localvalue,name,color,link=unpack(mw.text.split(slice,'%s*'..delimiter..'%s*'))
values[i]=tonumber(lang:parseFormattedNumber(value))
orerror(string.format('Slice %d: "%s", first item("%s") could not be parsed as a number',i,valueor'',slice))
colors[i]=notnulOrWhitespace(color)andcolorordefColors[i*2]
names[i]=nameor''
links[i]=link
end
radius=getArg('radius',150)
hideGroupLegends=notnulOrWhitespace(args[keywords.hideGroupLegends])
localslicesStr=getArg('slices')
localprefix=getArg('unitsPrefix','','_',' ')
localsuffix=getArg('unitsSuffix','','_',' ')
localpercent=args[keywords.percent]
localsum=0
locali=0
forsliceinstring.gmatch(slicesStror'',"%b()")do
i=i+1
addSlice(i,string.match(slice,'^%(%s*(.-)%s*%)$'))
end
fork,vinpairs(args)do
localind=string.match(k,'^'..keywords.slice..'%s+(%d+)$')
ifindthenaddSlice(tonumber(ind),v)end
end
for_,valinipairs(values)dosum=sum+valend
fori,valueinipairs(values)do
localaddprec=percentandstring.format(' (%0.1f%%)',value/sum*100)or''
legends[i]=string.format('%s: %s%s%s%s',names[i],prefix,lang:formatNum(value),suffix,addprec)
links[i]=mw.text.trim(links[i]orstring.format('[[#noSuchAnchor|%s]]',legends[i]))
end
end
localfunctionaddRes(...)
for_,vinpairs({...})do
table.insert(res,v)
end
end
localfunctioncreateImageMap()
addRes('{{#tag:imagemap|','File:Circle frame.svg{{!}}'..(radius*2)..'px')
addRes(unpack(imslices))
addRes('desc none','}}')
end
localfunctiondrawSlice(i,q,start)
localcolor=colors[i]
localangle=start*2*math.pi
localsin,cos=math.abs(math.sin(angle)),math.abs(math.cos(angle))
localwsin,wcos=sin*radius,cos*radius
locals1,s2,w1,w2,w3,w4,border
ifq==1then
border='left'
w1,w2,w3,w4=0,0,wsin,wcos
s1,s2='bottom','left'
elseifq==2then
border='bottom'
w1,w2,w3,w4=0,wcos,wsin,0
s1,s2='bottom','right'
elseifq==3then
border='right'
w1,w2,w3,w4=wsin,wcos,0,0
s1,s2='top','right'
else
border='top'
w1,w2,w3,w4=wsin,0,0,wcos
s1,s2='top','left'
end
localstyle=string.format('border:solid transparent;position:absolute;%s:%spx;%s:%spx;width:%spx;height:%spx',s1,radius,s2,radius,radius,radius)
ifstart<=(q-1)*0.25then
style=string.format('%s;border:0;background-color:%s',style,color)
else
style=string.format('%s;border-width:%spx %spx %spx %spx;border-%s-color:%s',style,w1,w2,w3,w4,border,color)
end
addRes(mw.text.tag('div',{style=style},''))
end
localfunctioncreateSlices()
localfunctioncoordsOfAngle(angle)
return(100+math.floor(100*math.cos(angle)))..' '..(100-math.floor(100*math.sin(angle)))
end
localsum,start=0,0
for_,valueinipairs(values)dosum=sum+valueend
fori,valueinipairs(values)do
localpoly={'poly 100 100'}
localstartC,endC=start/sum,(start+value)/sum
localstartQ,endQ=math.floor(startC*4+1),math.floor(endC*4+1)
forq=startQ,math.min(endQ,4)dodrawSlice(i,q,startC)end
forangle=startC*2*math.pi,endC*2*math.pi,0.02do
table.insert(poly,coordsOfAngle(angle))
end
table.insert(poly,coordsOfAngle(endC*2*math.pi)..' 100 100 '..links[i])
table.insert(imslices,table.concat(poly,' '))
start=start+values[i]
end
end
analyzeParams()
if#values==0thenerror("no slices found - can't draw pie chart")end
addRes(mw.text.tag('div',{class='chart noresize',style=string.format('margin-top:0.5em;max-width:%spx;',radius*2)}))
addRes(mw.text.tag('div',{style=string.format('position:relative;min-width:%spx;min-height:%spx;max-width:%spx;overflow:hidden;',radius*2,radius*2,radius*2)}))
createSlices()
addRes(mw.text.tag('div',{style=string.format('position:absolute;min-width:%spx;min-height:%spx;overflow:hidden;',radius*2,radius*2)}))
createImageMap()
addRes('</div>')-- close "position:relative" div that contains slices and imagemap.
addRes('</div>')-- close "position:relative" div that contains slices and imagemap.
createGroupList(res,legends,colors)-- legends
addRes('</div>')-- close containing div
returnframe:preprocess(table.concat(res,'\n'))
end
localfunctionbarChart(frame)
localres={}
localargs=frame.args-- can be changed to frame:getParent().args
localvalues,xlegends,colors,tooltips,yscales={},{},{},{},{}
localgroupNames,unitsSuffix,unitsPrefix,links={},{},{},{}
localwidth,height,yticks,stack,delimiter=500,350,-1,false,args.delimiteror':'
localchartWidth,chartHeight,defcolor,scalePerGroup,accumulateTooltip
localnumGroups,numValues
localscaleWidth
localfunctionvalidate()
localfunctionasGroups(name,tab,toDuplicate,emptyOK)
if#tab==0andnotemptyOKthen
error("must supply values for "..keywords[name])
end
if#tab==1andtoDuplicatethen
fori=2,numGroupsdotab[i]=tab[1]end
end
if#tab>0and#tab~=numGroupsthen
error(keywords[name]..' harus berisi jumlah item yang sama dengan jumlah grup, tetapi berisi '..#tab..' items and there are '..numGroups..' groups')
end
end
-- do all sorts of validation here, so we can assume all params are good from now on.
-- among other things, replace numerical values with mw.language:parseFormattedNumber() result
chartHeight=height-80
numGroups=#values
numValues=#values[1]
defcolor=defcoloror'blue'
colors[1]=colors[1]ordefcolor
scaleWidth=scalePerGroupand80*numGroupsor100
chartWidth=width-scaleWidth
asGroups('unitsPrefix',unitsPrefix,true,true)
asGroups('unitsSuffix',unitsSuffix,true,true)
asGroups('colors',colors,true,true)
asGroups('groupNames',groupNames,false,false)
ifstackandscalePerGroupthen
error(string.format('Illegal settings: %s and %s are incompatible.',keywords.stack,keywords.scalePerGroup))
end
forgi=2,numGroupsdo
if#values[gi]~=numValuesthenerror(keywords.group.." "..gi.." does not have same number of values as "..keywords.group.." 1")end
end
if#xlegends~=numValuesthenerror('Illegal number of '..keywords.xlegend..'. Seharusnya persis '..numValues..' bukan '..#xlegends)end
end
localfunctionextractParams()
localfunctiontestone(keyword,key,val,tab)
locali=keyword==keyand0orkey:match(keyword.."%s+(%d+)")
ifnotithenreturnend
i=tonumber(i)orerror("Expect numerical index for key "..keyword.." instead of '"..key.."'")
ifi>0thentab[i]={}end
forsinmw.text.gsplit(val,'%s*'..delimiter..'%s*')do
table.insert(i==0andtabortab[i],s)
end
returntrue
end
fork,vinpairs(args)do
ifk==keywords.widththen
width=tonumber(v)
ifnotwidthorwidth<200then
error('Nilai lebar tidak diperbolehkan (harus berupa angka, dan minimal 200): '..v)
end
elseifk==keywords.heightthen
height=tonumber(v)
ifnotheightorheight<200then
error('Nilai tinggi tidak diperbolehkan (harus berupa angka, dan minimal 200): '..v)
end
elseifk==keywords.stackthenstack=true
elseifk==keywords.yticksthenyticks=tonumber(v)or-1
elseifk==keywords.scalePerGroupthenscalePerGroup=true
elseifk==keywords.defcolorthendefcolor=v
elseifk==keywords.accumulateTooltipthenaccumulateTooltip=notnulOrWhitespace(v)
elseifk==keywords.hideGroupLegendsthenhideGroupLegends=notnulOrWhitespace(v)
else
forkeyword,tabinpairs({
group=values,
xlegend=xlegends,
colors=colors,
tooltip=tooltips,
unitsPrefix=unitsPrefix,
unitsSuffix=unitsSuffix,
groupNames=groupNames,
links=links,
})do
iftestone(keywords[keyword],k,v,tab)
thenbreak
end
end
end
end
end
localfunctionroundup(x)-- returns the next round number: eg., for 30 to 39.999 will return 40, for 3000 to 3999.99 wil return 4000. for 10 - 14.999 will return 15.
localordermag=10^math.floor(math.log10(x))
localnormalized=x/ordermag
localtop=normalized>=1.5and(math.floor(normalized+1))or1.5
returnordermag*top,top,ordermag
end
localfunctioncalcHeightLimits()-- if limits were passed by user, use them, otherwise calculate. for "stack" there's only one limet.
ifstackthen
localsums={}
for_,groupinpairs(values)do
fori,valinipairs(group)dosums[i]=(sums[i]or0)+valend
end
localsum=math.max(unpack(sums))
fori=1,#valuesdoyscales[i]=sumend
else
fori,groupinipairs(values)doyscales[i]=math.max(unpack(group))end
end
fori,scaleinipairs(yscales)doyscales[i]=roundup(scale*0.9999)end
ifnotscalePerGroupthenfori=1,#valuesdoyscales[i]=math.max(unpack(yscales))endend
end
localfunctiontooltip(gi,i,val)
iftooltipsandtooltips[gi]andnotnulOrWhitespace(tooltips[gi][i])thenreturntooltips[gi][i],trueend
localgroupName=mw.text.killMarkers(notnulOrWhitespace(groupNames[gi])andgroupNames[gi]..': 'or'')
localprefix=unitsPrefix[gi]orunitsPrefix[1]or''
localsuffix=unitsSuffix[gi]orunitsSuffix[1]or''
returnstring.gsub(groupName..prefix..mw.getContentLanguage():formatNum(tonumber(val)or0)..suffix,'_',' '),false
end
localfunctioncalcHeights(gi,i,val)
localbarHeight=math.max(2,math.floor(val/yscales[gi]*chartHeight+0.5))-- add half to make it "round" instead of "trunc", min height to 2 to avoid negative bar sizes
localtop,base=chartHeight-barHeight,0
ifstackthen
forj=1,gi-1do
iftonumber(values[j][i])>0then
base=base+math.max(2,math.floor(values[j][i]/yscales[gi]*chartHeight+0.5))-- sum the "i" value of all the groups below our group, gi, and keep the same calculation for each bar
end
end
end
returnbarHeight,top-base
end
localfunctiongroupBounds(i)
localsetWidth=math.floor(chartWidth/numValues)
localsetOffset=(i-1)*setWidth
returnsetOffset,setWidth
end
localfunctioncalcx(gi,i)
localsetOffset,setWidth=groupBounds(i)
ifstackornumGroups==1then
localbarWidth=math.min(38,math.floor(0.8*setWidth))
returnsetOffset+(setWidth-barWidth)/2,barWidth
end
setWidth=0.85*setWidth
localbarWidth=math.floor(0.75*setWidth/numGroups)
localleft=setOffset+math.floor((gi-1)/numGroups*setWidth)
returnleft,barWidth
end
localfunctiondrawbar(gi,i,val,ttval)
ifval=='0'thenreturnend-- do not show single line (borders....) if value is 0, or rather, '0'. see talkpage
localcolor,tooltip,custom=colors[gi]ordefcoloror'blue',tooltip(gi,i,ttvalorval)
localleft,barWidth=calcx(gi,i)
localbarHeight,top=calcHeights(gi,i,val)
-- borders so it shows up when printing
localstyle=string.format("position:absolute;left:%spx;top:%spx;height:%spx;min-width:%spx;max-width:%spx;color:inherit;background-color:%s;-webkit-print-color-adjust:exact;border:1px solid %s;border-bottom:none;overflow:hidden;",
left,top,barHeight-1,barWidth-2,barWidth-2,color,color)
locallink=links[gi]andlinks[gi][i]or''
localimg=notnulOrWhitespace(link)andstring.format('[[Berkas:Transparent.png|1000px|link=%s|%s]]',link,customandtooltipor'')or''
table.insert(res,mw.text.tag('div',{style=style,title=tooltip,},img))
end
localfunctiondrawYScale()
localfunctiondrawSingle(gi,color,width,yticks,single)
localyscale=yscales[gi]
local_,top,ordermag=roundup(yscale*0.999)
localnumnotches=yticks>=0andyticksor
(top<=1.5andtop*4
ortop<4andtop*2
ortop)
localvalStyleStr=
singleand'position:absolute;height=20px;text-align:right;vertical-align:middle;width:%spx;top:%spx;padding:0 2px'
or'position:absolute;height=20px;text-align:right;vertical-align:middle;width:%spx;top:%spx;left:3px;background-color:%s;color:white;font-weight:bold;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000;padding:0 2px'
localnotchStyleStr='position:absolute;height=1px;min-width:5px;top:%spx;left:%spx;border:1px solid %s;'
fori=1,numnotchesdo
localval=i/numnotches*yscale
localy=chartHeight-calcHeights(gi,1,val)
localdiv=mw.text.tag('div',{style=string.format(valStyleStr,width-10,y-10,color)},mw.getContentLanguage():formatNum(tonumber(val)or0))
table.insert(res,div)
div=mw.text.tag('div',{style=string.format(notchStyleStr,y,width-4,color)},'')
table.insert(res,div)
end
end
ifscalePerGroupthen
localcolWidth=80
localcolStyle="position:absolute;height:%spx;min-width:%spx;left:%spx;border-right:1px solid %s;color:%s"
forgi=1,numGroupsdo
localleft=(gi-1)*colWidth
localcolor=colors[gi]ordefcolor
table.insert(res,mw.text.tag('div',{style=string.format(colStyle,chartHeight,colWidth,left,color,color)}))
drawSingle(gi,color,colWidth,yticks)
table.insert(res,'</div>')
end
else
drawSingle(1,'black',scaleWidth,yticks,true)
end
end
localfunctiondrawXlegends()
localsetOffset,setWidth
locallegendDivStyleFormat="position:absolute;left:%spx;top:10px;min-width:%spx;max-width:%spx;text-align:center;vertical-align:top;"
localtickDivstyleFormat="position:absolute;left:%spx;height:10px;width:1px;border-left:1px solid black;"
fori=1,numValuesdo
ifnotnulOrWhitespace(xlegends[i])then
setOffset,setWidth=groupBounds(i)
-- setWidth = 0.85 * setWidth
table.insert(res,mw.text.tag('div',{style=string.format(legendDivStyleFormat,setOffset+1,setWidth-2,setWidth-2)},xlegends[i]or''))
table.insert(res,mw.text.tag('div',{style=string.format(tickDivstyleFormat,setOffset+setWidth/2)},''))
end
end
end
localfunctiondrawChart()
table.insert(res,mw.text.tag('div',{class='chart noresize',style=string.format('padding-top:10px;margin-top:1em;max-width:%spx;',width)}))
table.insert(res,mw.text.tag('div',{style=string.format("position:relative;min-height:%spx;min-width:%spx;max-width:%spx;",height,width,width)}))
table.insert(res,mw.text.tag('div',{style=string.format("float:right;position:relative;min-height:%spx;min-width:%spx;max-width:%spx;border-left:1px black solid;border-bottom:1px black solid;",chartHeight,chartWidth,chartWidth)}))
localacum=stackandaccumulateTooltipand{}
forgi,groupinpairs(values)do
fori,valinipairs(group)do
ifacumthenacum[i]=(acum[i]or0)+valend
drawbar(gi,i,val,acumandacum[i])
end
end
table.insert(res,'</div>')
table.insert(res,mw.text.tag('div',{style=string.format("position:absolute;height:%spx;min-width:%spx;max-width:%spx;",chartHeight,scaleWidth,scaleWidth,scaleWidth)}))
drawYScale()
table.insert(res,'</div>')
table.insert(res,mw.text.tag('div',{style=string.format("position:absolute;top:%spx;left:%spx;width:%spx;",chartHeight,scaleWidth,chartWidth)}))
drawXlegends()
table.insert(res,'</div>')
table.insert(res,'</div>')
createGroupList(res,groupNames,colors)
table.insert(res,'</div>')
end
extractParams()
validate()
calcHeightLimits()
drawChart()
returntable.concat(res,"\n")
end
return{
['bar-chart']=barChart,
[keywords.barChart]=barChart,
[keywords.pieChart]=pieChart,
}
Konten disalin dari Wikipedia Bahasa Indonesia (lisensi CC BY-SA) Lihat versi asli di Wikipedia

Rekomendasi Pilihan