---
title: "RTL Layout"
framework: vue
version: "14.1.0"
---

# RTL Layout

AG Charts supports right-to-left (RTL) text direction for languages such as Arabic, Persian, and Hebrew.

> **Note**
>
> The RTL option handles text within the data elements and controls the visual direction of the chart.  
> To change the language of chart UI elements see [Localisation](https://www.ag-grid.com/charts/vue/localisation/).

## Enabling RTL

Set `enableRtl: true` to enable right-to-left layout for the chart.

```js
{
    enableRtl: true,
}
```

AG Charts can also detect RTL automatically from the `dir="rtl"` attribute set on the chart container or any of its ancestor elements. When the `dir` attribute is present, `enableRtl` does not need to be set explicitly.

## Example: RTL and Localisation

Use the language dropdown to switch between English (LTR), Arabic, Persian, and Hebrew.

#### RTL Locale Switcher

```ts
import { createApp, defineComponent, ref } from "vue";
import { AgCharts } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import {
  BarSeriesModule,
  CategoryAxisModule,
  ContextMenuModule,
  LegendModule,
  LocaleModule,
  ModuleRegistry,
  NumberAxisModule,
  ZoomModule,
} from "ag-charts-enterprise";
import {
  AG_CHARTS_LOCALE_AR_EG,
  AG_CHARTS_LOCALE_EN_US,
  AG_CHARTS_LOCALE_FA_IR,
  AG_CHARTS_LOCALE_HE_IL,
} from "ag-charts-locale";
import clone from "clone";

type Language = "en" | "ar" | "fa" | "he";

const LANGUAGES = {
  en: {
    localeText: AG_CHARTS_LOCALE_EN_US,
    enableRtl: false,
    title: "Quarterly Product Sales Performance Overview",
    subtitle:
      "Comparison of Sales and Revenue Across Categories for the Year 2024",
    footnote: "Source: Regional Sales Department — Internal Report",
    yAxisTitle: "Amount in US Dollars ($)",
    seriesNames: ["Total Sales Volume", "Gross Revenue"],
    zoomControls: "Zoom Controls",
    legendControls: "Legend Controls",
    data: [
      { month: "January", sales: 150, revenue: 200 },
      { month: "February", sales: 230, revenue: 310 },
      { month: "March", sales: 180, revenue: 250 },
      { month: "April", sales: 290, revenue: 380 },
      { month: "May", sales: 210, revenue: 290 },
      { month: "June", sales: 260, revenue: 350 },
    ],
  },
  ar: {
    localeText: AG_CHARTS_LOCALE_AR_EG,
    enableRtl: true,
    title: "نظرة عامة على أداء Sales مبيعات المنتجات الفصلية",
    subtitle: "مقارنة بيانات Revenue المبيعات والإيرادات عبر الفئات لعام 2024",
    footnote: "المصدر: قسم المبيعات الإقليمي — Sales Department تقرير داخلي",
    yAxisTitle: "المبلغ Amount بالدولار الأمريكي",
    seriesNames: ["مبيعات Sales", "إيرادات Revenue"],
    zoomControls: "عناصر التكبير",
    legendControls: "عناصر وسيلة الإيضاح",
    data: [
      { month: "يناير", sales: 150, revenue: 200 },
      { month: "فبراير", sales: 230, revenue: 310 },
      { month: "مارس", sales: 180, revenue: 250 },
      { month: "أبريل", sales: 290, revenue: 380 },
      { month: "مايو", sales: 210, revenue: 290 },
      { month: "يونيو", sales: 260, revenue: 350 },
    ],
  },
  fa: {
    localeText: AG_CHARTS_LOCALE_FA_IR,
    enableRtl: true,
    title: "نمای کلی عملکرد Sales فروش محصولات فصلی",
    subtitle:
      "مقایسه داده‌های Revenue فروش و درآمد در دسته‌بندی‌ها برای سال 2024",
    footnote: "منبع: بخش فروش منطقه‌ای — Sales Department گزارش داخلی",
    yAxisTitle: "مبلغ Amount به دلار آمریکا",
    seriesNames: ["فروش Sales", "درآمد Revenue"],
    zoomControls: "کنترل‌های بزرگ‌نمایی",
    legendControls: "کنترل‌های راهنما",
    data: [
      { month: "ژانوِیه", sales: 150, revenue: 200 },
      { month: "فوریه", sales: 230, revenue: 310 },
      { month: "مارس", sales: 180, revenue: 250 },
      { month: "آوریل", sales: 290, revenue: 380 },
      { month: "مه", sales: 210, revenue: 290 },
      { month: "ژوئن", sales: 260, revenue: 350 },
    ],
  },
  he: {
    localeText: AG_CHARTS_LOCALE_HE_IL,
    enableRtl: true,
    title: "סקירת ביצועי Sales מכירות מוצרים רבעונית",
    subtitle: "השוואת נתוני Revenue מכירות והכנסות בין קטגוריות לשנת 2024",
    footnote: "מקור: מחלקת מכירות אזורית — Sales Department דוח פנימי",
    yAxisTitle: "הסכום Amount בשקלים חדשים",
    seriesNames: ["מכירות Sales", "הכנסות Revenue"],
    zoomControls: "פקדי זום",
    legendControls: "פקדי מקרא",
    data: [
      { month: "ינואר", sales: 150, revenue: 200 },
      { month: "פברואר", sales: 230, revenue: 310 },
      { month: "מרץ", sales: 180, revenue: 250 },
      { month: "אפריל", sales: 290, revenue: 380 },
      { month: "מאי", sales: 210, revenue: 290 },
      { month: "יוני", sales: 260, revenue: 350 },
    ],
  },
};

ModuleRegistry.registerModules([
  BarSeriesModule,
  CategoryAxisModule,
  ContextMenuModule,
  LegendModule,
  LocaleModule,
  NumberAxisModule,
  ZoomModule,
]);

const ChartExample = defineComponent({
  template: `
    <div class="example-controls">
      <div class="controls-row">
        <label for="locale">Language</label>
        <select id="locale" v-on:change="updateLanguage($event.target.value)">
          <option value="en">English</option>
          <option value="ar">العربية (Arabic)</option>
          <option value="fa">فارسی (Persian)</option>
          <option value="he">עברית (Hebrew)</option>
        </select>
      </div>
    </div>
    <ag-charts
      :options="options"
    />
  `,
  components: {
    "ag-charts": AgCharts,
  },
  setup(props) {
    const options = ref<AgCartesianChartOptions>({
      enableRtl: false,
      locale: {
        localeText: AG_CHARTS_LOCALE_EN_US,
      },
      title: { text: LANGUAGES.en.title, wrapping: "never", maxWidth: 300 },
      subtitle: {
        text: LANGUAGES.en.subtitle,
        wrapping: "always",
        maxWidth: 300,
      },
      footnote: { text: LANGUAGES.en.footnote },
      data: LANGUAGES.en.data,
      series: [
        {
          type: "bar",
          xKey: "month",
          yKey: "sales",
          yName: LANGUAGES.en.seriesNames[0],
        },
        {
          type: "bar",
          xKey: "month",
          yKey: "revenue",
          yName: LANGUAGES.en.seriesNames[1],
        },
      ],
      axes: {
        x: { type: "category" },
        y: {
          type: "number",
          title: { text: LANGUAGES.en.yAxisTitle },
        },
      },
      zoom: { enabled: true },
      contextMenu: {
        items: [
          "download",
          "separator",
          {
            showOn: "series-area",
            label: LANGUAGES.en.zoomControls,
            items: ["zoom-to-cursor", "pan-to-cursor", "reset-zoom"],
          },
          {
            showOn: "legend-item",
            label: LANGUAGES.en.legendControls,
            items: ["toggle-series-visibility", "toggle-other-series"],
          },
        ],
      },
    });

    const updateLanguage = (lang) => {
      const optionsCopy = clone(options.value);

      const config = LANGUAGES[lang];
      optionsCopy.enableRtl = config.enableRtl;
      optionsCopy.locale = { localeText: config.localeText };
      optionsCopy.title = {
        text: config.title,
        wrapping: "never",
        maxWidth: 300,
      };
      optionsCopy.subtitle = {
        text: config.subtitle,
        wrapping: "always",
        maxWidth: 300,
      };
      optionsCopy.footnote = { text: config.footnote };
      optionsCopy.data = config.data;
      optionsCopy.series = [
        {
          type: "bar",
          xKey: "month",
          yKey: "sales",
          yName: config.seriesNames[0],
        },
        {
          type: "bar",
          xKey: "month",
          yKey: "revenue",
          yName: config.seriesNames[1],
        },
      ];
      optionsCopy.axes = {
        x: { type: "category" },
        y: {
          type: "number",
          title: { text: config.yAxisTitle },
        },
      };
      optionsCopy.contextMenu = {
        items: [
          "download",
          "separator",
          {
            showOn: "series-area",
            label: config.zoomControls,
            items: ["zoom-to-cursor", "pan-to-cursor", "reset-zoom"],
          },
          {
            showOn: "legend-item",
            label: config.legendControls,
            items: ["toggle-series-visibility", "toggle-other-series"],
          },
        ],
      };

      options.value = optionsCopy;
    };

    return {
      options,
      updateLanguage,
    };
  },
});

createApp(ChartExample).mount("#app");
```

[Live example: RTL Locale Switcher](https://www.ag-grid.com/charts/vue3/rtl/examples/rtl-locale-switcher)

In this example:

- The `enableRtl` option is used to enable right-to-left layout.
- The `localeText` option is used for localisation.
- All bidirectional text is rendered correctly.
- The RTL text in the title and subtitle wrap and truncate on the left.
- The legend layout is mirrored as is the series order in the chart.
- The tooltip and context menu layout are mirrored.

## Axis Layout

The axis positions and directions are not changed in RTL mode. If required, users should manually set [Axis Placement](https://www.ag-grid.com/charts/vue/axes-position/) and `reverse` options explicitly.

## API Reference

#### Chart

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| enableRtl | boolean |  | Set to `true` to render the chart in right-to-left mode. If not specified, the chart will detect the `dir` attribute on the container or its ancestors. |
