Components

Custom overlays

Draw your own SVG inside a chart with the default slot and the chart composables

A chart renders its default slot inside its SVG. To draw your own marks, write a small component that reads the chart through a composable, and put it in the chart's default slot. The composables only work inside a chart, so call them in the child component, not in the component that renders the chart.

Plot area

usePlotArea() returns the box inside the axes as { x, y, width, height } in pixels.

PlotAreaTop.vue
<script setup>
import { usePlotArea } from 'vccs'

const plotArea = usePlotArea()
</script>

<template>
  <g>
    <line
      :x1="plotArea.x"
      :x2="plotArea.x + plotArea.width"
      :y1="plotArea.y"
      :y2="plotArea.y"
      stroke="#14b8a6"
      stroke-dasharray="4 4"
    />
    <text
      :x="plotArea.x + 4"
      :y="plotArea.y - 6"
      fill="#14b8a6"
      font-size="12"
    >
      Plot area top
    </text>
  </g>
</template>

Data values to pixels

useXAxisScale() and useYAxisScale() return functions that map a data value to a pixel position. Pass an axis id when the chart has more than one axis on that side.

DataMarker.vue
<script setup>
import { computed } from 'vue'
import { useXAxisScale, useYAxisScale } from 'vccs'

const props = defineProps({
  x: { type: String, required: true },
  y: { type: Number, required: true },
  label: { type: String, required: true },
})

const xScale = useXAxisScale()
const yScale = useYAxisScale()
const point = computed(() => {
  const cx = xScale.value?.(props.x)
  const cy = yScale.value?.(props.y)
  return cx == null || cy == null ? undefined : { cx, cy }
})
</script>

<template>
  <g v-if="point">
    <circle
      :cx="point.cx"
      :cy="point.cy"
      r="6"
      fill="none"
      stroke="#14b8a6"
      stroke-width="2"
    />
    <text
      :x="point.cx"
      :y="point.cy - 12"
      fill="#14b8a6"
      font-size="12"
      text-anchor="middle"
    >
      {{ label }}
    </text>
  </g>
</template>

For a line, area or dot at a data value, the built-in reference elements are often enough.

Composables

Composables lists every composable, what it returns and in which charts it works.

Customized (deprecated)

Customized is deprecated and is removed in 2.0. It still works in 1.0 and warns once in development. Move its slot content into a child component as shown above.

<!-- Before -->
<LineChart :data="data">
  <Customized>
    <template #default="{ offset }">
      <line :x1="offset.left" :y1="offset.top" … />
    </template>
  </Customized>
</LineChart>

<!-- After: PlotAreaTop calls usePlotArea() -->
<LineChart :data="data">
  <PlotAreaTop />
</LineChart>
Copyright © 2026