/**
  * Draws the Legend for the scatter plot
  *
  * @param g {@link Graphics}
  */
 private void drawLegend(Graphics g) {
   // set the color of the legend rectangle
   g.setColor(LEGEND_BACKGROUND);
   int lineHeight = g.getFontMetrics().getHeight() + 2; // height of a legend line
   // draw the legend rectangle
   g.fillRect(
       getWidth() - legendWidth - LENGEND_PAD - (LEGEND_INSET * 2),
       LENGEND_PAD,
       legendWidth + (LEGEND_INSET * 2),
       ((data.size() + 2) * lineHeight) + (LEGEND_INSET * 2));
   g.setColor(Colors.BLACK);
   g.drawRect(
       getWidth() - legendWidth - LENGEND_PAD - (LEGEND_INSET * 2),
       LENGEND_PAD,
       legendWidth + (LEGEND_INSET * 2),
       ((data.size() + 2) * lineHeight) + (LEGEND_INSET * 2));
   // search the position where to start the text of the legend
   Point p =
       new Point(
           getWidth() - legendWidth - LENGEND_PAD - LEGEND_INSET,
           LENGEND_PAD + LEGEND_INSET + g.getFontMetrics().getHeight());
   // draw the axis names
   g.drawString(X_AXIS_PREFIX + xAxis.getName(), p.x, p.y); // draw X-Axis legend
   g.drawString(Y_AXIS_PREFIX + yAxis.getName(), p.x, p.y + lineHeight); // draw Y-Axis legend
   // draw graph name legend
   for (int i = 0; i < data.size(); i++) {
     Color graphColor = data.get(i).getColor();
     String graphName = data.get(i).getName();
     g.setColor(graphColor);
     int yLine = p.y + ((i + 2) * lineHeight); // y position of the current line
     g.drawLine(p.x, yLine - 5, p.x + 25, yLine - 5); // draw a line with the color of the graph
     g.setColor(Colors.BLACK);
     g.drawString(graphName, p.x + 30, yLine); // draw the name of the graph
   }
 }
 /**
  * Method to plot the data points as a curve chart
  *
  * @param g (Graphics)
  */
 private void drawCurveGraphics(Graphics g) {
   for (ScatterPlotData currentScatterPlot : data) {
     g.setColor(currentScatterPlot.getColor());
     for (int j = 0; j < (currentScatterPlot.getData().length - 1); j++) {
       Point current =
           new Point(
               getTranslatedPoint(
                   currentScatterPlot.getData()[j][0], currentScatterPlot.getData()[j][1]));
       Point nexttonext =
           new Point(
               getTranslatedPoint(
                   currentScatterPlot.getData()[j + 1][0],
                   currentScatterPlot.getData()[j + 1][1]));
       g.drawLine(current.x, current.y, nexttonext.x, nexttonext.y);
       if ((currentScatterPlot.getData()[j][0] < xAxis.getMin())
           || (currentScatterPlot.getData()[j][0] > xAxis.getMax())
           || (currentScatterPlot.getData()[j + 1][1] <= yAxis.getMax())) {
         // we erase the part of the line that is not in the chart area
         // this means that the curve needs to be drawn before the axis and ticks and legend
         g.setColor(getBackground());
         g.fillRect(0, 0, getWidth(), PAD);
         g.fillRect(0, getHeight() - PAD, getWidth(), PAD);
         g.setColor(currentScatterPlot.getColor());
       }
     }
   }
 }
 /**
  * Method to translate the coordinates of the data point to the point on screen
  *
  * @param x x component of a data point
  * @param y y component of a data point
  * @return Point
  */
 private Point getTranslatedPoint(double x, double y) {
   Point translatedPoint = new Point();
   int realWidth = getWidth() - (2 * PAD);
   int realHeight = getHeight() - (2 * PAD);
   Rectangle clip = new Rectangle(PAD, PAD, realWidth, realHeight);
   translatedPoint.x = xAxis.dataValueToScreenPosition(x, clip);
   translatedPoint.y = yAxis.dataValueToScreenPosition(y, clip);
   return translatedPoint;
 }
 /** @return the width of the legend text in pixels */
 private int computeLegendWidth() {
   FontMetrics fm = getFontMetrics(getFont());
   int legendWidth = fm.stringWidth(X_AXIS_PREFIX + xAxis.getName());
   legendWidth = Math.max(legendWidth, fm.stringWidth(Y_AXIS_PREFIX + yAxis.getName()));
   for (ScatterPlotData currentPlot : data) {
     if (data != null) {
       legendWidth = Math.max(legendWidth, fm.stringWidth(currentPlot.getName()) + 30);
     }
   }
   return legendWidth;
 }
 /**
  * Method to plot the data points as a point chart
  *
  * @param g (Graphics)
  */
 private void drawPointGraphics(Graphics g) {
   for (ScatterPlotData currentScatterPlot : data) {
     g.setColor(currentScatterPlot.getColor());
     for (int j = 0; j < (currentScatterPlot.getData().length - 1); j++) {
       Point current =
           new Point(
               getTranslatedPoint(
                   currentScatterPlot.getData()[j][0], currentScatterPlot.getData()[j][1]));
       Point next =
           new Point(
               getTranslatedPoint(
                   currentScatterPlot.getData()[j + 1][0], currentScatterPlot.getData()[j][1]));
       if ((currentScatterPlot.getData()[j][0] >= xAxis.getMin())
           && (currentScatterPlot.getData()[j][0] <= xAxis.getMax())
           && (currentScatterPlot.getData()[j][1] >= yAxis.getMin())
           && (currentScatterPlot.getData()[j][1] <= yAxis.getMax())) {
         g.drawLine(current.x, current.y, next.x, next.y);
       }
     }
   }
 }
 /**
  * @param screenPoint {@link Point} of a screen position
  * @return original data Point corresponding to the specified screen position
  */
 private Point2D getDataPoint(Point screenPoint) {
   Point2D.Double retPoint = new Point2D.Double();
   retPoint.x =
       (((screenPoint.x - PAD) * (xAxis.getMax() - xAxis.getMin())) / (getWidth() - (2 * PAD)))
           + xAxis.getMin();
   retPoint.y =
       (-1
               * ((((screenPoint.y - getHeight()) + PAD) * (yAxis.getMax() - yAxis.getMin()))
                   / (getHeight() - (2 * PAD))))
           + yAxis.getMin();
   return retPoint;
 }
 @Override
 public void paint(Graphics g) {
   super.paint(g);
   // set where inside the dialog, the chart needs to be drawn
   Rectangle clip = new Rectangle(PAD, PAD, getWidth() - (2 * PAD), getHeight() - (2 * PAD));
   // draw the background of the chart
   drawChartBackground(g, clip);
   // set the position of the axis in case they moved
   if (yAxis.isLogScale()) {
     xAxis.setPosition(yAxis.dataValueToScreenPosition(1, clip));
   } else {
     xAxis.setPosition(yAxis.dataValueToScreenPosition(0, clip));
   }
   if (xAxis.isLogScale()) {
     yAxis.setPosition(xAxis.dataValueToScreenPosition(1, clip));
   } else {
     yAxis.setPosition(xAxis.dataValueToScreenPosition(0, clip));
   }
   // draw the grid
   xAxis.drawGrid(g, clip);
   yAxis.drawGrid(g, clip);
   // draw the curve
   drawGraphics(g, clip, chartType);
   // draw the axis
   xAxis.drawAxis(g, clip);
   yAxis.drawAxis(g, clip);
   // draw minor units
   xAxis.drawMinorUnit(g, clip);
   yAxis.drawMinorUnit(g, clip);
   // draw major units
   xAxis.drawMajorUnit(g, clip);
   yAxis.drawMajorUnit(g, clip);
   // draw the chart legend
   drawLegend(g);
 }