Last updated

PowerPoint and Word Integration

MAIDR's Office adapter reads the charts of a PowerPoint presentation or a Word document in an Office Add-in's task pane, and mounts MAIDR's accessible layer for them there: audio sonification, text descriptions, braille output, keyboard navigation and a description modal. One call does it for every Office application an add-in runs in: bindOffice(element) mounts the Excel adapter's pane in Excel, and this adapter's in PowerPoint and in Word.

Office.js has no way to read a chart in PowerPoint or Word. The adapter reads the file instead: PowerPoint hands an add-in its presentation as the file it would save, and Word hands over its body as Open XML. A chart in either is a DrawingML chart part, the same format as an Excel chart, holding a copy of each series' values as they were drawn. The adapter reads that copy into the snapshot the Excel adapter converts, so every chart type the Excel adapter reads is read here too.

What this adapter is not. It does not make PowerPoint's or Word's own chart accessible where it sits on the slide or the page. The reading is in the task pane, and the reader moves to the pane to hear it. The pane shows no picture of the chart either: neither application hands one to an add-in, and the chart is on the slide or the page beside the pane. See Limitations before you plan around it.

Looking for the add-in rather than the code? MAIDR publishes one built on this adapter, for Excel, PowerPoint and Word: MAIDR Accessible Charts.

Quick Start

An add-in is a web page an Office application opens in a task pane, and a manifest that tells it where the page is. Microsoft's PowerPoint and Word quick starts cover creating and sideloading one; MAIDR needs only the page below.

1. The task pane page

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Accessible charts</title>
    <script src="https://officeapis.public.onecdn.static.microsoft/1/office.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/maidr/dist/maidr.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/maidr/dist/office.js"></script>
  </head>
  <body>
    <main id="maidr" aria-label="Accessible charts"></main>
    <script>
      Office.onReady(() => {
        maidrOffice.bindOffice(document.getElementById('maidr'));
      });
    </script>
  </body>
</html>

bindOffice waits for Office.onReady as well, and asks it which application the page is open in: Excel, PowerPoint or Word. It appends one wrapper <div> to the element and changes nothing else. It resolves once the first chart has been read, and it never rejects: anything that stops it reading is said in the pane. An add-in for one application can call bindPowerPoint(element) or bindWord(element) directly instead.

A task pane built with a bundler imports the adapter. It is an ES module with React bundled in, and the Excel adapter with it, since bindOffice mounts Excel's pane in Excel:

npm install maidr
import { bindOffice } from 'maidr/office';

Office.onReady(() => bindOffice(document.getElementById('maidr')!));

2. The manifest

List every application the add-in runs in under Hosts — Workbook for Excel, Presentation for PowerPoint, Document for Word — and declare ReadWriteDocument permission, although the adapter writes nothing: Office requires it of any add-in that uses the Excel, PowerPoint or Word JavaScript API, even one that only reads.

<Hosts>
  <Host Name="Workbook" />
  <Host Name="Presentation" />
  <Host Name="Document" />
</Hosts>
<Permissions>ReadWriteDocument</Permissions>

Declare no requirement set the adapter needs, for the reason the Excel guide gives: an add-in left out of an older Office application is one its reader never finds, while one that opens there says in its pane why it cannot read. What each application needs is under How the Chart Is Read.

How It Works

The pane holds a native <select> labelled Chart, listing every chart of the file, then the figure area, then a Read again button. In a presentation the charts are listed slide by slide, as Slide 3: Sales by region, a hidden slide's as Slide 4 (hidden): …; in a document, in reading order, as Chart 2: Sales by region. A chart is named by the title it shows, or else by the alternative text its author gave it, or else by its name on the slide or page (Chart 3). A keyboard or screen-reader user chooses a chart from the picker, then presses Tab to reach MAIDR's figure and reads it with the usual keys.

The pane follows the file:

When there is nothing to read, the pane says why in a status message (role="status", focusable with Tab) where the figure would be: a file with no charts, a chart whose every value is blank, a chart type MAIDR does not know, a chart whose data cannot be read, a PowerPoint or Word too old to hand its file to add-ins, or a page that is not running in Office at all. If the reader was in the figure when it gave way to a message, focus moves to the message, so they hear why the chart went. A combo chart read without one of its series has a note above the figure naming what was left out.

Supported Chart Types

Every chart type the Excel adapter reads, with the same MAIDR layers: column, bar, line, pie, doughnut, pie of pie, bar of pie, scatter, bubble, area, radar, stock, surface and contour charts, and the chart types Office 2016 added — histogram, Pareto, box and whisker, waterfall, funnel, treemap, sunburst and map. A chart part's group (c:barChart, c:lineChart, and so on), grouping, direction and style are read into the Excel.ChartType Excel would report, and the chart is converted as the Excel adapter converts it; a chart of one of the newer types is read from its own part (chartExN.xml).

The file says some things Office.js does not tell the Excel adapter, so a chart in PowerPoint or Word reads them:

