Vessel profile
The vessel's side-view silhouette, drawn as an SVG that scales to its box.
On this page
SV Althea
- Model
- Hanse 460
- MMSI
- 224 123 456
- Call sign
- EA1234
- Engine
- Yanmar 4JH57
Stores and ground tackle
- Fuel
- 300 L
- Water
- 500 L
- House bank
- 360 Ah
- Chain
- 80 m
Code
import { Badge } from "@bosunkit/components/badge";
import { Card } from "@bosunkit/components/card";
import { DescriptionList, type DescriptionListItem } from "@bosunkit/components/description-list";
import { VesselProfile, type VesselProfileDimensions } from "@bosunkit/components/vessel-profile";
import { Anchor } from "lucide-react";
import type { ReactElement } from "react";
export const description: string =
"The vessel page of SV Althea, a Hanse 460: her profile drawn across the page with her lengths, draft, beam, air " +
"draft and displacement on it, and under it her identity beside the stores the drawing cannot show.";
/** What a side view can carry: the lengths and the draft as dimension lines, the rest in the strip under the hull. */
const DIMENSIONS: VesselProfileDimensions = {
lengthOverall: "14.60 m",
waterlineLength: "13.05 m",
draft: "2.25 m",
beam: "4.79 m",
airDraft: "21.90 m",
displacement: "12,560 kg",
};
/** Her fixed figures no drawing shows, as terms and values with no source: they are not live readings. */
const STORES: readonly DescriptionListItem[] = [
{ term: "Fuel", value: "300 L" },
{ term: "Water", value: "500 L" },
{ term: "House bank", value: "360 Ah" },
{ term: "Chain", value: "80 m" },
];
/** The identity card's names and numbers. */
const IDENTITY: readonly DescriptionListItem[] = [
{ term: "Model", value: "Hanse 460" },
{ term: "MMSI", value: "224 123 456" },
{ term: "Call sign", value: "EA1234" },
{ term: "Engine", value: "Yanmar 4JH57" },
];
export default function Showcase(): ReactElement {
return (
<div style={{ display: "flex", flexDirection: "column", gap: "var(--space-lg)", width: "100%" }}>
<VesselProfile width={900} dimensions={DIMENSIONS} />
<div style={{ display: "flex", gap: "var(--space-lg)", flexWrap: "wrap", alignItems: "stretch" }}>
<Card
title="SV Althea"
icon={<Anchor />}
style={{ flex: "1 1 240px" }}
footer={
<>
<Badge variant="green">At anchor</Badge>
<Badge variant="dim">Valencia</Badge>
</>
}
>
<DescriptionList items={IDENTITY} layout="columns" />
</Card>
<Card title="Stores and ground tackle" style={{ flex: "2 1 280px" }}>
<DescriptionList items={STORES} layout="columns" />
</Card>
</div>
</div>
);
}
A vessel profile is a side elevation of a vessel's hull and deck, bow to the right as a yard's drawing has it, without
the rig. It is drawn from an outline: a hull shape, or one builder's range, traced once from a side elevation its
builder or a magazine has published, as its outline and its windows. The default is Hanse's Berret-Racoupeau range
from 2021 on, traced from Hanse's hull plan of the 460: a straight sheer rising a little toward a plumb stem with its
bow roller, a reverse transom, three hull windows and a low coachroof with its window band, and below the waterline
the canoe body, the L-shaped fin keel, the saildrive and the spade rudder, darkening toward their foot. Every color is
a token, so the drawing follows the theme; the glass is dark in all four. It is a picture, not a reading, and it
carries no data. It names itself to a screen reader. The drawing is 800 by 200 pixels unless width and height say
otherwise, and it never grows wider than its container.
An outline marks the points a naval architect dimensions: the transom and the stem, the waterline's ends, the deck at
the bow, the bottom of the canoe body and the keel's foot. Given proportions, the vessel's particulars in meters, the
outline is stretched between those points to her own: each stretch along the hull takes its length (the aft overhang,
the waterline, the forward overhang), the deck at the bow moves to her freeboard and the keel's foot to her draft,
while the canoe body and the deck structures grow with her length. One outline then draws a Hanse 360 and a
Hanse 590 in their own proportions. A particular not given follows the length overall in the outline's proportion.
The vessel fills the frame unless frameLength names a longer length, which draws several vessels to one scale.
Every vessel has an outline to draw her from. VESSEL_OUTLINES holds one for each hull shape the vessel catalog
carries, each on its own page with the vessels it draws: a
cruising monohull with a fin keel and a spade rudder; a
sailing catamaran, one hull seen from the side with the saloon
on the bridgedeck above it; an outboard boat, whose outboard's
lower unit sets the draft and which has no rudder; a planing motor yacht
under a hardtop, with a swim platform, whose pod drives set the draft; a trawler, her full keel
running aft to the rudder; and a
cruising trimaran, her hulls as seen from the side under a
deckhouse and its hardtop. A range drawn in its own lines has its own outline: Hanse's from 2021 on.
Draw a vessel from her range's outline when her range has one, and otherwise from her shape's.
Given dimensions, the drawing is dimensioned as a naval architect's profile is: length overall from the transom to
the stem and length at the waterline, both under the keel; the draft beside the keel from the waterline to its foot;
the freeboard ahead of the bow from the waterline to the deck. The beam, the air draft and the displacement, which a
side view without its rig cannot show, are set in a strip under the drawing, as in a drawing's title block: each label
in small capitals over its value. Each value comes from the caller with its unit, in the crew's language; only those
given are drawn. The lines attach to the outline's points, so with proportions they span the hull as drawn; the frame grows
downward to hold them, and the dimensions join the drawing's accessible name.
Examples
Profile
Code
import { VesselProfile } from "@bosunkit/components/vessel-profile";
import type { ReactElement } from "react";
export const description: string = "The sailing yacht outline at its default size, 800 by 200 pixels, shrinking to fit a narrow screen.";
export default function Profile(): ReactElement {
return <VesselProfile />;
}
Dimensioned
Code
import { VesselProfile } from "@bosunkit/components/vessel-profile";
import type { ReactElement } from "react";
export const description: string =
"The profile dimensioned as a naval architect's drawing: length overall and at the waterline under the keel, " +
"draft beside it, freeboard at the bow, and the beam, air draft and displacement in the strip under it.";
export default function Dimensioned(): ReactElement {
return (
<VesselProfile
dimensions={{
lengthOverall: "13.95 m",
waterlineLength: "12.40 m",
draft: "2.25 m",
freeboard: "1.20 m",
beam: "4.42 m",
airDraft: "21.90 m",
displacement: "12,400 kg",
}}
/>
);
}
One outline for each hull shape
Code
import {
CRUISING_MONOHULL,
CRUISING_TRIMARAN,
MOTOR_YACHT,
OUTBOARD_BOAT,
SAILING_CATAMARAN,
VesselProfile,
type VesselOutline,
} from "@bosunkit/components/vessel-profile";
import type { ReactElement } from "react";
export const description: string =
"One vessel of each hull shape, drawn from her shape's outline stretched to her particulars and to one scale: a " +
"cruising monohull, a sailing catamaran, an outboard boat, a motor yacht and a cruising trimaran.";
interface Shaped {
/** The vessel, as the catalog names her. */
readonly name: string;
/** Her shape's outline. */
readonly outline: VesselOutline;
/** Length overall, meters. */
readonly loa: number;
/** Length at the waterline, meters, where the catalog has it. */
readonly lwl?: number;
/** Draft, meters. */
readonly draft: number;
/** Freeboard at the bow, meters, where the catalog has it. */
readonly freeboard?: number;
}
/** Particulars from the vessel catalog. */
const VESSELS: readonly Shaped[] = [
{ name: "Bavaria C42", outline: CRUISING_MONOHULL, loa: 12.4, lwl: 11.49, draft: 2.1 },
{ name: "Lagoon 46", outline: SAILING_CATAMARAN, loa: 13.99, lwl: 13.72, draft: 1.37 },
{ name: "Pursuit S 328", outline: OUTBOARD_BOAT, loa: 10.52, draft: 0.91 },
{ name: "Ferretti Yachts 500", outline: MOTOR_YACHT, loa: 15.33, draft: 1.23 },
{ name: "Neel 47", outline: CRUISING_TRIMARAN, loa: 14.2, draft: 1.6 },
];
export default function Shapes(): ReactElement {
return (
<div style={{ display: "grid", gap: "var(--space-md)" }}>
{VESSELS.map(
({ name, outline, loa, lwl, draft, freeboard }: Shaped): ReactElement => (
<figure key={name} style={{ margin: 0 }}>
<VesselProfile
outline={outline}
proportions={{ lengthOverall: loa, waterlineLength: lwl, draft, freeboard }}
frameLength={15.33}
dimensions={{
lengthOverall: `${loa.toFixed(2)} m`,
waterlineLength: lwl === undefined ? undefined : `${lwl.toFixed(2)} m`,
draft: `${draft.toFixed(2)} m`,
}}
/>
<figcaption style={{ marginTop: "var(--space-xs)", color: "var(--text-dim)", fontSize: "0.85em" }}>
{name}, drawn from the {outline.name.toLowerCase()} outline
</figcaption>
</figure>
),
)}
</div>
);
}
Illustration and evidence
Use the profile to explain layout or provide visual context. An outline is a range's typical lines, not the vessel's lines plan: stretched to her particulars, its length, waterline, freeboard and draft are hers, and everything between them is the outline's. Do not position measured clearances, equipment or load limits on it without a separate, verified coordinate and scale contract.
Keep the adjacent text clear about what the image represents. A report caption should name an illustrative vessel when appropriate. Use a dedicated instrument for changing measurements rather than inferring them from the silhouette's shape or size.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| width | number | undefined | 800 | The drawing's width in pixels; 800 by default. |
| height | number | undefined | – | The drawing's height in pixels; 200 by default, and in proportion to the taller frame with dimensions. |
| outline | VesselOutline | undefined | HANSE_2021 | The shape's or the range's outline to draw, one of VESSEL_OUTLINES; Hanse's range from 2021 on by default. |
| proportions | VesselProportions | undefined | – | The vessel's particulars as numbers in meters, which stretch the outline to her proportions: the length overall to the stem, the length at the waterline to the waterline's ends, the freeboard to the deck at the bow and the draft to the keel's foot. A particular not given follows the length overall in the outline's own proportion. The outline is drawn as it is when unset. |
| frameLength | number | undefined | – | The length in meters the drawing's hull span stands for: by default the vessel's own length overall, so she fills it. Give the longest vessel's length to draw several to one scale. |
| dimensions | VesselProfileDimensions | undefined | – | The particulars to dimension on the drawing, as a naval architect's profile does; the frame grows downward to hold
the lines, and the dimensions join the drawing's accessible name. The lines attach to the outline's hooks, so with
proportions they span the drawn hull. None when unset. |
| showWater | boolean | undefined | false | Whether the sea is laid under the waterline, a tint of the waterline's color fading toward the frame's foot, so the hull sits in water; off by default, for a drawing on a page or in a report. |
| className | string | undefined | – | Classes added to the drawing's own. |
Related
- Color: the colors the drawing takes from the theme.