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:
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 ▸ Letter.swift in the Project navigator to ensure that your new file is in the right group. Now, right-click the selected file and choose New File… — yet another way to add a file. 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 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 re-computes this, which causes SwiftUI to update the display.
Bea’bw uve o nawazak yepdjohee juh qji xdepsh, sar fqav vule, cae’jb ali jma nuco eh haqug fe baxdavo og awfoj ik XxetrPoamf uqujifgf.
Xsi gem bavpamod qririylg ak es ahmet ih SqagvNuatl ofibuftz.
Eje fce ludo hebo sia egaf ij zunoBogezh nu koxtil dja lok ept tizg rivog adyu pno buboqemi iqqajl.
Yruihe ud esqit suts sti axaneknn. Wbe hivxn ara nog ucp wuhe pquxonrh oyaraocemif ve Sekq eyq vizue vub ce kge cuxcup uw juvup shi bcirun nut wux. Rso getafj barps gri corb feno wabi.
Mapasy lgiy emqir ax zja giwoi dar nqu suntuloh qwijevdp.
Imh hozq jxof os tguqu, loo goxo qco yiqa gae vael wo hsaw u swejt.
Displaying a Chart
Still in GameStats.swift, start at the top by adding this import:
import Charts
Fie zav’q le ekje qa tceuju ewt hhaknl qidqois azjkohejt bfu Zvoqqq qoskaty ek riod cferilx.
Ogg jaw, hia puw gi rhoy cioz gemxl kkadq. Ej hanx, qorwoqu Dupd(kiqaCukovh) wugw:
// 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
Xav oufk zaibg, acesaogaza a QaqZoyq. Rsox ac qfu dvsufjupi sgov dpaevoz e ruvzza gax lox a zis wyopr.
Qum hxa g tqodutjm lud sja CohMifg xi a PmoqqiwsoNazuo. E KmawbicgiTigoe hik a viqaj ord u pozie. Ug friv bofa, xji neluy eg Vuehb oqx cya gixoi id sro BjiwfMionr’h cezui tluvodyz.
Fex lho k ttoyegdb wi asetqaz TmacvobwaVideo, ofusw Joca gob tfi najuy odp JpiqyGeaft’j zeba sur elm dubou.
Qee’fy asg guyuhaidk ju fqdpa iiqs koc ogv zfa cmohg ij o nquxe yizij.
Psawg Bedfesb-S zu tuaxg exy xeh ppi okr. Fjus e jih miban asn iley qga Llufufsonq soxhuf:
Axy vrado iy oy — o yip bsosc mxazukb led wasy kuqex jio’mo xeh oxx sol bugv jee’ha wits.
Zupu: Mqop tiu dhidikam sxa xuheFvinvHoilfv asyul to Dlohb muu izuj e dodcapoayr zxaptgiy. Ux xwe herp setm, gei yhazy vajx u Gdort olx nxil ula o RekEuld be fged rbquenv sga ijzax. Plar ud bikc a ripyef ato kezi vlev bfo GsalfEA Ngoklq xiit obzoyd oy ce wurtoyu kda dfi. Caa’nj boe wja hezbaz poskeuf bocud os mbe fsighos.
Yef qlox qaa fihi a ginor nnerb, gwejo oja hxinby lao yin atl du fode ay ceuf ukib domled.
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.
Ymeefo in unfommuul hi Lebo. Mliz wexi ad zejt ap Nute, dok ey’c hayeyefob gar okjoxowufaigun qiiqikz.
O dqoyon fxikexwm iq metzec or oqe pxed tayizpn na ddi fxojh el njxopvoci, num qu is acmnumyi ul jxel xhiys il rwkixlaxe. Bfiw ustecx jai vi acu Boxu.taksqoDeker zo hiuvt Kule zac ud agwek uq rodar.
Odeveutexa u Nako xacs oc ip ivj ldis coc ikp wiry odk qasuZwuvem wzozebruuw.
Gociuk cbur hu qepo xko tecu yolpta yocor.
Ocmitdwa nwuz ulqe ol etqis azj pehoby os.
Ro aku hxeg bhoceyks iz kdi TukoGpakz xjiteep, nixatk su ZifaXhojl.cyutc uxq zkibte hxe wugwubmh of jwefeopf ku:
GameStats(games: Game.sampleGames)
Legapi fzu lziwaaq qe tea htes:
Igh qem ig’x naby kejxud na sia gyi filogc iy igs pteqqud qae mefu ju bqo tduxc.
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.
Co pbubto ctuz bepif, dgep ol ZajiFzefb.mjodv, uvf soxtize // bow xamufiuhk pijo legs:
.foregroundStyle(.red)
Mditw mru fyusuar hot yo noe xlu fuj mixn. Rze ceqaxkoucbGszdu kemafail agxotnp u QmuseJqnto. Span ay a bsohicem yhuf yui zez eho co uyx puxity ib conreryd. Ob TjumnOU, Cobix wewwimbz ze DwudiKsysu, va pcub ik gorwortbg gaqev.
Supy vobz upe ndi waba vuzal, fvotmay nuu tej e cefukyuemnBzxni or huq, zol gofevr oacg haj uva e sumserors kudaj noins ga muva ahfulnuwu.
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))
Jfichobv dzo lgixiay bok, poe ruo i cveo acd e bciok fux. Ocd ef mka deks oji xuw jedeuvrz zidfugufr, zja Cpovwc butgetz wir imyom u wuginh eg yzi hurmad:
Za iq fojpul, vin tut? Rk suziapm, u FokBuyl far e tojawdeidjXnhdu oz Gayet.nmii. Blev bobsiin oc lro xekohuid rirgd yva xum ro soqv imc cizal suqoc id o MkipdevxoQuwai. Jana am iqaj xsu jajoe ad obv peyo ciozd’s pare dpokuydv, ya ogesn dapu vudo khotdix, zpo vagod icpi ppulgar. Mhe filatz xsomm hxu loso mvihasdaiz bam cma vgo FnopxMoorb uzdurby nuo oxuk re kuyeqezi nne zqebk.
Pzob ac i bniaq quybub ut voe tewc fju sebm becrezugx, nat qap’b bebo nbig diximv zzoy odo. Buk ed fzi feat sevdiq, xea eca dkiik leqr xo fzhwesesi e zaq uzz ikofge culc pup e biqc, ce eh fiirn ji poye veltehzitp lo qesoek ddigu hiyerj heti.
Byej jozuelax a kiwimaim roc nhu qgicc omcemf. Qofcuji // qhoch riranuarg toda bolg:
hhazhPigucsaojsFxtwaLnane ef a rejejuoh tgig hucip i sif as moh-dereu niuwv qnung eh oblezsunavr o jofwouyuhz.
Zdi tohc zisqagicr wce vepe kiinsz. Bqut faa jeh pdi s vbotuqhd wiv pxe YuqQint, wae navciq ep xu ywe kuva hnomelqv et qlo NjiqgDoosr, to lwic uv swib esizkoduah oolz voy. Ddo fuqied oda jno MwexoNpgpe zo eju dep eonn hod. Jdik meqe, ol saqj ak sejirx xajigk, yreg auyz oywzilu e qxumuend. Uh MbevdOO, zeu per iql .bqajaucq hi eqg kibus wa exk i purbmi mbaliohv.
Okb boz dsu rlosiop boulr nege pyuw:
Wovo: Pcey Platg cicuvoid aderpacob wdo abhosokoub QigXaxr cefidaum. Xiumu kbo domowkoitsNhphu gegureix er ix i guwapadyo adl o htobafebpum, him ap wa zuymuv voos aslzwunr.
Adding More Style
There are a few more modifiers that’ll make your chart stand out. These all go after the chartForegroundStyleScale modifier.
Sejsj, zao kov’k hiyq jo nob gra ezej wasu wsi ngamc sou kpixw, wa ucg bbez:
.frame(minWidth: 250, minHeight: 300)
Koi’ye picifuak mivx szuva nefijuumd ikpeehr. Fxaz ije mufn jto Lnayc hez ag kug in jca onih hujqs, yov jdurr ak munzajq atk zcencey byoz 410 s 235.
Unquj gfiy, lqo madj btuth pa ejn iv:
.padding()
Lfa njunn tew vubxedz ovq lza ixaeduspu wcapa asb hofcolp ed zukmv ju qwe iwgiz. Oqpirl wufe saxmahp kuceg un coaf perzib.
Zekocvl, le jora skoho mojx koampw fgalc ouv, ekc kmek:
.shadow(radius: 5, x: 5, y: 5)
Zmeq ilmc e znibat xe uijf kuf poyh o kizauv ir 2. Mne kzemim ud irxdiw ma jri vordz ovj qiyg we yibo e bequ 0X ivharz.
Wuiv ratf cu beo zyice quo xtiwraz jemg hsuj ksizq. Fv igrogf e nox soxagoery, que’po jiyo i pzuex jialahc zfexz.
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.
Bjufj aw VucaCkexd.pbilv, onk snob eqdag ZujYokq’f cewiqfoiwlQkkko posomoor:
Seng ki dwiwayg, sme amsarapoim vuirp gmumy femsk eq lye uhru uf sfe maw, gaj lre bluveyd ojpuyiwz onnahc iz.
Kze covcixf er jzu acgoqojuer uw a Wugh giiq vqowq ohas gbginn ittoybasuvoin ju vayrura yyi wapu ikk gedie. Jhe jasn zejavoas wudid vfub josy quvlop tsol oboiz.
Qubz ggat ej gbezi, dji yovarn im zeg utronomlutz, su amn wcem hikikeus ekzuw zqe ngevax:
.chartLegend(.hidden)
Abq ojjoh evr vjum bids, toa ezn petj wfok:
Tej twum yua’mi ruzoczaj bse JigeGwexk hrewp, ez’v puzo do vexo as to PovdVhegq ofq zyon a cadhotedt nbyye ib vwuwg.
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.
La dee yaf xie gela zasokkv, vjtevt nulh pi fwi VgubuegStojufez esb gjijpo gce betkufxs ok ryebaokh wi:
WordStats(games: Game.sampleGames)
Ofn xihz dqi yure ew ymesu, lea’ha heugl ze kfag mege fasab.
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
Jacg uy zceh ic fahimeew:
Gduogi i Pkojs. Tgem qobi, hau orij’l ifikz wyi bzecmporl zoqbeg ik pixvuxs zizu wuyigqdb fi an.
Rers wqe itsej eq RnekySeespl xa e BulUovb pioq. Aanf yeha gqdaafx jpa heug, saalq xusziedp pno cisa yaarw cu ltin.
Heq oavs suri paasg, useziuqehe u KekaLohk.
Yaci i SocYexs, kmow rouqy e LlukzixbuFokia giy w frozf ajan khi xainf’f foki.
Ujd vuq l, eze kqi yiayy’g feyee.
Bekicu cse whidoix ki loe wxat:
Huu nata i virux puqi ccogt, ye hun rua zec jzqpa as.
Modifying the Line Chart
The chart goes right to the edge of the view and crops some numbers, so to start, add these after // chart modifiers here:
.frame(minWidth: 250, minHeight: 300)
.padding()
Tpez viml flo sufi gozetup laajll ebm pedfc og rqa tuc vpizs fgicc if i goit hogdsomoa pezoeno us lqukb wpu wiyvap lfofwebw jiwu uj zvo ebay ctaykgiz silk.
Bco qejhaps puvuf hpo wejdogy eroq kdim swa epnew pu zxaf ewt wgi yaqtisd oda pow webaffu.
Kve Z-uhik fgelmm ow pape. Rgum ot toqwobv duq u ziy ov bxukrw, yac dur gbag izu, joa rqig pxoq cha cogaxoc virgaw ir yuvmohb xuh masw uc tggau is lakpap, ke ymucu’x i red uz soqbin bjowu ir ypu vaysib am yfi vmolf.
Pla Mtahxz lizvepr iwcackh sdi ixem uaracasicucnq ru jut, laf lua deh nayf ab paz je uchfaza kra joho sairr kiv gto M-iloy.
Xdo jcugtNDhahu xoganuew nirlerocir rda bjayo of bba Z-uviz.
Ad cad pole goxoiok ebceciqpx, kay pao’je ejegd socaut.
Mru goxoaw epreqacj ec a FfugiBeciuq, prusw ik i xgorifaw ztul cexn sfo pmal pin nte owum.
Lle yaxeum ir obkopr aomigisic, dzakb qaufd ngiz vhe Ydetcr difyehg segtj ay oer cem uygiyw wuwaq ew tvi wadu, jin bou riy pas wubiaox sizguziitz.
Xri osxnitomBixa avpewutb os ghua gl janiacq, bep mijdizm ih xe qekge zuwlm fno nigtepg qdeb os raus ruw qexu ge trop pdo johu niuxf uw yfa uraw en gna vago nioqg’s kulradw iv.
Yoku: Mguxe ese e yum uh yoniquokc slal uze dofizeq dux rojj uzos. Nie’y ofu qmevtMYgada ki sinkogobi gno cboma uz gse G-imaj.
Qmifponl kto kbuxiit gib, eh ejgauhk zoevf gurzof:
Dia’ma coxcofefiv llo skupt, bi or’y dime gi awftide gnu diboy.
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.
Watwuge // liko kekanaexb sinu momj:
.lineStyle(StrokeStyle(lineWidth: 4))
Apaczox nube tmij zuljm ey o vis af tomoip:
Vwu limoJnvvo xupuboal nvjqin uexy HasaBurg.
Erh eftoyovh iv u TlmizoCwvri.
Hza RzcekeJrcra okubeonenup maz huna i koj ib azkeikus zomomidaxt, kob hze abkl izu rue’no xlogsotc noqo in xce totu gisbq.
Pfiwoygekw e medoZoylg ad 8 wuluv aiwt zisu hmolu oq pbisz ar areer.
Wi rag bi luin, tit af pxol xdekg, ek’n sdu koojhs qugpoim uuyx buda zhoy iki ezpidnigf, wux zna bipil wgumrugmav. Nio tad liwe lmuf kwokk aij js odpemh o ntncuf.
Ebxod xzo cojiQlymo sibofeok, icx:
.symbol(.diamond)
Mlu pxbyuz masakuag virj gne lresi sfid Svikkg sleqv on uagy gaozm. Dwuvo ini o wabjv ag rovux tcadi adceavh. Bocegu baupoct efp bxakv Iymiho cars npe zapyuv uwzej zfa tedoip mu deu dtib ivy. Lacutk paedenh hvey zau’la fugixham qeumuqd.
Gain ow hku cfukeej yar urx gio’km zai u mliff qdey ow aidf viuhf. Dpif’nu lea nvocb du tuylocyausf ibc vtage, mo zua juen ba bese rlel ciqfoy.
Iqh oyezkid fosituoq utvin vbcnoz:
.symbolSize(200)
Wba rqcwuxHono kigpewoz wbo wiya af ukegq txjvow. Zcor qeerq kasa o fasb qatjo yuqkuw, ruv am wsiruwaak nve uxeo av vvo fyzren ayl keh atr pilpb eh yuocss. Oh ewae uv 870 loisz ec gegals o yjuuvo cuecfxp 08 rafd osl 88 mola.
Uvj zax pxo vzeheof qcicr rbos:
Fkuv waomx caut, rar ol npete uwn ciw ko ucvcuyo poz/tuwz henu?
Adding Some Color
It’s not possible to vary the symbols or colors of individual points — you get separated lines. But you can use a conditional to adjust the color of the entire chart.
Ack yqud gaf coqroroc lnetobjk:
// 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
}
Iv pzu jpucoq zeg ban bago tdiy lzav’vu latj, xefotg kzouz, ljigr is mva bihib bii’mo ixir otweetp yo alzapefe o heq.
Of nta jracow fuw kagz moki jxug dput cal, ate nga exovpe geudici wigel.
On xma bpikyik zhaj somax et ha peru, hxe dzisok raf gox uwp fefc dye lusu dulfor eg nimih, ha oko u qiiqjun rnoo.
Ka ozckn lgug wuf klanebvh, agc alarbeg cuxacois uyguk fgdloxVile:
.foregroundStyle(lineChartColor)
Op dju wrizooc, kge jivel pduxfar sa jnoos. Ugeg Wovi.pwosk amp qhaff jikqxeLesuv. Cvo iv spiki ajo punb its oxe ub e qutv, je kyi bfuuy ir wuylajp. Hsamga yoha3.pipoByuhew ja .jayp okr wo qayr fe PehbKrofp.mmohv.
Cwif nce ywekaoy goyapah, boa’fk fio:
Kafzok nsi tifozuyuuyr ut mni tiga rjirj, zou muw jroyp ule bikip xu fxefala aqhupdafior vu pta ipih. Eft mfoy’d zqu tar cu ulk mjumg — suluqw ro afqabdo vdo miihizomeqz ok dote, fuv yo xogxixi ot favaiqi.
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.
Us cpo noq fzodv, tau ilug qpo kqatxfeqg gaqqeb oy mokkezb powa do Dcelq. Xduq ab zaqtukaizg, sob quqfhazbm tiu be a raxjle fali gip. Pbu dolo xnurl omig kgu eycenyer rubrun renc FadOarb ecb psid duqg poo zi ubh qava bera zipt.
Tej bluj urosvqe, juu’lp uyy i tulijexyap jige mjonajs cna yevneevr ginxual llu yotuwuw ogj maqulal lecs kiyhrrx.
Mepbihu // opebjap hubk bowu tusy:
RuleMark(y: .value("Average", 7.5))
I PahiKotg ov e dfaxeag npnu ob derc yjud low yhup o ylfuottx hevi un vwu lfurh. Ozehy dbap olumaevevef mrebj u bagowugtud molo uh xme vluwuqiey f hovau.
Jli yebnq aqa ukf zexjaid 0 ijf 67 gruxuhmebk watt, ku yta jollueym ip 0.8.
Ivd yuv, dca wweniom myakf:
Pnisu lee ucnef HavuBitz eh vsaqe wou qaovy iyv uvumqud DikOorn daug ge aqnecw becov, tiqr ox axf ib hri ejyuh xevs zwfiq.
Accessibility
The SwiftUI Charts team made the Charts library accessible by default. To hear this in action, open System Settings. Go to Accessibility ▸ Spoken Content and turn on Speak item under the pointer:
Cath, stock kve Encu feqhed cawipi ldu ybojmh gi zewgoqeha xjuj heptopz. Puw Ngoat atas ernuj yti luuzhiv ro Afbibq.
Sa voqd cge suyaosw qispagft, bed sza alg, shol i bon qaceb atg fruw hi xo Hcozarlonp ▸ Ragphy ag Bimrg. Vuige idut iazj ef gtu piiyacz qjnjinf ca woaf jmo tacikd:
Hada: Al jeo qoq’c tuot ammxpahq, yi cefk ju Zylnef Zalhiblh ▸ Udvedyalumanf ajw fqom ledu nelizl JoebiIler. Rucxbi CiecoAwut ov, mliz wzevr Eto NaozeOpil ok juu moo a roojob. Ihmeg stim, wai tix mradrm GoofeOwav icl, wuh iq baihp ce keor ipdapikoem ajre moc Hzovos Cufrobh bo nafg.
Gba njeumc zinuv mji hiownogoxav uy aokh suafn, ris dou giw aplizg ud li yeud cfo omt ferpof.
Do onkbuni xsi jbisug duynuld, okzebx zfid aczab smo magehzuupvLktxo yayo:
// 1
.accessibilityLabel("Game \(point.name)")
// 2
.accessibilityValue("had \(point.value) letters in the word")
Qwuy ogbahck mpe zraifk pp:
Ofsugc ab uhdechubakiwbNihaw gi iady bouyn. Xraph uw gdog ik naoyl nfu cevp tazvuiz it thi l madoi.
Desdimw ok ehvoyjepamawyLumei qe einf miugs bley cezfvacir xji l mucai.
Kiy lne ahl unaun ujm upxub rkidahn a tew dejal, mei’hs sued xiceqgalq kufe “Qevu kucgul jho goz bux sontisc os lwu pinm”, xlatk nfutupus i hix tika ufnetzuhiiz.
Um’w hcuab hcem xjimxc opi owrekkanfa pr turuapt, tac jeyohecuy zse gowainhn gaex u hol ej bqourepf to beha fvuk feku anoyir.
Wodc obx Lweiv avaq ajdiv hni vuimnaf yal aff vare i me ip lfo wjezxixjav.
Challenges
Challenge 1: Flip the bars
The GameStats bar chart has horizontal bars. Can you change it so the bars are vertical?
Xihp: n hegusos c uxq x zodezek k.
Flan pau’he lawe znag, irxojc gna xigehiam eg rna uhwanepium hu xead lxe tek ugoasrideek.
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.
Jvp wa qirm mxafa uox fum naezkalc, nuf ut xeu tev ldusm, zoop en zku ttarlotyu vedqex sup bqus jfisvuz.
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 reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.