Legend
The legend lists the series with their icons, and is where series get filtered in and out of the chart. Its config covers where it sits (position, align, alignedToAxes), how it is drawn (backgroundStyle, item, icon) and what clicking and hovering its items do.
ts
// A styled legend above the plot: right-aligned against the chart bounds
// instead of the axes, boxed with a faint background, and with filtered
// series struck through rather than only greyed out. The long EMEA title is
// truncated once the legend row runs out of room.
import type { MochartInputConfig } from '@mochart/core';
export const config: MochartInputConfig = {
version: '1.0.0',
title: { text: 'Regional Revenue' },
categoryAxis: { property: 'quarter', type: 'string', scale: 'ordinal' },
valueAxes: [{ id: 'VA0', title: { text: 'Revenue ($k)' }, min: 0 }],
seriesDefaults: { renderer: 'line' },
series: [
{ property: 'north', title: 'North America' },
{ property: 'emea', title: 'Europe, Middle East and Africa' },
{ property: 'apac', title: 'Asia Pacific' },
{ property: 'latam', title: 'Latin America' }
],
legend: {
position: 'top',
align: 'right',
alignedToAxes: false,
margin: { top: 0, right: 0, bottom: 8, left: 0 },
padding: { top: 2, right: 6, bottom: 2, left: 6 },
backgroundStyle: {
strokeColor: 'currentColor',
strokeOpacity: 0.25,
strokeWidth: 1,
fillColor: 'currentColor',
fillOpacity: 0.04
},
item: {
margin: { top: 1, right: 4, bottom: 1, left: 4 },
padding: { top: 2, right: 4, bottom: 2, left: 4 },
textStyle: { fillColor: 'currentColor', fillOpacity: 0.85 }
},
icon: { size: 10, spacing: 6 },
strikeThroughFiltered: true,
truncation: { enabled: true, text: '…' }
}
};
export const data = [
{ quarter: 'Q1', north: 420, emea: 310, apac: 180, latam: 95 },
{ quarter: 'Q2', north: 455, emea: 335, apac: 210, latam: 110 },
{ quarter: 'Q3', north: 470, emea: 320, apac: 245, latam: 120 },
{ quarter: 'Q4', north: 510, emea: 360, apac: 270, latam: 140 }
];How it works
positionputs the legend above (top) or below (bottom, the default) the plot, andalignplaces itleft,centerorrightwithin its row.alignedToAxeschooses what that row is: the plot width between the axes (true, the default) or the full chart width (false), which is why the legend above lines up with the chart edge rather than the value axis. Items that do not fit the row wrap onto further rows.visibledefaults totrueonly above one series — a single-series chart has to set it, as the next example does.marginandpaddingspace the legend as a whole from the title and plot;backgroundStylefills and outlines the padded box (the margin lies outside it). Its default stroke and fill opacities are0, so set them to make the box show.itemstyles each series entry the same way:item.marginanditem.paddingaround the icon and title,item.backgroundStylebehind them anditem.textStylefor the title text, which follows the host page's colour throughcurrentColorby default. The padded item box is also the click target.iconconfigures the swatch:size(automatches the text height),spacingto the title,borderStyle, and whether it shows the series colour, its marker shape or a placeholder inunfilteredColor/filteredColor.truncation.enabled(on by default) cuts a title that is wider than the legend has room for and appendstruncation.text.- Clicking an item filters its series out and back in while
filterOnClickis on (the default); a filtered item's icon switches toicon.filteredColor(transparent by default), andstrikeThroughFilteredstrikes its title through as well. Hovering an item focuses its series whilefocusOnHoveris on (the default), andfocusOnClick— off by default — makes a click do the same, which is what touch users need since a tap never counts as a hover.
A single-series key
With one series there is nothing to filter or focus against, so this legend is a plain key: shown explicitly, and with all three interactions switched off so its item does not respond to the pointer.
ts
// One series: the legend only defaults to visible above one series, so
// visible is set explicitly. With filtering and focus switched off it is a
// plain key — clicking or hovering the item does nothing — and the icon
// drops its border to read as a colour swatch.
import type { MochartInputConfig } from '@mochart/core';
export const config: MochartInputConfig = {
version: '1.0.0',
title: { text: 'Daily Sign-ups' },
categoryAxis: { property: 'day', type: 'string', scale: 'ordinal' },
valueAxes: [{ id: 'VA0', title: { text: 'Sign-ups' }, min: 0 }],
series: [{ property: 'signups', title: 'New sign-ups', renderer: 'bar' }],
legend: {
visible: true,
position: 'bottom',
align: 'left',
alignedToAxes: true,
filterOnClick: false,
focusOnClick: false,
focusOnHover: false,
icon: { size: 12, borderStyle: { strokeOpacity: 0 } }
}
};
export const data = [
{ day: 'Mon', signups: 34 },
{ day: 'Tue', signups: 41 },
{ day: 'Wed', signups: 38 },
{ day: 'Thu', signups: 52 },
{ day: 'Fri', signups: 47 },
{ day: 'Sat', signups: 23 },
{ day: 'Sun', signups: 19 }
];- Setting
visible: trueis what makes the legend appear here; leaving it unset hides it whenever the chart has one series. - With
filterOnClick,focusOnClickandfocusOnHoverallfalsethe item is inert, and the legend leaves the keyboard tab order as well. - The default
bottomposition andalignedToAxes: trueline the legend up with the plot, soalign: 'left'starts it under the value axis edge.