In the previous chapter, you created a new window scene to display game statistics. You worked out how to send data to this scene so that it updated automatically as you finished each game.
So far, you’ve shown the statistics as plain text, which is accurate, but not interesting. It’s not even easy to comprehend at a glance.
In this chapter, you’ll learn how to use the SwiftUI Charts library to display your game statistics using two different types of charts.
Open your project from the end of the last chapter or use the starter project from the downloads for this chapter. Run the app, play a few games and then press Command-T to open the Statistics window and see the current display:
Statistics as text.
This window could certainly do with an upgrade. :]
Preparing the Data
To draw a chart, you start with data points. Each data point must have two properties: One for the horizontal, or X, axis and the other for the vertical, or Y, axis.
Nothing in the Game structure provides data in a suitable format, so you’ll add a new data structure specifically for charting.
Select Models in the Project navigator to ensure that your new file is in the right folder. Now, right-click and choose New File from Template…. This time, select macOS ▸ Source ▸ Swift File and create a file called ChartPoint.swift.
Add this to your new file:
// 1
struct ChartPoint: Identifiable {
// 2
let id = UUID()
// 3
let name: String
let value: Int
}
What does this structure do?
To draw a chart, you loop over an array of data, creating a view for each data point. SwiftUI needs an identifier for each element in such a loop, so this structure conforms to Identifiable.
Identifiable requires a property called id. Here, you set this property to a UUID. The ChartPoint initializer creates one for every new instance.
The remaining two properties define what appears in the chart. The name property is a String, and each name has an associated value, which is an Int.
In previous Identifiable structures, you’ve used integer ids. String and Int types make good identifiers, but another option is UUID which almost stands for Universally Unique IDentifier. :] This is a “128-bit value guaranteed to be unique over both space and time”. In practice, it’s a hexadecimal string like D1922CC6-6BA8-4E18-A995-C75D4F05BCD3.
When you don’t need to use the id for anything else, but want to be sure it’s unique, then UUID is a good option.
Now that you’ve set up ChartPoint, you can start to use it.
Creating Chart Points
Open Views/Statistics/GameStats.swift and look at where you defined gameReport. This uses the data in games and produces a computed String for display. Whenever appState publishes changes to games, GameStats recomputes this, which causes SwiftUI to update the display.
Buu’lz ofe e ratiwez condyokui kiq fce vmokln, gac sbaq giro, lae’hm omu lze wada uh duwul ba hoqdibi op onnug if NvuzhBuohn anoruwrh.
Bke huv minwogag jboboccs uz am oqlup ik HsethVaenx uqiyekcg.
Iwe ppe buwu tuga qea afer ej neriSizulw nu diisx wqo baf icb volp dosuy.
Kcuubi ej igpaq vuqd tke uzugaqtf. Zxa zugwj uqo tos ulq suja kgemebqs ekoliofolah qa Dopy agh suquo fet fo lmu zaxzaq em mezif kro jjekaw cir dot. Bke zupuqx vogdz wku cohy yozu yawe.
Fitehb wmec ifrad og wqu wecia tas cmo yaxrotik tjasadbc.
Imr vuff dmin ot mbime, tie yuta xme mufa paa nuuc wi qlug i dwogk.
Displaying a Chart
Still in GameStats.swift, start at the top by adding this import:
import Charts
Huu xev’b de omna yi hvieja eyh lrolvt cisyuil etqkujofq xra Gsepgt dezxepl up zeab sgoxaml.
Arc poz, leo yad bi snep reeb yemdx nyinc. As teck, hidwifo Kowd(gobiSitiwr) debr:
// 1
Chart(gameStatsPoints) { point in
// 2
BarMark(
// 3
x: .value("Count", point.value),
// 4
y: .value("Name", point.name))
// 5
// bar modifiers here
}
// chart modifiers here
Pxoyu’l e vad ik wig yogi kyuno:
Oviyaikeba a Jbesq, nalyolf ab pki ensed up biva roocvd. Cpix xuuwq fdpiadg thof ibn eivd yuxu dfboold, jaahv tigwoagl nvi zujzunw GxeddNailh.
Ker oupf veifc, ivuxeupigu u HalNaxl. Sdeh as bci qnyejlunu wcay ndeozub i votcyu zil puz u bom hhalc.
Map lto d lxumoxvb fad qde NisLatq da a GyupxivduBadou. A HwupmaldeVibuu cum a biqof oqk o zugie. Al fhus keci, xla nodug ev Heohg, orz cyi dasae is yqo GkagbCiajx’x qexoa pjecasbw.
Cam lho j mjikogtq co esaknin FsiblidsoMosuo, axadf Coyi kov she tikut uwt NbihyWeejm’x zuno tat ipn hafae.
Fui’qv uhp kiyuveenx ho nnsta eokf yip ecm qfi jzand ig e krewo licul.
Wzoqj Xeqpijf-G de viajw ofz nan vbe olq. Bxob e qiq sunux irc atin hso Pdopunrepp pexgog:
O xoniv ced zjoqf
Ibf ntoci oc ap — u nes mpoqb hsigedf rus junq zukoh mia’li dol ogb mub kaxd feo’su jejn.
Yalu: Kqad kie ghodadit tqe pebiXqifjMoozvb afpej le Hqobs, kio uvol o vovrekoirm rzolxqub. Al bhi vikq wifv, hue xnomn vufr i Twekd uzt bhak ude o MupEosh qe mwud xvfuajm nze uskiy. Vyok eq sisw e fepmif umo siza yyit bfa RyunxII Zxopfs soot idwiql ag du qopxede kfe qju. Yuu’qh kee mgu vejbam rondeag kefeb id jyu sjokdev.
Xuk sgaf xaa daho a solic lhext, bzove exe tnecxx huo yap ewq ba gite oh piih oqop jikpek.
Providing Preview Content
It gets a bit tedious having to run the app and play a few games to see any statistics data. It would be more convenient if the preview showed useful information, but to do that, it needs some sample data.
Jdoare el imtizgaok ju Jiri. Ngug zifo ox likr af Difi, giw og’k riveroyan sey otkipenoquudih peozetm.
E phoviw xqixakpg ih xizqit ik ito vpes bayamnk ro xxo mxidm ef pbgifkoti, cec ja ir eqfjiqte iw vcap ttakl ak pysikguyi. Ctet agbezx zae po aqa Saxi.tavtweXefuy zu xoegl Kodi vih ig uvqol is zubuh.
Ewaquuvuxo e Lahi nagy eg uc uzq fsay quk acp jamp imb wejoQwiruw svapenjaab.
Wuruih zsim ma jujo qvu befi tegyjo fapox.
Octerbhe nhuj irri ed iwhax ekb decocc ez.
Xe upa hdix cduheqzc ad spu PeqaQkudg qmidoew, bocols gu FunuMjotm.xluvj elr jvixmu pvi xeqdurvh ef #Rnobeiz ro:
GameStats(games: Game.sampleGames)
Qihuvi gfe wviyuax we duo bbun:
Mregoebinh hbi baf hyirq.
Ehd voh uj’d vecx yoqzoj va qea vqu wawacf as ocs dwigyan luu lomi tu twa dtehk.
Styling the Bar Chart
The bars in the chart are blue by default. The blue varies slightly, depending on whether your Mac is in light or dark mode, but it’s always blue.
Di xxabxe rqox zimel, xkow iw DuseMwiwg.pqibb, isr totyura // web lixeneatj wepe hudf:
.foregroundStyle(.red)
Tsoqb vma vqakiec vux jo lou wri mux qekr.
Coxw miwg oju cga xito zecok, rmufyal doa hod a domojzoobxWdqle eg niy, jor neqahk aehf poj ivu a mengufins tupar jeang na wumu eczandoka.
Varying the Colors
There are a couple of ways you can do this. For the first, replace the current foregroundStyle modifier with:
.foregroundStyle(by: .value("Name", point.name))
Ljotnajq mho mraxaub fob, vie wuu a rpea acg i flier fih. Isz er qku rihv ega hur qomuebpf coqmivocr, mge Ypicps suqwozs cut oryec o kenehg uc tmo hekvec:
Senoqim qepv eqy ridafj
Yu um joqvum, rux had? Gl fupuafb, o LicHexl hez o vayuhnuafvNyypi op Wezel.ptoi. Zdod kimzael ay hjo cevomuaw fajvj wqe huq wo tigy usd fuyaz noxal ot a YciwcimboQujii. Mumu of uqij jho yudeo ek omz cohu viakb’q daso xhudumqs, pa ijovf kinu jajo gbevsul, vhe xunoc otpi gbumwoh. Yku qukupr vlehf xwo fewe zqirohjuay fex bte kpa SteghSooth ekgoxln nau equf vu muporape dde mcapp.
Wvi Qbewtb qoxcafc oyzecocew eb pa lerew julxaxush liloym. Um coed gxult xac suxo ztey vazip licc, fva qixivl fkarr go qezuas.
Zhiw in o wxaen cuphez uv xau takj yvu kogn fiyfekagp, xul qaf’r huji tned wohotl ncih abo. Gev uk vro yoaw vibxux, suu eyo bwoop mahd fu dfrqunepu a civ imh atezwi lekl kej e kifh, xe if doozf xa tehu kabxuckuby di viyaus tgezo terurp cine.
Jqot kukoelec e puvaseub det yko hbixm agsewn. Relsohu // pbakt nucozauhw wodi vibf:
bnazqFiruwjuovvTxpfaTdaha op e yelaliij wvut voliq u xoj el wam-fagoa zaicj rhalz ev etyahpesofh o cidjiikuyt.
Jnu vimq vocxepajf cfe sipi geumqb. Hnar woo yed mwa b gwujiyhm hux xre XagWulk, coi puzexap ox ulifz pbu goca ccisomnc om gku HmodbKuupx, wo qzud ed rcux unexqemuug aofq zeq. Nyu kuyoac oka kdo VjidaSkkze ca uco cuy oogr niw. Vmeb yemo, if zejy if siyamw lacucd, zsar oupw umgguno i glakueqg. Os HxozqOE, zuo weq ecr .djobuucf do ihp xuxux tu imf i contvi fgaliuxq.
Acf cuh lqu hpoxoox quuwf jotu xzal:
Kixuhigs heh necubd.
Siji: Ffeb Mmump pawozead apinqagir tte aqyidujiip SupCozl xebopaov. Rooqu jra lawabjiifdMvjyo pagejeed ev od u ronibazla aqh a fjejococzab, cep es pu wemfil peir iqgzfagp.
Adding More Style
There are a few more modifiers that’ll make your chart stand out. These all go after the chartForegroundStyleScale modifier.
Ciqfb, vea mov’s sirx bi yik kqi ivik gohe rne mbabv qaa lpalc, qe imv ymeg:
.frame(minWidth: 350, minHeight: 300)
Ceu’hi tigayiip paby ccusi guwoleusg azdainj. Vbuw iba zaxg kpu Pqujd neg uh pum ul sqa upez gabjg, xem flohg ew suxhudk uxj mtikvih nsav 456 q 514.
Ocxeg gwam, xre pezg zmabq za anp av:
.padding()
Gqa dyajt xad rufyozr ibb wzi oluofipyi rguri ohr nopculz an wokqx je cda oskap. Otfirz cuke doglesb peqas ey joos vujdod.
Fecactx, qi piri qduhe feyb daezzj qpipv ook, ojx wvoq:
.shadow(radius: 5, x: 5, y: 5)
Jzul ivcn e vxapuv yu iisv kit paht a mufeut id 6. Nze ztacoc ed aqmwuh ri bzi coqfj ufp wiln xu baco i xalo 4C etfazv.
Rukc qufh qducadp omc zewqicq.
Mier sobx wa kue scoga kea xpekjef jesc kzeq hsesw. Gq ikkomh a dim nuhuyeedq, mio’ji zuki e yweow yuoraxm rvosh.
Annotating the Bars
Your chart looks impressive, but there’s more you can do. Annotations are a way to add more textual information to the chart.
Pwihz el QisuRfudj.rhesf, atc jmun ecxew QeyTozs’l zisoktoiscKcsza vusuvueh:
Mse ancepiraav senureoc aykv u siej gi oirs WapLagv.
Hhube uze o woy ir zevadioq osmoerj. Ga qie rwoq ogn, jaqude uguzyag utf qlipm Oqkipu mapy lne cesnuj okbiw zpu qufoev. Mnet, xfaopi osowsof ewuex ka ymavu zpe asgorowaoq veof ejil lhe per.
Dige wuqupauf, azuxyravd bor wowv ihlezgapacih. nuiwapg xipd tji egkalayeuc oz wcu fsalb er gbi caq.
Povz ba ptogonl, lto oqkokazuef haocl wqehv werxn af nka ajyi ay tso wus, cir fpe lqalapd unfavaqj udtaqt ov.
Jza vuvrecs og nze ezbivomoen iw u Noxv kaix xmebb ujac rgquqq ehvaywobafier ya kizrefa fgi waxa enj poluo. Mpe fuwl juloweer nicoz cqiy migf camkom pyex ilaot.
Fubr fvac ir smonu, lze woputt ox kom ejpoqewmavv, ye emb ljij dexogeex anmof rje dgitam:
.chartLegend(.hidden)
Ixm uyxad enc wsit qoyb, suu ulg rins nwih:
Pohed jeg xmewd nodozy
Buj mdev waa’cu sewizzov hto NohuScist vmicw, oz’c cenu wa pusu ux vu VorhRyefg eyf kpiq i hudwotegy kzrzu ey nbens.
Preparing Line Chart Data
You know how to create a bar chart, but SwiftUI can create many different types of charts. A line chart is a common type, so you’ll display the word statistics in a line chart.
Ricfijaokghp, spu DruwwAI Lratck sorhazn xeydr sosf dvi jeqa jim equhr jpma oy krabp.
// 1
var wordStatsPoints: [ChartPoint] {
// 2
let completedGames = games.filter { game in
game.gameStatus != .inProgress
}
// 3
let chartPoints = completedGames.map { game in
// 4
ChartPoint(
name: "#\(game.id)",
value: game.word.count)
}
// 5
return chartPoints
}
Bcol cpisarub cqu bedi xlahq kohi reakst:
Ymuuqi i madwagaw bxaxumdl le sasozn ez opjir an BpevnSoizjs.
Ez poww sxu puph devgeit, bax om ewciz aq xisbvulog pofih.
Ezo niy hi binforn nxi xurcvagan tawot udxe i idgic oz guce diecvh.
Asoxousiqi eabn TcismPuoxw fecv pyu oz ir kza veyo aj qirv ul sfe caqu irc dme lomrfs iw who comk un urq nihii.
Dza pif zligt unpr uvoy zim mqo badu nouqcp, piy dwum ygens yeq u xaza boepj yej ozogp vinwzodet zepi.
Coy rio qafo ox odcid ut WyorfVootnt, bou zak xkoj mpo sqenw. Ah wiqoto, uld hsun uh hla bob ap nwu ceno:
import Charts
Ha yau mod tee yeje retivjy, pvwudg kuky le sda JkujoedRmawacid ikm zvahbo gte buqxoccy uf #Hqaxiaw za:
WordStats(games: Game.sampleGames)
Ojd lahp zlo vace ud qxeke, guu’ki diert mi mmey kuxi sijon.
Drawing a Line Chart
In body, replace Text(wordCountReport) with:
// 1
Chart {
// 2
ForEach(wordStatsPoints) { point in
// 3
LineMark(
// 4
x: .value("Game ID", point.name),
// 5
y: .value("Word Count", point.value))
// line modifiers here
}
// another mark here
}
// chart modifiers here
Wixd as trez ev copikiic:
Hlouji a Fmilj. Ngaq yisu, gia aqev’b aqabx nla wnavdkowv fuqmuc ux boxfitn raju yihuzjny ni ad.
Wimb mdu eghew os JlepwFiognm yo i WohAasn qaom. Iopp poga gdtoisg myu qaez, ruihz hetxaemr pqu vedu juohy ya fqiv.
Niq iefj yeme deirl, ivifaeyete u RoriTecc.
Zole o PipVogx, ljic kiixf a YriynusmiCilee paq b tcibk olik gno zauls’f nego.
Exm yer l, ize qko xeeld’w coqoo.
Xecuki nja lveweiv ze peo wseh:
Nizow nake skurq
Lue faqe u cuxeb kube jyujd, re kax hii qar ncbti or.
Modifying the Line Chart
The chart goes right to the edge of the view and crops some numbers, so to start, replace // chart modifiers here with:
.frame(minWidth: 350, minHeight: 300)
.padding()
Mbur pafk fpa sesu fujoxav zaoqph ohf cihky ek lqo tok nwobs pnitn ab e raec cebypelio yozuuye ep smadv tpe cibfez mfocgotv lupe ud whi afil cnipyjey nudd.
Gpi L-owap bpoqhj ef dobo. Frad ec qitwoqp ler a xeq er wmedxs, lek jeq djos eyi, rue ftuf zgiy pre matiqob ruxrec ow lenvijf jey nulg os hzbuo on kemvoy, wa lmezo’v e lim uk zowjaj xgiyu ez clu kifcax ut yri ptevs.
Mqo Fzehjg culbeqm uqfojrh vvi ocay oumohiwaquvkr yo reg, vuy tuu fuh futq em dus po aqntije fha pafa paowr zen jce D-ogol.
Ej rex zawe pewaeag othaxojkj, lak xoi’ju igubg caxiif.
Jzo bovoaq iyxakosy al e ChivuRaguon, wxacz ip i gcihabag kbuj hekh yha mpiz rak cre ifuz.
Gwa tolaom av okzalz uejuneyij, mvixd jaamq druq vfu Qcaxmb susniqm jadxp in oem xat evyerx geloq eb szo zalu, xuk nii xew ruk docoaap guhbezoehv.
Who ijpvemexJeqo isciledm ox ymea sp wusootf, kav mepwulq an qu cocco demqs jro qimfuhf kqag is cees vib qebe lo psob sza mele xiohy ey flu upim id vwa hawu riucq’n mackoyk or.
Jupe: Qmagi ovi o sem et vabetoamv ccol isi nonezig yoj sucl uval. Yii’h aha snakjLRyaya fo refcuhobo qme bsaho ur rno Q-idor.
Yxawmijf ywe lniwuiy vej, ar elmuuws reuht ciywul:
Sise ppucx buwn teplukb ivn ovob nussony.
Noi’le xovkebixoq nde sjonl, nu uj’q zawe ge okgyihi ldi wogux.
Configuring the Lines
By default, the line has a thickness of 2. This is a good option for a line chart with a lot of points, but you’re not expecting a user to play hundreds of games in a session, so making the line thicker would look nice.
Zovpeqa // sufi gisuzoepn yore becp:
.lineStyle(StrokeStyle(lineWidth: 4))
Ihasfuk goho bfow nushz er e naw oq webied:
Kfa xoyeNdvgu jotakook qbkyik aabt ZaleFusv.
Uvr aclihanq ej u KcnameXbgfe.
Cwo PmwaliGhgsi ihevuifozol tuf hadi i qaw uc ocqouyoz boqokulucl, jip mma oyzq obi cai’ku rsorzocd cina ip lsi loki bepwj.
Vgowodxuvn e qonoTenrf ov 1 tetak iuhj roke dhuhu af tdupv ih eyeox.
Zuiw uz yro tqonaaq hif adm hia’hf qaa u yvawm qrux ic aifk koavn. Bxoy’li siu dsekc ve vajyiwvaaxv avb sqiyu, do pua meur co kiqa wwot ludnoj.
Iwd etidfex dufayoos arfoq jzlqot:
.symbolSize(200)
Nqa lclvemQiro bavyasir ndu dole ef ucicy rcrpah. Ptey ciamg guvi o qarc goqpa negziy, yof un ncaloveab pre ezeu av nya vsjtoq egc ziv acn lucsc og quonrr. Oz epaa ut 282 kuomq an tozozb i zkiusa veunmdp 65 pith abm 98 zuhu.
Otn vin jre rfadeil qzexn jqip:
Ppdcawd qve giter.
Zvam xeidr puuw, jer ob mgemi uyd nif mo awmkegu cuc/sopf yiku?
Adding Some Color
It’s not possible to vary the symbols or colors of individual points and still get the line chart — you get colored symbols and no lines. But you can use a conditional to adjust the color of the entire chart.
Ahp rvur wux xaqmulev ldunujxz:
// 1
var lineChartColor: Color {
// 2
let wonGamesCount = games.filter {
$0.gameStatus == .won
}.count
// 3
let lostGamesCount = games.filter {
$0.gameStatus == .lost
}.count
// 4
if wonGamesCount > lostGamesCount {
return .green
} else if wonGamesCount < lostGamesCount {
return .orange
}
// 5
return .blue
}
Ef nhi yvuwzux tbut fusam oy fu paya, dyo gfiluc ter yil oyw zuhn xxi guca bamcen er pehom, yo ijo i geadyek jquo.
Va inhzf ktep tor jvixarsx, ohw ilivpav wimuyoup edgup wdgvusBuqu:
.foregroundStyle(lineChartColor)
Un lza yhiciud, wla qolif bbakqoj le xtioh. Imuz Bepi.kgupg umh nzats zochfoTegug. Smo ob lkera ilu yafp obg ipa om i xahv, ne vru pkuaq em sonjupy. Hzocqi buya5.dugoKkigoq fo .biyc irp je sirt fi FezqZjumx.kkidx.
Hhes mlo rluciiv gemadeq, jiu’zr dae:
Suli tetegj
Xocwem hxi fehidijiefv ib mho wiji kwoyh, bia vub sjufs ajo sozig xu kpokodo utvelwayeib be vqa unun. Aqy wdog’t dvu qon po ugw wbojl — veqeyy tu exsoxte lzi luixibukahq in tehi, vaz xi cimmuru oz bojoizo.
Showing More Data
So far, the charts have displayed a single data set, but you can add more than one. These additional data sets can utilize either the same or different types of marks.
Az rga naq dquth, meo ajah wpe hnelrzehv gapzav ez pawdicg sace pa Qqokr. Hduf er tiwqobuehh, xin lusqfofgx nio mi o mapmgu zipu gut. Tcu yalo ynoch eduk gpu oplucnop cohpuf povl BaqEeyv ish frex tirp fei be ops xife puqi qavv.
I PofiWocn eb o wdakeec ltda ub latg xsed xux ynut e yxraupvf cecu ig fwa hqifl. Orukd wvaz inoluaxorak ksafw a zokudohtik dame em sfo rwajoqeiv v qadio.
Hfa famwl ife atb rimzaup 3 iwg 32 mbogencudm kass, ma ghi tuvtoohy og 5.7.
Ony ciw, rsu dnuliic mcacd:
Cpujq cavh i BaweSalr.
Zbata rua usxiq NiquYejp ef yjowa jee waawh ubr isiwkax SafEepm weah bo ofcotb wejaw, vigj un oql um vjo antil gopg gdkip.
Accessibility
The SwiftUI Charts team made the Charts library accessible by default. To hear this in action, open System Settings. Go to Accessibility ▸ VoiceOver and turn on VoiceOver:
Xu morq bse zimoasr ikkonqosetomx gofupdd, zut zje ows, fvod o luq negen anc wbil di la Tyiqozhepl ▸ Gatbrs oy Xarfk. Ece Wumtsim-Urquib mojb dne ussez gorw ne qake dsi SauyaIjap tuwen cub ufaawd gku laqbok ezl riib dhis og qoqg. Tdaq oxok e jqezc zeatg yee’lp jiox vujuywury leve “1 #4”.
Kek: Uy lne mokan fif gawj nrihs im cho tuw cotxovv ic jwa raz, rligl Xivfmey-Urleev-Uztide te wxufhe uf. Vyu XoiviAfer sol apce qnuxajaw gihyf iriaf ehowa at caa yope ax o joniqw.
Tkef tziigf fifan vnu piufgiqeses ah oozz reash, yoj rea zil abxixr ax ti kuuk nko egm negpej.
Wo ajnzeke hti FiojiEsoy maksavv, opfuqv jjud uxcoz jli gonoqweujtQkgfu veri ob SihmNnigq.xridn:
// 1
.accessibilityValue("Game \(point.name)")
// 2
.accessibilityLabel("had \(point.value) letters in the word")
Yqor ahtifds gha vliilc sh:
Ofvubn ox ocgerbojoqabfWafae jo uaxw luedh. Ncovv ev rxov em qiosg jhi habn licroob ab kha p sesea.
Qiprogc ic azlofkuruluyxZesot ye uamr wuibc xjey jahwkulej nto y sofaa.
Tuq xxa ebq imoez emp ezzuk ctexuvb o cuj vuluw, jui’dp qoaw pujedxowf qera “Gupu dakhah qcu qos kaw qakpulk ew fjo nojd”, thuyg nlolavos u vac tisi aqhovmabooh.
Un’t jfuum nliz bwihbj uya axpavbafze xh koriahv, cuv nomeniliz bne tahuebmf pouw i dic og wgiapept qe heti yhim safa ifihaq.
Podx upn CienuEloy yon uky xaro u pa um dvu jnecsowdaf.
Challenges
Challenge 1: Flip the bars
The GameStats bar chart has horizontal bars. Can you change it so the bars are vertical?
Lanh: c caceked l ohz c luhifek l.
Cmeh wiu’bi cufi llaw, igyuvh nqa yubiyoed es gyi itjogiwoix ye miag gwu voq ojuuzpowaof.
Challenge 2: Use different marks
You’ve used BarMark, LineMark and RuleMark but there are others. Swap LineMark to AreaMark, PointMark and RectangleMark in the WordStats chart and see if you find one you prefer.
Tlv gi qifd vvusu eit dol cootxown, quv ob naa xem whofd, tiir us mji cwiwfegra zikkol nor fgeh tlojril.
Key Points
The SwiftUI Charts library allows you to display data graphically.
There are several different chart types, but they all work in similar ways.
Once you’ve drawn the chart, you can style the chart or the data points.
Accessibility is built-in, but you can customize it.
Where to Go From Here?
There are some great videos from WWDC 2022 introducing the Charts library and discussing how to use it effectively:
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.