Text Annotations and Labels
Text marks enable you to add labels, annotations, and callouts to your charts. This guide demonstrates various text positioning and styling techniques.
Basic Text Labels
Simple Point Labels
Label each data point with text at its position:
data:
source: |
[
{"x": 10, "y": 20, "label": "Start"},
{"x": 30, "y": 50, "label": "Peak"},
{"x": 50, "y": 35, "label": "Valley"},
{"x": 70, "y": 60, "label": "End"}
]
width: 600
height: 400
marks:
- type: dot
configuration:
x: x
y: y
r: 6
fill: steelblue
- type: text
configuration:
x: x
y: y
text: label
dy: -10Key Features:
text: label- Field containing the text to displaydy: -10- Offset text 10 pixels above the point- Combines with dot marks for labeled scatter plots
Text Positioning
Using dx and dy Offsets
Fine-tune text position with pixel offsets:
data:
source: |
[
{"x": 1, "y": 10, "label": "Q1", "offset": 0},
{"x": 2, "y": 25, "label": "Q2", "offset": 5},
{"x": 3, "y": 18, "label": "Q3", "offset": -5},
{"x": 4, "y": 32, "label": "Q4", "offset": 0}
]
width: 600
height: 300
marks:
- type: line
configuration:
x: x
y: y
stroke: steelblue
strokeWidth: 2
- type: text
configuration:
x: x
y: y
text: label
dx: 0
dy: -12
fontSize: 14
fontWeight: boldUse Cases:
- Avoiding label overlap
- Aligning labels with specific visual elements
- Creating callouts that point to data
Text Anchor Points
Control horizontal alignment with textAnchor:
data:
source: |
[
{"x": 10, "value": 100, "label": "Start ←", "anchor": "end"},
{"x": 50, "value": 150, "label": "Middle", "anchor": "middle"},
{"x": 90, "value": 120, "label": "→ End", "anchor": "start"}
]
width: 600
height: 300
marks:
- type: rule
configuration:
x: x
y1: 0
y2: value
stroke: lightgray
- type: text
configuration:
x: x
y: value
text: label
textAnchor: anchor
dy: -8
fontSize: 12Text Anchor Options:
start- Text starts at the anchor point (left-aligned)middle- Text centered at anchor point (default)end- Text ends at anchor point (right-aligned)
Rotated Text
Angled Labels
Rotate text to fit in tight spaces or follow trends:
data:
source: |
[
{"category": "Product A", "value": 45},
{"category": "Product B", "value": 78},
{"category": "Product C", "value": 32},
{"category": "Product D", "value": 91},
{"category": "Product E", "value": 56}
]
width: 600
height: 400
marks:
- type: bar
configuration:
x: category
y: value
fill: steelblue
- type: text
configuration:
x: category
y: value
text: value
dy: -5
rotate: -45
fontSize: 11
textAnchor: endRotation Tips:
- Negative angles rotate counter-clockwise
- Useful for long categorical labels
- Combine with
textAnchorfor proper alignment
Font Styling
Custom Typography
Apply font styling for emphasis and hierarchy:
data:
source: |
[
{"x": 20, "y": 80, "text": "Title", "size": 18, "weight": "bold"},
{"x": 20, "y": 60, "text": "Subtitle", "size": 14, "weight": "normal"},
{"x": 20, "y": 40, "text": "Caption", "size": 10, "weight": "300"}
]
width: 600
height: 300
marks:
- type: text
configuration:
x: x
y: y
text: text
fontSize: size
fontWeight: weight
textAnchor: startFont Properties:
fontSize- Number or string (e.g., 12, "14px")fontWeight- "normal", "bold", "300", "600", etc.fontFamily- Font name (e.g., "Arial", "monospace")
Colored Text
Color-Coded Labels
Use fill encoding for categorical colors:
data:
source: |
[
{"x": 10, "y": 50, "label": "Group A", "category": "A"},
{"x": 30, "y": 70, "label": "Group B", "category": "B"},
{"x": 50, "y": 40, "label": "Group C", "category": "C"},
{"x": 70, "y": 85, "label": "Group D", "category": "D"}
]
width: 600
height: 400
scales:
color:
legend: true
marks:
- type: dot
configuration:
x: x
y: y
fill: category
r: 8
- type: text
configuration:
x: x
y: y
text: label
fill: category
dy: 15
fontSize: 12
fontWeight: boldColor Encoding:
fill: category- Map text color to categorical variable- Matches dot colors automatically
- Creates consistent visual grouping
Data Annotations
Highlight Specific Values
Add contextual information to charts:
data:
source: |
[
{"month": "Jan", "sales": 120},
{"month": "Feb", "sales": 145},
{"month": "Mar", "sales": 189},
{"month": "Apr", "sales": 156},
{"month": "May", "sales": 198},
{"month": "Jun", "sales": 221}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: month
y: sales
stroke: steelblue
strokeWidth: 2
- type: dot
configuration:
x: month
y: sales
r: 4
fill: steelblue
- type: text
configuration:
x: month
y: sales
text: sales
dy: -12
fontSize: 11Annotation Patterns:
- Show exact values above data points
- Add context with descriptive text
- Highlight outliers or important events
Callouts and Pointers
Annotated Events
Mark important events with styled callouts:
data:
source: |
[
{"date": "2024-01", "value": 100},
{"date": "2024-02", "value": 120},
{"date": "2024-03", "value": 150},
{"date": "2024-04", "value": 145},
{"date": "2024-05", "value": 180},
{"date": "2024-06", "value": 165}
]
width: 600
height: 350
marks:
- type: area
configuration:
x: date
y: value
fill: steelblue
fillOpacity: 0.3
- type: line
configuration:
x: date
y: value
stroke: steelblue
strokeWidth: 2
- type: text
configuration:
x: date
y: value
text: value
dy: -8
fontSize: 10
fill: "#333"Multi-Line Text
Stacked Labels
Create hierarchical labels with multiple text marks:
data:
source: |
[
{"x": 25, "y": 50, "title": "Product A", "subtitle": "45 units"},
{"x": 50, "y": 75, "title": "Product B", "subtitle": "78 units"},
{"x": 75, "y": 40, "title": "Product C", "subtitle": "32 units"}
]
width: 800
height: 400
marks:
- type: dot
configuration:
x: x
y: y
r: 10
fill: steelblue
- type: text
configuration:
x: x
y: y
text: title
dy: 20
fontSize: 13
fontWeight: bold
- type: text
configuration:
x: x
y: y
text: subtitle
dy: 35
fontSize: 10
fill: grayMulti-Line Technique:
- Create separate text marks for each line
- Use different
dyoffsets to stack vertically - Vary font size and weight for hierarchy
Best Practices
Positioning Guidelines
Avoid Overlap
- Use
dxanddyto offset labels from data points - Common offset:
dy: -10ordy: -12
- Use
Choose Appropriate Anchors
- Left-aligned text:
textAnchor: "start" - Centered text:
textAnchor: "middle"(default) - Right-aligned text:
textAnchor: "end"
- Left-aligned text:
Font Sizing
- Data labels: 10-12px
- Titles: 14-18px
- Annotations: 11-13px
Rotation
- Use sparingly - only when necessary
- Common angles: -45°, -90°, 45°
- Combine with appropriate
textAnchor
Performance Tips
Limit Label Count
- Show labels only for important points
- Filter data before creating text marks
- Consider showing labels only on hover (using tip instead)
Readable Fonts
- System fonts are fastest:
fontFamily: "system-ui" - Sans-serif fonts for clarity
- Avoid very small sizes (<9px)
- System fonts are fastest:
Common Patterns
1. Label First and Last Points Only
# Filter to show only first and last values
marks:
- type: text
configuration:
x: date
y: value
text: value
# Filter logic in data preprocessing2. Percentage Labels
marks:
- type: text
configuration:
x: category
y: percentage
text: percentage # Format as "45%" in data
dy: -83. Dynamic Positioning
# Adjust dy based on positive/negative values
marks:
- type: text
configuration:
x: date
y: value
text: label
dy: -12 # Above for positive, below for negativeTroubleshooting
Problem: Text overlaps with data points
- Solution: Increase
dyoffset (e.g.,dy: -15)
Problem: Long labels get cut off
- Solution: Adjust chart margins or rotate text
Problem: Text hard to read
- Solution: Increase
fontSizeor add contrastingfillcolor
Problem: Labels overlap each other
- Solution: Reduce number of labels or use variable
dx/dyoffsets
Related Examples
- Vector Arrows - Directional indicators with arrows
- Link Marks - Connect points with lines and labels
- Smooth Curves - Combine text with curved lines
Last Updated: 2025-01-12Part of Phase 3: Advanced Mark Types