Tooltips

Chart tooltip examples: indicators, labels, formatters, icons and a total.

Each example is an iv-card with a bar chart and an iv-chart-tooltip. It opens on the second day (defaultIndex); hover to move it. Copy the code under it. See Chart for the tooltip API.

import { IV_CHART_IMPORTS } from '@inlaylab/ivorie/chart';

Default

Tooltip - DefaultDefault tooltip with ChartTooltipContent.MonTueWedThuFriSat
2024-07-16
Running
380
Swimming
420
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';

@Component({
  selector: 'demo-chart-tooltip-default',
  imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-card class="w-full max-w-md">
      <iv-card-header>
        <iv-card-title>Tooltip - Default</iv-card-title>
        <iv-card-description>Default tooltip with ChartTooltipContent.</iv-card-description>
      </iv-card-header>
      <iv-card-content>
        <iv-chart [config]="config">
          <svg ivBarChart [data]="data">
            <g
              ivXAxis
              dataKey="date"
              [tickLine]="false"
              [tickMargin]="10"
              [axisLine]="false"
              [tickFormatter]="weekday"
            />
            <g ivBar dataKey="running" stackId="a" [radius]="[0, 0, 4, 4]" />
            <g ivBar dataKey="swimming" stackId="a" [radius]="[4, 4, 0, 0]" />
          </svg>
          <iv-chart-tooltip [cursor]="false" [defaultIndex]="1" />
        </iv-chart>
      </iv-card-content>
    </iv-card>
  `,
})
export default class ChartTooltipDefault {
  protected readonly data = [
    { date: '2024-07-15', running: 450, swimming: 300 },
    { date: '2024-07-16', running: 380, swimming: 420 },
    { date: '2024-07-17', running: 520, swimming: 120 },
    { date: '2024-07-18', running: 140, swimming: 550 },
    { date: '2024-07-19', running: 600, swimming: 350 },
    { date: '2024-07-20', running: 480, swimming: 400 },
  ];

  protected readonly config: IvChartConfig = {
    running: { label: 'Running', color: 'var(--chart-1)' },
    swimming: { label: 'Swimming', color: 'var(--chart-2)' },
  };

  /** Dates are UTC days: format them in UTC, so server and browser agree. */
  protected readonly weekday = (value: string) =>
    new Date(value).toLocaleDateString('en-US', { weekday: 'short', timeZone: 'UTC' });
}

Line Indicator

Tooltip - Line IndicatorTooltip with line indicator.MonTueWedThuFriSat
2024-07-16
Running
380
Swimming
420
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';

@Component({
  selector: 'demo-chart-tooltip-indicator-line',
  imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-card class="w-full max-w-md">
      <iv-card-header>
        <iv-card-title>Tooltip - Line Indicator</iv-card-title>
        <iv-card-description>Tooltip with line indicator.</iv-card-description>
      </iv-card-header>
      <iv-card-content>
        <iv-chart [config]="config">
          <svg ivBarChart [data]="data">
            <g
              ivXAxis
              dataKey="date"
              [tickLine]="false"
              [tickMargin]="10"
              [axisLine]="false"
              [tickFormatter]="weekday"
            />
            <g ivBar dataKey="running" stackId="a" [radius]="[0, 0, 4, 4]" />
            <g ivBar dataKey="swimming" stackId="a" [radius]="[4, 4, 0, 0]" />
          </svg>
          <iv-chart-tooltip indicator="line" [cursor]="false" [defaultIndex]="1" />
        </iv-chart>
      </iv-card-content>
    </iv-card>
  `,
})
export default class ChartTooltipIndicatorLine {
  protected readonly data = [
    { date: '2024-07-15', running: 450, swimming: 300 },
    { date: '2024-07-16', running: 380, swimming: 420 },
    { date: '2024-07-17', running: 520, swimming: 120 },
    { date: '2024-07-18', running: 140, swimming: 550 },
    { date: '2024-07-19', running: 600, swimming: 350 },
    { date: '2024-07-20', running: 480, swimming: 400 },
  ];

  protected readonly config: IvChartConfig = {
    running: { label: 'Running', color: 'var(--chart-1)' },
    swimming: { label: 'Swimming', color: 'var(--chart-2)' },
  };

