Skip to main content
Version: 4.1

Selection Region

Sometimes it's useful to give users the option to select areas of different shapes and sizes. For example, you might want users to find all the elements that are within a certain area on the paper.

This area can simply be a rectangle, but it can also be an irregular shape drawn by the user, like the lasso tool.

In JointJS, there are several built-in selection regions that you can use out of the box:

Draw region and select elements​

A typical use case is to allow the user to select elements on the paper by drawing a shape around them.

const region = new ui.RectangularSelectionRegion({ paper });

paper.on('blank:pointerdown', async () => {
const area = await region.getUserSelectionAsync();
if (!area) return;
const elements = graph.findModelsInArea(area);
/* do something with the elements */
});
Or an equivalent code using promise chaining
const region = new ui.RectangularSelectionRegion({ paper });

paper.on('blank:pointerdown', () => {
region.getUserSelectionAsync().then((area) => {
if (!area) return;
const elements = graph.findModelsInArea(area);
/* do something with the elements */
});
});

When getUserSelectionAsync() is called, the region will wait for the user to draw a shape on the paper (by listening to pointermove and pointerup events on document).

When the user finishes drawing, the promise will resolve with the area of the shape (rectangle, polygon or range) that the user drew.

Here are some examples of how to use the selection regions to select elements and add them to the selection collection.

Live selection​

This section shows how to use the SelectionRegion to select elements on the paper as the user drags the mouse (select them in real-time).

const region = new ui.RectangularSelectionRegion({
paper,
onChange: (area) => {
const elements = graph.findModelsInArea(area);
/* do something with the elements */
},
});

paper.on('blank:pointerdown', () => region.getUserSelectionAsync());

Other uses​

There are many other ways you can use the SelectionRegion tool. Here are a few examples:

Select area to zoom in​

A common use case is to zoom to the area selected by the user.

// `paperScroller` is an instance of ui.PaperScroller

paper.on('blank:pointerdown', async () => {
const region = new ui.RectangularSelectionRegion({ paper });
const rect = await region.getUserSelectionAsync();
rect && paperScroller.zoomToRect(rect);
region.remove();
});

Drill down through data​

In chart applications, such as a Marey chart, you may want to allow the user to drill down into a selected area.

// `drillDown(from, to)` is an example function that shows
// more detailed data for the selected area

paper.on('blank:pointerdown', async () => {
const region = new ui.RangeSelectionRegion({ paper });
const range = await region.getUserSelectionAsync();
range && drillDown(range[0], range[1]);
region.remove();
});

Space tool​

The RangeSelectionRegion can be used to create a space tool that allows the user to shift elements in the paper in a certain direction.

Custom selection region​

If you need a custom selection region, you can create your own by extending the SelectionRegion class.

The class is generic and you need to provide the geometry type and options type.

type MyGeometry = any;

interface MyRegionOptions extends ui.SelectionRegion.Options<MyGeometry> {
myOption?: string;
}

class MyRegion extends ui.SelectionRegion<MyGeometry, MyRegionOptions> {

preinitialize() {
// set up the region here properties here (e.g. `this.tagName = 'path'`)
}

addPoint(x: number, y: number) {
// add points to the region as the user draws it
}

resetPoints() {
// reset the region points before the user starts drawing a new region
}

validatePoint(x: number, y: number) {
// validate the point before adding it to the region
// use `return true` to skip the validation
}

usePoints(): MyGeometry {
// use the points to create the geometry of the region
}

update(geometry: MyGeometry) {
// update the DOM here (`this.el`)
// you can access options via `this.options`
// the geometry is not normalized
}

override normalizeGeometry(geometry: MyGeometry): MyGeometry {
// normalize the geometry before returning it to `onChange()` callback
// or `getUserSelectionAsync()` promise
return geometry;
}
}

Here is an example of a custom selection region that allows the user to draw a line on the paper and receive the line geometry.