Composed Chart

Documentation Index

Fetch the complete documentation index at: /llms.txt. Use this file to discover all available pages before exploring further.

Composed charts that combine bars, lines, gradients, and interactive states

Installation

npx shadcn-svelte@latest add https://evilcharts-sv.vercel.app/r/layerchart-composed-chart.json

Usage

<EvilComposedChart> is the container; compose the parts you need — <EvilComposedChart.Grid>, <EvilComposedChart.XAxis>, <EvilComposedChart.YAxis>, <EvilComposedChart.Legend>, <EvilComposedChart.Tooltip>, and one or more <EvilComposedChart.Bar> and <EvilComposedChart.Line> — as children. Each <Bar> carries its own variant, glow, and isClickable; each <Line> its own strokeVariant, curveType, glow, and isClickable, so one chart can mix bar and line styles freely.

<script lang="ts">
	import { EvilComposedChart } from '$lib/components/evilcharts/charts/layerchart-composed-chart';
	import { type ChartConfig } from '$lib/components/evilcharts/ui/layerchart-chart';
</script>
<script lang="ts">
	const chartConfig = {
		revenue: {
			label: 'Revenue',
			colors: { light: ['#3b82f6'], dark: ['#6A5ACD'] }
		},
		profit: {
			label: 'Profit',
			colors: { light: ['#10b981'], dark: ['#34d399'] }
		}
	} satisfies ChartConfig;
</script>

<EvilComposedChart xDataKey="month" {data} config={chartConfig}>
	<EvilComposedChart.Grid />
	<EvilComposedChart.XAxis dataKey="month" />
	<EvilComposedChart.YAxis />
	<EvilComposedChart.Legend isClickable />
	<EvilComposedChart.Tooltip />
	<EvilComposedChart.Bar dataKey="revenue" variant="gradient" isClickable />
	<EvilComposedChart.Line dataKey="profit" strokeVariant="dashed" isClickable>
		<EvilComposedChart.Dot variant="default" />
		<EvilComposedChart.ActiveDot variant="colored-border" />
	</EvilComposedChart.Line>
</EvilComposedChart>

Interactive Selection

Add isClickable to any <Bar>, <Line>, or <Legend> to make those series selectable. Handle selection with the onSelectionChange callback on <EvilComposedChart>:

<EvilComposedChart
	{data}
	config={chartConfig}
	onSelectionChange={(selectedDataKey) => {
		if (selectedDataKey) {
			console.log('Selected:', selectedDataKey);
		} else {
			console.log('Deselected');
		}
	}}
>
	<EvilComposedChart.XAxis dataKey="month" />
	<EvilComposedChart.Legend isClickable />
	<EvilComposedChart.Tooltip />
	<EvilComposedChart.Bar dataKey="revenue" isClickable />
	<EvilComposedChart.Line dataKey="profit" isClickable />
</EvilComposedChart>

Loading State

Examples

Customize each <Bar> with a variant, and each <Line> with a strokeVariant, curveType, and more.

Gradient Colors

Bar Variants

Line Stroke Variants

Curve Types

Line Dots

Hover Highlight

Glowing Effects

Dither rendering

Set renderStyle="dither" on the existing chart root to share one ordered-dither canvas across its bars and lines. SVG marks continue to own hover, selection, tooltips, dots, loading, and brush interaction; each <Bar /> or <Line /> can override ditherVariant.

The renderer is independently implemented for EvilCharts SV and inspired by Dither Kit by Boring Software.

API Reference

The props below are grouped by the component they belong to.

EvilComposedChart

The root container. It owns the data, shared selection state, loading skeleton, and optional brush; everything visual is composed as its children.

PropTypeDefaultDescription
data*TData[]

The chart data — an array of objects, one per data point (TData extends Record<string, unknown>).

config*Record<string, ChartConfig[string]>

Defines every bar and line series. Each key matches a data key in your data, with a corresponding color or color array.

children*Snippet

The composed chart parts — <Grid />, <XAxis />, <YAxis />, <Legend />, <Tooltip />, and one or more <Bar /> and <Line />.

accessibilityChartAccessibility

Names and optionally describes the chart wrapper. It remains a group, so interactive legends and marks stay available to assistive technology.

classNamestring

Extra CSS classes for the chart container.

curveType"basis" | "bumpX" | "bumpY" | "bump" | "linear" | "natural" | "monotoneX" | "monotoneY" | "monotone" | "step" | …"linear"

Default curve interpolation for every <Line />; each can override it locally.

animationType none| left-to-right| right-to-left| center-out| edges-in"left-to-right"

Default intro for every <Bar /> and <Line /> — lines wipe in along this direction, bars grow from their baseline staggered in this order. "none" disables it; OS reduce-motion falls back to "none" automatically.

barGapnumber

Gap between bars in the same category.

barCategoryGapnumber

Gap between bar categories.

defaultSelectedDataKeystring | nullnull

The data key selected by default.

onSelectionChange(selectedDataKey: string | null) => void

Fires when a series is selected or deselected by clicking a clickable <Bar />, <Line />, or <Legend /> entry. Receives the selected data key, or null when deselected.

isLoadingbooleanfalse