  /** Dates are UTC days: format them in UTC, so server and browser agree. */
  protected readonly weekday = (value: string) =>
    new Date(value).toLocaleDateString('en-US', { weekday: 'short', timeZone: 'UTC' });
}

No Indicator

Tooltip - No IndicatorTooltip with no indicator.MonTueWedThuFriSat
2024-07-16
Running
380
Swimming
420
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';

@Component({
  selector: 'demo-chart-tooltip-indicator-none',
  imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-card class="w-full max-w-md">
      <iv-card-header>
        <iv-card-title>Tooltip - No Indicator</iv-card-title>
        <iv-card-description>Tooltip with no indicator.</iv-card-description>
      </iv-card-header>
      <iv-card-content>
        <iv-chart [config]="config">
          <svg ivBarChart [data]="data">
            <g
              ivXAxis
              dataKey="date"
              [tickLine]="false"
              [tickMargin]="10"
              [axisLine]="false"
              [tickFormatter]="weekday"
            />
            <g ivBar dataKey="running" stackId="a" [radius]="[0, 0, 4, 4]" />
            <g ivBar dataKey="swimming" stackId="a" [radius]="[4, 4, 0, 0]" />
          </svg>
          <iv-chart-tooltip hideIndicator [cursor]="false" [defaultIndex]="1" />
        </iv-chart>
      </iv-card-content>
    </iv-card>
  `,
})
export default class ChartTooltipIndicatorNone {
  protected readonly data = [
    { date: '2024-07-15', running: 450, swimming: 300 },
    { date: '2024-07-16', running: 380, swimming: 420 },
    { date: '2024-07-17', running: 520, swimming: 120 },
    { date: '2024-07-18', running: 140, swimming: 550 },
    { date: '2024-07-19', running: 600, swimming: 350 },
    { date: '2024-07-20', running: 480, swimming: 400 },
  ];

  protected readonly config: IvChartConfig = {
    running: { label: 'Running', color: 'var(--chart-1)' },
    swimming: { label: 'Swimming', color: 'var(--chart-2)' },
  };

  /** Dates are UTC days: format them in UTC, so server and browser agree. */
  protected readonly weekday = (value: string) =>
    new Date(value).toLocaleDateString('en-US', { weekday: 'short', timeZone: 'UTC' });
}

Custom label

Tooltip - Custom labelTooltip with custom label from chartConfig.MonTueWedThuFriSat
Activities
Running
380
Swimming
420
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';

@Component({
  selector: 'demo-chart-tooltip-label-custom',
  imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-card class="w-full max-w-md">
      <iv-card-header>
        <iv-card-title>Tooltip - Custom label</iv-card-title>
        <iv-card-description>Tooltip with custom label from chartConfig.</iv-card-description>
      </iv-card-header>
      <iv-card-content>
        <iv-chart [config]="config">
          <svg ivBarChart [data]="data">
            <g
              ivXAxis
              dataKey="date"
              [tickLine]="false"
              [tickMargin]="10"
              [axisLine]="false"
              [tickFormatter]="weekday"
            />
            <g ivBar dataKey="running" stackId="a" [radius]="[0, 0, 4, 4]" />
            <g ivBar dataKey="swimming" stackId="a" [radius]="[4, 4, 0, 0]" />
          </svg>
          <iv-chart-tooltip
            labelKey="activities"
            indicator="line"
            [cursor]="false"
            [defaultIndex]="1"
          />
        </iv-chart>
      </iv-card-content>
    </iv-card>
  `,
})
export default class ChartTooltipLabelCustom {
  protected readonly data = [
    { date: '2024-07-15', running: 450, swimming: 300 },
    { date: '2024-07-16', running: 380, swimming: 420 },
    { date: '2024-07-17', running: 520, swimming: 120 },
    { date: '2024-07-18', running: 140, swimming: 550 },
    { date: '2024-07-19', running: 600, swimming: 350 },
    { date: '2024-07-20', running: 480, swimming: 400 },
  ];

  protected readonly config: IvChartConfig = {
    activities: { label: 'Activities' },
    running: { label: 'Running', color: 'var(--chart-1)' },
    swimming: { label: 'Swimming', color: 'var(--chart-2)' },
  };

  /** Dates are UTC days: format them in UTC, so server and browser agree. */
  protected readonly weekday = (value: string) =>
    new Date(value).toLocaleDateString('en-US', { weekday: 'short', timeZone: 'UTC' });
}

