Builds 22 - Hotels Revenue Management

Hi Enteprise on Demand Subscribers,

Enterprise DNA Challenge 22 is officially closed.

Another remarkable EDNA Challenge.

First and most important, we have reached over 2274 group members during data challenge 22!!

Let us revisit some highlights happened during Challenge 22:

Our data challenge hub grew up to 2274 members within 7 months.

We launched 40 + posts in EDNA Challenge Community Group.

We engaged 58,048 post views.

We interacted over 300 comments.

We accepted 51 finals entries.

Our participants have produced well 200+ analysis pages.

Our participants’ reports contain more 375+ DAX measures, well over 100+ Navigation buttons, Filed Parameters, Bookmarks and Tool tips.

The variety of native and customs visuals in the reports is a mastery of Data Visualization.

All highlights cannot be achieved without your dedication. You are the owner of our community; we love your passion and motivation on your data journey!

Welcome your invitations to your colleagues or friends, we can be better and stronger with more data friends!

Congratulations to all participants, you have done excellently well. Enterprise DNA thanks you for your efforts and dedication.

A round of applause to the Enterprise DNA Community Lead Team for a tremendous effort in the making and coordination of this challenges.

Let us say goodbye to Challenge 22 and wait for the winner announcement and Challenge 23 soon!

Federico Pastor
Head of Platform Experience and Data Challenges

Participant Entries_C22.pdf (6.0 MB)

1 Like

Really nice, clean report!

3 Likes

Hi everyone

Apologies for posting this with some delay.

Just want to go through some of the data cleaning steps and some assumptions used while attempting Challenge 22. The section wise details are

  1. Data Anomalies

This part has already been highlighted by a few challenge participants and is related to the reservation status portion. There are 2 columns in the raw dataset which indicate this. is_canceled and reservation_status.

image

On closer inspection of these 90 records, it was seen that reservation_status column was giving the incorrect picture of these records as the Check-Out records could not have a reservation_status_date which was less than the arrival_date as shown in the image.

So we decided to split the Fact table into 2 separate fact tables named Hotel Revenue and Cancellations with is_cancelled = 0 records (89108 records) filtered in Hotel Revenue and is_cancelled=1 (52477) in Cancellations. This also allowed us to retain fewer columns in Cancellations table as some of the columns were not required for revenue calculation analysis.

Another anomaly in the dataset for Checkout records was some of the discrepancies in Nights(Weekday) and Nights(Weekend) records like highlighted below. The Arrival Date and reservation_status_date columns have the same date value but Nights(Weekday) and Nights(Weekend) show a stay of 7 days.

image

In order to check for such discrepancies, another column named Duration of Stay was calculated by subtracting Arrival Date from reservation status date using

