## ScatterPlotModel: Plot Markers

A ScatterPlotModel can modify plot markers by

- assigning a MarkerStyle to the markers
- hiding the markers

As an alternative to using these techniques for changing plot markers, a variable role in a ScatterPlotTableDataModel can be used to control the markers according to the values of a data column in the graph's data source.

### Assigning a MarkerStyle

To use the MarkerStyle class to set plot marker attributes (color, visibility, symbol, size),

1. create a MarkerStyle array with the desired properties
2. call the ScatterPlotModel's getDataElementStyles() method to retrieve the DataElementStyles that encapsulate the visual properties of the plot markers
3. call the DataElementStyles' setMarkerStyles() method to assign the defined MarkerStyle to the plot.

For example, the following code fragment specifies a filled square as the marker shape:

    ScatterPlotModel graphModel=scatterPlot.getGraphModel();
    MarkerStyle[] markerStyle=new MarkerStyle[] {
                  new MarkerStyle(MarkerStyle.SYMBOL_SQUARE_FILLED)};
    graphModel.getDataElementStyles().setMarkerStyles(markerStyle);

Example
Changing Markers in a Scatter Plot: Swing-based code, Servlet-based code

### Hiding Plot Markers

To hide plot markers, call the ScatterPlotModel's setMarkerEnabled() method with the argument value false.

## ScatterPlotModel: Display Properties

In addition to changing the markers, the ScatterPlotModel can be used to change other general display properties, as shown in the following example.

    ScatterPlot scatterPlot = new ScatterPlot();
    ScatterPlotModel scatterPlotModel = scatterPlot.getGraphModel();

    // Set interplations enabled so that data points are connected to each other.
       scatterPlotModel.setInterpolationEnabled(true);

    // Define a new set of marker styles and set their symbols to
    // [filled square, filled circle, filled triangle]
    // and colors to [red, blue, green].
       com.sas.graphics.components.MarkerStyle[] markerStyles = new MarkerStyle[] {
           new MarkerStyle(MarkerStyle.SYMBOL_SQUARE_FILLED),
           new MarkerStyle(MarkerStyle.SYMBOL_CIRCLE_FILLED),
           new MarkerStyle(MarkerStyle.SYMBOL_TRIANGLE_FILLED)};
       markerStyles[0].setColor(java.awt.Color.red);
       markerStyles[1].setColor(java.awt.Color.green);
       markerStyles[2].setColor(java.awt.Color.blue);

       scatterPlotModel.getDataElementStyles().setMarkerStyles(markerStyles);

    // set the y-axis value text color to red
       scatterPlotModel.getYAxisModel().getValueTextStyle().setColor(Color.red);

Here is a more complex example using a data set with error columns:

    ScatterPlot linePlot = new ScatterPlot();
    ScatterPlotModel scatterPlotModel =scatterPlot.getGraphModel();
    scatterPlotModel.setMatchErrorColor(false);

    // Define the errorLineStyles
       StrokeLineStyle[] lineStyles = new StrokeLineStyle[] {
          new StrokeLineStyle(new BasicStroke(2), Color.yellow)} // Yellow for LeftError
        , new StrokeLineStyle(new BasicStroke(3), Color.blue)}   // Blue for the RightError
        , new StrokeLineStyle(new BasicStroke(3), Color.red)}    // Red for UpError
        , new StrokeLineStyle(new BasicStroke(3), Color.green)}  // Green for DownError
       };
    // Set the errorLineStyles in the dataElementStyles
       scatterPlotModel.getDataElementStyles().setErrorLineStyles(lineStyles);

    // Define the errorMarkerStyles:
       MarkerStyle[] markerStyles = new MarkerStyle[] {
          new MarkerStyle(MarkerStyle.SYMBOL_TRIANGLE_LEFT_BOLD, Color.yellow)} // Yellow for LeftError
        , new MarkerStyleMarkerStyle.SYMBOL_TRIANGLE_RIGHT_BOLD, Color.blue)}   // Blue for the RightError
        , new MarkerStyle(MarkerStyle.SYMBOL_TRIANGLE_BOLD, Color.red)}         // Red for UpError
        , new MarkerStyle(MarkerStyle.SYMBOL_TRIANGLE_DOWN_BOLD, Color.green)}  // Green for DownError
       };
    // Set the errorMarkerStyles in the dataElementStyles
       scatterPlotModel.getDataElementStyles().setErrorMarkerStyles(markerStyles);

Rather than changing individual properties, it may be easier to use the ScatterPlot to set a graph style, which makes it easier to manage multiple display properties.

## ScatterPlotModel: Interpolation Lines

By default for a ScatterPlotModel, plot markers are displayed but the plot points are not connected by an interpolated line. To connect plot points with an interpolated line, call the ScatterPlotModel's setInterpolationEnabled() method with the argument value true.

To set an interpolation method for plot points, use the plot's DataElementStyles to get the array of MarkerStyles, and then use a MarkerStyle element to set an interpolation value on the setInterpolation() method.