How the Chart Is Read

The adapter never imports Office.js. It reads the Office, PowerPoint and Word objects the page loaded structurally, so any Office.js version is accepted as it is.

A presentation's charts are found slide by slide in the order of the slide show, and on each slide in the order its shapes are drawn, charts inside groups included. A document's are found in reading order. Office often writes a chart twice, once for current versions and once as a fallback picture for older ones, inside a markup-compatibility block; the fallback is skipped, so every chart is read once.

Each chart is read from the copy of its values the part keeps, as the Excel adapter reads Office.js's answers: a blank is a gap, never a zero, unless the chart plots blanks as zeros; categories keep their order; a series without a name is called Series1, Series2, as Excel calls it; a scatter whose x values are missing or text is plotted, and read, at 1, 2, 3. The chart's title is its own, or, for a chart of one named series whose automatic title the author has not deleted, the series' name, as the application shows it. An axis title is read when the axis is shown, and a series measured on the far value axis is read against it.

Keyboard

Reaching the task pane is the application's keyboard model. In PowerPoint and Word for Windows and Mac, F6 moves focus between the main areas of the window — the document, the ribbon, the status bar and an open task pane — and Shift+F6 moves back; on the web the keys are Ctrl+F6 and Ctrl+Shift+F6. Inside the pane, Tab moves from the Chart picker to MAIDR's figure (or to the pane's message), and on to Read again.

Once the figure is focused, the standard MAIDR shortcuts apply, as in the Excel guide; the Keyboard Controls reference lists them all. A pie of pie or bar of pie is two panels, so its figure opens at MAIDR's lobby: the arrow keys choose a panel, Enter goes into it and Escape comes back out.

API Reference

bindOffice(container, options?)

Mounts the pane for the application the page is open in, and returns a Promise of its binding: bindExcel's in Excel (an ExcelBinding), and in PowerPoint and Word an OfficeBinding. Anywhere else — Outlook, or outside Office — it mounts a PowerPoint pane, which says it found no PowerPoint or Word to read. It never rejects. Its options are OfficeBindOptions, and excel for the options of Excel's pane (see ExcelBindOptions).

bindPowerPoint(container, options?) and bindWord(container, options?)

Mount one application's pane. Each returns a Promise<OfficeBinding> that resolves once the first chart has been read, and never rejects.

OfficeBindOptions

Option Type Description
office OfficeAppHost? The Office namespace. Default window.Office.
powerpoint PowerPointHost? The PowerPoint namespace. Default window.PowerPoint.
word WordHost? The Word namespace. Default window.Word.
followSelection boolean? Show the chart the user selects. Default true.
selectionDelay number? Milliseconds the selection has to settle before it is followed. Default 250.
id string? The figure id, unique on the page. Default maidr-office-<n>.
labels Partial<OfficePaneLabels>? Replacements for the pane's wording: picker, choose, refresh, reading, read ({count} is how many charts), loading, noCharts, noData, unsupported ({type} names the chart type), unreadable, partial ({series} names what was left out), noOffice, unsupportedHost ({host} names the application), readFailed, chartGone, and the picker's slide, hiddenSlide and documentChart ({n} and {title}). DEFAULT_OFFICE_LABELS holds the English defaults.

OfficeBinding

Member Type Description
host 'PowerPoint' | 'Word' The application the pane reads.
maidr Maidr | null The figure on show, or null while the pane shows a message.
chart OfficeChartInfo | null The chart on show.
charts readonly OfficeChartInfo[] Every chart the picker offers: { id, position, name, title?, description?, label }.
show (chartId?: string) => Promise<void> Show a chart by id; with no id, the chart on show, or else the first.
refresh () => Promise<void> Read the file again, as Read again does.
dispose () => Promise<void> Stop following the selection, and unmount MAIDR and the wrapper.

Reading without the pane

readPowerPointCharts(office) and readWordCharts(word) read every chart of the open file, as OfficeCharts: { id, position, name, description?, slideId?, shapeId?, hidden?, snapshot }, where snapshot is the ExcelChartSnapshot the Excel adapter's convertExcelChart turns into a MAIDR figure, or null for a chart whose part cannot be read. readChartPart(root) and readChartExPart(root) read one chart part's root element, for a file read some other way.

import { convertExcelChart, readPowerPointCharts } from 'maidr/office';

const charts = await readPowerPointCharts(Office);
const maidr = convertExcelChart(charts[0]?.snapshot);

Script tags

The UMD build (dist/office.js) exposes window.maidrOffice with bindOffice, bindPowerPoint, bindWord, bindExcel, convertExcelChart, readPowerPointCharts, readWordCharts, readChartPart, readChartExPart and DEFAULT_OFFICE_LABELS.

Type exports

The Office…, PowerPoint… and Word… interfaces exported from maidr/office are minimal structural types: only the parts of Office.js the adapter reads, so nothing here depends on @types/office-js.

Limitations

Examples

API Documentation

For the complete TypeScript API reference, see the API Documentation.