Chart New

A chart to visualize data as lines, areas, bars or a donut.

Usage

The Chart component is built on top of TanStack Charts and renders an SVG on the server.

TanStack Charts is an optional peer dependency, install it first:

pnpm add @tanstack/charts

Data

Use the data prop to pass an array of objects, the index prop to set the key used for the x axis and the categories prop to set the series, each with the key of its values and an optional label and color.

<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
You can also pass categories as strings, like ['desktop', 'mobile'], when they read well as names.
Use the aria-label prop to name the chart for assistive technologies.

Type

Use the type prop to change the type of chart. Defaults to line.

With donut, each row of data is a slice. The index sets its label and the first key of categories its value.
<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    type="donut"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    type="donut"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Stacked

Use the stacked prop to stack the series on top of each other.

This prop only works when type is area or bar.
<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    type="bar"
    stacked
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    type="bar"
    stacked
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Curve

Use the curve prop to change the shape of the line between values. Defaults to linear.

This prop only works when type is line or area.
<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    type="line"
    curve="monotone"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    type="line"
    curve="monotone"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Colors

Use the colors prop to set the color of each series with theme colors or any CSS color.

The colors follow the categories order, or the data order with donut. A color set on a category takes precedence. When there are more series than colors, they repeat as lighter tints.
<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :colors="['success', '#8b5cf6']"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :colors="['success', '#8b5cf6']"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
The colors default to the --ui-chart-* CSS variables, which you can customize in your main.css file.

Points

Use the points prop to draw a dot at each value.

This prop only works when type is line.
<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    points
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    points
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Grid

Use the grid prop to toggle the horizontal grid lines. Defaults to true.

<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Axis

Use the x-axis and y-axis props to toggle each axis. Both default to true.

<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Axis labels

Use the x-label and y-label props to display a title along each axis.

<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    x-label="Month"
    y-label="Visitors"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    x-label="Month"
    y-label="Visitors"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Legend

Use the legend prop to toggle the legend.

The legend is displayed by default when there is more than one category, or more than one slice with donut.
<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Tooltip

Use the tooltip prop to customize or hide the Tooltip displayed on the focused values. Defaults to true.

You can also use the #tooltip slot to replace its content.
<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Thickness

Use the thickness prop to set the width of the ring in pixels. Defaults to 24.

This prop only works when type is donut.
<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    type="donut"
    :thickness="12"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    type="donut"
    :thickness="12"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Size

Use the height prop to set the height of the chart in pixels. Defaults to 300.

The chart follows the width of its container. Use the aspect-ratio prop to derive the height from the width, or the width prop to set a fixed width.
With a fixed height, the chart fades in once its container is measured. With aspect-ratio, the chart rendered on the server is displayed right away.
<script setup lang="ts">
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :height="200"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'pohon-ui'

const data = ref<ChartData[]>([
  {
    month: 'January',
    desktop: 186,
    mobile: 80
  },
  {
    month: 'February',
    desktop: 305,
    mobile: 200
  },
  {
    month: 'March',
    desktop: 237,
    mobile: 120
  },
  {
    month: 'April',
    desktop: 73,
    mobile: 190
  },
  {
    month: 'May',
    desktop: 209,
    mobile: 130
  },
  {
    month: 'June',
    desktop: 214,
    mobile: 140
  }
])
</script>

<template>
  <PChart
    :height="200"
    :data="data"
    index="month"
    :categories="[
      {
        key: 'desktop',
        label: 'Desktop'
      },
      {
        key: 'mobile',
        label: 'Mobile'
      }
    ]"
  />
</template>

Examples

With formatted values

Use the format prop to format the values on the y axis and in the tooltip.

<script setup lang="ts">
const data = [
  { month: 'January', revenue: 18600 },
  { month: 'February', revenue: 30500 },
  { month: 'March', revenue: 23700 },
  { month: 'April', revenue: 27300 },
  { month: 'May', revenue: 20900 },
  { month: 'June', revenue: 31400 },
];

const currency = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', notation: 'compact' });
</script>