The following code fragments interpolates vertical needles for the plot points:

    ScatterPlotModel graphModel=scatterPlot.getGraphModel();
    graphModel.setInterpolationEnabled(true);
    DataElementStyles des=graphModel.getDataElementStyles();
    MarkerStyle[] markerStyles=des.getMarkerStyles();
    markerStyles[0].setInterpolation(MarkerStyle.INTERPOLATION_VERTICAL_NEEDLES);

Example
Interpolate Plot Lines: Swing-based code

## ScatterPlotModel: Line Styles

A ScatterPlotModel can be used to modify the line style (color, width, visibility, ...) of any of the various lines in a ScatterPlot.

The following table shows the lines you can set and the method(s) to call to access and/or set the line attributes.

To change ... | Call ...
--- | ---
marker outlines | getDataElementStyles().setOutlineLineStyle(LineStyle)
plot line(s) | getDataElementStyles().setLineStyles(StrokeLineStyle[] )
needle lines | setNeedleLineStyle(LineStyle)
X axis lines (axis, grid, tick, and reference lines) | getXAxisModel() and use the returned AxisModel to set axis line style, grid line styles, major tick styles, minor tick styles, and reference line models
Y (left) axis lines (axis, grid, tick, and reference lines) | getYAxisModel() and use the returned AxisModel to set axis line style, grid line styles, major tick styles, minor tick styles, and reference line models
Y2 (right) axis lines (axis, grid, tick, and reference lines) | getY2AxisModel() and use the returned AxisModel to set axis line style, grid line styles, major tick styles, minor tick styles, and reference line models
legend frame | getColorLegendModel().setFrameLineStyle(LineStyle)
missing-values lines | getDataElementStyles().setMissingLineStyle(StrokeLineStyle)
error-value lines | getDataElementStyles().setErrorLineStyles(StrokeLineStyle[] )
column axis lines (available when ColumnVariable role is used) | getColumnAxisModel().setFrameLineStyle(LineStyle)
row axis lines (available when RowVariable role is used) | getRowAxisModel().setFrameLineStyle(LineStyle)
frame lines around column/row cells (available when ColumnVariable and/or RowVariable roles are used) | setFrameLineStyle(LineStyle)

The following code fragment specifies 3-point red lines for a plot's needle lines:

    ScatterPlotModel graphModel=scatterPlot.getGraphModel();

    LineStyle lineStyle = new LineStyle(
              Color.red,
              new BaseLength(3, "pt"),
              GraphConstants.TRUE);

    graphModel.setNeedleLineStyle(lineStyle);

Example
Change the Needle Lines: Swing-based code, Servlet-based code
Change the Axis Lines: Swing-based code

## ScatterPlotModel: Filled Areas

When the specifications on the data model generate multiple plot lines, the areas between the lines can be filled by calling the ScatterPlotModel's setFillAreaEnabled() method with the argument value true.

A unique FillStyle is used to fill the area under each plot. To change the fill styles, use the plot's DataElementStyles to set an alternative FillStyle array. The following code fragment creates transparent fills and then assigns them to the plot areas:

    ScatterPlotModel graphModel=scatterPlot.getGraphModel();
    graphModel.setFillAreaEnabled(true);

    // Creates new FillStyles. The fourth argument on the
    // java.awt.Color constructors is the transparency level
    FillStyle[] transparencies=new FillStyle[] {
      new FillStyle(new Color(204,0,102,100) ),    // red transparency
      new FillStyle(new Color(102,153,102,100) ),  // green transparency
      new FillStyle(new Color(51,102,255,100) ) }; // blue transparency

    // Assign the fills to the plot's areas (data elements)
    graphModel.getDataElementStyles().setFillStyles(transparencies);

You can influence the order in which the filled areas are painted to the screen, depending on how the multiple plots are generated.

- If the multiple plots are generated because the data model specifies multiple response variables, then the order that the variables are specified on the VariableList is the order that they are painted to the screen. To change the paint order, change the order that the variables are specified on the VariableList.
- If the multiple plots are generated because the data model specifies a GroupVariable role, then the order that the group values are sorted on the ClassificationVariable is the order that they are painted to the screen. To change the paint order, change the ClassificationVariable's sort order.

If changing the paint order does not provide a satisfactory display of the plot areas, try defining transparent fills for the areas, as shown by the code above.

Example
Filling Plot Areas: Swing-based code

## ScatterPlotModel: Behavior

ScatterPlotModel properties are bound properties. Modifying a property triggers a PropertyChangeEvent. The ScatterPlot asynchronously updates when a PropertyChangeEvent is received from the ScatterPlotModel. Similarly, modifying a property in any of the ScatterPlotModel's contained models triggers a PropertyChangeEvent. A PropertyChangeEvent from contained models will bubble up to cause a PropertyChangeEvent to be fired from the ScatterPlotModel.

For example, the following call

    scatterPlotModel.getColorLegendModel().getValueTextStyle().setColor(java.awt.Color.yellow);

would cause the legend's value text style model to fire a "color" PropertyChangeEvent, causing legend model to fire a "valueTextStyle" PropertyChangeEvent, causing the ScatterPlotModel to fire a "colorLegendModel" PropertyChangeEvent. This bubbling up of events enables the graph or any other listener to manage updates at a higher level of containment.