Skip to main content

XYLabels

The XYLabels component allows you to add text labels directly onto your XY charts at specific data coordinates.

Basic Configuration

Get started with just two required properties - x, y accessors and an optional label function.

<VisXYLabels
x={x}
y={y}
label={label}
color="#374151"
backgroundColor="rgba(255, 255, 255, 0.9)"
/>
Loading...
// Basic configuration
const xyLabels = new XYLabels({
x: d => d.x,
y: d => d.y,
label: d => d.label
})

Label Content

The label property accepts a string accessor function that determines what text to display for each data point.

<VisXYLabels
x={x}
y={y}
label={label}
color="#374151"
backgroundColor="rgba(255, 255, 255, 0.95)"
/>
Loading...
// Custom label content
label: d => `${d.label}: ${d.y}`

Positioning

XYLabels supports three different positioning modes through the xPositioning and yPositioning properties:

Data Space Positioning (Default)

By default, labels are positioned in data space, meaning their coordinates correspond to data values. This is ideal when you want labels to move with your data:

<VisXYLabels
x={x}
y={y}
label={label}
xPositioning="data_space"
yPositioning="data_space"
color="#0F172A"
backgroundColor="rgba(255, 255, 255, 0.9)"
/>
Loading...
// Data space positioning (default)
xPositioning: XYLabelPositioning.DataSpace,
yPositioning: XYLabelPositioning.DataSpace

Absolute Pixel Positioning

Position labels using absolute pixel coordinates from the top-left corner of the chart area:

<VisXYLabels
x={x}
y={y}
label={label}
xPositioning="absolute_px"
yPositioning="absolute_px"
color="#065F46"
backgroundColor="rgba(255, 255, 255, 0.95)"
/>
Loading...
// Absolute pixel positioning
xPositioning: XYLabelPositioning.AbsolutePx,
yPositioning: XYLabelPositioning.AbsolutePx,
x: 100, // 100 pixels from left
y: 50 // 50 pixels from top

Absolute Percentage Positioning

Position labels using percentage coordinates (0-100) relative to the chart container dimensions:

<VisXYLabels
x={x}
y={y}
label={label}
xPositioning="absolute_percentage"
yPositioning="absolute_percentage"
color="#92400E"
backgroundColor="rgba(255, 255, 255, 0.95)"
/>
Loading...
// Absolute percentage positioning
xPositioning: XYLabelPositioning.AbsolutePercentage,
yPositioning: XYLabelPositioning.AbsolutePercentage,
x: 75, // 75% from left edge
y: 25 // 25% from top edge

Mixed Positioning

You can mix different positioning modes for x and y coordinates:

// Mix data space with screen space
xPositioning: XYLabelPositioning.DataSpace, // Follow data horizontally
yPositioning: XYLabelPositioning.AbsolutePx, // Fixed vertical position
y: 20 // Always 20px from top

Styling

Label Color

Control label text color with the color property. You can use dynamic colors based on your data:

<VisXYLabels
x={x}
y={y}
label={label}
color={color}
backgroundColor="rgba(255, 255, 255, 0.9)"
/>
Loading...

Background Color

Add background colors to make labels more readable, especially over complex visualizations:

<VisXYLabels
x={x}
y={y}
label={label}
backgroundColor="rgba(255, 255, 255, 0.95)"
color="#374151"
/>
Loading...

Font Size

Customize label font size with the labelFontSize property. You can make it dynamic based on data values:

<VisXYLabels
x={x}
y={y}
label={label}
labelFontSize={labelFontSize}
color="#831843"
backgroundColor="rgba(255, 255, 255, 0.9)"
/>
Loading...

Label Clustering

When labels overlap, XYLabels can automatically cluster them to reduce visual clutter. This feature is enabled by default and is particularly useful for dense datasets.

Enabling/Disabling Clustering

Control clustering with the clustering property. When enabled, overlapping labels are automatically grouped together to reduce visual clutter. Toggle the checkbox below to see the difference:

Loading...
// Enable/disable clustering programmatically
const xyLabels = new XYLabels({
x: d => d.x,
y: d => d.y,
label: d => d.label,
clustering: true, // Set to false to disable clustering

// Optional: Customize cluster appearance when clustering is enabled
clusterLabel: (records) => `${records.length} items`,
clusterBackgroundColor: 'rgba(132, 204, 22, 0.2)',
clusterLabelColor: '#365314'
})

Cluster Customization

Customize cluster appearance with cluster-specific properties:

// Cluster configuration
clusterLabel: (records) => `${records.length} items`,
clusterFontSize: 14,
clusterBackgroundColor: 'rgba(59, 130, 246, 0.1)',
clusterLabelColor: '#1E40AF'
<VisXYLabels
x={x}
y={y}
label={label}
clustering={true}
clusterLabel={clusterLabel}
clusterBackgroundColor="rgba(59, 130, 246, 0.1)"
clusterLabelColor="#1E40AF"
color="#1E40AF"
backgroundColor="rgba(255, 255, 255, 0.95)"
/>
Loading...

Events

The XYLabels component supports interactive events on both individual labels and clusters. Available selectors:

  • XYLabels.selectors.label - Events for individual labels
  • XYLabels.selectors.cluster - Events for label clusters (when clustering is enabled)
import { XYLabels } from '@unovis/ts'

const events = {
[XYLabels.selectors.label]: {
click: (d: Datum) => alert(`Clicked: ${d.label}`),
mouseover: (d: Datum) => console.log('Label hovered:', d),
mouseleave: (d: Datum) => console.log('Label unhovered:', d)
},
[XYLabels.selectors.cluster]: {
click: (cluster: XYLabel<Datum>[]) => {
const labels = cluster.map(d => d.label).join(', ')
alert(`Cluster clicked! Contains: ${labels}`)
},
mouseover: (cluster: XYLabel<Datum>[]) => {
console.log('Cluster hovered:', cluster.length, 'labels')
}
}
}

Interactive Labels

Click on any label below to see event handling in action:

<VisXYLabels
x={x}
y={y}
label={label}
color="#1E40AF"
backgroundColor="rgba(255, 255, 255, 0.95)"
cursor="pointer"
events={events}
/>
Loading...

CSS Variables

The following CSS variables can be used to customize the default appearance:

/* Label styling */
--vis-xy-label-font-size: 12px;
--vis-xy-label-font-family: var(--vis-font-family);
--vis-xy-label-text-color: #000;
--vis-xy-label-background-fill-color: none;
--vis-xy-label-background-stroke-color: none;
--vis-xy-label-background-stroke-width: 0;
--vis-xy-label-padding: 4px;

/* Cluster styling */
--vis-xy-label-cluster-font-size: 14px;
--vis-xy-label-cluster-text-color: #000;
--vis-xy-label-cluster-background-fill-color: #f0f0f0;
--vis-xy-label-cluster-background-stroke-color: #ccc;
--vis-xy-label-cluster-background-stroke-width: 1px;
--vis-xy-label-cluster-padding: 6px;

/* Dark theme overrides */
--vis-dark-xy-label-text-color: #fff;
--vis-dark-xy-label-cluster-text-color: #fff;
--vis-dark-xy-label-cluster-background-fill-color: #333;
--vis-dark-xy-label-cluster-background-stroke-color: #666;

Component Props

NameTypeDescription
* required property