<template>
  <PChart
    type="bar"
    :data="data"
    index="month"
    :categories="[{ key: 'revenue', label: 'Revenue' }]"
    :format="(value) => currency.format(value)"
    aria-label="Monthly revenue"
  />
</template>

With a chart definition

Use the definition prop to pass a complete TanStack Charts definition when the other props are not enough.

A definition from the TanStack Charts examples renders as is, with the tooltip and the responsive sizing applied.
<script setup lang="ts">
import { defineChart, lineY, ruleY } from '@tanstack/charts';
import { scaleLinear } from '@tanstack/charts/scales/linear';
import { scalePoint } from '@tanstack/charts/scales/point';

const data = [
  { month: 'January', revenue: 186 },
  { month: 'February', revenue: 305 },
  { month: 'March', revenue: 237 },
  { month: 'April', revenue: 273 },
  { month: 'May', revenue: 209 },
  { month: 'June', revenue: 314 },
];

const definition = defineChart({
  marks: [
    ruleY([250], { stroke: 'var(--ui-color-error)', strokeDasharray: '4 4' }),
    lineY(data, { x: 'month', y: 'revenue', stroke: 'var(--ui-color-primary)', strokeWidth: 2, points: true }),
  ],
  scales: {
    x: { scale: () => scalePoint<string>().padding(0.2) },
    y: { scale: scaleLinear, nice: true, grid: true, axis: { label: 'Revenue' } },
  },
});
</script>

<template>
  <PChart
    :definition="definition"
    aria-label="Revenue against target"
  />
</template>
Series without an explicit color use the --ui-chart-* CSS variables. Colors set in the definition are kept.
When the definition brings its own tooltip, it is displayed in place of the tooltip prop.
Examples importing d3-* packages need them installed in your project.

With center slot

Use the #center slot to display content in the middle of a donut chart.

835Visitors
<script setup lang="ts">
const data = [
  { browser: 'Chrome', visitors: 275 },
  { browser: 'Safari', visitors: 200 },
  { browser: 'Firefox', visitors: 187 },
  { browser: 'Edge', visitors: 173 },
];
</script>

<template>
  <PChart
    type="donut"
    :data="data"
    index="browser"
    :categories="['visitors']"
    legend
    aria-label="Visitors by browser"
  >
    <template #center>
      <span class="text-2xl color-text-highlighted font-semibold">835</span>
      <span class="text-xs color-text-muted">Visitors</span>
    </template>
  </PChart>
</template>

With tooltip slot

Use the #tooltip slot to replace the tooltip content. It receives the title, the rows with their label, value and color, and the focused points.

<script setup lang="ts">
const data = [
  { month: 'January', revenue: 18600, expenses: 12400 },
  { month: 'February', revenue: 30500, expenses: 21800 },
  { month: 'March', revenue: 23700, expenses: 25100 },
  { month: 'April', revenue: 27300, expenses: 19600 },
  { month: 'May', revenue: 20900, expenses: 22300 },
  { month: 'June', revenue: 31400, expenses: 20700 },
];

const currency = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 });

function profit(month?: string) {
  const row = data.find((row) => row.month === month);

  return row ? row.revenue - row.expenses : 0;
}
</script>

<template>
  <PChart
    type="bar"
    :data="data"
    index="month"
    :categories="[{ key: 'revenue', label: 'Revenue', color: 'success' }, { key: 'expenses', label: 'Expenses', color: 'error' }]"
    :format="(value) => currency.format(value)"
    aria-label="Revenue and expenses"
  >
    <template #tooltip="{ title, rows }">
      <p class="color-text-highlighted font-medium">
        {{ title }}
      </p>

      <div
        v-for="row in rows"
        :key="row.label"
        class="flex gap-2 items-center"
      >
        <span
          class="rounded-full size-2"
          :style="{ backgroundColor: row.color }"
        />
        <span class="color-text-muted">{{ row.label }}</span>
        <span class="ms-auto ps-4 tabular-nums">{{ row.value }}</span>
      </div>

      <PSeparator class="my-1" />

      <div class="flex gap-2 items-center">
        <span class="color-text-muted">Profit</span>
        <PBadge
          :color="profit(title) >= 0 ? 'success' : 'error'"
          :label="currency.format(profit(title))"
          variant="subtle"
          size="sm"
          class="ms-auto tabular-nums"
        />
      </div>
    </template>
  </PChart>