Label Formatter

Tooltip - Label FormatterTooltip with label formatter.MonTueWedThuFriSat
July 16, 2024
Running
380
Swimming
420
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';

@Component({
  selector: 'demo-chart-tooltip-label-formatter',
  imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-card class="w-full max-w-md">
      <iv-card-header>
        <iv-card-title>Tooltip - Label Formatter</iv-card-title>
        <iv-card-description>Tooltip with label formatter.</iv-card-description>
      </iv-card-header>
      <iv-card-content>
        <iv-chart [config]="config">
          <svg ivBarChart [data]="data">
            <g
              ivXAxis
              dataKey="date"
              [tickLine]="false"
              [tickMargin]="10"
              [axisLine]="false"
              [tickFormatter]="weekday"
            />
            <g ivBar dataKey="running" stackId="a" [radius]="[0, 0, 4, 4]" />
            <g ivBar dataKey="swimming" stackId="a" [radius]="[4, 4, 0, 0]" />
          </svg>
          <iv-chart-tooltip [labelFormatter]="longDate" [cursor]="false" [defaultIndex]="1" />
        </iv-chart>
      </iv-card-content>
    </iv-card>
  `,
})
export default class ChartTooltipLabelFormatter {
  protected readonly data = [
    { date: '2024-07-15', running: 450, swimming: 300 },
    { date: '2024-07-16', running: 380, swimming: 420 },
    { date: '2024-07-17', running: 520, swimming: 120 },
    { date: '2024-07-18', running: 140, swimming: 550 },
    { date: '2024-07-19', running: 600, swimming: 350 },
    { date: '2024-07-20', running: 480, swimming: 400 },
  ];

  protected readonly config: IvChartConfig = {
    running: { label: 'Running', color: 'var(--chart-1)' },
    swimming: { label: 'Swimming', color: 'var(--chart-2)' },
  };

  /** Dates are UTC days: format them in UTC, so server and browser agree. */
  protected readonly weekday = (value: string) =>
    new Date(value).toLocaleDateString('en-US', { weekday: 'short', timeZone: 'UTC' });

  protected readonly longDate = (value: string) =>
    new Date(value).toLocaleDateString('en-US', {
      day: 'numeric',
      month: 'long',
      year: 'numeric',
      timeZone: 'UTC',
    });
}

No Label

Tooltip - No LabelTooltip with no label.MonTueWedThuFriSat
Running
380
Swimming
420
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';

@Component({
  selector: 'demo-chart-tooltip-label-none',
  imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-card class="w-full max-w-md">
      <iv-card-header>
        <iv-card-title>Tooltip - No Label</iv-card-title>
        <iv-card-description>Tooltip with no label.</iv-card-description>
      </iv-card-header>
      <iv-card-content>
        <iv-chart [config]="config">
          <svg ivBarChart [data]="data">
            <g
              ivXAxis
              dataKey="date"
              [tickLine]="false"
              [tickMargin]="10"
              [axisLine]="false"
              [tickFormatter]="weekday"
            />
            <g ivBar dataKey="running" stackId="a" [radius]="[0, 0, 4, 4]" />
            <g ivBar dataKey="swimming" stackId="a" [radius]="[4, 4, 0, 0]" />
          </svg>
          <iv-chart-tooltip hideIndicator hideLabel [cursor]="false" [defaultIndex]="1" />
        </iv-chart>
      </iv-card-content>
    </iv-card>
  `,
})
export default class ChartTooltipLabelNone {
  protected readonly data = [
    { date: '2024-07-15', running: 450, swimming: 300 },
    { date: '2024-07-16', running: 380, swimming: 420 },
    { date: '2024-07-17', running: 520, swimming: 120 },
    { date: '2024-07-18', running: 140, swimming: 550 },
    { date: '2024-07-19', running: 600, swimming: 350 },
    { date: '2024-07-20', running: 480, swimming: 400 },
  ];

  protected readonly config: IvChartConfig = {
    running: { label: 'Running', color: 'var(--chart-1)' },
    swimming: { label: 'Swimming', color: 'var(--chart-2)' },
  };

  /** Dates are UTC days: format them in UTC, so server and browser agree. */
  protected readonly weekday = (value: string) =>
    new Date(value).toLocaleDateString('en-US', { weekday: 'short', timeZone: 'UTC' });
}