Shows a skeleton with a shimmer effect while data is being fetched.

loadingBarsnumber12

Number of bars in the loading skeleton.

xDataKeykeyof TData & string

The x-axis data key. Only needed by the brush footer — the axis reads its own key from <XAxis dataKey="…" />.

renderStyle svg| dither"svg"Selects the SVG or ordered-dither renderer.
ditherVariant gradient| dotted| hatched| solid"gradient"Default texture for dithered series.
ditherCellSizenumber2Dither cell size in CSS pixels.
bloom off| low| high| aura"off"Optional bounded glow around dither pixels.
chartPropsComponentProps<typeof ComposedChart>

Extra props forwarded to the underlying LayerChart Chart. See the LayerChart Chart documentation .

Bar

A single bar series. Each <Bar /> generates its own gradient/pattern definitions, so a chart can hold any number of bars — each with its own variant, glow, and clickability.

PropTypeDefaultDescription
dataKey*string

The series key. Must exist on both the data rows and the chart config.

variant default| hatched| duotone| duotone-reverse| gradient| stripped"default"

The bar fill’s visual style. Applies to this bar only.

radiusnumber4

The bar’s corner radius, in pixels.

animationType none| left-to-right| right-to-left| center-out| edges-in

The grow-in order for this bar series. Falls back to the chart’s animationType when omitted.

glowbooleanfalse

Applies a soft outer neon glow to this bar.

isClickablebooleanfalse

Makes this bar selectable on click. When any series is selected, unselected series become semi-transparent.

enableHoverHighlightbooleanfalse

When set, hovering a column dims the other bars, making it easier to focus on specific data points.

barPropsComponentProps<typeof Bar>

Escape hatch for raw props forwarded to the underlying LayerChart Bar.

Line

A single line series. Each <Line /> generates its own color gradient and glow filter, so a chart can hold any number of lines — each with its own stroke, curve, glow, and clickability.

PropTypeDefaultDescription
dataKey*string

The series key. Must exist on both the data rows and the chart config.

strokeVariant solid| dashed| animated-dashed"solid"

The stroke style for this line.

curveType"basis" | "bump" | "linear" | "natural" | "monotoneX" | "monotoneY" | "monotone" | "step" | "stepBefore" | "stepAfter" | …

The curve interpolation for this line. Falls back to the chart’s curveType when omitted.

animationType none| left-to-right| right-to-left| center-out| edges-in

The intro reveal direction for this line. Falls back to the chart’s animationType when omitted.

connectNullsbooleanfalse

Whether to connect line segments across null or missing values.

glowbooleanfalse

Applies a soft outer neon glow to this line.

isClickablebooleanfalse

Makes this line selectable on click. When any series is selected, unselected series become semi-transparent.

childrenSnippet

Optional <Dot /> and <ActiveDot /> that add point markers to this line.

linePropsComponentProps<typeof Line>

Escape hatch for raw props forwarded to the underlying LayerChart Line.

Dot and ActiveDot

Point markers composed inside a <Line />. <Dot /> is the resting marker; <ActiveDot /> is the hovered marker. They render nothing on their own — the parent <Line /> reads their variant.

PropTypeDefaultDescription
variant default| border| colored-border

The visual style of the point marker.

XAxis and YAxis

The category and value axes. Both ship with the chart’s flat default styling and forward every LayerChart axis prop — dataKey, tickFormatter, tickMargin, etc. pass straight through. They hide automatically while the chart is loading.

PropTypeDefaultDescription
dataKeystring

The data key for the axis values.

…axisProps

Every other LayerChart axis prop is forwarded as-is. See the LayerChart Axis documentation .

Grid

The background grid lines. Defaults to horizontal-only dashed lines and forwards every LayerChart CartesianGrid prop.

PropTypeDefaultDescription
…gridProps

Every LayerChart grid prop is forwarded as-is. See the LayerChart Grid documentation .

Tooltip

The hover tooltip. It reads the chart’s selection state so its content dims unselected series.

PropTypeDefaultDescription
variant default| frosted-glass"default"

The visual style of the tooltip surface.

roundness sm| md| lg| xl"lg"

Controls the border-radius of the tooltip.

defaultIndexnumber

When set, the tooltip shows by default at this data point index.

cursorbooleantrue

Whether the vertical cursor line follows the pointer on hover.

Legend

The series legend. When isClickable is set, each entry toggles selection of its series.

PropTypeDefaultDescription
variant square| circle| circle-outline| rounded-square| rounded-square-outline| vertical-bar| horizontal-bar

The visual style of the legend indicators.

align left| center| right"right"

Horizontal placement of the legend.

verticalAlign top| middle| bottom"top"

Vertical placement of the legend.

isClickablebooleanfalse

Lets each legend entry toggle selection of its series.

Brush

An optional zoom brush below the chart. Include <EvilComposedChart.Brush /> to render it; dragging the range filters the main chart.

PropTypeDefaultDescription
heightnumber

Height of the brush preview strip in pixels.

formatLabel(value: unknown, index: number) => string

Formats the range-handle labels below the brush.

onChange(range: { startIndex: number; endIndex: number }) => void

Fires when the brush selection range changes.