</template>

API

Props

Prop Default Type

Slots

Slot Type

Emits

Event Type

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    chart: {
      slots: {
        root: [
          'relative w-full text-xs color-text-muted [&_[data-akar-popper-content-wrapper]]:pointer-events-none',
          '[--ts-chart-tooltip-background:var(--ui-color-bg)] [--ts-chart-tooltip-color:var(--ui-color-text-highlighted)] [--ts-chart-tooltip-border:1px_solid_var(--ui-color-border)] [--ts-chart-tooltip-border-radius:var(--radius-sm)] [--ts-chart-tooltip-shadow:var(--shadow-sm)] [--ts-chart-tooltip-padding:calc(var(--spacing)*1.5)_calc(var(--spacing)*2.5)] [--ts-chart-tooltip-font:inherit]'
        ],
        base: 'opacity-0 in-data-[measured]:opacity-100 transition-opacity duration-150 [&_.ts-chart]:rounded-md [&_.ts-chart]:outline-0 [&_.ts-chart]:outline-primary/25 [&_.ts-chart:focus-visible]:outline-3 [&_.ts-chart:focus-visible]:ring [&_.ts-chart:focus-visible]:ring-primary',
        tooltip: 'flex-col items-stretch gap-1 h-auto min-w-32 py-1.5 pointer-events-none',
        tooltipTitle: 'font-medium color-text-highlighted',
        tooltipRow: 'flex items-center gap-1.5 color-text-muted data-[active=true]:color-text-highlighted',
        tooltipIndicator: 'size-2 shrink-0 rounded-full',
        tooltipLabel: 'truncate',
        tooltipValue: 'ms-auto ps-4 font-medium color-text-highlighted tabular-nums',
        center: 'absolute inset-0 flex flex-col items-center justify-center pointer-events-none opacity-0 in-data-[measured]:opacity-100 transition-opacity duration-150'
      },
      variants: {
        type: {
          line: '',
          area: '',
          bar: '',
          donut: ''
        }
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from 'pohon-ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        chart: {
          slots: {
            root: [
              'relative w-full text-xs color-text-muted [&_[data-akar-popper-content-wrapper]]:pointer-events-none',
              '[--ts-chart-tooltip-background:var(--ui-color-bg)] [--ts-chart-tooltip-color:var(--ui-color-text-highlighted)] [--ts-chart-tooltip-border:1px_solid_var(--ui-color-border)] [--ts-chart-tooltip-border-radius:var(--radius-sm)] [--ts-chart-tooltip-shadow:var(--shadow-sm)] [--ts-chart-tooltip-padding:calc(var(--spacing)*1.5)_calc(var(--spacing)*2.5)] [--ts-chart-tooltip-font:inherit]'
            ],
            base: 'opacity-0 in-data-[measured]:opacity-100 transition-opacity duration-150 [&_.ts-chart]:rounded-md [&_.ts-chart]:outline-0 [&_.ts-chart]:outline-primary/25 [&_.ts-chart:focus-visible]:outline-3 [&_.ts-chart:focus-visible]:ring [&_.ts-chart:focus-visible]:ring-primary',
            tooltip: 'flex-col items-stretch gap-1 h-auto min-w-32 py-1.5 pointer-events-none',
            tooltipTitle: 'font-medium color-text-highlighted',
            tooltipRow: 'flex items-center gap-1.5 color-text-muted data-[active=true]:color-text-highlighted',
            tooltipIndicator: 'size-2 shrink-0 rounded-full',
            tooltipLabel: 'truncate',
            tooltipValue: 'ms-auto ps-4 font-medium color-text-highlighted tabular-nums',
            center: 'absolute inset-0 flex flex-col items-center justify-center pointer-events-none opacity-0 in-data-[measured]:opacity-100 transition-opacity duration-150'
          },
          variants: {
            type: {
              line: '',
              area: '',
              bar: '',
              donut: ''
            }
          }
        }
      }
    })
  ]
})

Changelog

No recent changes