= Table.AddColumn(#“Filtered Rows”, “Duration of Stay”, each Duration.Days([reservation_status_date] - [Arrival Date]))

It was found that some of records had negative values for this column.

On filtering the records it was found that there was a logical discrepancy in the data entries for December 2019. For some records that had Arrival Date in December 2019 and reservation status date in 2020, the system had mistakenly put the reservation status date as 2019.



In order to remove the error for these records, a condition was applied where the reservation status date for these records was corrected by adding 365 to the Arrival Date

Table.AddColumn(#“Changed Type1”, “Checkout Date”, each if [Duration of Stay] < 0 then Date.AddDays([reservation_status_date],365)

** Duration of Stay** column was used for subsequent calculations and where the Arrival Date and reservation status date were the same (Duration of Stay = 0), the value was replaced as 1 so that revenue calculations do not result in 0 output.

  1. Data Model
    Based on the data cleaning methodology above, the data model was modified to have separate Fact tables for Checkouts and Cancellations

  1. DAX Calculations

For all calculations, the discount rate was applied on both the Room Rent as well as Meal charges.

The logic used to compute Room Rent was to multiply Avg Daily Rate with duration of stay and discount applicable for that market segment.

Room Rent =
SUMX(‘Hotel Revenue’,
(‘Hotel Revenue’[AVG Daily Rate] * ‘Hotel Revenue’[Duration of Stay] * (1 - RELATED(‘Market Segment’[Discount]))))

The Room Rent for Checkouts was filtered based on date to just compute values of Room Rent generated from Checkouts.

Room Rent Checkout =

VAR CurDate =
LASTDATE ( ‘Dates’[Date] )

VAR CheckOut =
CALCULATE (
[Room Rent],
FILTER ( ALL ( ‘Dates’ ), ‘Dates’[Date] == CurDate ),
USERELATIONSHIP ( ‘Dates’[Date], ‘Hotel Revenue’[Checkout Date] )
)
RETURN
CheckOut

For the Meal Cost, similar logic was applied on a per Adult basis only.

Meal Cost = SUMX(‘Hotel Revenue’, ‘Hotel Revenue’[Adults] * RELATED(‘Meal Cost’[Cost]) * (1 - RELATED(‘Market Segment’[Discount])))

Meal Cost Checkout =
VAR CurDate =
LASTDATE ( ‘Dates’[Date] )

VAR CheckOut =
CALCULATE (
[Meal Cost],
FILTER ( ALL ( ‘Dates’ ), ‘Dates’[Date] == CurDate ),
USERELATIONSHIP ( ‘Dates’[Date], ‘Hotel Revenue’[Checkout Date] )
)
RETURN
CheckOut

The total revenue generated was computed by adding the Room Rent and Meal Cost and aggregated on a daily basis

Rev. Generated (Checked Out) = [Room Rent Checkout] + [Meal Cost Checkout]
Total Revenue Generated =

SUMX(
ADDCOLUMNS(
VALUES(‘Dates’[Date]),
“Rev. Generated”, [Rev. Generated (Checked Out)]
),
[Rev. Generated]
)

Just shared these assumption and data cleaning steps with the community to get feedback and a better understanding of the dataset. I think there were a few other things that could have been done but were not done due to time constraints.

Kindly provide feedback or suggestions for further improvements.

Best Regards
Team MAK2

2 Likes

@BolajiO

Sorry I have been unable to reply to you sooner. Thank you for your input.

We do normally provide a basic data dicitionary within our challenges documentation and expect participants to exercise due research in the specific subject matter and or ask questions here and in the LinkedIn group to clarify any doubt they may have. Just like real work!

I hope this helps and once more thanks for your input.

Federico

Hi @Alvi and Team MAK2 members,

Thanks for sharing very interesting inside of your work.

My assumption for this data set dates were:
-Arrival date - date of arrival
Reservation status date - date of Reservation Status - date when reservation status changed

So to calculate Reservation date I use Lead time but also there are some discrepancies.

So I calculate Reservation Date = Arrival Time - Lead time, but I checked also Reservation status date and used min of this too (and correct Lead time). Back and forwards approach :slight_smile:

To compare with Meal charges I use Meal revenue term - and calculate for Adults but add also for Children (since I personally always need to paid for them too (how much they eat no wonder - but that is another story). Only I didn’t paid when they were babies.

I didn’t get idea to separate Checkout and Cancellations in separate tables but I use indicator Ind Revenue instead - to have 0 for both is_cancelled + error in booking (to have Check-out status with nights and 0 guests also separated) to calculate everything afterwards.

Very interested how same data set can cause different approaches.

Best regards,
Maja

3 Likes

Thanks for sharing this @mspanic.

I agree the approaches can be different and it is always good to share your underlying assumptions as well as any data cleaning or transformation steps that have been applied.

2 Likes

@Alvi
I agree.

Regarding other data cleaning and trasformation - what I also did:

  • combine CN / CHN together to CHN (ISO 3 Country code) so I can merge with web data source about countries + combine with other web data sources to get hemisphere - so I can calculate seasons ( for that I use Country / Hemisphere + Month from Arrival Time).

So I can get revenue per seasons - use % per season to highlight when each customer type spent the most.

  • Also for Repeated customers reservations I use in FILTER part
    Filter ('fct_Hotel Revenue', 'fct_Hotel Revenue'[Returning Guest] *'fct_Hotel Revenue'[Previous Bookings (No Cancelled)] >0)

One more thing I would like to share:
Finally what I am so glad that I learn during this challenge is how to rename measures/column on a visual (specially when I had a table) - so simple just double click and change:

image

I try to find this feature in Power BI for some time, and I am so happy that I finally did :tada:.

2 Likes

Hi everyone,
Below I explain the process followed for the development of the Hotel Revenue Management report:

DEVELOPMENT PROCESS HOTEL REVENUE MANAGEMENT

In the process of developing this report I have followed the following phases:

  1. Loading and Cleaning Data from Power Query
    • First, we create a query called Data_Source that contains the path to the data source.

• 2018: Data from 2018. Created using Reference on Data_Source and selecting the 2018 tab.

• 2019: Created using Reference on Data_Source and selecting the 2019 tab.
• 2020: Created using Reference on Data_Source and selecting the 2020 tab.
• Dim_Market_Segment: Created using Reference on Data_Source and selecting the market_segment tab.

• Dim_Meal_Cost: Created using Reference on Data_Source and selecting the meal_cost tab.

• Hotel_Revenue_RAW: We combine the 2018, 2019 and 2020 queries.
Before combining them, we make sure they have the same number of columns and they have the same name. In the case of the 2018 table, there is a column called “AVG Daily Rate” and in the other two tables it is called “adr”, so they are unified to AVG Daily Rate.

• Dim_Hotel_Type: Created using Reference on Hotel_Revenue_RAW.

• Dim_Country: Created using Reference on Hotel_Revenue_RAW.

  • In order to show the photo of the flag of each country, we use the table in Excel Countries with flags:

  • To segment the data by the Continent of each country, we use the Countries by ISO table, which has the following web address: https://www.geonames.org/countries/
  • To the Countries by ISO table, we add the information of the photo of the flag contained in Countries with flag.

  • Finally, we add the information from this table to the Dim_Country table

• Dim_Distribution_Channel: Created using Reference on Hotel_Revenue_RAW.

• Dim_Reserved_Room_Type: Created using Reference on Hotel_Revenue_RAW.

• Dim_Assigned_Room_Type: Created using Reference on Hotel_Revenue_RAW.

• Dim_Deposit_Type: Created using Reference on Hotel_Revenue_RAW.

• Dim_Agents: Created using Reference on Hotel_Revenue_RAW.

• Dim_Companies: Created using Reference on Hotel_Revenue_RAW.

• Dim_Customer_Type: Created using Reference on Hotel_Revenue_RAW.

• Dim_Reservation_Status: Created using Reference on Hotel_Revenue_RAW.

• One of the requirements of the report is to analyze the information by holiday periods, so I have created the fxHolidays function that, based on the country and year code, obtains the national or national and local holidays.

This is the code in the Advanced Editor:

let fnHolidaysTable = (Country as text, Year as text, OnlyNationalHolidays as number) as table =>
    let
        _National_Holidays = if OnlyNationalHolidays = 1 then "national-holidays/" else "",
        Source = Web.BrowserContents("https://www.whenonearth.com/calendar/"&Country&"/"&_National_Holidays&Year),
        #"Extracted Table From Html" = Html.Table(Source, {{"Column1", ".day"}, {"Column2", ".day + *"}, {"Column3", ".desc"}}, [RowSelector=".hdays TR"])
    in
        #"Extracted Table From Html",
      Documentation = [
      Documentation.Name =  " fxHolidays", 
      Documentation.Description = " Date table function to create table with all holydays or only the nationals one for a Country and Year ", 
      Documentation.LongDescription = " Date table function to create table with all holydays or only the nationals one for a Country and Year ", 
      Documentation.Category = " Table", 
      Documentation.Version = " 1.00: full code review",
      Documentation.Source = " local", 
      Documentation.Author = " José Antonio Fernández Puga", 
      Documentation.Examples = { [Description =  " See: https://www.whenonearth.com/calendar to see the available values for the Country and Year parameters ", 
        Code = " fxHolidays ( ""united-kingdom"", 2018, 1 ) //Only national holidays"
        &Character.FromNumber(13)&Character.FromNumber(10)&" fxHolidays ( ""united-kingdom"", 2018, 0 ) //All holidays ... ", 
        Result = " " ] }
      ]
  in 
  Value.ReplaceType( fnHolidaysTable, Value.ReplaceMetadata( Value.Type( fnHolidaysTable ), Documentation ))

• The Holydays table contains the national holidays of united-kingdom for the years 2018 to 2020.

We join this table to Dim_Dates to add the Holiday Name column.

• Dim_Dates: Table of EDNA dates that is contained in the .pbit file, from which we create the report.
We have created it with the following call, in which we pass the Holidays[Date] field as the third parameter:
fxDates(fxStartDate, fxEndDate, 1, Holidays[Date], 1)

We add the following columns:

  • Holiday Name from the Holidays table
  • InHoliday: Yes/Not
  • Season: Spring/ Summer/ Autumn/ Winter
  • Stay in: Week/Weekend

• Fact_Hotel_Revenue: Fact table created using Reference on Hotel_Revenue_RAW.

  • Joins with each of the dimension tables we created earlier as a reference to Hotel_Revenue_RAW, leaving only the primary key fields in the fact table.

  • The following columns are added:
    Nights: [Nights in Weekend] + [Nights in Week]
    Reservation Date: Date.AddDays( [Arrival Date], -1 * [Lead Time] )
    Departure Date: Date.AddDays( [Arrival Date], [Nights] )

  • I have followed the approach of generating a record for the day of the stay and basing the calculations of time on the date of the stay instead of taking only the arrival date of the reservation, since it facilitates the temporal analysis, although it increases the size of the data set.
    To do this, we add an index to the table and create a column by calling the fxCreatePeriodTable function:

let
Source = (StartDate as date, EndDate as date) as table =>
let
DayCount = Duration.Days(EndDate-StartDate)+1,
DateList = List.Dates(StartDate,DayCount,#duration(1,0,0,0)),
AddPeriodName = List.Transform(DateList,
each {_}),
CreateTable = #table(
type table[ Date=date],
AddPeriodName)
in
CreateTable
in
Source

We create a table with the days between the arrival date and the departure date:

Table.AddColumn(#"Added Index", "Days of Stay", each fxCreatePeriodTable([Arrival Date], if [Nights] > 0 then Date.AddDays( [Departure Date], - 1 ) else [Arrival Date] )),

  • Añadimos una columna con Guest Type:
Table.AddColumn(#"Changed Type1", "Guest Type", 
    each if ([Childrens] + [Babies]) = 0 and [Adults] = 1 then "Singles" else
    if ([Childrens] + [Babies]) = 0 and [Adults] = 2 then "Couples" else
    if ([Childrens] + [Babies]) > 0 then "Families"
    else "Groups")
  1. Data Modeling

• I have followed the Star Scheme to model the data.

• For its graphical representation I have used the cascade design.

  1. Creating DAX Measures

• All measures have been organized in folders within the Key Measures and Report Measures tables.

• Some main measures:


- # of Booking = DISTINCTCOUNT( Fact_Hotel_Revenue[Index] )

-	Room Gross Revenue = SUM( Fact_Hotel_Revenue[AVG Daily Rate] )

-	Room Discount = SUMX( Fact_Hotel_Revenue, [AVG Daily Rate] * RELATED( Dim_Market_Segment[Discount] ) )

-	Room Net Revenue = [Room Gross Revenue] - [Room Discount]


-	Meal Revenue = SUMX( Fact_Hotel_Revenue,
-	 (Fact_Hotel_Revenue[Adults] + Fact_Hotel_Revenue[Childrens]) * RELATED( Dim_Meal_Cost[Meal Cost] )  )

-	Total Net Revenue = [Room Net Revenue] + [Meal Revenue]


-	AVG ADR = AVERAGE( Fact_Hotel_Revenue[AVG Daily Rate] )

-	AVG Net ADR = AVERAGEX( Fact_Hotel_Revenue, [AVG Daily Rate] * ( 1 - RELATED( Dim_Market_Segment[Discount] ) ) )


-	AVG ADR Discount = [AVG ADR] - [AVG Net ADR]

-	# of Nights = 
SUMX( SUMMARIZE( Fact_Hotel_Revenue,
      Fact_Hotel_Revenue[Index] ,
     "Nights", MAX( Fact_Hotel_Revenue[Nights] ) ) ,
     [Nights] )
-	# of Adults = 
SUMX( 
      SUMMARIZE( Fact_Hotel_Revenue,
      Fact_Hotel_Revenue[Index],
     "Adults", MAX( Fact_Hotel_Revenue[Adults] ) ),
     [Adults] )

-	# of Childrens = 
SUMX( 
      SUMMARIZE( Fact_Hotel_Revenue,
      Fact_Hotel_Revenue[Index],
     "Childrens", MAX( Fact_Hotel_Revenue[Childrens] ) ),
     [Childrens] )
-	# of Babies = 
SUMX( 
      SUMMARIZE( Fact_Hotel_Revenue,
      Fact_Hotel_Revenue[Index],
     "Babies", MAX( Fact_Hotel_Revenue[Babies] ) ),
     [Babies] )

-	# of Guest = [# of Adults] + [# of Childrens] + [# of Babies]

-	# of Agents = CALCULATE( DISTINCTCOUNT( Fact_Hotel_Revenue[Agent Key] ), Dim_Agents[Agent Code] <> 0 )
  1. UI design
    The report consists of the following screens:
    •General Overview
  • In this Overview screen, we have at the top the main KPIs in which the current value and the value of the same period in the previous year are compared, showing the % change and applying conditional formatting.
    For the Net KPIs, we have a Tooltips in the information icon with the breakdown of the gross amount and the discount.

  • We can select the measure that we want to show in the graphs in the Chart Measure slicer. For this, the PrmMeasures field parameter has been used.

  • The donut graph that shows the measure for Canceled has a tooltip for Reservation Status.

  • In the clustered column chart, we compare the current value with last year’s value.
    The current value is represented in the chart columns and last year’s value as error bars. I have opted for this configuration to be able to have the tooltips when there is no information from last year, since with the error bars the tooltip is not shown.
    We can view the information by Year, Quarter or Month by using the PrmDimDate field parameter.
    The legend is made with a 100% Stacked Column Chart.
    The tooltip displays the same information but for a lower level in the chart hierarchy: Quarter, Month, and Day. If we are viewing the information by month, the tooltip shows us the information by day for that month.
    The PrmDimDateTooltip field parameter has been used which is related to PrmDimDate by the Order column.

image

• Time Analysis

  • In the Time Analysis screen we show the main KPIs at the top.
  • Donuts graph to show the Number of Nights per Week or Weekend.
    It has a tooltip to display the information by the days of the week.

  • Donut chart to segment nights into Holidays or not.
    It has a tooltip to break down the information by the holiday or the day of the week.

  • Line graph in which we can see the trend of the selected measure by Year, Quarter or Month.
    The maximum and minimum value of the measurement is shown in green and red respectively.
    It has a tooltip to see the trend at a lower level of the Year, Quarter and Month hierarchy.

  • Bar graph to see the Number of Reservations according to the groups created for the Lead Time.

Two columns have been created in the Fact_Hotel_Revenue table to be able to filter the report by these groups:

LeadTimeGroup Key = CALCULATE(
     VALUES( LeadTimeGroups[Index] ),
     FILTER( LeadTimeGroups, 
     Fact_Hotel_Revenue[Lead Time] >= LeadTimeGroups[Min] &&
     Fact_Hotel_Revenue[Lead Time] <= LeadTimeGroups[Max] )
)

LeadTimeGroup Name = CALCULATE(
     VALUES( LeadTimeGroups[Group] ),
     FILTER( LeadTimeGroups, 
     Fact_Hotel_Revenue[Lead Time] >= LeadTimeGroups[Min] &&
     Fact_Hotel_Revenue[Lead Time] <= LeadTimeGroups[Max] ))
  • 100% Stacked Bar Chart to show the Number of Reservations according to the groups created for the Lead Time and if they are canceled or not.

Using Bookmark to toggle between both charts.

• AgentAnalysis

  • In the Agent Analysis screen, we show the KPIs at the top. These KPIS are calculated for those records that have an agent.
# of Booking with Agent = 
 CALCULATE( [# of Booking], Dim_Agents[Agent Code] <> 0 )
  • Dynamic Pareto chart for the selected measure.
    We can indicate the % that we want to analyze and it shows us the % of Agents that have contributed to this percentage.
    For this %, the Prm%Pareto support table has been used:

The % Slicer has the following filter Filter Prm%Pareto is 1 to show those % greater than or equal to the percentage of the agent with the highest value.

Filter Prm%Pareto = 
IF( ROUND( [Prm%Pareto Value], 2 ) >= ROUND([% Pareto First Agent], 2 ), 1, 0 )

% Pareto First Agent = 
VAR _VirtualTable = ADDCOLUMNS(
    ALLSELECTED( Dim_Agents ),
    "@Measure", [Selected Agent Measure],
    "@PorcPareto", [% Pareto Selected Agent Measure]  )
VAR _Result = MAXX( TOPN( 1, _VirtualTable, [@Measure], DESC), [@PorcPareto] )
RETURN _Result
  • The Enlighten Waffle Chart custom object has been used to show the % of Agents and the % selected.

image

  • Smart Narrative that shows the Number of total Agents, Number of Agents that have contributed to the selected % and value obtained.

Text Agent Pareto = 
VAR _SelectedMeasure = MAX( PrmAgentMeasures[PrmAgentMeasures] )
VAR _Result = "Of a total of "&
    FORMAT( [# of Agents], "#,###" ) &
    " Agents, "&
    FORMAT( [# of Agent Selected Agent Measure], "#,###" ) &
    " Agents represent " &
    FORMAT( [Prm%Pareto Value], "###%" ) &
    " of " &
    _SelectedMeasure &
    ", with a value of "&
    [Txt Value Selected Measure with Agent % Pareto]
 RETURN _Result
  • The Pareto chart has conditional formatting to highlight the agents that have contributed the selected %.
  • It has the following tooltip to show the information if it is canceled or not and if it is about repeating guests or not.

  • We can see the information of the agents in table format, which shows the ranking, measurement, % change, ADR and Canceled for the current and previous year.

To display these measurements in the table, the following related field parameters have been created:

•Guest Analysis

On the Guest Analysis screen we show the KPIs at the top.
In the # of Guest KPI I have added a tooltip that shows their distribution in Adults, Children and Babies using the HTML Content custom visual and the measure developed by Jefferson Alves:

Image Adults = 

/*
Código desenvolvido por Jefferson Alves - Dados Criativos 

Me siga nas Redes Sociais 

Instagram: @dadoscriativos_
https://www.instagram.com/dadoscriativos_/

Linkedin: Jefferson Alves
https://www.linkedin.com/in/jeffersonallvesneves/

Youtube: Jefferson Alves - Dados Criativos
https://www.youtube.com/c/JeffersonAlvesDadosCriativos

*/


Var vPorcentagem = [% of Adults]

Var vOpacidade = 0.2

Var vImagem = "https://i.ibb.co/WBJB9LR/couple.png"

Return 


"
<style>.conteiner{ position: relative; width: 100vw; height: 100vh; display: flex; justify-content: center; align-items: center; } .img_1, .img_2 {position: absolute;width: 90%;height: 90%;opacity: "& FORMAT( vOpacidade, "0.0", "en-US")  &";}.img_2{opacity: 1;clip-path: polygon(0 var(--porcentagem), 100% var(--porcentagem), 100% 100%, 0 100%);animation: anima_img 1s linear forwards;}@keyframes anima_img{from{clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%);} to{" & Var vPercentual =  ROUND( vPorcentagem * 100, 0)Var vResultado = SWITCH( TRUE(), vPercentual > 100, 0,vPercentual < 0, 100,100 - vPercentual )Return"clip-path: polygon(0 "& vResultado & "%, 100%  "& vResultado & "%, 100% 100%, 0 100%);}} </style> <div class='conteiner'> <img src='" & vImagem & "' class='img_1'> <img src='" & vImagem& "' class='img_2'> </div> 
"

  • Column chart by guest type: Singles, Couples, Families and Groups.
  • Column chart by Client Type: Transient, Transient-Party, Contract and Group.
  • Column Chart by Length of Stay Group:

In the Fact_Hotel_Revenue table, two columns have been added to be able to filter by the Length of Stay Group:

image

LengthofStayGroup Key = CALCULATE(
     VALUES( LengthofStayGroup[Index] ),
     FILTER( LengthofStayGroup, 
     Fact_Hotel_Revenue[Nights] >= LengthofStayGroup[Min] &&
     Fact_Hotel_Revenue[Nights] <= LengthofStayGroup[Max] )
)

LengthofStayGroup Name = CALCULATE(
     VALUES( LengthofStayGroup[Group] ),
     FILTER( LengthofStayGroup, 
     Fact_Hotel_Revenue[Nights] >= LengthofStayGroup[Min] &&
     Fact_Hotel_Revenue[Nights] <= LengthofStayGroup[Max] )
)
  • Column chart by type of deposit.

  • Bar chart by Market Segment.

• NationalityAnalysis

  • In the Nationality Analysis screen we show a bar graph by Continent.
  • Table that we can see by Continent or by Country with the ranking information and the value of the selected measure for the current year and for the previous year.
  • On the map we represent the color of the bubbles with a gradient according to the value of the selected measure.

It has a tooltip in which we show the information of the selected country: Flag, Name, the month and the season with the highest value of the measure along with the monthly distribution.

Regards,

8 Likes

Excellent share @jafernandezpuga!

Very detailed description of each step and nicely documented too!!

I think this dataset provided the opportunity to perform data exploration, cleaning and transformation close to what a real life dataset would require.

Well done!

3 Likes

Thank you very much @Alvi,
I have modified the post to add the images. :joy:
Regards,

1 Like

Exceptional report and writeup @jafernandezpuga … thanks for sharing.
Greg

3 Likes

Thank you so much @Greg
I think that explaining the development process helps the members of the forum and the judges of the challenge to know in more detail the report made.

Regards,

1 Like

Hey participants and followers of the Enterprise DNA Challenges :person_raising_hand:t3:,

:trophy: We are proud to announce the winners of the Enterprise DNA Challenge 22 “Hotel Revenue Management” :trophy:

This month’s Winners are:

Experts & Previous Challenge Winner
:1st_place_medal: Gustaw Dudek :1st_place_medal:
:trophy:Expert Winner badge
:trophy:$50 Amazon Voucher
:bar_chart: Display of Report into the EDNA Showcases

Overall and Platform Member Winner
:1st_place_medal: Gerard Duggan :1st_place_medal:
:trophy:Challenge Winner badge
:trophy:$50 Amazon Voucher
:bar_chart: Display of Report into the EDNA Showcases

Newcomer Winner
:1st_place_medal: Bolaji Olatunde :1st_place_medal:
:trophy:Challenge Winner Certificate
:trophy:$50 Amazon Voucher
:bar_chart: Display of Report into the EDNA Showcases

Non-Member Winner
:1st_place_medal: Jerson Andre Arrelucea :1st_place_medal:
:trophy:Challenge Winner Certificate
:trophy: 1 Year Enterprise DNA on Demand Subscription
:bar_chart: Display of Report into the EDNA Showcases
Out of the Box Thinker Winner
:1st_place_medal: Komal Bhatt :1st_place_medal:
:trophy:Challenge Winner Certificate
:trophy:$50 Amazon Voucher
:bar_chart: Display of Report into the EDNA Showcases

Creative Head Winner
:1st_place_medal: Wan Teck Chung :1st_place_medal:
:trophy:Challenge Winner Certificate
:trophy: 1 Year Enterprise DNA on Demand Subscription
:bar_chart: Display of Report into the EDNA Showcases

Special mention to our Runners up in the different categories:

Camilo Corrales Gallo, Wanderson Barbosa, Manish Acharya

It has been amazing to see the Enterprise DNA data platform family and Challenges Group members come together and learn on this month’s challenge and create stunning and creative reports!

Thank you to our judges panel Heather Rowe, Jarrett Moore, and Brian Julius for providing their expertise and time.

Check the recording of the judging panel :film_projector::vhs:

Finally, a big thank you to the Enterprise DNA Challenges Group “Community Lead Team” for their help and support during challenge 22, Solar Zhu, Kiruba Selvi, Komal Bhatt and Argenis Chaffardet.

:man_construction_worker:t3::construction_worker_woman:t3: The Challenges Team is working hard to bring you Challenge 23. Challenge 23 will be launched on :rotating_light::rotating_light: 26th September 2022​:rotating_light::rotating_light: .

And join us on

Thank you!!

Federico Pastor

The Winners_C22.pdf (1.7 MB)

7 Likes

Well done everyone, superb stuff!

3 Likes

@DavieJoe

Well, when are you coming in?..we miss you!!!

Federico

1 Like

I know, I know! I talk a lot and submit nothing :rofl:

I need to start the challenges early as I get to them late and I end up being swamped with work and don’t have as much time to commit to a decent effort. I appreciate that lots of other people are in a similar situation and still manage to submit brilliant reports, I just need to be better at starting early rather than with 4 days to go.

I will do my best to submit an entry to the next challenge, an interesting topic. Look forward to checking out the data set and brief!

3 Likes

Hi Bolaji

I really enjoyed your report and found the calendar visual heatmap particularly interesting.

I’m following along on your Calendar Heatmap article on Medium. I’m not quite sure how to build the matrix visual with the disconnected HeatMap table - I get an error saying Power BI cannot detect the relationship between the two fields? Should the two tables - DimDate and DateHeat not have a relationship between them?

For reference, I’m stuck in your explanation as below:

“Add the Quarter column from the Dates table, and the Week Index column from the Date Heat table to the rows.”

2 Likes

Thanks to everyone who participated in this challenge!

Congratulations to all the winners!

3 Likes

Great job!
Well done Gustaw…
If possible can you please share pbix file along with data sample and data dictionary for my learning.
Please drop @ khurram.powerbi@gmail.com

Thank you

1 Like

Amazing submissions, and congrats to all winners. There is so much to learn from these hacks and tricks, which greatly improve the end-user experience. I feel like I am outdated here :slight_smile:

Are we able to download Power BI Challenges pbix files? Thanks

1 Like