Formatter

Tooltip - FormatterTooltip with custom formatter .MonTueWedThuFriSat
Running
380 kcal
Swimming
420 kcal
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';

@Component({
  selector: 'demo-chart-tooltip-formatter',
  imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-card class="w-full max-w-md">
      <iv-card-header>
        <iv-card-title>Tooltip - Formatter</iv-card-title>
        <iv-card-description>Tooltip with custom formatter .</iv-card-description>
      </iv-card-header>
      <iv-card-content>
        <iv-chart [config]="config">
          <svg ivBarChart [data]="data">
            <g
              ivXAxis
              dataKey="date"
              [tickLine]="false"
              [tickMargin]="10"
              [axisLine]="false"
              [tickFormatter]="weekday"
            />
            <g ivBar dataKey="running" stackId="a" [radius]="[0, 0, 4, 4]" />
            <g ivBar dataKey="swimming" stackId="a" [radius]="[4, 4, 0, 0]" />
          </svg>
          <iv-chart-tooltip hideLabel [cursor]="false" [defaultIndex]="1">
            <ng-template ivChartTooltipItem let-item let-label="label">
              <div class="flex min-w-[130px] items-center text-xs text-muted-foreground">
                {{ label }}
                <div
                  class="ml-auto flex items-baseline gap-0.5 font-mono font-medium text-foreground tabular-nums"
                >
                  {{ item.value }}
                  <span class="font-normal text-muted-foreground">kcal</span>
                </div>
              </div>
            </ng-template>
          </iv-chart-tooltip>
        </iv-chart>
      </iv-card-content>
    </iv-card>
  `,
})
export default class ChartTooltipFormatter {
  protected readonly data = [
    { date: '2024-07-15', running: 450, swimming: 300 },
    { date: '2024-07-16', running: 380, swimming: 420 },
    { date: '2024-07-17', running: 520, swimming: 120 },
    { date: '2024-07-18', running: 140, swimming: 550 },
    { date: '2024-07-19', running: 600, swimming: 350 },
    { date: '2024-07-20', running: 480, swimming: 400 },
  ];

  protected readonly config: IvChartConfig = {
    running: { label: 'Running', color: 'var(--chart-1)' },
    swimming: { label: 'Swimming', color: 'var(--chart-2)' },
  };

  /** Dates are UTC days: format them in UTC, so server and browser agree. */
  protected readonly weekday = (value: string) =>
    new Date(value).toLocaleDateString('en-US', { weekday: 'short', timeZone: 'UTC' });
}

Icons

Tooltip - IconsTooltip with icons.MonTueWedThuFriSat
Running
380
Swimming
420
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { lucideFootprints, lucideWaves } from '@ng-icons/lucide';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';

/** Config icons: any component. These wrap an ng-icon. */
@Component({
  selector: 'demo-footprints-icon',
  imports: [NgIcon],
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'flex text-muted-foreground' },
  template: `<ng-icon [svg]="icon" />`,
})
class FootprintsIcon {
  protected readonly icon = lucideFootprints;
}

@Component({
  selector: 'demo-waves-icon',
  imports: [NgIcon],
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'flex text-muted-foreground' },
  template: `<ng-icon [svg]="icon" />`,
})
class WavesIcon {
  protected readonly icon = lucideWaves;
}

@Component({
  selector: 'demo-chart-tooltip-icons',
  imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-card class="w-full max-w-md">
      <iv-card-header>
        <iv-card-title>Tooltip - Icons</iv-card-title>
        <iv-card-description>Tooltip with icons.</iv-card-description>
      </iv-card-header>
      <iv-card-content>
        <iv-chart [config]="config">
          <svg ivBarChart [data]="data">
            <g
              ivXAxis
              dataKey="date"
              [tickLine]="false"
              [tickMargin]="10"
              [axisLine]="false"
              [tickFormatter]="weekday"
            />
            <g ivBar dataKey="running" stackId="a" [radius]="[0, 0, 4, 4]" />
            <g ivBar dataKey="swimming" stackId="a" [radius]="[4, 4, 0, 0]" />
          </svg>
          <iv-chart-tooltip hideLabel [cursor]="false" [defaultIndex]="1" />
        </iv-chart>
      </iv-card-content>
    </iv-card>
  `,
})
export default class ChartTooltipIcons {
  protected readonly data = [
    { date: '2024-07-15', running: 450, swimming: 300 },
    { date: '2024-07-16', running: 380, swimming: 420 },
    { date: '2024-07-17', running: 520, swimming: 120 },
    { date: '2024-07-18', running: 140, swimming: 550 },
    { date: '2024-07-19', running: 600, swimming: 350 },
    { date: '2024-07-20', running: 480, swimming: 400 },
  ];

