shadcn.io is an independent project built on shadcn/ui
Installation
The command adds the example above to components/charts/ and, the first time, the chart kit to components/ui/charts/. Both are source files in your project from then on: read them, change them, delete what you don't use.
Usage
Rows need a longitude and a latitude, plus a name for the tooltip. The land is worldCountries, installed in components/charts/data/ with any example that uses it.
import { worldCountries } from "@/components/charts/data/world-countries";
import {
GlobeChart,
GlobeLand,
GlobeMarkers,
GlobeSphere,
GlobeTooltip,
} from "@/components/ui/charts";
const offices = [
{ latitude: 51.51, longitude: -0.13, name: "London" },
{ latitude: 52.52, longitude: 13.4, name: "Berlin" },
{ latitude: 40.71, longitude: -74.01, name: "New York" },
{ latitude: 1.35, longitude: 103.82, name: "Singapore" },
];
export const OfficesGlobe = () => (
<GlobeChart
ariaLabel="Our offices"
center={[10, 30]}
data={offices}
geography={worldCountries}
>
<GlobeSphere />
<GlobeLand />
<GlobeMarkers />
<GlobeTooltip />
</GlobeChart>
);Anatomy
The layers stack in a fixed order: the ocean, the graticule, the land, then the markers.
<GlobeChart center={[12, 30]} data={regions} geography={worldCountries}>
<GlobeSphere />
<GlobeGraticule />
<GlobeLand />
<GlobeMarkers />
<GlobeTooltip />
</GlobeChart>GlobeChart: Holds the places, the countries and the projection, and turns it on drag.GlobeSphere: The ocean and the globe's rim.GlobeGraticule: Lines of longitude and latitude, every 20° by default.GlobeLand: The countries fromgeography.GlobeMarkers: A dot on each place, one size or scaled bydataKey.GlobeTooltip: The marker'snameand, withdataKey, its value.
Turning the globe
center is the [longitude, latitude] that faces the reader, [10, 20] by default. A drag turns the globe from there, 0.35° per pixel, and the tilt stops at 80° so it never rolls over a pole.
Markers on the far side are hidden and take no hover until they come round. The tooltip is hidden while the globe turns.
Touch screens
On a touch screen, a finger on the globe turns it instead of scrolling the page or opening a tooltip. Where that gets in the way, for example in a narrow column on a phone, set draggable={false}: taps then show the tooltips.
Sized markers
Give <GlobeMarkers> a dataKey and each marker's area follows its value, the largest drawn at radius. Without a dataKey, every marker takes radius, 5 px by default.
The largest markers are drawn first, so small ones stay on top. The tooltip adds the value under the place's name.
Customization
The kit is in your project, in components/ui/charts/: your framework's components over a shared core/. Change a default there and every chart picks it up.
className goes on the chart's container, so size and spacing are utility classes.
Every layer's colors are props: fill and stroke on <GlobeSphere>, fill, stroke and strokeWidth on <GlobeLand>, color on <GlobeMarkers>. content on <GlobeTooltip> gets the hovered row as marker.
<GlobeChart center={[-60, 15]} data={customers} geography={worldCountries}>
<GlobeSphere fill="var(--muted)" />
<GlobeLand fill="var(--chart-scale-03)" stroke="var(--muted)" />
<GlobeMarkers color="var(--chart-2)" dataKey="customers" radius={14} />
<GlobeTooltip
content={({ marker }) => (
<div className="px-3 py-2 text-sm">
{String(marker.name)}: {Number(marker.customers).toLocaleString()}
</div>
)}
/>
</GlobeChart>Where a part renders content of its own, you pass it in. In React:
GlobeTooltip:content={({ marker, index }) => …}
Loading state
With status="loading", a skeleton disc and the land's outline breathe in the globe's place under its graticule, with a few skeleton markers. Dragging and hover are off until "ready", when the globe grows in.
loadingLabel puts a short line of text over it.
Animation
The globe grows in over 700 ms, the land fades in from 150 ms, and the markers pop in from 450 ms, largest first, spread over animationDuration (900 ms).
Dragging never replays it. animate={false} and reduced motion both draw the globe at rest.
Theming
Every color in the kit is one of your theme's tokens or a mix of them, except --chart-positive, a fixed green. A preset or the .dark class restyles the chart, and overriding a token in your CSS changes it everywhere.
The ocean is --chart-scale-01 and the land --chart-scale-02, both mixed from --chart-1 into --muted, so the globe follows your theme's first chart color. Country borders take the ocean's color and the rim is --border.
| Token | Default | Paints |
|---|---|---|
--chart-1 | your theme's | the first series |
--chart-scale-01 | --chart-1 at 10% over --muted | the low end of a color scale |
--chart-graticule | --chart-grid | a map's lines of longitude and latitude |
--chart-background | --card | dot halos, the gaps between stacked marks |
--chart-tooltip-background | --popover | the tooltip panel |
:root {
--chart-background: var(--background);
--chart-tooltip-background: var(--card);
}Accessibility
The globe is announced as an image named by ariaLabel ("Globe" by default). Arrow keys move through the markers on the side facing the reader, left to right.
The keyboard can't turn the globe, and markers on the far side can't be focused. If those places matter, name them in ariaDescription or list them next to the chart.
- Tab
- Moves focus to the globe, on its leftmost visible marker.
- Arrow Right
- Moves to the next marker to the right. ArrowDown does the same.
- Arrow Left
- Moves to the previous marker. ArrowUp does the same.
- Home
- Jumps to the leftmost visible marker.
- End
- Jumps to the rightmost visible marker.
API reference
GlobeChart
data?readonly SpatialRow[]
The places to mark on the globe: one row per marker, with a longitude and a latitude.
geography?FeatureCollection<Geometry, Readonly<Record<string, unknown>> | null>
The countries to draw (GeoJSON; GlobeLand styles them), such as the kit's worldCountries.
- Type
FeatureCollection<Geometry, Readonly<Record<string, unknown>> | null>
center?readonly [number, number]
The point that faces the reader, [longitude, latitude] in degrees.
- Default
[10, 20]
draggable?boolean
Rotate the globe by dragging it (mouse, pen or touch).
- Default
true
longitudeKey?string
Key of each row's longitude, in degrees.
- Default
"longitude"
latitudeKey?string
Key of each row's latitude, in degrees.
- Default
"latitude"
nameKey?string
Key of each row's name, the tooltip's title.
- Default
"name"
aspectRatio?string
Aspect ratio of the chart as "width / height".
- Default
"4 / 3"
margin?Partial<SpatialMargin>
Space around the plot in pixels. Any side you omit keeps its default.
- Type
Partial<SpatialMargin>
animate?boolean
Play the entrance animation.
- Default
true
animationDuration?number
Length of the entrance sweep in milliseconds: the time from the first mark starting to the last one.
- Default
900
revealSignature?string
Changing this value replays the entrance animation.
status?ChartStatus
"loading" draws a pulsing skeleton of the chart's shape in place of its marks (the axes, grid and land stay) and ignores the pointer; switching to "ready" plays the entrance.
- Default
"ready"
loadingLabel?string
Text shown centered over the chart, with a shimmer, while status is "loading". Nothing is shown when it is unset or empty.
className?string
Additional class name for the chart container.
children?ReactNode
The chart's carriers: its layers, axes, grid, tooltip and legend.
ariaLabel?string
Accessible label of the chart.
ariaDescription?string
Longer accessible description of the chart.
GlobeSphere
fill?string
Fill of the ocean.
- Default
"var(--chart-scale-01)"
stroke?string
Color of the rim.
- Default
"var(--border)"
GlobeLand
fill?string
Fill of the land.
- Default
"var(--muted)"
stroke?string
Color of the borders between countries.
- Default
"var(--chart-background)"
strokeWidth?number
Width of the borders, in pixels.
- Default
0.5
GlobeGraticule
step?readonly [number, number]
Degrees between the lines, [longitude, latitude].
- Default
[20, 20]
stroke?string
Color of the lines.
- Default
"var(--chart-graticule)"
strokeWidth?number
Width of the lines, in pixels.
- Default
0.5
GlobeMarkers
dataKey?string
Key of each row's value: a marker's area. Without it every marker takes radius.
radius?number
Radius of the markers (the largest, with dataKey), in pixels.
- Default
5
color?string
Fill of the markers.
- Default
"var(--chart-1)"
fadeOnHover?boolean
Dim the layer's other marks while one is hovered or focused.
- Default
true
inactiveOpacity?number
Opacity of the other marks while one is hovered or focused.
- Default
0.35
GlobeTooltip
content?(args: GlobeTooltipArgs) => ReactNode
Custom tooltip content. Replaces the default title and rows, inside the same panel.
- Type
(args: GlobeTooltipArgs) => ReactNode
formatValue?(value: number) => string
Formats the value row of the default content.
- Type
(value: number) => string- Default
the number with thousands separators
valueLabel?string
The label of the value row of the default content.
className?string
Additional class name for the tooltip panel.
panelStyle?CSSProperties
Inline styles merged onto the tooltip panel.
backgroundColor?string
Background color of the tooltip panel. Overrides the theme's popover color.
Examples
3 examples on React, each live with its code and its own install command.


