## File: README.md

[Demos][demo-url] | [Documentation](https://tradingview.github.io/lightweight-charts/) | [Reddit](https://www.reddit.com/r/TradingView/)

TradingView Lightweight Charts™ are one of the smallest and fastest financial HTML5 charts.

The Lightweight Charts™ library is the best choice for you if you want to display financial data as an interactive chart on your web page without affecting your web page loading speed and performance.

It is the best choice for you if you want to replace static image charts with interactive ones.
The size of the library is close to static images but if you have dozens of image charts on a web page then using this library can make the size of your web page smaller.

Take a look at [awesome-tradingview](https://github.com/tradingview/awesome-tradingview?tab=readme-ov-file#lightweight-charts) for related projects created by our community members.

The library provides a rich set of charting capabilities out of the box, but developers can also extend its functionality by building custom plugins. See the [interactive plugin examples here](https://tradingview.github.io/lightweight-charts/plugin-examples/), or check out [plugin-examples/README.md](https://github.com/tradingview/lightweight-charts/tree/master/plugin-examples) for more details.

## Installing

### es6 via npm

```bash
npm install lightweight-charts
```

### Latest master build

To try the latest `master` build without waiting for a release (powered by [pkg.pr.new](https://pkg.pr.new)):

```bash
npm install https://pkg.pr.new/lightweight-charts@master
```

The import and usage below applies to both npm installation options:

```js
import { createChart, LineSeries } from 'lightweight-charts';

const chart = createChart(document.body, { width: 400, height: 300 });
const lineSeries = chart.addSeries(LineSeries);
lineSeries.setData([
    { time: '2019-04-11', value: 80.01 },
    { time: '2019-04-12', value: 96.63 },
    { time: '2019-04-13', value: 76.64 },
    { time: '2019-04-14', value: 81.89 },
    { time: '2019-04-15', value: 74.43 },
    { time: '2019-04-16', value: 80.01 },
    { time: '2019-04-17', value: 96.63 },
    { time: '2019-04-18', value: 76.64 },
    { time: '2019-04-19', value: 81.89 },
    { time: '2019-04-20', value: 74.43 },
]);
```

### CDN

You can use [unpkg](https://unpkg.com/):

<https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js>

The standalone version creates `window.LightweightCharts` object with all exports from `esm` version:

```js
const chart = LightweightCharts.createChart(document.body, { width: 400, height: 300 });
const lineSeries = chart.addSeries(LightweightCharts.LineSeries);
lineSeries.setData([
    { time: '2019-04-11', value: 80.01 },
    { time: '2019-04-12', value: 96.63 },
    { time: '2019-04-13', value: 76.64 },
    { time: '2019-04-14', value: 81.89 },
    { time: '2019-04-15', value: 74.43 },
    { time: '2019-04-16', value: 80.01 },
    { time: '2019-04-17', value: 96.63 },
    { time: '2019-04-18', value: 76.64 },
    { time: '2019-04-19', value: 81.89 },
    { time: '2019-04-20', value: 74.43 },
]);
```

### Build Variants

|Dependencies included|Mode|ES module|IIFE (`window.LightweightCharts`)|
|-|-|-|-|
|No|PROD|`lightweight-charts.production.mjs`|N/A|
|No|DEV|`lightweight-charts.development.mjs`|N/A|
|Yes (standalone)|PROD|`lightweight-charts.standalone.production.mjs`|`lightweight-charts.standalone.production.js`|
|Yes (standalone)|DEV|`lightweight-charts.standalone.development.mjs`|`lightweight-charts.standalone.development.js`|

## AI coding assistants

This repository ships an [Agent Skill](https://github.com/tradingview/lightweight-charts/blob/master/.github/skills/lightweight-charts/SKILL.md) that teaches AI coding assistants how to work with Lightweight Charts™ - the v5 API conventions, the mental model, and the common time, scale, marker, plugin, and wrapper foot-guns.

Install it into your project with the `skills` CLI:

```console
npx skills add https://github.com/tradingview/lightweight-charts
```

This makes the skill available to compatible assistants (such as Claude Code, Codex, etc.), streamlining your workflow: they scaffold charts, wire up series and data, and answer API questions against the current v5 conventions out of the box - instead of relying on outdated snippets and stumbling into common foot-guns.

## Development

See [BUILDING.md](./BUILDING.md) for instructions on how to build `lightweight-charts` from source.

## License

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this software except in compliance with the License.
You may obtain a copy of the License at LICENSE file.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

This software incorporates several parts of tslib (<https://github.com/Microsoft/tslib>, (c) Microsoft Corporation) that are covered by BSD Zero Clause License.

This license requires specifying TradingView as the product creator.
You shall add the "attribution notice" from the NOTICE file and a link to <https://www.tradingview.com/> to the page of your website or mobile application that is available to your users.
As thanks for creating this product, we'd be grateful if you add it in a prominent place.
You can use the [`attributionLogo`](https://tradingview.github.io/lightweight-charts/docs/api/interfaces/LayoutOptions#attributionLogo) chart option for displaying an appropriate link to <https://www.tradingview.com/> on the chart itself, which will satisfy the link requirement.

[demo-url]: https://www.tradingview.com/lightweight-charts/

[ci-img]: https://img.shields.io/circleci/build/github/tradingview/lightweight-charts.svg
[ci-link]: https://circleci.com/gh/tradingview/lightweight-charts

[npm-version-img]: https://badge.fury.io/js/lightweight-charts.svg
[npm-downloads-img]: https://img.shields.io/npm/dm/lightweight-charts.svg
[npm-link]: https://www.npmjs.com/package/lightweight-charts

[bundle-size-img]: https://badgen.net/bundlephobia/minzip/lightweight-charts
[deps-count-img]: https://img.shields.io/badge/dynamic/json.svg?label=dependencies&color=brightgreen&query=$.dependencyCount&uri=https%3A%2F%2Fbundlephobia.com%2Fapi%2Fsize%3Fpackage%3Dlightweight-charts
[bundle-size-link]: https://bundlephobia.com/result?p=lightweight-charts
[pkg-pr-new-img]: https://pkg.pr.new/badge/tradingview/lightweight-charts
[pkg-pr-new-link]: https://pkg.pr.new/~/tradingview/lightweight-charts

---

## File: debug/README.md

# Debug Folder

This folder is dedicated to creating and testing debug files that won't be committed to the repository. It provides a safe environment for contributors to experiment and test without impacting the main codebase.
It also offers an easy way to manage multiple sandboxes and includes a default template to help you get started quickly.

## Usage

Before using the package, initialize the common root directory for all experiments by running:

```bash
npm run init
```

### Creating a Sandbox

To create a new sandbox, use the following command:

```bash
npm run create <NAME>
```

Replace `<NAME>` with the desired name for your new sandbox, which will be created under `playground/<NAME>.d`.

By default, the sandbox includes lightweight-charts, typescript, and vite. Additional packages can be installed as needed, and any installed package will be shared across all sandboxes, both existing and future.

### Running a Sandbox

Ensure that lightweight-charts is built, as it depends on your local copy.

To (re)build lightweight-charts, run:

```bash
npm run build --prefix ..
```

To run a sandbox, use the serve command. This starts a web server, compiles TypeScript, and enables live reload when files change.

```bash
npm run serve <NAME>
```

To run sandbox against production (minified) build of the lightweight-charts:

```bash
npm run serve:prod <NAME>
```

### Removing a Sandbox

If you need to delete a sandbox, use the following command:

```bash
npm run remove <NAME>
```

This will remove everything under `playground/<NAME>.d`, including the directory itself.

---

## File: packages/create-lwc-plugin/template-common/README.md

# _PLUGINNAME_ - Lightweight Charts™ Plugin

Description of the Plugin.

- Developed for Lightweight Charts version: `v5.0.0`

## Running Locally

```shell
npm install
npm run dev
```

Visit `localhost:5173` in the browser.

## Compiling

```shell
npm run compile
```

Check the output in the `dist` folder.

## Publishing To NPM

You can configure the contents of the package's `package.json` within the
`compile.mjs` script.

Once you have compiled the plugin (see above section) then you can publish the
package to NPM with these commands:

```shell
cd dist
npm publish
```

Hint: append `--dry-run` to the end of the publish command to see the results of
the publish command without actually uploading the package to NPM.

---

## File: packages/create-lwc-plugin/README.md

# create-lwc-plugin

**create-lwc-plugin** is an npm package designed to simplify the process of
creating a new plugin for Lightweight Charts™. With this generator, you can
quickly scaffold a project from a template for either

- a Drawing primitive plugin, or
- a Custom series plugin.

By using this wizard-like tool, you can customize the initial setup of their
plugin project by answering a few questions. This allows for a seamless and
efficient starting point, saving valuable time and effort.

Whether you are developing a new Drawing primitive plugin or a Custom series
plugin for Lightweight Charts, this generator provides a structured and
organized foundation. It ensures that your plugin adheres to the best practices
and conventions of Lightweight Charts, making it easier to develop, maintain,
and contribute to the community.

Getting started with your Lightweight Charts plugin development has never been
easier. Let the Lightweight Charts™ Plugin Scaffold Generator
(`create-lwc-plugin`) handle the initial setup, so you can focus on creating
outstanding plugins for Lightweight Charts™.

✨ Need some examples for inspiration? Check out the
[plugin-examples](https://github.com/tradingview/lightweight-charts/tree/master/plugin-examples)
folder in the Lightweight Charts repo.

## Scaffolding Your First Lightweight Charts™ Plugin

With NPM:

```bash
npm create lwc-plugin@latest
```

With Yarn:

```bash
yarn create lwc-plugin
```

With PNPM:

```bash
pnpm create lwc-plugin
```

## Using the generated project

### Running Locally (during development)

```shell
npm install
npm run dev
```

Visit `localhost:5173` in the browser.

### Compiling the Plugin

```shell
npm run compile
```

Check the output in the `dist` folder.

### Publishing To NPM

You can configure the contents of the package's `package.json` within the
`compile.mjs` script.

Once you have compiled the plugin (see above section) then you can publish the
package to NPM with these commands:

```shell
cd dist
npm publish
```

Hint: append `--dry-run` to the end of the publish command to see the results of
the publish command without actually uploading the package to NPM.

---

## File: plugin-examples/README.md

# Lightweight Charts™ Plugin Examples

This folder contains a collection of example plugins designed to extend the
functionality of Lightweight Charts™ and inspire the development of your own
plugins.

**Disclaimer:** These plugins are provided as-is, and are primarily intended as
proof-of-concept examples and starting points. They have not been fully
optimized for production and may not receive updates or improvements over time.

We believe in the power of community collaboration, and we warmly welcome any
pull requests (PRs) aimed at enhancing and fixing the existing examples.
Additionally, we encourage you to create your own plugins and share them with
the community. We would be delighted to showcase the best plugins our users
create in this readme document.

✨ If you have something cool to share or if you need assistance, please don't
hesitate to get in touch.

🚀 Need a starting point for your plugin idea? Check out
[create-lwc-plugin](https://www.npmjs.com/package/create-lwc-plugin) package.

📊 You can view a demo page of the plugins within this repo at his link:
[Plugin Examples](https://tradingview.github.io/lightweight-charts/plugin-examples)

## Learning More

- [Documentation for Plugins](https://tradingview.github.io/lightweight-charts/docs/next/plugins/intro)
- [Learn more about Lightweight Charts™](https://www.tradingview.com/lightweight-charts/)

## Running Locally

To run this repo locally, follow these steps:

1. Clone the repo to your local machine
2. First build the library

   ```shell
   npm install
   npm run build:prod
   ```

3. Switch to the Plugin Examples Folder, install and start the development server

   ```shell
   cd plugin-examples
   npm install
   npm run dev
   ```

4. Visit `localhost:5173` in the browser.

## Compiling the Examples

```shell
npm run compile
```

Check the output in the `compiled` folder.

## Using an Example

Once you have compiled the examples then simply copy that folder into your
project and import the JS module in your code.

1. Copy the compiled plugin folder into your project, example:
   `plugins/background-shade-series` (from `compiled/background-shade-series`)
2. Within your project, you can import the class as follows:

   ```js
   import { BackgroundShadeSeries } from '../plugins/background-shade-series/background-shade-series';

   // ...

   const backgroundShadeSeriesPlugin = new BackgroundShadeSeries();
   const myCustomSeries = chart.addCustomSeries(backgroundShadeSeriesPlugin, {
       lowValue: 0,
       highValue: 1000,
   });
   ```

## Creating your own Plugin

[create-lwc-plugin](https://github.com/tradingview/lightweight-charts/tree/master/packages/create-lwc-plugin) is an npm
package designed to simplify the process of creating a new plugin for
Lightweight Charts™. With this generator, you can quickly scaffold a project
from a template for either

- a Drawing primitive plugin, or
- a Custom series plugin.

You can get started with this simple command:

```shell
npm create lwc-plugin@latest
```

---

## File: website/docs/migrations/from-v2-to-v3.md

# From v2 to v3

Lightweight Charts™ library 3.0 announces the major improvements: supporting two price scales and improving the time scale API.
In order of keep the API clear and consistent, we decided to allow breaking change of the API.

In this document you can find the migration guide from the previous version to 3.0.

## Time Scale API

Previously, to handle changing visible time range you needed to use `subscribeVisibleTimeRangeChange` and `unsubscribeVisibleTimeRangeChange` to subscribe and unsubscribe from visible range events.
These methods were available in the chart object  (e.g. you call it like `chart.subscribeVisibleTimeRangeChange(func)`).

In 3.0 in order to make API more consistent with the new API we decided to move these methods to [ITimeScaleApi](/api/interfaces/ITimeScaleApi.md)
(along with the new subscription methods [`ITimeScaleApi.subscribeVisibleLogicalRangeChange`](/api/interfaces/ITimeScaleApi.md#subscribevisiblelogicalrangechange) and [`ITimeScaleApi.unsubscribeVisibleLogicalRangeChange`](/api/interfaces/ITimeScaleApi.md#unsubscribevisiblelogicalrangechange)).

So, to migrate your code to 3.0 you just need to replace:

- `chart.subscribeVisibleTimeRangeChange` with `chart.timeScale().subscribeVisibleTimeRangeChange`
- `chart.unsubscribeVisibleTimeRangeChange` with `chart.timeScale().unsubscribeVisibleTimeRangeChange`

## Two price scales

We understand disadvantages of breaking changes in the API, so we have not removed support of the current API at all, but have deprecated it, so the most common cases will continue to work.

You can refer to the new API [here](../price-scale.md).

Following are migration rules.

### Default behavior

Default behavior is not changed. If you do not specify price scale options, the chart will have the right price scale visible and all the series will assign to it.

### Left price scale

If you need the price scale to be drawn on the left side, you should make the following changes.
instead of

```js
const chart = LightweightCharts.createChart(container, {
    priceScale: {
        position: 'left',
    },
});
```

use

```js
const chart = LightweightCharts.createChart(container, {
    rightPriceScale: {
        visible: false,
    },
    leftPriceScale: {
        visible: true,
    },
});
```

then specify target price scale while creating a series:

```js
const histSeries = chart.addHistogramSeries({
    priceScaleId: 'left',
});
```

New version fully supports this case via the old API, however this support will be removed in the future releases.

### No price scale

To create chart without any visible price scale, instead of

```js
const chart = LightweightCharts.createChart(container, {
    priceScale: {
        position: 'none',
    },
});
```

use

```js
const chart = LightweightCharts.createChart(container, {
    leftPriceScale: {
        visible: false,
    },
    rightPriceScale: {
        visible: false,
    },
});
```

New version fully supports this case via the old API, however this support will be removed in the future releases.

### Creating overlay

To create an overlay series, instead of

```js
const histogramSeries = chart.addHistogramSeries({
    overlay: true,
});
```

use

```js
const histogramSeries = chart.addHistogramSeries({
    // or any other _the same_ id for all overlay series
    priceScaleId: '',
});
```

New version fully supports this case via the old API, however this support will be removed in the future releases.

### Move price scale from right to left or vice versa

To do this, instead of

```js
const chart = LightweightCharts.createChart(container);

const mainSeries = chart.addLineSeries();

// ...

chart.applyOptions({
    priceScale: {
        position: 'left',
    },
});
```

use

```js
const chart = LightweightCharts.createChart(container);

const mainSeries = chart.addLineSeries();

// ...

chart.applyOptions({
    leftPriceScale: {
        visible: true,
    },
    rightPriceScale: {
        visible: false,
    },
});

mainSeries.applyOptions({
    priceScaleId: 'left',
});
```

New version does not support this case via the old API, so, if you use it, you should migrate your code in order of keeping it working.

---

## File: website/docs/migrations/from-v3-to-v4.md

# From v3 to v4

In this document you can find the migration guide from the previous version v3 to v4.

## Exported enum `LasPriceAnimationMode` has been removed

Please use [`LastPriceAnimationMode`](/api/enumerations/LastPriceAnimationMode.md) instead.

## `scaleMargins` option has been removed from series options

Previously, you could do something like the following:

```js
const series = chart.addLineSeries({
    scaleMargins: { /* options here */},
});
```

And `scaleMargins` option was applied to series' price scale as `scaleMargins` option.

Since v4 this option won't be applied to the price scale and will be just ignored (if you're using TypeScript you will get a compilation error).

To fix this, you need to apply these options to series' price scale:

```js
const series = chart.addLineSeries();

series.priceScale().applyOptions({
    scaleMargins: { /* options here */},
});
```

## `backgroundColor` from `layout` options has been removed

If you want to have solid background color you need to use [`background`](/api/interfaces/LayoutOptions.md#background) property instead, e.g. instead of:

```js
const chart = createChart({
    layout: {
        backgroundColor: 'red',
    },
});
```

use

```js
const chart = createChart({
    layout: {
        background: {
            type: ColorType.Solid,
            color: 'red',
        },
    },
});
```

## `overlay` property of series options has been removed

Please follow [the guide for migrating from v2 to v3](./from-v2-to-v3.md#creating-overlay) where this option was deprecated.

## `priceScale` option has been removed

Please follow [the guide for migrating from v2 to v3](./from-v2-to-v3.md#two-price-scales).

## `priceScale()` method of chart API now requires to provide price scale id

Before v4 you could write the following code:

```js
const priceScale = chart.priceScale();
```

And in `priceScale` you had a right price scale if it is visible and a left price scale otherwise.

Since v4 you have to provide an ID of price scale explicitly, e.g. if you want to get a right price scale you need to provide `'right'`:

```js
const rightPriceScale = chart.priceScale('right');
const leftPriceScale = chart.priceScale('left');
```

## `drawTicks` from `leftPriceScale` and `rightPriceScale` options has been renamed to `ticksVisible`

Since v4 you have to use `ticksVisible` instead of `drawTicks`.

```js
const chart = createChart({
    leftPriceScale: {
        ticksVisible: false,
    },
    rightPriceScale: {
        ticksVisible: false,
    },
});
```

Also this option is off by default.

## The type of outbound time values has been changed

Affected API:

- [`IChartApi.subscribeClick`](/api/interfaces/IChartApi.md#subscribeclick) (via [`MouseEventParams.time`](/api/interfaces/MouseEventParams.md#time))
- [`IChartApi.subscribeCrosshairMove`](/api/interfaces/IChartApi.md#subscribecrosshairmove) (via [`MouseEventParams.time`](/api/interfaces/MouseEventParams.md#time))
- [`LocalizationOptions.timeFormatter`](/api/interfaces/LocalizationOptions.md#timeformatter) (via argument of [`TimeFormatterFn`](/api/type-aliases/TimeFormatterFn.md))
- [`TimeScaleOptions.tickMarkFormatter`](/api/interfaces/TimeScaleOptions.md#tickmarkformatter) (via argument of [`TickMarkFormatter`](/api/type-aliases/TickMarkFormatter.md))

Previously the type of an inbound time (a values you provide to the library, e.g. in [`ISeriesApi.setData`](/api/interfaces/ISeriesApi.md#setdata)) was different from an outbound one (a values the library provides to your code, e.g. an argument of [`LocalizationOptions.timeFormatter`](/api/interfaces/LocalizationOptions.md#timeformatter)).
So the difference between types was that outbound time couldn't be a business day string.

Since v4 we improved our API in this matter and now the library will return exactly the same values back for all time-related properties.

Thus, if you provide a string to your series in [`ISeriesApi.setData`](/api/interfaces/ISeriesApi.md#setdata), you'll receive exactly the same value back:

```js
series.setData([
    { time: '2001-01-01', value: 1 },
]);

chart.applyOptions({
    localization: {
        timeFormatter: time => time, // will be '2001-01-01' for the bar above
    },
    timeScale: {
        tickMarkFormatter: time => time, // will be '2001-01-01' for the bar above
    },
});

chart.subscribeCrosshairMove(param => {
    console.log(param.time); // will be '2001-01-01' if you hover the bar above
});

chart.subscribeClick(param => {
    console.log(param.time); // will be '2001-01-01' if you click on the bar above
});
```

Handling this breaking change depends on your needs and your handlers, but generally speaking you need to convert provided time to a desired format manually if it is required.
For example, you could use provided helpers to check the type of a time:

```js
import {
    createChart,
    isUTCTimestamp,
    isBusinessDay,
} from 'lightweight-charts';

const chart = createChart(document.body);

chart.subscribeClick(param => {
    if (param.time === undefined) {
        // the time is undefined, i.e. there is no any data point where a time could be received from
        return;
    }

    if (isUTCTimestamp(param.time)) {
        // param.time is UTCTimestamp
    } else if (isBusinessDay(param.time)) {
        // param.time is a BusinessDay object
    } else {
        // param.time is a business day string in ISO format, e.g. `'2010-01-01'`
    }
});
```

## `seriesPrices` property from `MouseEventParams` has been removed

Affected API:

- [`IChartApi.subscribeClick`](/api/interfaces/IChartApi.md#subscribeclick)
- [`IChartApi.subscribeCrosshairMove`](/api/interfaces/IChartApi.md#subscribecrosshairmove)

The property `seriesPrices` of [`MouseEventParams`](/api/interfaces/MouseEventParams.md) has been removed.

Instead, you can use [`MouseEventParams.seriesData`](/api/interfaces/MouseEventParams.md#seriesdata) - it is pretty similar to the old `seriesPrices`, but it contains series' data items instead of just prices:

```js
lineSeries.setData([{ time: '2001-01-01', value: 1 }]);
barSeries.setData([{ time: '2001-01-01', open: 5, high: 10, low: 1, close: 7 }]);

chart.subscribeCrosshairMove(param => {
    console.log(param.seriesData.get(lineSeries)); // { time: '2001-01-01', value: 1 } or undefined
    console.log(param.seriesData.get(barSeries)); // { time: '2001-01-01', open: 5, high: 10, low: 1, close: 7 } or undefined
});
```

## `MouseEventParams` field `hoveredMarkerId` was renamed to `hoveredObjectId`

Since v4 you have to use `hoveredObjectId` instead of `hoveredMarkerId`.

```js
chart.subscribeCrosshairMove(param => {
    console.log(param.hoveredObjectId);
});

chart.subscribeClick(param => {
    console.log(param.hoveredObjectId);
});
```

---

## File: website/docs/migrations/from-v4-to-v5.md

# From v4 to v5

In this document you can find the migration guide from the previous version v4
to v5.

## Table of Contents

- [Series changes](#series-changes)
- [Series Markers](#series-markers)
- [Watermarks](#watermarks)
- [Plugin Typings](#plugin-typings)

## Series changes

### Overview of Changes {#overview-changes-series}

- Unified series creation API using single `addSeries` function
- Better tree-shaking support
- Individual series types must now be imported separately (for ESM)

### Migration Steps {#migration-steps-series}

Replace all series creation calls with the new `addSeries` syntax. Here's how the migration works for each series type:

#### Before (v4) {#v4-series}

```js
// Example with Line Series in v4
import { createChart } from 'lightweight-charts';
const chart = createChart(container, {});
const lineSeries = chart.addLineSeries({ color: 'red' });
```

#### After (v5) {#v5-series}

```js
// Example with Line Series in v5
import { createChart, LineSeries } from 'lightweight-charts';
const chart = createChart(container, {});
const lineSeries = chart.addSeries(LineSeries, { color: 'red' });
```

#### Migration Reference {#migration-reference-series}

Here's how to migrate each series type:

| v4 Method | v5 Method |
|-----------|-----------|
| `chart.addLineSeries(options)` | `chart.addSeries(LineSeries, options)` |
| `chart.addAreaSeries(options)` | `chart.addSeries(AreaSeries, options)` |
| `chart.addBarSeries(options)` | `chart.addSeries(BarSeries, options)` |
| `chart.addBaselineSeries(options)` | `chart.addSeries(BaselineSeries, options)` |
| `chart.addCandlestickSeries(options)` | `chart.addSeries(CandlestickSeries, options)` |
| `chart.addHistogramSeries(options)` | `chart.addSeries(HistogramSeries, options)` |

### Usage Examples {#usage-examples-series}

ESM (ES Modules):

```js
import { createChart, LineSeries } from 'lightweight-charts';

const chart = createChart(container, {});
const lineSeries = chart.addSeries(LineSeries, { color: 'red' });
```

UMD (Universal Module Definition):

```js
const chart = LightweightCharts.createChart(container, {});
const lineSeries = chart.addSeries(LightweightCharts.LineSeries, { color: 'red' });
```

Note: Make sure to import the specific series type (e.g., `LineSeries`, `AreaSeries`) along with `createChart` when using ES Modules. For UMD builds, all series types are available under the `LightweightCharts` namespace.

## Series Markers

### Overview of Changes {#overview-changes-markers}

- Markers moved to separate primitive for optimized bundle size
- New ⁠`createSeriesMarkers` function required
- Marker management through dedicated primitive instance

### Migration Steps {#migration-steps-markers}

#### Before (v4) {#v4-markers}

```javascript
// Markers were directly managed through the series instance
series.setMarkers([
    {
        time: '2019-04-09',
        position: 'aboveBar',
        color: 'black',
        shape: 'arrowDown',
    },
]);

// Getting markers
const markers = series.markers();
```

#### After (v5) {#v5-markers}

```javascript
// Import the markers primitive
import { createSeriesMarkers } from 'lightweight-charts';

// Create a markers primitive instance
const seriesMarkers = createSeriesMarkers(series, [
    {
        time: '2019-04-09',
        position: 'aboveBar',
        color: 'black',
        shape: 'arrowDown',
    },
]);

// Getting markers
const markers = seriesMarkers.markers();

// Updating markers
seriesMarkers.setMarkers([/* new markers */]);

// Remove all markers
seriesMarkers.setMarkers([]);
```

### Key Changes {#key-changes-markers}

- You must now import `createSeriesMarkers` separately
- Instead of calling methods directly on the series instance, create a markers primitive using `createSeriesMarkers`
- The markers API is now accessed through the markers primitive instance
- The marker configuration object format remains the same
- This change results in smaller bundle sizes when markers aren't used

If your application doesn't use markers, you can now benefit from a smaller bundle size as this functionality is no longer included in the core package.

## Watermarks

### Overview of Changes {#overview-changes-watermarks}

In the new version of Lightweight Charts, the watermark feature has undergone significant changes:

- Extraction from Core: The watermark functionality has been extracted from the core library.
- Re-implementation: It's now re-implemented as a Pane Primitive (plugin) included within the library.
- Improved Tree-shaking: This change makes the feature more tree-shakeable, potentially reducing bundle sizes for users who don't need watermarks.
- Added an Image Watermark Primitive: In addition to the usual text based watermark, there is now
an image watermark feature provided by the [`createImageWatermark`](/api/functions/createImageWatermark.md) plugin.

### Migration Steps {#migration-steps-watermarks}

#### Before (v4) {#v4-watermarks}

```js
const chart = createChart(container, {
    watermark: {
        text: 'Watermark Text',
        color: 'rgba(255,0,0,0.5)',
    },
});
```

#### After (v5) {#v5-watermarks}

```js
import { createChart, createTextWatermark } from 'lightweight-charts';

const chart = createChart(container, options);
const firstPane = chart.panes()[0];

createTextWatermark(firstPane, {
    horzAlign: 'center',
    vertAlign: 'center',
    lines: [{
        text: 'Watermark Text',
        color: 'rgba(255,0,0,0.5)',
        fontSize: 50,
    }],
});

```

### Accessing the New TextWatermark

The TextWatermark plugin is now available as follows:

- **ESM builds**: Import [`createTextWatermark`](/api/functions/createTextWatermark.md) directly.
- **Standalone script build**: Access via `LightweightCharts.createTextWatermark`.

### Changes in Options

The options structure for watermarks has been revised:

1. **Multiple Lines**: The plugin now supports multiple lines of text.
2. **Text Options**: Text-related options are now defined per line within the `lines` property of the options object.

### Attaching the Watermark

To use the plugin, you need pass a pane object to the `createTextWatermark` function. The pane object specifies where the watermark should be attached:

1. **Single Pane**: If you're using only one pane, you can easily fetch it using `chart.panes()[0]`.
2. **Multiple Panes**: For charts with multiple panes, you'll need to specify which pane to attach the watermark to.

### Example: Implementing a Text Watermark

Here's a comprehensive example demonstrating how to implement a text watermark in the new version:

```js
const chart = createChart(container, options);
const mainSeries = chart.addSeries(LineSeries);
mainSeries.setData(generateData());

const firstPane = chart.panes()[0];
createTextWatermark(firstPane, {
    horzAlign: 'center',
    vertAlign: 'center',
    lines: [
        {
            text: 'Hello',
            color: 'rgba(255,0,0,0.5)',
            fontSize: 100,
            fontStyle: 'bold',
        },
        {
            text: 'This is a text watermark',
            color: 'rgba(0,0,255,0.5)',
            fontSize: 50,
            fontStyle: 'italic',
            fontFamily: 'monospace',
        },
    ],
});
```

## Plugin Typings

### Overview of Changes {#overview-changes-plugins}

Some of the plugin types and interfaces have been renamed due to the additional
of Pane Primitives.

- `ISeriesPrimitivePaneView` → `IPrimitivePaneView`
- `ISeriesPrimitivePaneRenderer` → `IPrimitivePaneRenderer`
- `SeriesPrimitivePaneViewZOrder` → `PrimitivePaneViewZOrder`

---

## File: website/docs/plugins/pixel-perfect-rendering/widths/candlestick.md

---
sidebar_position: 0
sidebar_label: Candlesticks
pagination_title: Candlestick Widths
title: Candlestick Width Calculations
keywords:
  - plugins
  - extensions
  - rendering
  - canvas
  - bitmap
  - media
  - pixels
  - candlestick
  - width
---

:::tip

It is recommend that you first read the [Pixel Perfect Rendering](../index.md) page.

:::

The following functions can be used to get the calculated width that the library would use for a candlestick at a specific bar spacing and device pixel ratio.

Below a bar spacing of 4, the library will attempt to use as large a width as possible without the possibility of overlapping, whilst above 4 then the width will start to trend towards an 80% width of the available space.

:::warning

It is expected that candles can overlap slightly at smaller bar spacings (more pronounced on lower resolution devices). This produces a more readable chart. If you need to ensure that bars can never overlap then rather use the widths for [Columns](./columns.md) or the [full bar width](./full-bar-width.md) calculation.

:::

```typescript
function optimalCandlestickWidth(
    barSpacing: number,
    pixelRatio: number
): number {
    const barSpacingSpecialCaseFrom = 2.5;
    const barSpacingSpecialCaseTo = 4;
    const barSpacingSpecialCaseCoeff = 3;
    if (barSpacing >= barSpacingSpecialCaseFrom && barSpacing <= barSpacingSpecialCaseTo) {
        return Math.floor(barSpacingSpecialCaseCoeff * pixelRatio);
    }
    // coeff should be 1 on small barspacing and go to 0.8 while bar spacing grows
    const barSpacingReducingCoeff = 0.2;
    const coeff =
        1 -
        (barSpacingReducingCoeff *
            Math.atan(
                Math.max(barSpacingSpecialCaseTo, barSpacing) - barSpacingSpecialCaseTo
            )) /
            (Math.PI * 0.5);
    const res = Math.floor(barSpacing * coeff * pixelRatio);
    const scaledBarSpacing = Math.floor(barSpacing * pixelRatio);
    const optimal = Math.min(res, scaledBarSpacing);
    return Math.max(Math.floor(pixelRatio), optimal);
}

/**
 * Calculates the candlestick width that the library would use for the current
 * bar spacing.
 * @param barSpacing - bar spacing in media coordinates
 * @param horizontalPixelRatio - horizontal pixel ratio
 * @returns The width (in bitmap coordinates) that the chart would use to draw a candle body
 */
export function candlestickWidth(
    barSpacing: number,
    horizontalPixelRatio: number
): number {
    let width = optimalCandlestickWidth(barSpacing, horizontalPixelRatio);
    if (width >= 2) {
        const wickWidth = Math.floor(horizontalPixelRatio);
        if (wickWidth % 2 !== width % 2) {
            width--;
        }
    }
    return width;
}
```

---

## File: website/docs/plugins/pixel-perfect-rendering/widths/columns.md

---
sidebar_position: 0
sidebar_label: Columns
pagination_title: Histogram Column Widths
title: Histogram Column Width Calculations
keywords:
  - plugins
  - extensions
  - rendering
  - canvas
  - bitmap
  - media
  - pixels
  - histogram
  - column
  - width
---

:::tip

It is recommend that you first read the [Pixel Perfect Rendering](../index.md) page.

:::

The following functions can be used to get the calculated width that the library would use for a histogram column at a specific bar spacing and device pixel ratio.

You can use the `calculateColumnPositionsInPlace` function instead of the `calculateColumnPositions` function to perform the calculation on an existing array of items without needing to create additional arrays (which is more efficient). It is recommended that you memoize the majority of the calculations below to improve the rendering performance.

```
/* Detailed source-code truncated for AI context efficiency. */
```