  protected readonly config: IvChartConfig = {
    running: { label: 'Running', color: 'var(--chart-1)', icon: FootprintsIcon },
    swimming: { label: 'Swimming', color: 'var(--chart-2)', icon: WavesIcon },
  };

  /** Dates are UTC days: format them in UTC, so server and browser agree. */
  protected readonly weekday = (value: string) =>
    new Date(value).toLocaleDateString('en-US', { weekday: 'short', timeZone: 'UTC' });
}

Advanced

Tooltip - AdvancedTooltip with custom formatter and total.MonTueWedThuFriSat
Running
380 kcal
Swimming
420 kcal
Total
800 kcal
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig, IvChartDatum } from '@inlaylab/ivorie/chart';

@Component({
  selector: 'demo-chart-tooltip-advanced',
  imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-card class="w-full max-w-md">
      <iv-card-header>
        <iv-card-title>Tooltip - Advanced</iv-card-title>
        <iv-card-description>Tooltip with custom formatter and total.</iv-card-description>
      </iv-card-header>
      <iv-card-content>
        <iv-chart [config]="config">
          <svg ivBarChart [data]="data">
            <g
              ivXAxis
              dataKey="date"
              [tickLine]="false"
              [tickMargin]="10"
              [axisLine]="false"
              [tickFormatter]="weekday"
            />
            <g ivBar dataKey="running" stackId="a" [radius]="[0, 0, 4, 4]" />
            <g ivBar dataKey="swimming" stackId="a" [radius]="[4, 4, 0, 0]" />
          </svg>
          <iv-chart-tooltip hideLabel class="w-[180px]" [cursor]="false" [defaultIndex]="1">
            <ng-template
              ivChartTooltipItem
              let-item
              let-label="label"
              let-name="name"
              let-index="index"
            >
              <div
                class="h-2.5 w-2.5 shrink-0 rounded-[2px] bg-(--color-bg)"
                [style.--color-bg]="'var(--color-' + name + ')'"
              ></div>
              {{ label }}
              <div
                class="ml-auto flex items-baseline gap-0.5 font-mono font-medium text-foreground tabular-nums"
              >
                {{ item.value }}
                <span class="font-normal text-muted-foreground">kcal</span>
              </div>
              <!-- After the last item -->
              @if (index === 1) {
                <div
                  class="mt-1.5 flex basis-full items-center border-t pt-1.5 text-xs font-medium text-foreground"
                >
                  Total
                  <div
                    class="ml-auto flex items-baseline gap-0.5 font-mono font-medium text-foreground tabular-nums"
                  >
                    {{ total(item.row) }}
                    <span class="font-normal text-muted-foreground">kcal</span>
                  </div>
                </div>
              }
            </ng-template>
          </iv-chart-tooltip>
        </iv-chart>
      </iv-card-content>
    </iv-card>
  `,
})
export default class ChartTooltipAdvanced {
  protected readonly data = [
    { date: '2024-07-15', running: 450, swimming: 300 },
    { date: '2024-07-16', running: 380, swimming: 420 },
    { date: '2024-07-17', running: 520, swimming: 120 },
    { date: '2024-07-18', running: 140, swimming: 550 },
    { date: '2024-07-19', running: 600, swimming: 350 },
    { date: '2024-07-20', running: 480, swimming: 400 },
  ];

  protected readonly config: IvChartConfig = {
    running: { label: 'Running', color: 'var(--chart-1)' },
    swimming: { label: 'Swimming', color: 'var(--chart-2)' },
  };

  /** Dates are UTC days: format them in UTC, so server and browser agree. */
  protected readonly weekday = (value: string) =>
    new Date(value).toLocaleDateString('en-US', { weekday: 'short', timeZone: 'UTC' });

  protected readonly total = (row: IvChartDatum) =>
    Number(row['running']) + Number(row['swimming']);
}