Core concepts
Infographics
An infographic is a template that draws one designed poster. This guide covers the templates, the poster frame, the poster themes, the poster primitives, PNG download and the phone layout.
An infographic is a template whose category is infographic. It draws one sheet with a painted background, a large title, little other text and one large graphic or several graphics laid out together. The catalogue has 10 infographics, listed on the Infographics page.
import { CountPoster } from "insightcharts";
export function Example() {
return (
<CountPoster
theme="noir"
kicker="Education"
title="Norland's schools taught 1.84 million pupils in 2025"
subtitle="Pupils enrolled in state schools by stage, autumn term 2025."
unit={1000}
unitLabel="1,000 people"
icon="person"
hero={{
data: [
{ stage: "Primary", pupils: 820000 },
{ stage: "Lower secondary", pupils: 460000 },
{ stage: "Upper secondary", pupils: 390000 },
{ stage: "Vocational", pupils: 170000 },
],
name: "stage",
value: "pupils",
title: "820,000 pupils were in primary school",
}}
reference={{
data: [
{ group: "Teachers", people: 142000 },
{ group: "Support staff", people: 61000 },
{ group: "Pupils who left without a certificate", people: 38000 },
],
name: "group",
value: "people",
title: "142,000 teachers taught them",
}}
area={{
data: [
{ school: "Largest secondary school", pupils: 3640 },
{ school: "Median primary school", pupils: 280 },
],
name: "school",
value: "pupils",
title: "The largest school had 3,640 pupils",
}}
bars={{
data: [
{ year: "2000", m: 1.42 },
{ year: "2005", m: 1.51 },
{ year: "2010", m: 1.6 },
{ year: "2015", m: 1.69 },
{ year: "2020", m: 1.77 },
{ year: "2025", m: 1.84 },
],
name: "year",
value: "m",
format: "{value}m",
title: "Enrolment was 1.42 million in 2000",
}}
shares={{
data: [
{ year: "2013", share: 6 },
{ year: "2017", share: 19 },
{ year: "2021", share: 44 },
{ year: "2025", share: 68 },
],
name: "year",
value: "share",
highlight: "2025",
wholeLabel: "All pupils",
title: "68% of pupils had a school laptop in 2025",
}}
sources="Norland Ministry of Education, school census 2025"
note="Norland is an invented country. All figures are illustrative."
credit="InsightCharts"
/>
);
}{
"type": "count-poster",
"theme": "noir",
"kicker": "Education",
"title": "Norland's schools taught 1.84 million pupils in 2025",
"subtitle": "Pupils enrolled in state schools by stage, autumn term 2025.",
"unit": 1000,
"unitLabel": "1,000 people",
"icon": "person",
"hero": {
"data": [
{ "stage": "Primary", "pupils": 820000 },
{ "stage": "Lower secondary", "pupils": 460000 },
{ "stage": "Upper secondary", "pupils": 390000 },
{ "stage": "Vocational", "pupils": 170000 }
],
"name": "stage",
"value": "pupils",
"title": "820,000 pupils were in primary school"
},
"reference": {
"data": [
{ "group": "Teachers", "people": 142000 },
{ "group": "Support staff", "people": 61000 },
{ "group": "Pupils who left without a certificate", "people": 38000 }
],
"name": "group",
"value": "people",
"title": "142,000 teachers taught them"
},
"area": {
"data": [
{ "school": "Largest secondary school", "pupils": 3640 },
{ "school": "Median primary school", "pupils": 280 }
],
"name": "school",
"value": "pupils",
"title": "The largest school had 3,640 pupils"
},
"bars": {
"data": [
{ "year": "2000", "m": 1.42 },
{ "year": "2005", "m": 1.51 },
{ "year": "2010", "m": 1.6 },
{ "year": "2015", "m": 1.69 },
{ "year": "2020", "m": 1.77 },
{ "year": "2025", "m": 1.84 }
],
"name": "year",
"value": "m",
"format": "{value}m",
"title": "Enrolment was 1.42 million in 2000"
},
"shares": {
"data": [
{ "year": "2013", "share": 6 },
{ "year": "2017", "share": 19 },
{ "year": "2021", "share": 44 },
{ "year": "2025", "share": 68 }
],
"name": "year",
"value": "share",
"highlight": "2025",
"wholeLabel": "All pupils",
"title": "68% of pupils had a school laptop in 2025"
},
"sources": "Norland Ministry of Education, school census 2025",
"note": "Norland is an invented country. All figures are illustrative.",
"credit": "InsightCharts"
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Three things make up the set.
| Part | What it is | Where |
|---|---|---|
| Infographic templates | 10 templates that each lay out one kind of poster. | Infographics |
| The poster frame | One molecule, poster. It paints the ground and lays out a masthead, a grid of panels and a footer. Every infographic is composed on it. | Poster |
| Poster primitives | 19 atoms drawn for a poster ground. | Atoms, poster primitives |
Choosing an infographic
Each infographic fits one kind of subject. The "use when" and "avoid when" on each page name the alternative.
| type | What it is | Built from |
|---|---|---|
| atlas-poster | A landscape spread of up to eleven small illustrations of one subject, each a different graphic form, in three bands of unequal panels: a statement in large type, spokes round an icon and a network of circles; a smooth trend with its peak labelled, nested squares and a slope chart; a pill ranking, a treemap, a tile map and sized circles; and a closing row of icon statements. | Poster, Radial spokes, Bubble network, Area chart, Proportional area, Slope chart, Pill rank, Treemap, Choropleth map, Stat circles, Icon stat |
| count-poster | A poster that counts at scale. Blocks of thousands of unit icons fill most of the sheet, a second band counts reference groups with the same icon at the same size in a muted colour, and a bottom row holds three small graphics: squares sized by area with a ratio bracket, thick bars with the numbers inside, and shares as nested outlines or filled silhouettes. | Poster, Unit blocks, Proportional area, Block bars, Nested shares, Shape fill |
| flow-poster | A portrait poster of where something comes from and where it goes, in three stacked bands painted in one colour: the producers as large labelled tiles, the leading producer's output fanning out as ribbons to an aligned column of destinations, and the destinations as bubbles on a scale of how much each depends on that producer. | Poster, Treemap, Fan flow, Bubble scale |
| matrix-poster | One wide landscape graphic that compares 4 to 12 entities on five to seven measures: two measures as S-curves between parallel scales on the left, joined to a table on the right in which every other number is drawn as dots, squares, icons, a ring, a circle or a bar. Both halves share one row order and one colour per entity. | Poster, Curve rank, Glyph table |
| network-poster | A poster of who is connected to whom: a full-width arc diagram with one arc per connection, as thick as its value (arc-diagram), a strip of two to four large figures, and a bottom row where the same entities return as circles joined by lines (bubble-network) and as a ranking of centred pills (pill-rank). | Poster, Arc diagram, Bubble network, Pill rank |
| profile-poster | A poster that describes one subject from four sides: the subject as one large silhouette filled to a share (shape-fill), two to four large figures, its place among other things on one scale (scale-ladder), and a table that sets it beside its peers with every number drawn as a small form (glyph-table). | Poster, Shape fill, Scale ladder, Glyph table |
| radial-poster | A poster with one subject in the middle of the sheet: a wheel of spokes round an icon (radial-spokes), two to four large figures standing either side of it, and a bottom row with the same subject's surroundings on concentric rings (orbit-chart) and a ranking as centred pills (pill-rank). | Poster, Radial spokes, Orbit chart, Pill rank |
| ranking-poster | A poster of one subject by the numbers, in four rows: two figures in large type or as filled silhouettes, two treemaps side by side, a full-width ranking of centred pills with one row highlighted, and packed circles with icons beside a column of sized circles and a closing figure. | Poster, Shape fill, Treemap, Pill rank, Circle pack, Stat circles |
| scale-poster | A tall poster that is one illustrated scale: a full-height scale-ladder with icons, leader-labelled items and named zones, and a narrow side column of large figures and one small graphic, each set level with the part of the scale it describes. | Poster, Scale ladder, Stat circles |
| timeline-poster | A poster of change over a run of periods: a full-width ribbon of bands whose thickness is each entity's value and whose order is its rank (ribbon-chart), a strip of two to four dated figures under it, and a bottom row with one measure per period as thick bars (block-bar) and one share at several dates as nested outlines (nested-shares). | Poster, Ribbon chart, Block bars, Nested shares |
Choose an infographic when the piece is one image that should be read in a few seconds and shared as a picture. Choose a report-style template when the reader needs paragraphs, a method note, recommendations or charts with axes.
Using an infographic from JSON
An infographic takes all of its content as props. A spec is { type, ...props }, and Insight renders it.
import { Insight } from "insightcharts";
const spec = {
type: "scale-poster",
theme: "ocean",
title: "The Meridian Deep survey logged 12 sightings between 8 m and 3,750 m",
scale: { data: sightings, name: "sighting", value: "m", direction: "down", format: "{value} m" },
sources: "Meridian Deep survey log",
};
<Insight spec={spec} />This is the scale poster with its full example. The JSON tab holds the whole document.
import { ScalePoster } from "insightcharts";
export function Example() {
return (
<ScalePoster
theme="ocean"
kicker="Oceans"
title="The Meridian Deep survey logged 12 sightings between 8 m and 3,750 m"
subtitle="Depth of each sighting on one research dive, metres below the surface."
scale={{
data: [
{ sighting: "Survey ship hull", m: 8, icon: "ship" },
{ sighting: "Kelp canopy", m: 120, icon: "leaf" },
{ sighting: "Sardine shoal", m: 310, icon: "fish" },
{ sighting: "Lanternfish layer", m: 560, icon: "fish" },
{ sighting: "Swordfish", m: 820, icon: "fish" },
{ sighting: "Coral mound", m: 1150, icon: "tree" },
{ sighting: "Sperm whale", m: 1480, icon: "wave" },
{ sighting: "Anglerfish", m: 1900, icon: "fish" },
{ sighting: "Sensor array", m: 2300, icon: "satellite" },
{ sighting: "Dumbo octopus", m: 2750, icon: "star" },
{ sighting: "Sea cucumbers", m: 3200, icon: "circle" },
{ sighting: "Seabed lander", m: 3750, icon: "pin" },
],
name: "sighting",
value: "m",
iconField: "icon",
direction: "down",
min: 0,
max: 4000,
format: "{value} m",
scaleLabel: "Depth, metres",
zones: [
{ from: 0, to: 200, label: "Sunlit" },
{ from: 200, to: 1000, label: "Twilight zone" },
{ from: 1000, to: 4000, label: "Dark zone" },
],
}}
figures={[
{ at: 200, value: "1%", label: "of surface light is left" },
{ at: 1000, value: "4°C", label: "water temperature" },
{ at: 3000, value: "376 atm", label: "pressure at the lander, 3,750 m down" },
]}
side={{
data: [
{ zone: "species in the sunlit zone", species: 148 },
{ zone: "species in the twilight zone", species: 61 },
{ zone: "species in the dark zone", species: 23 },
],
name: "zone",
value: "species",
title: "Species logged",
height: 250,
}}
sideAt={1900}
sources="Meridian Deep survey log"
note="The Meridian Deep survey is invented. All figures are illustrative."
credit="InsightCharts"
/>
);
}{
"type": "scale-poster",
"theme": "ocean",
"kicker": "Oceans",
"title": "The Meridian Deep survey logged 12 sightings between 8 m and 3,750 m",
"subtitle": "Depth of each sighting on one research dive, metres below the surface.",
"scale": {
"data": [
{ "sighting": "Survey ship hull", "m": 8, "icon": "ship" },
{ "sighting": "Kelp canopy", "m": 120, "icon": "leaf" },
{ "sighting": "Sardine shoal", "m": 310, "icon": "fish" },
{ "sighting": "Lanternfish layer", "m": 560, "icon": "fish" },
{ "sighting": "Swordfish", "m": 820, "icon": "fish" },
{ "sighting": "Coral mound", "m": 1150, "icon": "tree" },
{ "sighting": "Sperm whale", "m": 1480, "icon": "wave" },
{ "sighting": "Anglerfish", "m": 1900, "icon": "fish" },
{ "sighting": "Sensor array", "m": 2300, "icon": "satellite" },
{ "sighting": "Dumbo octopus", "m": 2750, "icon": "star" },
{ "sighting": "Sea cucumbers", "m": 3200, "icon": "circle" },
{ "sighting": "Seabed lander", "m": 3750, "icon": "pin" }
],
"name": "sighting",
"value": "m",
"iconField": "icon",
"direction": "down",
"min": 0,
"max": 4000,
"format": "{value} m",
"scaleLabel": "Depth, metres",
"zones": [
{ "from": 0, "to": 200, "label": "Sunlit" },
{ "from": 200, "to": 1000, "label": "Twilight zone" },
{ "from": 1000, "to": 4000, "label": "Dark zone" }
]
},
"figures": [
{ "at": 200, "value": "1%", "label": "of surface light is left" },
{ "at": 1000, "value": "4°C", "label": "water temperature" },
{ "at": 3000, "value": "376 atm", "label": "pressure at the lander, 3,750 m down" }
],
"side": {
"data": [
{ "zone": "species in the sunlit zone", "species": 148 },
{ "zone": "species in the twilight zone", "species": 61 },
{ "zone": "species in the dark zone", "species": 23 }
],
"name": "zone",
"value": "species",
"title": "Species logged",
"height": 250
},
"sideAt": 1900,
"sources": "Meridian Deep survey log",
"note": "The Meridian Deep survey is invented. All figures are illustrative.",
"credit": "InsightCharts"
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Reading an infographic spec from the top:
typenames the template.title,kicker,subtitleare the masthead. The title is the poster's one fact, written as a plain sentence with its number.themeis a poster theme name. Each template has its own default.- Region props hold the graphics. Each template names its own regions, such as
scaleandsideon the scale poster orhero,reference,area,barsandshareson the count poster. sources,note,creditare the footer.
A region takes a compact config: the rows in data, the field names, and any other prop of the primitive that draws the region. A title, subtitle, source or note in the config becomes the heading and source line of that panel. A region also takes a full spec with its own type, or a React element. That replaces the primitive the template would have drawn.
{
"type": "count-poster",
"title": "Norland's schools taught 1.84 million pupils in 2025",
"unit": 1000,
"unitLabel": "1,000 people",
"hero": { "data": [{ "stage": "Primary", "pupils": 820000 }, { "stage": "Lower secondary", "pupils": 480000 }], "name": "stage", "value": "pupils", "title": "820,000 pupils were in primary school" },
"bars": { "type": "bar-chart", "data": [{ "year": "2000", "m": 1.42 }, { "year": "2025", "m": 1.84 }], "x": "year", "y": "m", "title": "Enrolment was 1.42 million in 2000" }
}Props shared by infographics
| Prop | Purpose |
|---|---|
title | The poster's one fact, as a plain sentence with its number. |
kicker | Small label above the title: the topic. |
subtitle | One line under the title: the measure, population and period. |
theme | Poster theme: noir, magenta, dusk, ocean, forest, blueprint, sunrise, paper, any other theme name, or a theme object. |
mode | Colour mode of the poster and everything in it. A poster paints its own ground and does not follow the page unless you set auto. Only paper has a different dark variant. |
download | Show a "Download PNG" control under the poster that saves the whole poster as one image. |
maxWidth | Widest the poster is drawn. It is centred in wider containers. |
linked | Make the marks clickable. Clicking a mark in one graphic highlights the same name in every other graphic that has it, and filters the graphics that read the shared data. Click it again, or the empty ground of that graphic, to clear. |
data | Rows shared by every region whose config leaves out its own data. With linked, a click filters those regions. |
sources | Where the data comes from, shown in the footer. |
note | Caveat shown in the footer, e.g. "Illustrative data". |
credit | Who made the poster, shown at the right of the footer. |
level | Heading level of the title. Panel headings are one level down. |
linked joins the panels by name. A click on a mark in one graphic highlights the same name in every other graphic that has it. Graphics that read the shared data prop are filtered by the click.
Composing a poster with the poster frame
Use the poster molecule directly when no template has the layout you need. A poster has a masthead (kicker, title, subtitle), a list of panels and a footer (sources, note, credit).
import { Poster, registerAll } from "insightcharts";
// The slot props below are JSON specs. This makes their `type` names resolvable.
registerAll();
export function Example() {
return (
<Poster
theme="forest"
kicker="Transport"
title="Tarn Valley buses carried 9.6 million passengers in 2025"
subtitle="Passengers on the valley's seven bus routes, January to December 2025."
panels={[
{
span: 5,
valign: "center",
content: {
type: "big-number",
size: "hero",
value: "9.6 million",
label: "Passengers in 2025",
context: "8.9 million in 2024",
},
},
{
span: 7,
title: "Route 4 carried 2.3 million passengers",
subtitle: "Passengers by route, thousands, 2025",
content: {
type: "pill-rank",
data: [
{ route: "Route 4", k: 2300 },
{ route: "Route 1", k: 1900 },
{ route: "Route 7", k: 1500 },
{ route: "Route 2", k: 1400 },
{ route: "Route 9", k: 1100 },
{ route: "Route 5", k: 800 },
{ route: "Route 3", k: 600 },
],
name: "route",
value: "k",
format: "{value}k",
highlight: "Route 4",
},
},
{
span: 7,
title: "Passenger numbers were 6.1 million in 2021",
subtitle: "Passengers per year, millions",
content: {
type: "block-bar",
data: [
{ year: "2021", m: 6.1 },
{ year: "2022", m: 7.4 },
{ year: "2023", m: 8.2 },
{ year: "2024", m: 8.9 },
{ year: "2025", m: 9.6 },
],
name: "year",
value: "m",
format: "{value}m",
},
},
{
span: 5,
title: "40% of the 120 buses were electric in 2025",
content: {
type: "shape-fill",
data: [
{ fleet: "Electric buses", share: 40 },
],
name: "fleet",
value: "share",
icon: "bus",
format: "{value}%",
},
},
]}
sources="Tarn Valley Transport Authority"
note="Tarn Valley is an invented place. All figures are illustrative."
credit="InsightCharts"
/>
);
}{
"type": "poster",
"theme": "forest",
"kicker": "Transport",
"title": "Tarn Valley buses carried 9.6 million passengers in 2025",
"subtitle": "Passengers on the valley's seven bus routes, January to December 2025.",
"panels": [
{
"span": 5,
"valign": "center",
"content": {
"type": "big-number",
"size": "hero",
"value": "9.6 million",
"label": "Passengers in 2025",
"context": "8.9 million in 2024"
}
},
{
"span": 7,
"title": "Route 4 carried 2.3 million passengers",
"subtitle": "Passengers by route, thousands, 2025",
"content": {
"type": "pill-rank",
"data": [
{ "route": "Route 4", "k": 2300 },
{ "route": "Route 1", "k": 1900 },
{ "route": "Route 7", "k": 1500 },
{ "route": "Route 2", "k": 1400 },
{ "route": "Route 9", "k": 1100 },
{ "route": "Route 5", "k": 800 },
{ "route": "Route 3", "k": 600 }
],
"name": "route",
"value": "k",
"format": "{value}k",
"highlight": "Route 4"
}
},
{
"span": 7,
"title": "Passenger numbers were 6.1 million in 2021",
"subtitle": "Passengers per year, millions",
"content": {
"type": "block-bar",
"data": [
{ "year": "2021", "m": 6.1 },
{ "year": "2022", "m": 7.4 },
{ "year": "2023", "m": 8.2 },
{ "year": "2024", "m": 8.9 },
{ "year": "2025", "m": 9.6 }
],
"name": "year",
"value": "m",
"format": "{value}m"
}
},
{
"span": 5,
"title": "40% of the 120 buses were electric in 2025",
"content": {
"type": "shape-fill",
"data": [
{ "fleet": "Electric buses", "share": 40 }
],
"name": "fleet",
"value": "share",
"icon": "bus",
"format": "{value}%"
}
}
],
"sources": "Tarn Valley Transport Authority",
"note": "Tarn Valley is an invented place. All figures are illustrative.",
"credit": "InsightCharts"
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Panels
Each panel is one block of the poster.
| Panel field | Default | Purpose |
|---|---|---|
content | required | A component spec such as { type: "pill-rank", ... }, or a React element. |
title, subtitle | none | A small heading over the content and one line under it. |
span | the full width | Columns the panel covers, out of the poster's columns. |
rowSpan | 1 | Rows the panel covers. It is ignored when the poster reflows to fewer columns. |
source, note | none | A source line and a caveat under the panel. |
align | "left" | Alignment of the heading, the source line and text content. |
valign | "start" | Where the content sits when a neighbouring panel is taller. |
bleed | false | Runs the content to the poster's left and right edges where the panel touches them. |
id | none | Set as data-panel on the panel. |
columns is 12 by default, so span: 5 beside span: 7 makes one row. A small number such as columns: 2 or columns: 3 gives a simple grid. Panels are placed in reading order. A dotted rule is drawn under the masthead, between rows of panels and above the footer. rules changes it to "solid" or "none".
The frame passes its theme and one colour mode to everything inside it. A chart in a panel needs no theme or mode of its own.
Shape and size
| Prop | Default | Purpose |
|---|---|---|
maxWidth | 1200 | The widest the poster is drawn. It is centred in a wider container. |
aspect | none | A fixed shape as width / height, such as "4:5" or 0.75. The poster still grows when its content needs more height. |
padding | 56 | Space between the poster's edge and its content. It is 36 under 900 px and 20 under 600 px. |
gap | 40 | Space between panels. It is 28 under 600 px. |
Poster themes
A poster theme sets the ground of the sheet, the type colours and four or five strong mark colours. There are eight. Pass the name as theme to the frame or to any infographic.
Near-black sheet, white type, yellow and sky blue marks.
#0d0d0f
Saturated magenta sheet, pale pink blocks, cyan accent.
#c2006b
Violet gradient, marks from orange to yellow.
linear-gradient(160deg, #24104f 0%, #3d1663 55%, #5e2067 100%)
Warm off-white stock, black ink, one red.
#f3ecdf
dark: #1d1b18
Navy to teal gradient, aqua and coral marks.
linear-gradient(180deg, #041c3a 0%, #06365a 55%, #084c5c 100%)
Dark green sheet, lime and cream marks.
#0f3d2a
Cobalt sheet, white linework, yellow accent.
#1447c8
Cream to peach gradient, plum and tangerine marks.
linear-gradient(180deg, #fff1e0 0%, #ffdfc6 100%)
Seven of the eight themes have one look. Their light and dark tokens are the same, so the poster has the same colours on a light page and on a dark page. paper has a second variant on charcoal stock, which you get with mode="dark".
The frame's mode is "light" by default. A poster does not follow the page's colour mode unless you set mode="auto".
posterThemes holds the eight themes by name and posterBackgrounds[name][mode] holds the CSS background each one paints. Three of the grounds are gradients. Both are exported from insightcharts/themes, and the themes are also in the themes record. See theming for using a poster theme outside the frame.
import { Poster } from "insightcharts";
<Poster theme="blueprint" title="..." panels={panels} />
<Poster theme="paper" mode="dark" title="..." panels={panels} />
<Poster theme="noir" background="linear-gradient(180deg, #0d0d0f, #1b1b22)" title="..." panels={panels} />background replaces the ground with any CSS colour or gradient. Keep it close to the theme's surface, because charts draw the gaps between touching marks in the surface colour.
Poster primitives
A poster primitive is an atom with the category poster. It is a chart built with defineChart, so it takes data, title, highlight, format, select and the other common chart props. It differs from the other chart atoms in four ways.
- Marks are large flat fills in the theme's colours.
- The name and value are printed inside the mark when they fit and beside it when they do not.
- There are no axes or gridlines by default.
- The graphic takes the height its layout needs and is laid out again for a narrow width.
A primitive works in any theme and outside a poster. In a poster it takes the frame's theme.
| type | Use it for | Used in |
|---|---|---|
| arc-diagram | Connections among up to about 20 entities that have a meaningful order. | Network poster |
| block-bar | A short series or ranking of 3 to 12 values, as thick bars with the value printed inside. | Count poster, Timeline poster |
| bubble-network | Which of up to about 12 named things are connected, with each sized by value. | Atlas poster, Network poster |
| bubble-scale | 5 to about 40 things with a position on one scale and a magnitude shown as area. | Flow poster |
| circle-pack | 5 to about 60 parts of very different sizes, as packed circles with one level of grouping. | Ranking poster |
| curve-rank | Two measures of the same 4 to about 15 entities, as one curve per entity between two scales. | Matrix poster |
| fan-flow | One total split among 4 to about 14 destinations, or collected from that many origins. | Flow poster |
| glyph-table | 3 to about 12 entities across 2 to 5 measures with different units, as a table of small graphics. | Matrix poster, Profile poster |
| icon-array-grid | Counts of up to about 150 in 4 to 24 categories, as one tile of icons per category. | none yet |
| nested-shares | The share of one whole at 2 to 8 dates or in 2 to 8 categories, as outlines nested in a square. | Count poster, Timeline poster |
| orbit-chart | 6 to about 40 named things grouped by level or period, as dots on rings round one centre. | Radial poster |
| pill-rank | A ranking of 4 to about 20 named things, as centred rounded bars with name, value and rank. | Atlas poster, Network poster, Radial poster, Ranking poster |
| proportional-area | Two to eight quantities that differ by 2 to 100 times, as squares or circles sized by area. | Atlas poster, Count poster |
| radial-spokes | 4 to 12 attributes of one subject, as spokes round a centre disc. | Atlas poster, Radial poster |
| ribbon-chart | 4 to 8 entities over 4 to 10 periods, as bands whose thickness is the value and whose position is the rank. | Timeline poster |
| scale-ladder | 4 to about 20 things on one shared scale such as depth, height, temperature or age. | Profile poster, Scale poster |
| shape-fill | One to six percentages, each as an icon silhouette filled to its level. | Count poster, Profile poster, Ranking poster |
| stat-circles | Two to six related magnitudes, as circles sized by area with the number set large. | Atlas poster, Ranking poster, Scale poster |
| unit-blocks | Large counts in 2 to 12 groups, drawn as blocks of one icon per fixed number of units. | Count poster |
import { StatCircles } from "insightcharts";
const data = [
{ who: "per person in the United States", kg: 124 },
{ who: "per person in Brazil", kg: 100 },
{ who: "per person in China", kg: 63 },
{ who: "per person in India", kg: 6 },
];
export function Example() {
return (
<StatCircles
data={data}
name="who"
value="kg"
unit="kg"
title="Meat supply in the United States was 124 kg per person in 2021"
subtitle="Meat supply per person per year, kilograms, 2021"
source="FAO food balance sheets"
note="Rounded, approximate figures for illustration"
/>
);
}{
"type": "stat-circles",
"data": [
{ "who": "per person in the United States", "kg": 124 },
{ "who": "per person in Brazil", "kg": 100 },
{ "who": "per person in China", "kg": 63 },
{ "who": "per person in India", "kg": 6 }
],
"name": "who",
"value": "kg",
"unit": "kg",
"title": "Meat supply in the United States was 124 kg per person in 2021",
"subtitle": "Meat supply per person per year, kilograms, 2021",
"source": "FAO food balance sheets",
"note": "Rounded, approximate figures for illustration"
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Any other atom also fits a panel. The poster page lists the ones its examples use, such as treemap, waffle chart and pictogram chart.
Icons
The library has 69 built-in icons. An icon prop takes a built-in name such as "person" or "wind-turbine", or a custom path written as "path://M0 0...". Unit charts repeat an icon by count. No chart scales an icon's width and height by a value.
{ "type": "unit-blocks", "data": "/data/finishers.csv", "name": "age", "value": "finishers", "unit": 10, "unitLabel": "10 finishers", "icon": "person" }The icons page shows every icon with its name.
Saving a poster as a PNG
Set download on the frame or on any infographic. A "Download PNG" control appears under the poster. It saves the whole sheet as one image, without the control.
<Poster download exportWidth={3000} filename="bus-passengers-2025" onExport={(blob) => upload(blob)} title="..." panels={panels} />
<Insight spec={{ type: "count-poster", download: true, ...rest }} />| Prop | Default | Purpose |
|---|---|---|
download | false | Shows the control. |
exportWidth | 2400 | Width of the image in pixels. The height follows the poster's shape. |
filename | a slug of the title | File name without the extension. |
downloadLabel | "Download PNG" | Label of the control. |
onExport | none | Called with the PNG Blob after a download. |
exportWidth, filename, downloadLabel and onExport are props of the poster frame. The infographic templates take download only.
With download set, every chart in the poster mounts at once instead of when it scrolls into view. The image is then complete when the reader saves it.
The image is drawn from the DOM onto a canvas by rasterize, which is exported from insightcharts/core. To save a poster from your own button, pass it the sheet element.
import { canvasToBlob, downloadBlob, rasterize } from "insightcharts/core";
async function save() {
const sheet = document.querySelector<HTMLElement>('[data-slot="ic-poster"]');
const blob = await canvasToBlob(await rasterize(sheet, 2400));
downloadBlob(blob, "poster.png");
}rasterize paints box backgrounds including linear and radial gradients, borders, corner radii, clipping, text, inline SVG and canvases. It does not paint outer or blurred shadows, CSS transforms, conic or repeating gradients, or url() background images. It skips any element with the data-ic-export-ignore attribute. See export for the other export paths.
Posters on a phone
A poster lays itself out from its own width, not from the viewport. A poster in a 400 px column has the phone layout on any screen.
| Poster width | Layout |
|---|---|
| 760 px and wider | The grid you wrote, with every span and rowSpan. |
| 600 to 759 px | Two columns. On a 12-column grid a panel with span up to 6 takes one column and a wider panel takes both. |
| Under 600 px | One column. Every panel is full width, in reading order. |
Under 600 px the padding is 20 px, the gap is 28 px, the title is 30 to 40 px and a fixed aspect is dropped. The poster grows as tall as its panels need.
Each poster primitive lays itself out again for the narrower panel. A primitive sets its own height from its rows and its measured width, so a graphic can be taller on a phone. The preview toolbar on each infographic page has phone and tablet width buttons on screens 768 px and wider.
Writing the text
A poster has little text, so each line carries a number.
- The
titleis one plain statement of fact with its number and period, such as "Riverton's bike-share scheme carried 4.2 million trips in 2025". - A panel
titleis one fact about that panel's graphic, or a plain label. - A
subtitlenames the measure, the unit, the population and the period. sourcesnames the source. Put a caveat such as "Illustrative data" innote.