npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tradingview/lwc-plugin-brushable-area-series

v1.0.0

Published

Area series that can style ranges of data differently. Pair it with your own pointer handling to build a brush selection.

Readme

Brushable area series

An area series that can style parts of the data differently. You set a base style for the whole series and any number of brush ranges. A brush range is a span of data points with its own line and fill colors.

The series itself only draws the styles. Attach the optional BrushableAreaInteraction primitive, or add your own pointer handling, to turn it into a brush selection: the user drags across the chart, the brush range for the selected span is set, and the rest of the series keeps the base style. Give outsideStyle a semi-transparent style to get the classic effect where the selection stays vivid and the rest looks faded.

Use it for range selection on a sparkline or an overview chart. It also fits highlighting a period, such as a trading session, an event window, or a backtest sample, and comparing segments of one series visually.

Installation

npm

Install the package. It requires lightweight-charts ^5.0.0 in your project:

npm install @tradingview/lwc-plugin-brushable-area-series

Then import the plugin and add it to a chart:

import { createChart } from 'lightweight-charts';
import { createBrushableAreaSeries } from '@tradingview/lwc-plugin-brushable-area-series';

const chart = createChart(document.getElementById('container'));
const series = createBrushableAreaSeries(chart, {
    lineColor: 'rgb(41, 98, 255)',
    topColor: 'rgba(41, 98, 255, 0.4)',
    bottomColor: 'rgba(41, 98, 255, 0)',
    priceLineVisible: false,
});
series.setData(data); // [{ time, value }, ...]

CDN

The plugin is published as ES modules. Map the library and the plugin to their CDN builds with an import map:

<script type="importmap">
{
  "imports": {
    "lightweight-charts": "https://unpkg.com/lightweight-charts@^5/dist/lightweight-charts.standalone.production.mjs",
    "@tradingview/lwc-plugin-brushable-area-series": "https://unpkg.com/@tradingview/lwc-plugin-brushable-area-series/dist/brushable-area-series.standalone.js"
  }
}
</script>

The plugin can then be imported by name, exactly as it is under a bundler:

<script type="module">
import { createChart } from 'lightweight-charts';
import { createBrushableAreaSeries } from '@tradingview/lwc-plugin-brushable-area-series';

const chart = createChart(document.getElementById('container'));
const series = createBrushableAreaSeries(chart, {
    lineColor: 'rgb(41, 98, 255)',
    topColor: 'rgba(41, 98, 255, 0.4)',
    bottomColor: 'rgba(41, 98, 255, 0)',
    priceLineVisible: false,
});
series.setData(data); // [{ time, value }, ...]
</script>

Usage

Add the custom series with createBrushableAreaSeries, set single-value data, then set brushRanges whenever the selection changes:

import { createChart } from 'lightweight-charts';
import { createBrushableAreaSeries } from '@tradingview/lwc-plugin-brushable-area-series';

const chart = createChart(document.getElementById('container'));
const series = createBrushableAreaSeries(chart, {
    lineColor: 'rgb(41, 98, 255)',
    topColor: 'rgba(41, 98, 255, 0.4)',
    bottomColor: 'rgba(41, 98, 255, 0)',
    priceLineVisible: false,
});
series.setData(data); // [{ time, value }, ...]

// Highlight points 40–80 in green and fade everything else.
series.applyOptions({
    brushRanges: [
        {
            range: { from: 40, to: 80 },
            style: {
                lineColor: '#089981',
                topColor: 'rgba(8, 153, 129, 0.4)',
                bottomColor: 'rgba(8, 153, 129, 0)',
                lineWidth: 3,
            },
        },
    ],
    outsideStyle: {
        lineColor: 'rgba(41, 98, 255, 0.2)',
        topColor: 'rgba(41, 98, 255, 0.05)',
    },
});

// Clear the selection: the whole series goes back to the base style.
series.applyOptions({ brushRanges: [] });

A range's style and outsideStyle are both partial: every property left out falls back to the base style set on the series.

