Row

This dashboard examines Australia’s progress towards Closing the Gap Target 3 – achieving 95% Aboriginal and Torres Strait Islander children enrolled in early childhood education by 2025. From 61.3% in 2016 to 94.2% in 2024, Australia has demonstrated remarkable progress and is well-positioned to achieve universal access within the target timeframe.

Row

Current Enrolment

94.2%

Gap to Target

0.8 pp

Total Progress

+32.9 pp

Time Remaining

1 year

Row

National Enrolment Trends: Journey to Universal Access

Performance by Jurisdiction: Success Stories and Priorities

Row

Indigenous vs Non-Indigenous Enrolment Comparison

Key Insights & Priorities

Status

Indigenous ECE enrolment is 94.2% (2024), up from 61.3% in 2016. Only 0.8 pp short of the 95% target.

Highlights

  • Growth: Steady increases across years
  • Leaders: 5 states already ≥95%
  • Equity: 6 states show parity with non-Indigenous

Priorities

  • Remote NT support
  • Urban access in ACT
  • Regional scale-up in NSW
  • Share lessons from high performers

Data sources
Productivity Commission. (2025). Closing the Gap – Outcome Area 3: Early childhood education. View source
RIFIC. (2025). Target 3 data platform. View source

---
title: "Closing the Gap – Early Childhood Education (Target 3)"
subtitle: "Australia’s progress towards universal access by 2025"
author: "Hannah Samson (S4116329)"
output:
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
    theme: flatly
    social: menu
    source_code: embed
---

<style>
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap');

