Selecting data points in the graph

In this recipe, we will look at selecting data points in the graph. You can have a system to select one point at a time, or multiple points. In this recipe we will look at the more difficult, latter option.

We'll show how to implement a dragging action, where you drag the mouse, forming a rectangle around the points you want to select. Selecting multiple points can be used in several ways: if you are editing a graph and want to remove or changed multiple points at once or if you want to zoom in on a specific area.

Getting ready

The starting point is exactly the same as the previous recipe. To keep your workspace tidy, copy it into a new Recipe4 document class.

How to do it...

Implementing a select action involves two steps:

  1. Let the user define the area in which we will have to select the items.
  2. Calculate which items are in the selection area.

In order to manage everything we'll need a few variables. Add the following fields to the Recipe4 class:

private var _selection:Shape = new Shape();
private var _selectionArea:Shape;
private var _selectionStart:Point;

In the constructor we attach the selection area and event listeners:

addChild(_selection);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);

The bulk of the work is done inside those listeners:

private function mouseDown(event:MouseEvent):void {
    if (_selectionArea != null) {
        removeChild(_selectionArea);
    }
    _selection.graphics.clear();

    _selectionArea = new Shape();
    addChild(_selectionArea);
    _selectionStart = new Point(mouseX, mouseY);
    addEventListener(Event.ENTER_FRAME, enterFrame);
}

private function mouseUp(event:MouseEvent):void {
    for (var i:int = 0; i < _graph.points.length; i++) {
        if (_selectionArea.hitTestObject(_graph.points[i])) {
            addSelection(_graph.points[i]);
        }
    }

    removeChild(_selectionArea);
    removeEventListener(Event.ENTER_FRAME, enterFrame);
    _selectionArea = null;
}

The listener attached to the "enter frame" event needs to be implemented:

private function enterFrame(event:Event):void {
    var g:Graphics = _selectionArea.graphics;
    g.clear();
    g.lineStyle(1, 0x555555);
    g.moveTo(_selectionStart.x, _selectionStart.y);
    g.lineTo(mouseX, _selectionStart.y);
    g.lineTo(mouseX, mouseY);
    g.lineTo(_selectionStart.x, mouseY);
    g.lineTo(_selectionStart.x, _selectionStart.y);	}

And last but not least, we use a small helper method to show which elements were selected:

private function addSelection(pgp:PointGraphPoint):void {
    _selection.graphics.beginFill(0x888888, .5);
    _selection.graphics.drawCircle(pgp.x, pgp.y, 7);
    _selection.graphics.endFill();

    trace("Selected " + pgp.message);
}

How it works...

To completely understand everything that is happening, it's important to know what the variables we introduced are for:

  • _selection: This variable contains the circles we draw to mark that the items are selected. This is an overlay that we use to indicate the selection. It's also the first thing that gets cleared and removed when the selection is cleared.
  • _selectionArea: This is the shape that will display the box around the area during the selection process. It is only visible while the user is dragging the mouse.
  • _selectionStart: This is the starting point of the selection. We keep this to be able to draw the area.

In this recipe, we use a technique that is commonly used when implementing drag gestures:

  • In the mouse down listener, a new event listener is attached to the "enter frame" event.
  • In the mouse up listener, this event listener is removed.
  • The "enter frame" listener is called every time Flash refreshes the image. This listener is responsible for continuously updating the rectangle that shows the selection the user is making.

In the mouse up listener, we check all the graph points and verify whether or not they lie inside the selection. We use the ActionScript hitTestObject method for this, but we could just as well have compared the coordinates of both objects (although the code would have been a bit longer).

The addSelection function shown here is just an example of what you can do with the selection. In this case, it just draws a gray transparent circle over the points to show the selection. And it prints the message associated with that data point.

There's more...

Depending on how you are going to use the selection, you may want to consider a few alternatives and extensions.

Selection by clicking

If you only want to select individual points, it's a lot easier to just use the mouse click listener. There's no need for the mouse down or mouse up code that was shown here.

Drawing selected items

In the previous recipe, the highlight to indicate the selection is drawn on top of the image, completely separate from the points in the chart. This has the advantage of being the most flexible solution.

However, if you have different shapes of points you may run into a few issues. A possibility is to extend the PointGraphPoint class and add a setSelected method that controls how the point is drawn when selected.

Adding to and removing from a selection

Many applications that allow for selecting multiple items, also allow you to add and remove items from the selection by pressing Ctrl or Shift while making a selection.

Implementing this can be done fairly and easily by using the controlKey and shiftKey properties of the mouse event. You can check these properties in the mouse up or down listeners and change your actions accordingly.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.44.23