Core guide 02
Choose a course. Define a graphic.
A graphic request identifies measured course data, selects a hole, green, complete course, or side-view elevation profile, and defines the clean artifact that every authorized overlay must match.
Courses
Start with a stable CADDIE.100 course ID.
listCourses returns the licensed course directory available to the current publishable key. Use the stable course ID in every subsequent request instead of relying on a display name.
const courses = await caddie.listCourses();
const raymondMemorial = courses.find(
(course) => course.name === "Raymond Memorial",
);Pass an AbortSignal through the optional operation options when course search belongs to a component that may unmount or issue a newer request.
Browser reuse
Reuse verified pixels without weakening overlay authorization.
Publishable-key clients cache immutable image Blobs in IndexedDB for two hours by default. Graphics JS partitions entries with a one-way representation of the key, verifies the artifact SHA-256 on write and read, removes expired or corrupt entries, and bounds storage by age, count, bytes, and least-recently-used access.
The render descriptor and overlay receipt stay in the current tab only and never outlive the server's 30-minute authorization. A same-tab reload can therefore avoid both requests. A new tab or expired receipt makes one descriptor request, then reuses the larger image only when the refreshed artifact key, checksum, dimensions, and content type still match. If they differ, the SDK downloads the replacement before requesting components.
const caddie = createCaddie100Client({
apiKey: "c100_pk_live_…",
imageCache: {
maxAgeMs: 2 * 60 * 60 * 1000,
maxEntries: 24,
maxBytes: 100 * 1024 * 1024,
},
});
// Clear only Graphics JS entries for this API origin.
await caddie.clearImageCache();
// Opt out when the host application requires it.
const uncached = createCaddie100Client({
apiKey: "c100_pk_live_…",
imageCache: false,
});Inspect asset.descriptorCacheState and asset.imageCacheState for HIT/MISS diagnostics. Mounted views expose the same values on view.root as data-caddie-descriptor-cache and data-caddie-image-cache.
GraphicRequest
Describe the clean rendered artifact.
const graphicRequest = {
courseId: "34697689-6423-4c2e-a2c4-b0ecbbfc77d2",
subject: { type: "hole", holeNumber: 1 },
output: {
format: "webp",
width: 900,
height: 1500,
quality: 92,
},
style: {
graphicStyle: "traditional",
paperTheme: "light",
fairwayPattern: "auto",
teePattern: "plain",
perimeterTreatment: "classic",
nearbyHoles: "hidden",
},
composition: {
layout: "portrait",
flagAnchor: "middle",
teeAnchor: "middle",
padding: [0.025, 0.05],
},
};| Group | Purpose | Common values |
|---|---|---|
| courseId | Stable measured-course identity. | UUID from listCourses |
| subject | Selects the spatial subject to compose. | hole, green, course, or profile-elevation |
| output | Defines encoding, dimensions, and quality. | WebP, PNG, JPEG/JPG |
| style | Selects the graphic style and controls its paper, terrain, turf, context, perimeter, or elevation-profile presentation. | traditional, plus explicit renderer settings |
| style.pencilFeatures | Controls Pencil paths, buildings, and the final envelope outline. | buildings/paths default false; perimeter defaults true |
| style.graphicStyling | Deep-merges the supported Pencil or Colored Pencil palette into versioned defaults. | Pencil paper/strokes with optional feature fills and green-boundary width; Colored Pencil ground/features; plus elevation-profile colors |
| composition | Fits and orients a hole inside the requested aspect ratio. | Portrait/landscape, anchors, and CSS-style padding |
| courseComposition | Controls spacing around the automatically rotated full course. | auto or CSS-style padding |
| greenComposition | Controls a green-detail crop, orientation, and placement. | Approach/north, bottom-default approach edge with explicit alternatives or auto compatibility, mutually exclusive output-space or meter padding, rotation, center/auto/edge/corner gravity |
| greenData | Adds supported green-detail analysis to the clean image. | Green elevation heatmap and break presentation |
Pencil-family styling
Build a custom graphic language from stable style defaults.
Pencil and Colored Pencil accept their own style.graphicStyling schema for hole, green, course, and profile-elevation subjects. The API retains only supported keys, validates #RRGGBB and #RRGGBBAA colors plus supported stroke widths from 0 through 16, then strictly deep-merges the partial object into that style's versioned defaults.
Pencil exposes light/dark paper, graphite strokes, opt-in fills for fairway, tee, green, bunker, water, tree, and forest features, plus a configurable green-boundary width; those feature fills default to transparent. Colored Pencil exposes ground visibility, shared strokes, and colors for green, fairway, tee, bunker, water, tree, forest, path, parking, and building features. Both expose light/dark elevation-profile palettes; the profile background chooses the applicable palette. Every normalized result participates in render and cache identity. Unknown properties, malformed values, cross-style fields, and use with Traditional are rejected rather than ignored.
const customPencilProfile = await caddie.renderGraphic({
courseId: "34697689-6423-4c2e-a2c4-b0ecbbfc77d2",
subject: { type: "profile-elevation", holeNumber: 2 },
style: {
graphicStyle: "pencil",
graphicStyling: {
paper: { light: "#FFFDF7" },
strokes: { light: { primary: "#202124CC" } },
profileElevation: {
light: { surface: "#4D514D", labelStroke: "#4D514D55" },
},
},
},
});const customColoredPencil = await caddie.renderGraphic({
courseId: "34697689-6423-4c2e-a2c4-b0ecbbfc77d2",
subject: { type: "green", holeNumber: 2 },
style: {
graphicStyle: "colored-pencil",
graphicStyling: {
ground: { visible: false },
strokes: { primary: "#24452ECC" },
features: {
green: {
fill: "#B7D99A",
strokeColor: "#24452ECC",
strokeWidth: 2,
},
},
},
},
});Pencil optional features
Add secondary context without changing Pencil's hierarchy.
The Pencil branch of GraphicRequest accepts style.pencilFeatures.buildings, style.pencilFeatures.paths, and style.pencilFeatures.perimeter for hole, green, and course subjects. Buildings and paths default false; perimeter defaults true. Buildings use simple Overture footprints. Paths combine course-authored cart paths with the restrained Overture service and non-motorized allowlist.
Paths and buildings remain visually subordinate and clipped to the envelope selected by perimeterTreatment. Setting perimeter to false skips only the final Pencil outline stroke, retaining the same envelope, projection, clipping, and framing. The options are absent from the Traditional and Colored Pencil type branches and are not valid for profile-elevation. Each pixel-distinct combination has its own normalized render identity and cache entry.
import type { GraphicRequest } from "@caddie100/graphics-js";
// Omitted options preserve today's Pencil output; both default false.
const defaultPencilRequest: GraphicRequest = {
courseId: "34697689-6423-4c2e-a2c4-b0ecbbfc77d2",
subject: { type: "hole", holeNumber: 1 },
output: { format: "webp", width: 1440, height: 2400 },
style: { graphicStyle: "pencil" },
};
const contextualPencilRequest: GraphicRequest = {
...defaultPencilRequest,
style: {
graphicStyle: "pencil",
pencilFeatures: { buildings: true, paths: true, perimeter: false },
},
};Elevation profiles
Render a hole as a measured side view.
profile-elevation is a hole-scoped subject with a 1600 × 600 default output. Its style controls select smooth or stepped terrain, label and yardage sizes, an optional single tee by id, name, or color, tee-marker size, yards/feet/meters for horizontal stations, CSS-style outer padding, and a six-digit RGB background. Signed vertical elevation remains in feet. Every tee position renders as a colored square by default; an unmatched single-tee selector falls back to the furthest tee. Labeled approach stations use outlined circles. At the default size tee and approach markers measure 18 and 14 pixels respectively, with outlines chosen to remain legible when printed.
const profileRequest = {
courseId: "34697689-6423-4c2e-a2c4-b0ecbbfc77d2",
subject: { type: "profile-elevation", holeNumber: 7 },
output: { format: "png", width: 1600, height: 600 },
style: {
graphicStyle: "colored-pencil",
profileLineStyle: "stepped",
profileLabelSize: "medium",
profileYardageSize: 12,
profileTee: "Green",
profileTeeMarkerSize: 36,
profileDistanceUnit: "meters",
profilePadding: [0, 24, 16, 24],
profileBackgroundColor: "#FFFFFF",
},
};
const profile = await caddie.renderGraphic(profileRequest);
profile.download("hole-7-elevation-profile.png");
profile.destroy();renderGraphic for a downloadable asset, or call mount with an empty component list for a responsive browser view. The renderer reserves enough top space for the flag and elevation pills, even at the highest terrain station. Hole, course, and green composition or analysis fields do not apply to profiles.Inspect profileElevation.presentation in renderer metadata for the resolved marker styles and dimensions, top safety band, minimum label-to-surface gap, padding, background, and omitted-distance break. Marker fields include teeMarkerStyle, teeMarkerSizePixels, approachMarkerStyle, approachMarkerDiameterPixels, and markerOutlinePixels.
Delivery methods
Choose the level of browser behavior you need.
// Descriptor only: create the render and receive its artifact contract.
const descriptor = await caddie.createGraphic(graphicRequest);
// Browser asset: authenticate the artifact and create a temporary blob URL.
const asset = await caddie.renderGraphic(graphicRequest);
asset.download("raymond-hole-1.webp");
asset.destroy();
// Interactive view: mount the image and manage optional HTML components.
// The default contain stage preserves the complete artifact in fixed-size hosts.
const view = await caddie.mount(container, graphicRequest, overlays, { fit: "contain" });Descriptor
Returns the clean image contract and short-lived render receipt without downloading the artifact.
Asset
Downloads the authenticated image and exposes a blob-backed URL plus download and cleanup methods.
Interactive view
Creates an observed, aspect-ratio-locked stage containing the image and its independently requested overlay layer.
Components later
Reconciles or appends independently identified instances, including repeated component types, while reusing view-cached placements.
Lifecycle
Cancel stale work and release browser assets.
- Pass an
AbortSignaltolistCourses,createGraphic,renderGraphic, ormountwhen the calling UI can be replaced. - Use the default
containfit for fixed cards and split panes. Usewidthwhen the host grows or scrolls vertically. - Call
asset.destroy()for a standalone rendered asset after its blob URL is no longer needed. - Call
view.destroy()when an interactive graphic unmounts. It disconnects responsive observation, aborts active overlay work, removes image handlers and DOM, and revokes the asset URL.