/* Base */
body{font-family:'Open Sans',Arial,sans-serif;font-size:14px;color:#212529;line-height:1.5}
.navbar-inverse{background-color:#5126ab !important;border-color:#5126ab !important;min-height:46px}
.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav > li > a{color:#fff !important}

/* Remove grey auto H3 headings; keep our purple headers */
.section.level3 > h3{display:none !important}

/* Purple section headers + compact cards */
.section-title{background:#5126ab;color:#fff;padding:8px 16px;margin:0 0 6px 0;border-radius:6px 6px 0 0;font-size:12px;font-weight:600;text-transform:uppercase}
.chart-box{background:#fff;border:1px solid #dee2e6;border-radius:0 0 6px 6px;padding:8px;height:100%}

/* Intro panel compact */
.intro-panel{background:#fafafa;border:1px solid #dee2e6;border-left:4px solid #5126ab;padding:12px 14px;border-radius:6px;margin-bottom:6px}

/* Value boxes (4 across) */
.value-box{border:2px solid #5126ab;border-radius:6px;background:#fff !important}
.value-box .value{font-size:28px;font-weight:600;color:#5126ab !important}
.value-box .caption{font-size:11px;font-weight:500;text-transform:uppercase;color:#5126ab !important}

/* Optional centre divider for the 2×2 area */
.split-left{padding-right:10px;border-right:1px solid #eee}
.split-right{padding-left:10px}


.insights-box h4 {
  font-size: 11px;   /* smaller than current 12px */
  font-weight: 600;
  margin: 4px 0;
  color: #5126ab;
  text-transform: uppercase;
} 

</style>

```{r setup, include=FALSE}
knitr::opts_chunk$set(message=FALSE, warning=FALSE, echo=FALSE, fig.width=8, fig.height=3.2)

library(tidyverse)
library(readr)
library(scales)
library(plotly)
library(flexdashboard)
library(htmltools)

pal <- list(
  primary = "#5126ab",
  success = "#28a745",
  warning = "#ffc107",
  info    = "#17a2b8",
  danger  = "#dc3545",
  neutral = "#6c757d"
)
```

```{r data_processing, include=FALSE}
# Load CSV (ensure file exists in project)
df_raw <- read_csv("ctg-202507-ctg03-childhood-education-dataset.csv",
                   locale = locale(encoding = "latin1"))

# Tidy data
actual_data <- df_raw %>%
  filter(Description2 == "Actual",
         Description3 == "Proportion",
         Unit == "%",
         Indigenous_Status %in% c("Aboriginal and Torres Strait Islander people","Non-Indigenous people")) %>%
  select(Year, Indigenous_Status, NSW:Aust) %>%
  mutate(Year = suppressWarnings(as.numeric(Year))) %>%
  filter(!is.na(Year)) %>%
  pivot_longer(NSW:Aust, names_to = "jurisdiction", values_to = "rate_text") %>%
  mutate(rate = as.numeric(str_replace_all(rate_text, "[^0-9.]", ""))) %>%
  filter(!is.na(rate)) %>%
  mutate(rate = rate/100) %>%
  select(Year, Indigenous_Status, jurisdiction, rate)

# Metrics
target_rate <- 0.95

latest_national <- actual_data %>%
  filter(jurisdiction == "Aust",
         Indigenous_Status == "Aboriginal and Torres Strait Islander people") %>%
  arrange(desc(Year)) %>%
  slice(1)

current_rate <- latest_national$rate
current_year <- latest_national$Year

baseline_data <- actual_data %>%
  filter(jurisdiction == "Aust",
         Indigenous_Status == "Aboriginal and Torres Strait Islander people",
         Year == min(Year, na.rm = TRUE))

baseline_rate <- baseline_data$rate[1]
baseline_year <- baseline_data$Year[1]

current_pct   <- round(current_rate*100, 1)
gap_to_target <- round((target_rate - current_rate)*100, 1)
improvement   <- round((current_rate - baseline_rate)*100, 1)
years_left    <- 2025 - current_year

# National series
national_trends <- actual_data %>%
  filter(jurisdiction == "Aust") %>%
  mutate(population = if_else(Indigenous_Status == "Aboriginal and Torres Strait Islander people","Indigenous","Non-Indigenous")) %>%
  select(Year, population, rate)

# Latest state year
latest_year_states <- actual_data %>%
  filter(jurisdiction != "Aust") %>%
  summarize(y = max(Year, na.rm = TRUE)) %>% pull(y)

# State performance (Indigenous)
state_performance <- actual_data %>%
  filter(Year == latest_year_states,
         jurisdiction != "Aust",
         Indigenous_Status == "Aboriginal and Torres Strait Islander people") %>%
  mutate(
    state_name = case_when(
      jurisdiction == "NSW" ~ "New South Wales",
      jurisdiction == "Vic" ~ "Victoria",
      jurisdiction == "Qld" ~ "Queensland",
      jurisdiction == "WA"  ~ "Western Australia",
      jurisdiction == "SA"  ~ "South Australia",
      jurisdiction == "Tas" ~ "Tasmania",
      jurisdiction == "ACT" ~ "Australian Capital Territory",
      jurisdiction == "NT"  ~ "Northern Territory"
    ),
    performance = case_when(
      rate >= target_rate ~ "Exceeds target",
      rate >= 0.90        ~ "Close to target",
      TRUE                ~ "Needs support"
    )
  ) %>%
  arrange(rate) %>%
  mutate(state_name = factor(state_name, levels = state_name))

# Equity (Indigenous vs Non‑Indigenous)
equity_data <- actual_data %>%
  filter(Year == latest_year_states, jurisdiction != "Aust") %>%
  select(jurisdiction, Indigenous_Status, rate) %>%
  pivot_wider(names_from = Indigenous_Status, values_from = rate) %>%
  mutate(
    gap_pp = (`Aboriginal and Torres Strait Islander people` - `Non-Indigenous people`) * 100,
    state_name = case_when(
      jurisdiction == "NSW" ~ "New South Wales",
      jurisdiction == "Vic" ~ "Victoria",
      jurisdiction == "Qld" ~ "Queensland",
      jurisdiction == "WA"  ~ "Western Australia",
      jurisdiction == "SA"  ~ "South Australia",
      jurisdiction == "Tas" ~ "Tasmania",
      jurisdiction == "ACT" ~ "Australian Capital Territory",
      jurisdiction == "NT"  ~ "Northern Territory"
    ),
    gap_status = case_when(
      gap_pp >= 0   ~ "Indigenous ≥ Non-Indigenous",
      gap_pp >= -5  ~ "Small gap",
      TRUE          ~ "Large gap"
    )
  ) %>%
  arrange(gap_pp) %>%
  mutate(state_name = factor(state_name, levels = state_name))

exceeds_count <- sum(state_performance$performance == "Exceeds target", na.rm = TRUE)
equity_count  <- sum(equity_data$gap_status == "Indigenous ≥ Non-Indigenous", na.rm = TRUE)
```

Row {data-height=40}
-----------------------------------------------------------------------

<div class="intro-panel">
This dashboard examines Australia's progress towards <strong>Closing the Gap Target 3</strong> – achieving 95% Aboriginal and Torres Strait Islander children enrolled in early childhood education by 2025. From <strong>`r round(baseline_rate*100,1)`%</strong> in `r baseline_year` to <strong>`r current_pct`%</strong> in `r current_year`, Australia has demonstrated remarkable progress and is well-positioned to achieve universal access within the target timeframe.
</div>

Row {data-height=40}
-----------------------------------------------------------------------

### Current Enrolment {.value-box}
```{r}
valueBox(
  value = paste0(current_pct, "%"),
  caption = paste0("Indigenous ECE Enrolment (", current_year, ")"),
  icon = "fa-graduation-cap"
)
```

### Gap to Target {.value-box}
```{r}
valueBox(
  value = paste0(gap_to_target, " pp"),
  caption = "Gap to 95% Target",
  icon = "fa-bullseye"
)
```

### Total Progress {.value-box}
```{r}
valueBox(
  value = paste0("+", improvement, " pp"),
  caption = paste0("Improvement Since ", baseline_year),
  icon = "fa-arrow-up"
)
```

### Time Remaining {.value-box}
```{r}
valueBox(
  value = paste0(years_left, " year", if(years_left != 1) "s" else ""),
  caption = "Until 2025 Target",
  icon = "fa-calendar"
)
```

Row {data-height=180}
-----------------------------------------------------------------------

### 
<div class="section-title">National Enrolment Trends: Journey to Universal Access</div>
<div class="chart-box">

```{r}
p1 <- national_trends %>%
  ggplot(aes(Year, rate, colour = population)) +
  geom_hline(yintercept = target_rate, linetype = "dashed", 
             colour = pal$danger, linewidth = 1.2) +
  geom_line(linewidth = 1.5) + 
  geom_point(size = 2.5) +
  scale_colour_manual(
    values = c("Indigenous" = pal$primary, "Non-Indigenous" = pal$neutral),
    name = "Population"
  ) +
  scale_y_continuous(
    labels = percent_format(accuracy = 1), 
    limits = c(0.55, 1.05), 
    breaks = seq(0.6, 1.0, 0.1)
  ) +
  scale_x_continuous(breaks = pretty_breaks(6)) +
  labs(
    title = "Early Childhood Education Enrolment Rates",
    subtitle = "Dashed line shows 95% target",
    x = "Year", 
    y = "Enrolment Rate"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    legend.position = "bottom",
    legend.title = element_blank(),
    panel.grid.minor = element_blank(),
    plot.title = element_text(size = 12, face = "bold", colour = pal$primary),
    plot.subtitle = element_text(size = 10, colour = pal$neutral)
  )

ggplotly(p1, tooltip = c("x", "y", "colour"))
```

</div>

### 

<div class="section-title">Performance by Jurisdiction: Success Stories and Priorities</div>
<div class="chart-box">

```{r}
p2 <- state_performance %>%
  mutate(rate_pct = scales::percent(rate, accuracy = 0.1)) %>%
  ggplot(aes(
    x = reorder(state_name, rate),
    y = rate,
    fill = performance,
    text = paste0(
      "Jurisdiction: ", state_name,
      "<br>Enrolment: ", rate_pct,
      "<br>Performance: ", performance
    )
  )) +
  geom_col(width = 0.7) +
  geom_hline(yintercept = target_rate, linetype = "dashed",
             colour = pal$danger, linewidth = 1.2) +
  coord_flip() +
  scale_y_continuous(labels = percent_format(accuracy = 1),
                     limits = c(0, 1.1), expand = c(0, 0)) +
  scale_fill_manual(values = c(
    "Exceeds target" = pal$success,
    "Close to target" = pal$info,
    "Needs support"  = pal$warning
  ), name = "Performance") +
  labs(
    title = paste0("Indigenous ECE Enrolment by Jurisdiction (", latest_year_states, ")"),
    subtitle = "Dashed line shows 95% target",
    x = NULL, y = "Enrolment Rate"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    legend.position = "bottom",
    legend.title = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor = element_blank(),
    plot.title = element_text(size = 12, face = "bold", colour = pal$primary),
    plot.subtitle = element_text(size = 10, colour = pal$neutral)
  )

ggplotly(p2, tooltip = "text") %>%
  layout(margin = list(t = 0, r = 10, b = 40, l = 60))

```

</div>

Row {data-height=180}
-----------------------------------------------------------------------

### 

<div class="section-title">Indigenous vs Non-Indigenous Enrolment Comparison</div>
<div class="chart-box">

```{r}
p3 <- equity_data %>%
  ggplot(aes(
    reorder(state_name, gap_pp),
    gap_pp,
    fill = gap_status,
    text = paste0(
      "State: ", state_name,
      "<br>Gap: ", round(gap_pp, 1), " pp",
      "<br>Status: ", gap_status
    )
  )) +
  geom_hline(yintercept = 0, colour = pal$neutral, linewidth = 1.2) + 
  geom_col(width = 0.7) + 
  coord_flip() +
  scale_fill_manual(
    values = c(
      "Indigenous ≥ Non-Indigenous" = pal$success,
      "Small gap" = pal$info,
      "Large gap" = pal$warning
    ),
    name = "Equity Status"
  ) +
  labs(
    title = paste0("Enrolment Gap Analysis (", latest_year_states, ")"),
    subtitle = "Positive values show Indigenous rates exceed Non-Indigenous",
    x = NULL, 
    y = "Percentage Points (Indigenous − Non-Indigenous)"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    legend.position = "bottom",
    panel.grid.major.y = element_blank(),
    panel.grid.minor = element_blank(),
    plot.title = element_text(size = 12, face = "bold", colour = pal$primary),
    plot.subtitle = element_text(size = 10, colour = pal$neutral)
  )

ggplotly(p3, tooltip = "text")
```

</div>

### 

<div class="section-title">Key Insights & Priorities</div>

<div class="insights-box">
<h4>Status</h4>
Indigenous ECE enrolment is <span class="highlight">`r current_pct`%</span> (`r current_year`), up from <span class="highlight">`r round(baseline_rate*100,1)`%</span> in `r baseline_year`. Only <span class="highlight">`r gap_to_target` pp</span> short of the 95% target.

<h4>Highlights</h4>
<ul>
<li><strong>Growth:</strong> Steady increases across years</li>
<li><strong>Leaders:</strong> `r exceeds_count` states already ≥95%</li>
<li><strong>Equity:</strong> `r equity_count` states show parity with non-Indigenous</li>
</ul>

<h4>Priorities</h4>
<ul>
<li>Remote NT support</li>
<li>Urban access in ACT</li>
<li>Regional scale-up in NSW</li>
<li>Share lessons from high performers</li>
</ul>

<div class="references">
<strong>Data sources</strong><br>
Productivity Commission. (2025). Closing the Gap – Outcome Area 3: Early childhood education. 
<a href="https://www.pc.gov.au/closing-the-gap-data/dashboard/se/outcome-area3" target="_blank">View source</a><br>
RIFIC. (2025). Target 3 data platform. 
<a href="https://www.rific.gov.au/closing-the-gap?app=rific&code=ctg&release=r3&latitude=-24&longitude=134&region=Target3_AUS" target="_blank">View source</a>