Skip to contents

mschart2 keeps the full mschart API and adds native Microsoft Office chart elements that the original package could not produce. This vignette is a guided tour of those additions, built around a small workplace-analytics dataset so the examples resemble a real report.

Every chart below is a genuine, editable Office chart: once dropped into a PowerPoint, Word or Excel file with officer, the data travels with the chart and stays live.

The examples here use compact, self-contained data so the vignette always builds. A fuller version of this tour - driven by the real vivainsights::pq_data person-query dataset and rendered to a multi-slide deck - lives in the package’s showcase/ folder (showcase/vivainsights_showcase.R and showcase/chartex_bugbash.R).

A workplace-analytics dataset

We use a small frame of weekly collaboration metrics for a handful of organizations. The shape mirrors a Viva Insights person query: one row per person per week, with organization, level and a few numeric metrics.

set.seed(2024)
orgs <- c("Finance", "IT", "Research", "Sales")
levels <- c("Junior IC", "Senior IC", "Senior Manager", "Executive")

pq <- expand.grid(
  Organization = orgs,
  Level = levels,
  Week = 1:6,
  stringsAsFactors = FALSE
)
pq$Collaboration_hours <- round(runif(nrow(pq), 15, 45), 1)
pq$Meeting_hours <- round(runif(nrow(pq), 5, 20), 1)
pq$Emails_sent <- round(runif(nrow(pq), 10, 60))

# A per-organization summary we will reuse.
collab_by_org <- aggregate(
  Collaboration_hours ~ Organization,
  data = pq, FUN = mean
)
head(collab_by_org)
#>   Organization Collaboration_hours
#> 1      Finance            27.67500
#> 2           IT            29.01667
#> 3     Research            31.23750
#> 4        Sales            30.86250

Rich titles: title, subtitle and alignment

chart_title() sets the title text, adds a native subtitle line, and controls horizontal alignment - all as real c:title content.

bc <- ms_barchart(
  data = collab_by_org, x = "Organization", y = "Collaboration_hours"
)
bc <- chart_title(
  bc,
  title = "Average weekly collaboration hours",
  subtitle = "By organization",
  align = "left"
)

Footers / source notes

chart_footer() adds a caption along the bottom edge of the chart - handy for a data source - rendered as a native chart text box (c:userShapes).

bc <- chart_footer(bc, text = "Source: internal analytics, 2024", align = "left")

One font for every text element

chart_font() restyles all of a chart’s text (title, subtitle, axis titles, tick labels, legend, data labels and footer) in a single call. Omit size to swap the typeface while keeping the theme’s relative sizing. Axis titles accept spaces and special characters such as #, & and parentheses.

bc <- chart_labels(
  bc,
  xlab = "# of distinct organizations",
  ylab = "Collaboration hours (avg) & focus"
)
bc <- chart_font(bc, family = "Calibri")

Error bars

chart_error_bars() adds native error bars: fixed value, percentage, standard deviation, standard error, or fully custom plus/minus vectors.

se <- aggregate(
  Collaboration_hours ~ Organization,
  data = pq,
  FUN = function(v) sd(v) / sqrt(length(v))
)$Collaboration_hours

bc <- chart_error_bars(
  bc, type = "cust", plus = se, minus = se, direction = "both", errdir = "y"
)

Number-format helpers

The fmt_*() helpers build Office number-format codes so you do not have to remember the raw Excel strings.

bc <- chart_ax_y(bc, num_fmt = fmt_number(decimals = 1))
# Other helpers: fmt_percent(), fmt_thousands(), fmt_millions(),
# fmt_billions(), fmt_currency(), fmt_scientific().

Trendlines

chart_trendline() adds a native fit line to a line or scatter series - linear, polynomial, exponential, logarithmic, power or moving-average - with optional equation and R-squared display.

weekly <- aggregate(Meeting_hours ~ Week, data = pq, FUN = mean)
weekly$series <- "All"

lc <- ms_linechart(
  data = weekly, x = "Week", y = "Meeting_hours", group = "series"
)
lc <- chart_trendline(lc, series = "All", type = "movingAvg", period = 2)

Reference / target lines

chart_reference_line() draws a constant-value line (a target, budget or average) that shares the chart’s axes. Call it repeatedly for several lines.

lc <- chart_reference_line(
  lc,
  value = mean(weekly$Meeting_hours),
  label = "Overall mean",
  colour = "red",
  line_style = "dash"
)

Multi-level (nested) category axis

chart_multilevel_axis() turns the category axis into a native two-row axis, merging the outer level across the categories it spans.

