Package org.adoptopenjdk.jitwatch.ui.graphing

Source Code of org.adoptopenjdk.jitwatch.ui.graphing.SceneResizeListener

/*
* Copyright (c) 2013, 2014 Chris Newland.
* Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD
* Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki
*/
package org.adoptopenjdk.jitwatch.ui.graphing;

import org.adoptopenjdk.jitwatch.ui.JITWatchUI;
import org.adoptopenjdk.jitwatch.util.StringUtil;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;

public abstract class AbstractGraphStage extends Stage
{
  protected Canvas canvas;
  protected GraphicsContext gc;
  protected JITWatchUI parent;

  protected static double graphGapLeft = 20.5;
  protected static final double graphGapRight = 20.5;
  protected static final double graphGapTop = 20.5;

  protected static final int[] Y_SCALE = new int[21];

  protected double width;
  protected double height;
  protected double chartWidth;
  protected double chartHeight;

  protected long minX;
  protected long maxX;
  protected long minY;
  protected long maxY;
 
  protected long minXQ;
  protected long maxXQ;
  protected long minYQ;
  protected long maxYQ;

  private boolean xAxisTime = false;

  static
  {
    int multiplier = 1;

    for (int i = 0; i < Y_SCALE.length; i += 3)
    {
      Y_SCALE[i + 0] = 1 * multiplier;
      Y_SCALE[i + 1] = 2 * multiplier;
      Y_SCALE[i + 2] = 5 * multiplier;

      multiplier *= 10;
    }
  }

  public AbstractGraphStage(final JITWatchUI parent, int width, int height, boolean xAxisTime)
  {
    this.parent = parent;
    this.width = width;
    this.height = height;
    this.xAxisTime = xAxisTime;

    canvas = new Canvas(width, height);
    gc = canvas.getGraphicsContext2D();

    initStyle(StageStyle.DECORATED);

    setOnCloseRequest(new EventHandler<WindowEvent>()
    {
      @Override
      public void handle(WindowEvent arg0)
      {
        parent.handleStageClosed(AbstractGraphStage.this);
      }
    });

    class SceneResizeListener implements ChangeListener<Number>
    {
      @Override
      public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2)
      {
        redraw();
      }
    }

    SceneResizeListener rl = new SceneResizeListener();

    canvas.widthProperty().addListener(rl);
    canvas.heightProperty().addListener(rl);
  }

  public abstract void redraw();

  protected void baseRedraw()
  {
    width = canvas.getWidth();
    height = canvas.getHeight();
    chartWidth = width - graphGapLeft - graphGapRight;
    chartHeight = height - graphGapTop * 2;

    gc.setFill(Color.WHITE);
    gc.fillRect(0, 0, width, height);
    gc.setFill(Color.rgb(210, 255, 255));
    gc.fillRect(graphGapLeft, graphGapTop, chartWidth, chartHeight);
    gc.setStroke(Color.BLACK);
    gc.strokeRect(graphGapLeft, graphGapTop, chartWidth, chartHeight);
  }

  protected void drawAxes()
  {   
    if (xAxisTime)
    {
      drawXAxisTime();
    }
    else
    {
      drawXAxis();
    }

    drawYAxis();
  }
 
  private void drawXAxisTime()
  {
    long xInc = getXStepTime();
   
    minXQ = (minX / xInc) * xInc;

    maxXQ =  (1 + (maxX / xInc)) * xInc;

    long gridX = minXQ;

    while (gridX <= maxX)
    {
      double x = graphGapLeft + normaliseX(gridX);
      gc.strokeLine(fix(x), fix(graphGapTop), fix(x), fix(graphGapTop + chartHeight));

      boolean showMillis = maxX  < 5000;
     
      gc.strokeText(StringUtil.formatTimestamp(gridX, showMillis), fix(x), fix(graphGapTop + chartHeight + 12));

      gridX += xInc;
    }
  }

  private void drawXAxis()
  {
    long xInc = findScale(maxX - minX);

    minXQ = (minX / xInc) * xInc;

    maxXQ =  (1 + (maxX / xInc)) * xInc;
   
    long gridX = minXQ;

    while (gridX <= maxX)
    {
      double x = graphGapLeft + normaliseX(gridX);
      gc.strokeLine(fix(x), fix(graphGapTop), fix(x), fix(graphGapTop + chartHeight));
      gc.strokeText(StringUtil.formatThousands(Long.toString(gridX)), fix(x), fix(graphGapTop + chartHeight + 12));

      gridX += xInc;
    }
  }

  private void drawYAxis()
  {
    long yInc = findScale(maxY - minY);

    minYQ = (minY / yInc) * yInc;

    maxYQ =  (1 + (maxY / yInc)) * yInc;
   
    long gridY = minYQ;

    int maxYLabelWidth = StringUtil.formatThousands(Long.toString(maxYQ)).length();

    graphGapLeft = Math.max(40.5, maxYLabelWidth*7);
   
    double yLabelX = graphGapLeft - (1 + maxYLabelWidth) * 6;

    while (gridY <= maxYQ)
    {
      if (gridY >= minYQ)
      {
        double y = graphGapTop + normaliseY(gridY);
        gc.strokeLine(fix(graphGapLeft), fix(y), fix(graphGapLeft + chartWidth), fix(y));
        gc.strokeText(StringUtil.formatThousands(Long.toString(gridY)), fix(yLabelX), fix(y + 2));
      }

      gridY += yInc;
    }
  }

  private long getXStepTime()
  {
    long rangeMillis = maxX - minX;
   
    int requiredLines = 5;

    long[] gapMillis = new long[] { 30 * 24 * 60 * 60000, 14 * 24 * 60 * 60000, 7 * 24 * 60 * 60000, 4 * 24 * 60 * 60000,
        2 * 24 * 60 * 60000, 24 * 60 * 60000, 16 * 60 * 60000, 12 * 60 * 60000, 8 * 60 * 60000, 6 * 60 * 60000,
        4 * 60 * 60000, 2 * 60 * 60000, 60 * 60000, 30 * 60000, 15 * 60000, 10 * 60000, 5 * 60000, 2 * 60000, 1 * 60000,
        30000, 15000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1 };

    long incrementMillis = 120 * 60000;

    for (int i = 0; i < gapMillis.length; i++)
    {
      if (rangeMillis / gapMillis[i] >= requiredLines)
      {
        incrementMillis = gapMillis[i];
        break;
      }
    }

    return incrementMillis;
  }

  protected long findScale(long range)
  {
    long requiredLines = 8;

    for (int i = 0; i < Y_SCALE.length; i++)
    {
      if (range / Y_SCALE[i] < requiredLines)
      {
        return Y_SCALE[i];
      }
    }

    return range / requiredLines;
  }

  protected double normaliseX(double value)
  {
    return normalise(value, minXQ, maxXQ, chartWidth, false);
  }

  protected double normaliseY(double value)
  {
    return normalise(value, minYQ, maxYQ, chartHeight, true);
  }

  protected double normalise(double value, double min, double max, double size, boolean invert)
  {
    double range = max - min;
    double result = 0;

    if (range == 0)
    {
      result = 0;
    }
    else
    {
      result = (value - min) / range;
    }

    result *= size;

    if (invert)
    {
      result = size - result;
    }

    return result;
  }

  // prevent blurry lines in JavaFX
  protected double fix(double pixel)
  {
    return 0.5 + (int) pixel;
  }
}
TOP

Related Classes of org.adoptopenjdk.jitwatch.ui.graphing.SceneResizeListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.