Isoissa myyntihankkeissa, projekteissa jne. tehdään usein hyvinkin kattavaa riskiarviointia. Yksi elementti arvioinnissa on riskien todennäköisyydet (propability, likelihood) sekä niiden vaikutukset mikäli ne toteutuvat (impact).
Tätä paria kuvataan usein lämpökartan avulla (heat map). Sen oikeaan yläkulmaan sijoittuvat riskit joiden todennäköisyys on korkea ja vaikutus suuri. Vasemmassa alareunassa taas ovat riskit, joiden todennäköisyys on matala ja vaikutus vaatimaton.

Tällä kertaa tietenkin toteutamme Power Appsilla tällaisen lämpökartan.
Riskien tallennus (Dataverse)
Hankkeiden riskit on tallennettu omaan tauluunsa Dataverseen. Kiinnostavat kentät ovat Impact ja Probability.

Muutama rivikin löytyy. Voimme aloittaa varsinaisen työn.

Lämpökartan muodostaminen
Tarkoitus on muodostaa 9×9 solun kokoinen lämpökartta impact ja probability akseleilla (käytettävä arviointiväli on 1-9). Tarvitsemme sen pohjaksi kokoelman, joka sisältää tarvittavat 81 lukuparia.
Ensimmäisenä tulee mieleen
- Luoda Sequence-funktiolla arvot 1-9 todennäköisyydelle
- Käydä luodut arvot läpi (ForAll) ja jokaisen kohdalla luoda arvot 1-9 vaikutuksille ja käydä vastaavasti ne läpi
- Sisimmässä silmukassa lisätä uuteen kokoelmaan vuorossa oleva todennäköisyys+vaikutus pari
ForAll(RenameColumns(Sequence(9), "Value", "ProbabilityValue"),
ForAll(RenameColumns(Sequence(9), "Value", "ImpactValue"),
Collect(colHeatMap,{Probability:ProbabilityValue,Impact:ImpactValue})
)
)
Kas näin.

Tämä edellyttää kokoelman luontia. Toteutetaan tämä kuitenkin elegantimmalla tavalla, jonka opin mainion Brian Dangin mainiolta videolta, jossa hän esittelee pelin tekoa Power Appsilla.
Luodaan aluksi taulukko, joka sisältää vaikutusten mahdolliset arvot (1-9).

Tämän jälkeen lisätään taulukkoon uusi sarake (AddColumns) nimeltään ”ProbabilityTable”. Uusi sarake on taulukko, joka sisältää todennäköisyyden arvojoukon 1-9.

Lopuksi puretaan todennäköisyydet sisältävä taulukko omiksi riveikseen Ungroup-funktiolla. Näin meillä on 81-riviä sisältäen kaikki vaikutus-todennäköisyys parit. Kaavan voi asettaa gallerian Items-ominaisuuden arvoksi.

Lisätään galleriaan tekstikenttä, jonka arvona on kyseisen solun vaikutus + todennäköisyys arvot. Näin meidän on helpompi hahmottaa mitä olemme tekemässä.

Käyttämämme skaala on 1-9, joten asetetaan gallerian ”sarakemääräksi” (Wrap count) 9.

Tämä alkaa jo hahmottua! Järjestetään vielä taulukkomme arvot oikeaan järjestykseen ja lisätään akseleille otsikot.

Lopullinen kaava gallerian sisällölle on seuraava.
SortByColumns(
Ungroup(
AddColumns(
RenameColumns(Sequence(9),"Value", "Impact"),
"ProbabilityTable", RenameColumns(Sequence(9),"Value", "Probability")
),
"ProbabilityTable"
),
"Impact",Descending,"Probability",Ascending
)
Lämpökartan värit
Karttapohja on valmis, mutta se pitäisi vielä saada väritettyä esikuvansa mukaisesti.
Muotoillaan gallerian solut sopivan kokoiseksi ja asetetaan niiden välinen tila (Template padding) nollaksi. Lopuksi asetetaan solun taustaväriksi (TemplateFill) tummansininen (RGBA(56, 96, 178, 1)).

Värimäärityksen viimeisellä parametrillä säädetään värin läpinäkyvyyttä. Hyödynnetään tätä.
Oikeassa yläkulmassa todennäköisyyden ja vaikutuksen summa on 18. Määritellään väri siten, että sen läpinäkyys on tällöin 1 (eli ei laisinkaan läpinäkyvä). Muissa tapauksissa asteittain vähemmän ja vasemmassa alakulmassa lähes 0.
RGBA(56, 96, 178, (ThisItem.Impact+ThisItem.Probability)/18)

