Show an elevation profile props
The generated props of every element on Show an elevation profile. The guide is where they are explained; this is the whole surface.
ItineraryProfile
itineraryIdstring
An itinerary to draw, resolved through the client on the provider.
One prop instead of a fetch, a state variable and three mappings: the response carries the geometry, the server's own figures and the itinerary's waypoints in a single round trip, so all three arrive together. Two elements given the same id share one request.
Nothing here fetches. The element hands the provider's client to fetchItinerary, which calls a method on it: one credential, one retry policy, one error taxonomy.
An id with no client on the provider renders the empty state and reports through onError, rather than throwing during render.
surface"published"
Reads the itinerary's published snapshot rather than its draft.
unitsUnitFormatOptions
Units, slope notation and the locale to format in.
heightnumber
The plot's height in CSS pixels.
A number rather than a CSS length, because the value also has to be a length the marks layer can share: accepting 40vh would mean measuring the element to place a pin, which is the one thing this element never does.
statsreadonly ProfileStatKey[]
Which figures the strip carries, in the order given. [] drops the strip.
curveColorsProfileColoring
Draws the curve itself in more than one colour.
Three shapes, one pipeline. A list of coloured stretches paints them as given: an itinerary assembled from parts reads as those parts when the line carries their colours. { mode: "slope" } computes the stretches from the itinerary's own steepness. { mode: "classify" } takes stretches a caller has named, and the name is what the hover card reads.
Distinct from ItineraryProfile.Bands, which paints a strip beneath the chart. This is the curve, and the area fill under it, which carries the same gradient.
segmentsreadonly ItinerarySegmentInput[]
The itinerary's authored legs, which the section chips state.
Places mark the itinerary; segments divide it. The itinerary's waypoints put pins on the curve and names under the axis; its segments decide where one leg ends and the next begins, and what each chip says about it. They are different lists doing different jobs, and one resolved itinerary supplies both.
The chips read the SAME array <ItinerarySegmentTable> renders its rows from, which is why the derivation lives in @mountaya/elements/profile rather than in either element.
Resolved from the itinerary, and stated here only by a caller already holding the chain (an editor whose geometry changes as it is drawn, or a chain assembled from directions). A stated chain is also the curve: the line is walked from these legs, in this order, so the chips can never describe a line they did not come from. Beside itineraryId, it is the one way data reaches the element, and <ItinerarySegmentTable> takes it too.
A new array of the same legs, in the same order, is the same chain: the element walks it again only when a leg object changes.
childrenReactNode
Marks of your own, drawn on the curve.
The itinerary's own waypoints cover the common case (a pin at a place) and stay thin on purpose. An application whose marks carry more than that (a drop line to the baseline, a hover state, a hit target wider than the glyph, a tooltip) renders them here instead, and positions each one with useProfilePlot, which answers with the same scale the curve is drawn against.
Children are placed in the same layer as the built-in pins and the cursor dot. That layer is pointer-transparent; opt individual children back in.
amenitiesboolean | ItineraryProfileAmenitiesOptions
The services each place offers, stacked above its pin.
On by default, unlike every other opt-in part of this element, and the data is the switch: the layer renders nothing at all for an itinerary whose waypoints declare no amenities. Pass false to suppress it on an itinerary that does, or an object to cap the stack.
formatCutoffAt(iso: string) => string
Writes a published cut-off's instant, an ISO 8601 string, as the time above a dashed vertical at its place.
The cut-offs are drawn exactly when it is given: an instant needs a locale and a time zone, which are the application's. A hut-to-hut itinerary publishes none and draws nothing either way. <ItineraryWaypointTable> and <WaypointCard> take the same function.
A new function is a new way of printing, and redraws the cut-offs: hold it stable.
axisboolean | ProfileAxes
Which scales the chart draws.
true is the elevation scale alone. The distance scale takes a row of its own under the chart, so it is asked for by name: axis={{ x: true, y: true }}.
The elevation scale is off by default, because the stat strip already states the itinerary's lowest and highest point and two places for one number is one too many. An application that drops the strip turns it on, and gives up the width the labels need.
sectionsboolean | ItineraryProfileSectionsOptions
A chip per section, stating what each leg between two dividing waypoints measures.
Reads the same array an <ItinerarySegmentTable> renders its rows from, so a leg stated under the chart and the same leg stated in a table beside it cannot disagree. Renders nothing when no waypoint divides the itinerary.
tooltipboolean | ItineraryProfileTooltipOptions
A card at the cursor, stating what it is standing on.
Turning it on makes the stat strip stop following the cursor and state the itinerary's own figures instead: the card owns what is under my finger, the strip owns what the itinerary is, and one number in two places is one place too many.
navigatorboolean | ItineraryProfileNavigatorOptions
A strip below the chart showing the whole itinerary, with the drawn window marked on it.
Dragging either handle zooms the curve. The window is range; this is the control for it, and a caller who wants their own control leaves this off and drives range directly.
rangeProfileRange | null
The stretch of itinerary the chart is drawn over, in meters.
Omit for an uncontrolled window the element moves itself. null is a controlled whole itinerary: the value a controlled caller writes to zoom out without knowing the itinerary's length.
defaultRangeProfileRange
Where an uncontrolled window starts.
Read once for each itinerary: a new itineraryId or surface is a new profile, and its window starts over from here. A chain stated through segments is one profile for as long as it is stated, whatever id comes with it, so its window stands until the element is given another key.
anchor"route" | "sea-level" | "window"
What the elevation scale is measured from.
"route" anchors on the route's own lowest point, because the shape of the climb is what a profile is read for: a ridge traverse between 2,400 m and 2,600 m is a ridge, not a flat line four fifths of the way up an empty frame.
"sea-level" anchors at zero instead. The curve then sits at its true height in the frame, so two itineraries drawn side by side are comparable, at the cost of flattening every itinerary that does not start near the sea.
"window" anchors on whatever the drawn window contains, so zooming into a section rescales to that section's own climb rather than keeping it a fifth of the frame tall.
highlightedstring | null
The leg to light on the curve, by id.
Takes over the map-to-chart half. With a map in context the chart already listens for the leg under the map's own cursor and tints its stretch; state an id here and the element stops listening and tints yours instead, the same controlled/uncontrolled pair range draws. Matches a leg's own id or, on a collapsed group, any of its members'.
null states "nothing", which is not the same as leaving it out: one is a caller saying the cursor is off the route, the other is a caller not answering the question at all.
emphasisColorstring
Colour of the lit stretch on the MAP.
disabledboolean
Renders the profile non-interactive.
No cursor, no scrub, no map marker, no lit leg, no drag. The curve, the strip and the bands still draw and still read: a disabled profile is a picture, not a blank. A scrub a child asks for through useProfilePlot().scrubTo is not taken either, and onHover hears null for the cursor a disable clears.
markerIdstring
The id the MAP's cursor marker is pinned under.
A map marker, not a waypoint: this is the pin MapLibre draws where the cursor is, and it is the one place in this element where "marker" means the renderer's own object.
markerColorstring
Colour of the map's cursor marker.
stringsItineraryProfileStrings
Overrides the words this element renders, for this element only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone. Scoped to the sections this element reads: a key it never renders is a type error rather than a silent no-op.
ItineraryProfile.Amenities
ItineraryProfileAmenities stacks a place's services above its pin.
waypointsreadonly PlacedWaypointMark[]
The same placed marks the pin layer draws; the ones with no services are skipped.
stringsItineraryProfileAmenitiesStrings
Overrides the words this element renders, for this element only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone. Scoped to the sections this element reads: a key it never renders is a type error rather than a silent no-op.
maxnumber
default: DEFAULT_PROFILE_AMENITY_MAX
How many badges one stack shows before it counts the rest.
A fraction is rounded down. A value below zero, or one that is no number, shows no badge and counts every service.
ItineraryProfile.Cutoffs
ItineraryProfileCutoffs draws a dashed vertical at each published cut-off, with its time above the chart.
cutoffsreadonly PlacedCutoff[]
The placed cut-offs, already filtered to the visible window.
formatCutoffAt(iso: string) => string
Writes a cut-off's instant, an ISO 8601 string, as the label above its line.
Formatting an instant needs a locale and a time zone, and both are the application's: an element that picked toLocaleTimeString() would print a Paris race in the reader's own zone and be quietly wrong for every reader not standing on the course.
stringsItineraryProfileCutoffsStrings
Overrides the words this element renders, for this element only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone. Scoped to the sections this element reads: a key it never renders is a type error rather than a silent no-op.
ItineraryProfile.Bands
ItineraryProfileBands paints a caller's spans beneath the curve.
bandsreadonly ProfileBand[]
totalDistancenumber
rangeProfileRange
The stretch of itinerary the strip is drawn over, in meters from its start: the window of the chart it sits under, so a band stays under the stretch of curve it describes at any zoom. A band the window does not reach is not drawn, and one that crosses an end of it is cut there.
stringsItineraryProfileBandsStrings
Overrides the words this element renders, for this element only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone. Scoped to the sections this element reads: a key it never renders is a type error rather than a silent no-op.
ItineraryProfile.Chart
ItineraryProfileChart draws the curve, and answers "where along the itinerary is the pointer".
pointsreadonly ElevationPoint[]
totalDistancenumber
domainElevationDomain
activeIndexnumber | null
disabledboolean
default: false
Renders the chart non-interactive: no scrub, no key, still drawn and still read.
labelstring
The chart's accessible name.
valueTextstring
What the cursor currently reads, spoken rather than shown. "" while no cursor stands.
curveColorsreadonly CurveColor[]
Stretches drawn in a colour of their own. Empty leaves the curve on its CSS fill.
rangeProfileRange
The stretch of itinerary drawn. The whole itinerary when nothing has zoomed.
ItineraryProfile.DropLines
ItineraryProfileDropLines draws a dashed line from each dividing waypoint down to the curve.
dividersreadonly PlacedDivider[]
ItineraryProfile.Navigator
ItineraryProfileNavigator is the whole itinerary in miniature, with the drawn window marked on it.
seriesElevationSeries
domainElevationDomain
rangeProfileRange
curveColorsreadonly CurveColor[]
disabledboolean
default: false
Renders the strip non-interactive: no grid, both handles disabled.
unitsUnitFormatOptions
stringsItineraryProfileNavigatorStrings
Overrides the words this element renders, for this element only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone. Scoped to the sections this element reads: a key it never renders is a type error rather than a silent no-op.
ItineraryProfile.Sections
ItineraryProfileSections states each leg between the itinerary's dividing waypoints.
rowsreadonly ItinerarySegmentRow[]
statsreadonly ProfileSectionStatKey[]
rangeProfileRange
totalDistancenumber
unitsUnitFormatOptions
stringsItineraryProfileSectionsStrings
Overrides the words this element renders, for this element only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone. Scoped to the sections this element reads: a key it never renders is a type error rather than a silent no-op.
ItineraryProfile.Stats
ItineraryProfileStats states the itinerary's figures, and follows the cursor while one is scrubbing.
statsreadonly ProfileStatKey[]
characteristicsResolvedCharacteristics
unitsUnitFormatOptions
cursor{ readonly distance: number; readonly elevation: number } | null
What the cursor is over, if anything.
distance and elevation state the hovered point while a scrub is in progress and the itinerary's figures otherwise, so the strip reads as one row that follows the cursor rather than as a second row that appears beside it and shifts the layout.
Held null when the hover card is on: the card owns what is under my finger, the strip owns what the itinerary is, and one number in two places is one place too many.
cursorGradenumber | null
The grade under the cursor, in degrees. The itinerary's maximum when nothing is hovered.
stringsItineraryProfileStatsStrings
Overrides the words this element renders, for this element only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone. Scoped to the sections this element reads: a key it never renders is a type error rather than a silent no-op.
ItineraryProfile.Tooltip
ItineraryProfileTooltip states what the cursor is standing on.
pointElevationPoint
seriesElevationSeries
cumulativeCumulativeElevation
domainElevationDomain
rangeProfileRange
gradenumber | null
classificationProfileClass | null
statsreadonly ProfileTooltipStatKey[]
placement"top" | "cursor"
unitsUnitFormatOptions
stringsItineraryProfileTooltipStrings
Overrides the words this element renders, for this element only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone. Scoped to the sections this element reads: a key it never renders is a type error rather than a silent no-op.
ItineraryProfile.Waypoints
ItineraryProfileWaypoints draws the places sitting on the curve.
waypointsreadonly PlacedWaypointMark[]
disabledboolean
default: false
Renders the pins inert: drawn, and pressed by nobody.
stringsItineraryProfileWaypointsStrings
Overrides the words this element renders, for this element only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone. Scoped to the sections this element reads: a key it never renders is a type error rather than a silent no-op.
ItineraryProfile.XAxis
ItineraryProfileXAxis states where along the itinerary the chart is, and names the places on it.
optionsItineraryProfileXAxisOptions
rangeProfileRange
totalDistancenumber
dividersreadonly PlacedDivider[]
unitsUnitFormatOptions
stringsItineraryProfileXAxisStrings
Overrides the words this element renders, for this element only.
Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone. Scoped to the sections this element reads: a key it never renders is a type error rather than a silent no-op.
Handlers
An on* handler suppresses the element's own default. Left unset, the element acts; set, it becomes presentational and your handler decides. The two never both fire.
onHover(point: ElevationPoint | null) => void
Takes over what a hover does.
Left unset, and with a map in context, the profile drives the map itself: it pins a marker at the hovered coordinate and moves it as the cursor sweeps. Set, that is suppressed entirely and the element becomes presentational: the handler receives the hovered point, or null on leave, and decides. The assembled studio routes the cursor through its tool bus this way while rendering this exact component.
A cursor that goes with no pointer leaving reports null as well, once: the profile is disabled under it, draws another itinerary (a new itineraryId, a new surface, or another chain stated under the same one), or is unmounted.
onWaypointClick(id: string) => void
Called with a waypoint's id when its pin is pressed. Unset leaves the pins inert.
onRangeChange(next: ProfileRange) => void
The window, reported whole after every change a reader makes to it. Additive: it does not suppress the drag.
A new itinerary starts over from defaultRange and reports nothing, as an uncontrolled value under a new key does. A caller that mirrors the window controls range.
onError(error: Error) => void
Reports a failure resolving itineraryId. Additive; the element renders its empty state.