Functions
applyThemeStyle
function applyThemeStyle(look: ShapeLook, style: ShapeStyleReference | undefined, theme: Theme): ShapeLook
Fills in what a shape leaves to the theme.
What the shape states itself always wins: `p:style` is the default, and
`p:spPr` is the override. A shape that turns its fill off states that too,
and `filled: false` is respected rather than overwritten.
colorOf
function colorOf(container: XmlElement | undefined): DiagramColor | undefined
The colour inside a container such as `a:solidFill` or `a:fillRef`.
dashArray
function dashArray(dash: string | undefined, strokeWidth: number): string | undefined
fillCss
function fillCss(fill: DiagramFill | undefined, themeColor: ThemeColorLookup): string | undefined
A fill as a CSS background.
A gradient becomes a gradient, a pattern becomes a repeating one — CSS has no
hatch, and a striped background at the right density and angle reads as the
same texture — and a picture returns nothing, because the caller has to
resolve the part before it can name a URL.
fillOf
function fillOf(properties: XmlElement | undefined): DiagramFill | undefined
Reads whichever fill a shape's properties carry.
The five are alternatives in the schema and the first one found wins, which
is also what the schema says: a shape has one fill.
geometryOf
function geometryOf(properties: XmlElement | undefined): DiagramGeometry | undefined
Reads `p:spPr`/`xdr:spPr`: what shape the shape is.
`a:prstGeom` names one of the specification's shapes and adjusts it;
`a:custGeom` writes the outline out. Both are read here, into one type, so
that a slide and a worksheet describe an arrow the same way and the renderer
that draws one draws the other.
geometryPath
function geometryPath(geometry: DiagramGeometry | undefined, box: GeometryBox): ShapeOutlinePath | undefined
The path a geometry describes, or nothing when it is one CSS handles.
A zero-sized box has no path: a shape whose frame the file never stated would
otherwise produce `M 0 0 Z`, which paints a dot at the corner of the slide.
hasPreset
function hasPreset(preset: string | undefined): boolean
Whether a preset is one this library can draw.
isCssGeometry
function isCssGeometry(preset: string | undefined): boolean
The three shapes CSS draws better than an SVG path would.
A rectangle is a div, a rounded rectangle is a border-radius, and an ellipse
is a fifty-per-cent one. Those three are 2 568 of the corpus's 4 311 shapes,
and routing them through a path would trade working code for a redraw.
outlineOf
function outlineOf(line: XmlElement | undefined): DiagramOutline | undefined
`a:ln`: the width, the dash pattern and the colour it is stroked with.
parseChart
function parseChart(parser: XmlPullParser): ChartDefinition
Parses a whole chart part.
parseTheme
function parseTheme(root: XmlElement): Theme
Reads a theme part whole.
presetOf
function presetOf(geometry: string | DiagramGeometry | undefined): string | undefined
The preset's name, whichever of the two forms the look carries.
readColorContainer
function readColorContainer(parser: XmlPullParser): DiagramColor | undefined
Reads the colour inside a container such as `a:solidFill`.
Every colour model shares one shape: an element that names the colour, with
the transforms applied to it as its children.
readGeometry
function readGeometry(parser: XmlPullParser): DiagramGeometry
Reads `a:prstGeom` or `a:custGeom` from a stream.
The DOM reader in `element.ts` answers the same question for the formats that
parse a drawing into a tree first. A document does not: `word/document.xml`
is read once, in order, and so the shape of a shape has to be taken as it
goes past.
The parser must be positioned on the geometry element itself; it is consumed
whole.
readOutline
function readOutline(parser: XmlPullParser): DiagramOutline
Reads `a:ln`: width, dash pattern and the colour it is stroked with.
renderChart
function renderChart(context: ChartRenderContext, chart: ChartDefinition, widthEmu: number | undefined, heightEmu: number | undefined): HTMLElement
Renders a chart part into an element of the given frame size.
resolveColor
function resolveColor(themeColor: ThemeColorLookup, color: DiagramColor | undefined): string | undefined
Turns a DrawingML colour into CSS.
The transforms are applied in the order they were written, because they
compose: SmartArt colour lists shift hue, saturation and luminance together to
derive one node's colour from the previous one, and applying them in a fixed
order of our own choosing produces a different palette.
shadowCss
function shadowCss(shadow: DiagramShadow | undefined, themeColor: ThemeColorLookup): string | undefined
A shadow as CSS.
The file states a distance and a direction; CSS wants two offsets, so the
angle is resolved into them. The blur radius is DrawingML's, which is twice
what CSS calls one — a `blurRad` of 40 000 EMUs is a soft edge four pixels
wide, not eight.
shadowOf
function shadowOf(properties: XmlElement | undefined): DiagramShadow | undefined
Reads `a:effectLst`: what the shape does beyond its own outline.
Only the shadow, and only the first one: a shape may state a glow, a
reflection and a soft edge as well, and of the corpus's 1 044 effect lists
784 hold a shadow while three hold a glow. The shadow is what shows.
shapeCss
function shapeCss(shape: ShapeLook, box: { width: number; height: number; }, themeColor: ThemeColorLookup): ShapeCss
The declarations that draw a shape.
The geometry is honoured as far as CSS can take it: a rectangle is a
rectangle, rounded corners are a radius, an ellipse is a radius of half.
Everything else is drawn as its bounding rectangle — which the corpus says is
a fair trade, since of the 2 862 shapes in it 2 827 are plain rectangles and
34 are rounded ones.
shapeOutlineSvg
function shapeOutlineSvg(ownerDocument: Document, shape: ShapeLook, box: GeometryBox, themeColor: ThemeColorLookup, options?: { className?: string; scale?: number; }): { element: SVGElement; path: ShapeOutlinePath; } | undefined
The shape's outline as an SVG, for the geometries CSS cannot draw.
Returned rather than appended so that the caller decides where it goes; every
viewer puts it behind the shape's text, which the browser lays out in the
shape's own box.
The path is painted with the shape's own fill and line. A path the file marks
as unfilled — a brace, a connector, a freehand squiggle — is stroked only,
whatever fill the shape carries, because filling it would blot the slide.
styleOf
function styleOf(style: XmlElement | undefined): ShapeStyleReference | undefined
Reads `p:style`, `xdr:style` or `wps:style`: how the theme paints the shape.
The element is in the format's own namespace but everything inside it is
DrawingML, which is why one reader serves all three.
themeColors
function themeColors(root: XmlElement): ThemeColorLookup
Builds a lookup from a theme part.
The pairs are aliases: `tx1` is `dk1` and `bg1` is `lt1`, which is how a
chart and a cell can name the same colour differently.
themeFill
function themeFill(reference: StyleReference | undefined, theme: Theme): DiagramColor | undefined
The colour of the theme entry a fill reference names.
themeLine
function themeLine(reference: StyleReference | undefined, theme: Theme): DiagramOutline | undefined
The line of the theme entry a line reference names.
Interfaces
ChartAxis
interface ChartAxis
position
"l" | "r" | "b" | "t"
`c:axPos`: `l`, `r`, `b` or `t`.
kind
"category" | "value" | "date" | "series"
Whether the axis is a category axis, a value axis or a date axis.
deleted
boolean
`c:delete`, an axis that is present in the file and not on the page.
reversed
boolean
`c:scaling/c:orientation`; `maxMin` reverses the axis.
numberFormat
string | undefined
`c:numFmt/@formatCode`, the format the tick labels are printed in.
labelled
boolean
Whether tick labels are drawn at all, from `c:tickLblPos`.
line
DiagramOutline | undefined
The axis line itself, `c:spPr/a:ln`.
text
ChartTextStyle | undefined
`c:txPr`: the type its tick labels are set in.
majorTickMark
string | undefined
`c:majorTickMark`: `none`, `in`, `out` or `cross`.
crossBetween
string | undefined
`c:crossBetween`: whether the marks sit between the ticks or on them.
`between` puts a bar in the middle of its band, which is what a bar chart
wants; `midCat` puts a line's first point on the axis itself, which is what
a line chart wants and what makes its curve start at the left edge instead
of half a band in.
ChartDefinition
interface ChartDefinition
A chart part, reduced to what is drawn.
legend
ChartLegendPosition | undefined
fill
DiagramColor | undefined
Fill of the whole chart area, `c:chartSpace/c:spPr`.
outline
DiagramOutline | undefined
plotFill
DiagramColor | undefined
Fill of the plot area, which is usually absent and then transparent.
blanks
"gap" | "zero" | "span"
`c:dispBlanksAs`: what a plot does where its data has a hole.
`gap` leaves the mark out, `zero` draws it on the floor, `span` joins across
it. Word's own default is `gap`, and a series of measurements taken weekly
with a fortnight missing looks entirely different under each of the three.
ChartPlot
interface ChartPlot
One `c:*Chart` inside the plot area.
direction
"bar" | "col"
`c:barDir`: `col` for vertical bars, `bar` for horizontal ones.
gapWidth
number
Space between category groups as a percentage of bar width, `c:gapWidth`.
overlap
number
How far bars of one category overlap, as a percentage, `c:overlap`.
holeSize
number
Hole of a doughnut as a percentage of its diameter, `c:holeSize`.
markers
boolean
Whether a line plot draws markers at its points.
varyColors
boolean
`c:varyColors`: paint each point of the plot differently.
What makes a one-series bar chart a row of coloured bars rather than a row
of identical ones, and it is on by default for a pie — where it is the only
thing that tells one slice from the next.
scatterStyle
string | undefined
`c:scatterStyle`: whether a scatter plot joins its points, and with what.
`marker` is a cloud of points with no line; `line` and `lineMarker` join
them with segments; `smooth` and `smoothMarker` with a curve.
showValues
boolean
Whether the plot asks for its values to be printed beside every mark.
axisIds
readonly string[]
Axis ids this plot is drawn against, in the order they were declared.
ChartPoint
interface ChartPoint
One value of a series, with the point it belongs to.
ChartRenderContext
interface ChartRenderContext
What drawing a chart needs from the application around it.
Two things and no more: a document to create elements in, and the theme's
answer for a colour slot. Deliberately this narrow — the renderer used to
take the Word view's whole render context, and that is the only reason it
could not be used from a spreadsheet.
themeColor
ThemeColorLookup
Resolves a theme colour slot such as `accent1`.
classPrefix?
string | undefined
Prefix for the generated class names, so each host keeps its own.
ChartSeries
interface ChartSeries
One series of a plot.
name
string | undefined
`c:tx`, the cached series name.
categories
readonly (string | undefined)[]
Category labels, from `c:cat`; sparse points are `undefined`.
values
readonly (number | undefined)[]
Values, from `c:val` or `c:yVal`.
xValues
readonly (number | undefined)[] | undefined
Horizontal values of a scatter or bubble plot, from `c:xVal`.
sizes
readonly (number | undefined)[] | undefined
Bubble sizes, from `c:bubbleSize`.
outline
DiagramOutline | undefined
invertIfNegative
boolean
`c:invertIfNegative`, a bar below zero drawn in the inverse of its fill.
pointFills
ReadonlyMap<number, DiagramColor>
`c:dPt`, one point painted differently from the rest of its series.
smooth
boolean
`c:smooth`, a line drawn as a spline rather than as segments.
marker
string | undefined
`c:marker/c:symbol`; `none` when the series asks for no marker.
showValues
boolean
Whether the series asked for its values to be printed beside the marks.
order
number
Order the series is drawn and listed in, `c:order`.
ChartTextStyle
interface ChartTextStyle
The text of one part of a chart, `c:txPr/a:pPr/a:defRPr`.
A chart states its type sizes rather than inheriting them from the page: an
axis whose labels are 9pt says so, and drawing them at the renderer's own
default is a chart whose every label is the wrong size — which is what
`long_legendentry` measures as 13.33px against Word's 12.
sizePoints
number | undefined
`a:defRPr/@sz`, in points.
CustomGeometry
interface CustomGeometry
`a:custGeom`: one or more outlines, each in its own coordinate space.
width
number
The shape's own extent in EMUs, which is the space a path that declares
none is written in.
Without it such a path is drawn in EMUs against a box measured in pixels —
ten thousand times too large, and what reaches the screen is a few stray
strokes where a rounded box should be.
DiagramColor
interface DiagramColor
kind
"srgb" | "scheme" | "system"
`srgb` is literal, `scheme` refers to the theme, `system` to the host.
value
string
Hex digits, a theme slot name, or the last colour Word saw for a system slot.
transforms
readonly DiagramColorTransform[]
DiagramColorTransform
interface DiagramColorTransform
One transform applied to a colour, `a:lumMod` and its siblings.
Kept as a list rather than resolved fields because the transforms compose in
document order, and SmartArt relies on that: a colour list shifts hue,
saturation and luminance together to spread one accent colour across the
nodes of a diagram.
name
string
Local name, such as `lumMod`, `satOff`, `hueOff`, `alpha`, `tint`.
value
number
Percentages as a fraction; `hueMod` and `hueOff` in degrees.
DiagramGeometry
interface DiagramGeometry
What shape a shape is: a named preset with its adjustments, or an outline
written out point by point.
The two are alternatives in the file (`a:prstGeom` or `a:custGeom`) and are
kept as alternatives here. The preset's name matters even when the renderer
cannot draw it — a `rect` is a div and needs no path at all — so the name is
carried rather than resolved at parse time.
preset
string | undefined
`a:prstGeom/@prst`, or `undefined` for a custom outline.
adjustments
Readonly<Record<string, number>>
`a:avLst`: the preset's adjust values, by name, as the file states them.
custom
CustomGeometry | undefined
DiagramOutline
interface DiagramOutline
dash
string | undefined
`a:prstDash/@val`, such as `dash` or `sysDot`.
cap?
"round" | "square" | "flat" | undefined
`a:ln/@cap`: how the line ends, `rnd`, `sq` or flat.
join?
"round" | "bevel" | "miter" | undefined
`a:round`/`a:bevel`/`a:miter`: how two segments meet.
headEnd?
DiagramLineEnd | undefined
`a:headEnd` and `a:tailEnd`: what the line carries at each end.
An arrow is the difference between a diagram that says "A causes B" and one
that says the two are related: 185 lines of the corpus carry one, and drawn
without it a flow chart loses its direction.
tailEnd?
DiagramLineEnd | undefined
DiagramShadow
interface DiagramShadow
`a:outerShdw`: the shadow a shape casts.
Stated as a distance and a direction rather than as two offsets, because that
is how a drawing application asks for one: "ten points, down and to the
right". Seven hundred and eighty-four shapes of the corpus cast one, and a
panel drawn without its shadow sits flat against the slide behind it.
blurEmu
number
`@blurRad`, in EMUs.
distanceEmu
number
`@dist`, in EMUs: how far the shadow is thrown.
directionDegrees
number
`@dir`, in degrees clockwise from the positive x axis.
inner
boolean
`a:innerShdw` rather than `a:outerShdw`.
GeometryBox
interface GeometryBox
The box a shape is drawn in, in pixels.
GeometryPath
interface GeometryPath
width
number
`a:path/@w` and `@h`; zero means the coordinates are the shape's own.
filled
boolean
`@fill="none"` draws an open figure — a squiggle rather than a blob.
commands
readonly GeometryCommand[]
GradientStop
interface GradientStop
position
number
`@pos`, as a fraction of the way along.
ShapeLook
interface ShapeLook
The look of a shape, as much of it as the format states.
Every field is optional because the formats state different amounts: a
spreadsheet shape carries text insets and a wrap flag, a slide shape carries
neither, and both carry a geometry, a fill and an outline.
geometry?
string | DiagramGeometry | undefined
The shape's geometry: its preset name, or the whole record.
Both are accepted because both are useful. The CSS below needs only the
name — a rounded rectangle is a border-radius — while an arrow needs the
adjust values and a freeform needs its points, and those live on the record
that {@link geometryPath} turns into a path.
outline?
DiagramOutline | undefined
shadow?
DiagramShadow | undefined
`a:effectLst/a:outerShdw`, when the shape casts one.
paint?
DiagramFill | undefined
The fill as the file states it, when it is not a flat colour.
`fill` above is the solid case, which is what most shapes have and what
every caller already reads. This carries the other four — gradient,
pattern, picture, none — and wins over `fill` when it is present.
typeface?
string | undefined
The typeface the shape's `a:fontRef` resolves to, if any.
fontSize?
number | undefined
Point size in hundredths, as `a:rPr/@sz` states it.
insets?
{ left: number; top: number; right: number; bottom: number; } | undefined
horizontalAlignment?
"left" | "center" | "right" | "justify" | undefined
verticalAlignment?
"center" | "top" | "bottom" | undefined
ShapeOutlinePath
interface ShapeOutlinePath
Where a shape's outline is drawn and how it is painted.
d
string
The `d` attribute of an SVG path, in the box's pixel space.
fillRule
"nonzero" | "evenodd"
`evenodd` for shapes with a hole in them: a ring, a frame, a donut.
filled
boolean
Whether the path encloses an area at all, or is a stroke such as a brace.
ShapeStyleReference
interface ShapeStyleReference
`p:style`: the four references a shape is painted by.
fill
StyleReference | undefined
line
StyleReference | undefined
effect
StyleReference | undefined
font
{ readonly typeface: "major" | "minor" | "none"; readonly color: DiagramColor | undefined; } | undefined
`a:fontRef`, whose `@idx` is `major`, `minor` or `none`.
StyleReference
interface StyleReference
One `a:fillRef`/`a:lnRef`/`a:effectRef`/`a:fontRef`.
index
number
`@idx`: which entry of the theme's list, one-based. Zero means none.
color
DiagramColor | undefined
The colour that replaces the entry's `phClr` placeholder.
Theme
interface Theme
The whole theme, not just its colours.
A shape rarely states how it is painted. It states a *reference* — "the
second fill of the theme, in accent 1" — and the theme's `a:fmtScheme` holds
the three fills, the three lines and the three effect sets that every shape
in the deck is drawn from. Thirty per cent of the corpus's slides have shapes
like that, and without the format scheme they are drawn with no fill at all,
which is how a SmartArt diagram comes out as invisible text on white.
color
ThemeColorLookup
A theme colour by its slot name.
fills
readonly ThemeFill[]
`a:fillStyleLst`: the subtle, moderate and intense fills, in order.
lines
readonly DiagramOutline[]
`a:lnStyleLst`, in the same order.
backgrounds
readonly ThemeFill[]
`a:bgFillStyleLst`: the same three, for backgrounds.
fonts
{ readonly major: string | undefined; readonly minor: string | undefined; }
`a:fontScheme`: the deck's two typefaces.
ThemeFill
interface ThemeFill
One entry of the theme's fill list.
Every colour in it is `phClr` — the placeholder the referring shape fills in
— carrying the transforms that make the entry what it is: the "moderate" fill
is the shape's own colour tinted and lightened. Only the first colour is
kept, because a gradient drawn as its first stop is much closer than a
gradient drawn as nothing.
gradient
boolean
Whether the entry was a gradient rather than a flat colour.
picture?
string | undefined
`a:blipFill`: the picture this entry paints with, by relationship id.
Office themes carry their textured backgrounds here — the third entry of
`a:bgFillStyleLst` is a photograph in a good many of them — and a master
that names it with `p:bgRef idx="1003"` is asking for that photograph and
nothing else. Resolved against the *theme* part, which is where the
relationship lives.
Type aliases
ChartGrouping
type ChartGrouping = 'clustered' | 'stacked' | 'percentStacked' | 'standard'
`c:grouping`, which decides whether values stack.
ChartKind
type ChartKind = | 'bar'
| 'line'
| 'pie'
| 'doughnut'
| 'area'
| 'scatter'
| 'bubble'
| 'radar'
| 'stock'
| 'surface'
How the marks of one plot are laid out.
ChartLegendPosition
type ChartLegendPosition = 'l' | 'r' | 't' | 'b' | 'tr'
Where the legend goes, `c:legendPos`.
DiagramFill
type DiagramFill = | { readonly kind: 'solid'; readonly color: DiagramColor | undefined }
| {
readonly kind: 'gradient';
readonly stops: readonly GradientStop[];
/** `a:lin/@ang` in degrees clockwise; a path gradient has no angle. */
readonly angleDegrees: number;
/** `a:path`: the gradient radiates rather than sweeps. */
readonly radial: boolean;
}
| {
readonly kind: 'pattern';
/** `@prst`: `pct25`, `ltDnDiag`, `narVert` and seven dozen others. */
readonly preset: string;
readonly foreground: DiagramColor | undefined;
readonly background: DiagramColor | undefined;
}
| {
readonly kind: 'picture';
/** `a:blip/@r:embed`: the part holding the image. */
readonly relationshipId: string | undefined;
readonly tile: boolean;
}
| { readonly kind: 'none' }
How a shape is filled, when a flat colour is not the answer.
`a:solidFill` is one of five, and the other four were all drawn as nothing: a
gradient panel, a hatched box, a shape filled with a photograph and a shape
explicitly filled with nothing came out identical — unpainted.
GeometryCommand
type GeometryCommand = | { readonly kind: 'move'; readonly x: number; readonly y: number }
| { readonly kind: 'line'; readonly x: number; readonly y: number }
| {
readonly kind: 'cubic';
readonly x1: number;
readonly y1: number;
readonly x2: number;
readonly y2: number;
readonly x: number;
readonly y: number;
}
| {
readonly kind: 'quadratic';
readonly x1: number;
readonly y1: number;
readonly x: number;
readonly y: number;
}
| {
/** `a:arcTo`: two radii and a turn, rather than a destination. */
readonly kind: 'arc';
readonly radiusX: number;
readonly radiusY: number;
/** Sixtieths of a degree, as the file states them. */
readonly startAngle: number;
readonly swingAngle: number;
}
| { readonly kind: 'close' }
ShapeCss
type ShapeCss = Partial<Record<string, string>>
ThemeColorLookup
type ThemeColorLookup = (slot: string) => string | undefined
How a chart finds out what a theme slot is worth.