Ranges are expressed in logical indices of the time scale (the position on the chart's own index, shared by every series), not in time and not in the series' own array positions. To turn a pointer position into a logical index, use chart.timeScale().coordinateToLogical(x), where x is the pointer's horizontal position within the plot area.

Each data point is { time, value }. Points without a value are treated as whitespace, and the line breaks at the gap rather than bridging it.

Brush selection

BrushableAreaInteraction is an optional series primitive that turns a mouse drag, a one-finger drag or a two-finger gesture into a brush range, so the pointer handling does not have to be written again in every application:

import {
    BrushableAreaInteraction,
} from '@tradingview/lwc-plugin-brushable-area-series';

const brush = new BrushableAreaInteraction({
    style: { lineColor: '#089981', topColor: 'rgba(8, 153, 129, 0.4)' },
    outsideStyle: { lineColor: 'rgba(41, 98, 255, 0.2)' },
});
series.attachPrimitive(brush);

brush.activeRange().subscribe(range => {
    // null once the selection is cleared by a click without a drag
    if (range !== null) {
        console.log(range.from, range.to, range.fromTime, range.toTime);
    }
});

| Interaction option | Type | Default | Description | | --- | --- | --- | --- | | style | Partial<style> | green | Style applied to the brushed range. | | outsideStyle | Partial<style> | faded blue | Style applied outside the brushed range. | | applyToSeries | boolean | true | Set the series' brushRanges as the user drags. Turn it off to only receive activeRange events. | | minimumRangeWidth | number | 1 | Smallest drag, in logical indices, that counts as a range. |

The defaults are exported as defaultInteractionOptions. The range reported by activeRange() carries from / to as logical indices and fromTime / toTime as the times of the data points at those indices (null where the series has no point there). brush.clear() removes the selection, and brush.range() returns the current one.

The chart's own drag gesture competes with brushing, so a chart using this primitive normally sets handleScroll: false and handleScale: false.

Options

In addition to the standard series options (priceLineVisible, lastValueVisible, priceFormat, autoscaleInfoProvider, …):

| Option | Type | Default | Description | | --- | --- | --- | --- | | lineColor | string | 'rgb(40,98,255)' | Base line color, used outside brush ranges. | | topColor | string | 'rgba(40,98,255, 0.4)' | Base fill color at the line (top of the gradient). | | bottomColor | string | 'rgba(40,98,255, 0)' | Base fill color at the base price (bottom of the gradient). | | lineWidth | 1 \| 2 \| 3 \| 4 | 2 | Base line width, in CSS pixels. | | lineStyle | LineStyle | LineStyle.Solid | Base dash pattern of the line. | | lineVisible | boolean | true | Draw the line itself. Set it to false for the fill only. | | lineType | LineType | LineType.Simple | Shape of the line between two points: straight, stepped or curved. The fill follows the same shape. | | relativeGradient | boolean | false | Anchor the far end of the fill gradient to the outermost point in view rather than to the edge of the pane, as AreaSeries does. | | invertFilledArea | boolean | false | Fill the area above the line, up to the top of the pane, instead of down to basePrice. | | basePrice | number | 0 | Price the area is filled down to. | | brushRanges | { range: { from: number; to: number }; style: Partial<style> }[] | [] | Ranges of logical indices rendered in their own style. from is inclusive, to is exclusive. Set an empty array to clear. | | outsideStyle | Partial<style> | — | Style of the points outside every brush range. Used only while at least one range is set. |

style is { lineColor, topColor, bottomColor, lineWidth, lineStyle } — the same five properties as the base style, and each one optional.

Notes

  • A point inside a brush range is drawn with that range's style; if ranges overlap, the last matching range wins, so a new selection covers the ones it is dragged over.
  • Each drawn segment takes the style of its right-hand point, and consecutive points sharing a style are drawn as one path, so no seam shows inside a run.
  • The fill is a vertical gradient from bottomColor at basePrice to topColor at the edge of the pane the fill extends towards (or at the outermost point in view with relativeGradient). When basePrice falls outside the visible price range, the fill reaches the edge of the pane.
  • The line and the fill are drawn one bar past each edge of the visible range, so they leave the pane rather than stopping at the last visible point while the chart is panned.
  • Points whose value falls outside the current price scale, and gaps in the data, break the line rather than being drawn to an invalid coordinate.
  • The examples disable chart scrolling and scaling (handleScroll, handleScale) so that dragging brushes instead of panning; decide which gesture your chart should own.

Explicit whitespace

Use createBrushableAreaSeries to retain whitespace passed through setData and update, including historical corrections. Other series' timestamps do not break the area. The low-level BrushableAreaSeries view remains available, but without the factory's gap predicate it draws continuously: the host does not provide whitespace to custom renderers.

Under time-scale conflation the area is drawn from buckets of several bars, and a whitespace run narrower than one bucket cannot be resolved at that bar spacing: it is absorbed into the bucket rather than breaking the area at every bar. Zooming in past the conflation threshold shows the gap again.