nested <- aggregate(
  Meeting_hours ~ Organization + Level, data = pq, FUN = mean
)
nested <- nested[order(nested$Organization, nested$Level), ]

nc <- ms_barchart(data = nested, x = "Level", y = "Meeting_hours")
nc <- chart_multilevel_axis(nc, levels = c("Organization", "Level"))

Data-label leader lines

chart_labels_leaders() enables native leader lines - most useful on a pie or doughnut chart with labels pushed outside the slices.

pie_df <- aggregate(Collaboration_hours ~ Organization, data = pq, FUN = sum)

pie <- ms_piechart(
  data = pie_df, x = "Organization", y = "Collaboration_hours"
)
pie <- chart_data_labels(pie, show_percent = TRUE, position = "outEnd")
pie <- chart_labels_leaders(pie, show = TRUE)

Per-point data labels

chart_labels_at() targets an individual point: delete its label, or restyle it with its own number format, position or text formatting.

emails <- aggregate(Emails_sent ~ Organization, data = pq, FUN = mean)

eb <- ms_barchart(data = emails, x = "Organization", y = "Emails_sent")
eb <- chart_data_labels(eb, show_val = TRUE, position = "outEnd")
busiest <- which.max(emails$Emails_sent)
eb <- chart_labels_at(
  eb, index = busiest,
  text = officer::fp_text(bold = TRUE, color = "red", font.size = 12)
)

chartEx charts

mschart2 also carries the full set of “chartEx” (Office 2016+) chart types. Each is built the same way as a classical chart.

# Box plot - distribution of a metric by group
bp <- ms_boxplotchart(
  data = pq, x = "Organization", y = "Collaboration_hours",
  show_mean_marker = TRUE, show_outliers = TRUE
)

# Treemap and sunburst - a hierarchy of value
hier <- aggregate(
  Collaboration_hours ~ Organization + Level, data = pq, FUN = sum
)
tm <- ms_treemapchart(
  data = hier, path = c("Organization", "Level"), value = "Collaboration_hours"
)
sb <- ms_sunburstchart(
  data = hier, path = c("Organization", "Level"), value = "Collaboration_hours"
)

# Funnel - a descending sequence
funnel_df <- aggregate(Emails_sent ~ Level, data = pq, FUN = sum)
funnel_df <- funnel_df[order(-funnel_df$Emails_sent), ]
fn <- ms_funnelchart(data = funnel_df, x = "Level", y = "Emails_sent")

# Pareto and histogram
pareto_df <- aggregate(Emails_sent ~ Organization, data = pq, FUN = sum)
pr <- ms_paretochart(data = pareto_df, x = "Organization", y = "Emails_sent")
hg <- ms_histogramchart(data = pq, value = "Collaboration_hours", bin_count = 8)

# Waterfall - contributions plus a subtotal bar
wf_df <- rbind(
  collab_by_org,
  data.frame(Organization = "Total", Collaboration_hours = 0)
)
wf <- ms_waterfallchart(
  data = wf_df, x = "Organization", y = "Collaboration_hours",
  subtotals = nrow(wf_df)
)

Sending charts to a document

Any chart object above can be placed into a PowerPoint, Word or Excel file with officer. The data is embedded automatically and remains editable.

library(officer)

doc <- read_pptx()
doc <- add_slide(doc, "Title and Content", "Office Theme")
doc <- ph_with(doc, bc, location = ph_location_fullsize())
print(doc, target = "collaboration.pptx")

Use print(chart, preview = TRUE) to open a single chart in PowerPoint while iterating.

Capability matrix

The table below summarises which native features mschart2 adds on top of the original mschart API. Everything from mschart continues to work unchanged.

Feature Function Applies to New in mschart2
Trendline / fit line chart_trendline() bar, line, scatter Yes
Error bars chart_error_bars() bar, line, scatter Yes
Multi-level category axis chart_multilevel_axis() bar, line, area Yes
Reference / target line chart_reference_line() bar, line Yes
Rich title + subtitle + alignment chart_title() all classical Yes
Footer / source note chart_footer() all classical Yes
One-call font for all text chart_font() all charts Yes
Data-label leader lines chart_labels_leaders() pie, doughnut, … Yes
Per-point data labels chart_labels_at() all classical Yes
Number-format helpers fmt_number(), fmt_percent(), … axes, labels Yes
Box plot ms_boxplotchart() - Yes
Histogram ms_histogramchart() - Yes
Pareto ms_paretochart() - Yes
Treemap ms_treemapchart() - Yes
Sunburst ms_sunburstchart() - Yes
Funnel ms_funnelchart() - Yes
Waterfall ms_waterfallchart() - Yes

For the underlying issues each feature addresses, see NEWS.md.