Poistetaan samalla otsikko gallerian sisältä. Emmeköhän pärjää nyt ilman sitä.
Riskien sijoittaminen lämpökartalle
Vielä pitäisi jotenkin sijoittaa käyttäjän syöttämät riskit tälle kartalle.
Tulemme tekemään jokaisesta lämpökartan solusta kyselyn, jotta tiedämme onko kyseiselle todennäköisyys-vaikutus parille tallennettu yhtään riskiä. Käytännössä 81 kyselyä. Tästä syystä riskit tulee tallentaa kokoelmaan näytön avaamisen (OnVisible) yhteydessä. Muutoin lämpökartan lataaminen on todella hidasta.

Lisätään galleriaan pieni musta ympyrä ja sijoitetaan se keskelle ruutua.

Ympyrä on näkyvillä ainoastaan mikäli solun arvoilla (impact ja probability) löytyy riski.
Not(
IsBlank(
LookUp(
colRisks,Impact = ThisItem.Impact And Probability = ThisItem.Probability
)
)
)

Riskien lukumäärä vs ympyrän koko
Esimerkkidatassamme on kaksi riskiä arvoilla impact = 8 ja probability = 5. Olisi tyylikkäämpää visualisoida myös se, montako riskiä ympyrä sisältää.
Tehdään tämä kasvattamalla ympyrän kokoa vastaamaan löytyneiden riskien lukumäärää.
Lisätään galleriaan oma tekstikenttä, jonka arvo on kyseistä solua vastaavien riskien lukumäärä. Tämä siksi, että käytämme lukumäärää hyväksemme useassa paikassa, mutta haluamme tehdä kyselyn kokoelmaamme ainoastaan kerran.
CountRows(
Filter(
colRisks, Impact = ThisItem.Impact And Probability = ThisItem.Probability
)
)

Vaihdetaan merkkipalleron näkyvyys riippumaan löydettyjen riskien lukumäärästä (pallo näkyy jos riskejä löytyi enemmän kuin 0).

Säädetän palleron leveys. Nyt on tyyli vapaa! Itse laitoin leveydeksi 7.5 ja lisään siihen 2.5 jokaista löytynyttä riskiä kohden.

Korkeudessa pääsee helpoimmalla viittaamalla ympyrän leveyteen.

Nyt ympyrät eivät ole aina automaattisesti keskellä ruutua. Koska niiden leveys vaihtelee. Korjataan vielä tämä. Esimerkissäni solujen leveys ja korkeus on 45. Keskipiste on siis 22,5. Siitä kun vielä vähennetään puolikas ympyrän halkaisijasta, niin saadaan oikea sijainti.

Ja sama tietenkin Y-akselin kanssa.
Riskien tietojen esittäminen ja uusien riskien lisääminen
Lämpökartta on tavallinen galleria, joten valitusta pisteestä voi normaaliin tapaan esittää toisessa galleriassa tietoja. Alla esimerkki miltä valitun pisteen tietojen esittäminen voisi näyttää.

Samoin voi olla tarpeen tarjota käyttäjällä mahdollisuus lisätä uusia riskejä.
Esimerkiksi näin.

Merkkivärit liukuvärin sijaan
Entä jos haluaisimme käyttää perinteistä vihreä-keltainen-oranssi-punainen väritystä? Silloin määritämme halutun logiikan lämpökartta-gallerian TemplateFill-ominaisuuteen.
Esimerkiksi näin
If(ThisItem.Impact = 1 Or ThisItem.Probability = 1 Or ThisItem.Impact+ThisItem.Probability<6, Green,
If(ThisItem.Impact+ThisItem.Probability<12,Yellow,
If(ThisItem.Impact+ThisItem.Probability<16,Orange,Red)))
Nyt väri on vihreä jos jompi kumpi arvoista on 1 tai niiden yhteissumma on alle 6. Keltaiselle pääsee, jos summa pysyy alle 12. Oranssia ovat arvot välillä 12-15 ja punaista sitten loput.

On tämä veikeä työkalu.
Ja jos riskit on linkitetty esimerkiksi Dynamics 365:n myyntimahdollisuuksin (opportunity), voit helposti nostaa tämän Canvas Power Appsin osaksi model-driven appsin opportunity-lomaketta.