plano de coordenadas giratorio para datos y texto en Java

Necesito:
1.) mover el origen y también rotar el plano de coordenadas para que los valores x progresen hacia la derecha y los valores y progresen hacia arriba desde el nuevo origen (que debe ser la esquina inferior izquierda del rectángulo azul interior en el código siguiente). Esto me permitirá trazar puntos en los pares de coordenadas x, y en el siguiente código.
2.) trazar tags giradas para las marcas de tic en el eje y de la gráfica de datos.

El código a continuación configura este problema. Funciona, a excepción de dos problemas:
1.) los puntos de datos se trazan con la esquina superior izquierda como el origen y los valores y descendiendo hacia abajo
2.) las tags para las marcas de tic en el eje y no se dibujan en la pantalla

¿Alguien puede mostrarme cómo corregir el código a continuación para que solucione estos dos problemas y haga lo que describe el primer párrafo?

El código está en los siguientes dos archivos java:

DataGUI.java

import java.awt.*; import java.util.ArrayList; import javax.swing.*; class DataGUI extends JFrame{ DataGUI() { super("X,Y Plot"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setPreferredSize(new Dimension(800, 400)); this.pack(); this.setSize(new Dimension(800, 600)); this.setLocationRelativeTo(null); setLayout(new GridLayout()); ArrayList myDiffs = new ArrayList(); myDiffs.add(25.0); myDiffs.add(9.0); myDiffs.add(7.0); myDiffs.add(16.0); myDiffs.add(15.0); myDiffs.add(6.0); myDiffs.add(2.0); myDiffs.add(8.0); myDiffs.add(2.0); myDiffs.add(27.0); myDiffs.add(14.0); myDiffs.add(12.0); myDiffs.add(19.0); myDiffs.add(10.0); myDiffs.add(11.0); myDiffs.add(8.0); myDiffs.add(19.0); myDiffs.add(2.0); myDiffs.add(16.0); myDiffs.add(5.0); myDiffs.add(18.0); myDiffs.add(23.0); myDiffs.add(9.0); myDiffs.add(4.0); myDiffs.add(8.0); myDiffs.add(9.0); myDiffs.add(3.0); myDiffs.add(3.0); myDiffs.add(9.0); myDiffs.add(13.0); myDiffs.add(17.0); myDiffs.add(7.0); myDiffs.add(0.0); myDiffs.add(2.0); myDiffs.add(3.0); myDiffs.add(33.0); myDiffs.add(23.0); myDiffs.add(26.0); myDiffs.add(12.0); myDiffs.add(12.0); myDiffs.add(19.0); myDiffs.add(14.0); myDiffs.add(9.0); myDiffs.add(26.0); myDiffs.add(24.0); myDiffs.add(13.0); myDiffs.add(19.0); myDiffs.add(2.0); myDiffs.add(7.0); myDiffs.add(28.0); myDiffs.add(15.0); myDiffs.add(2.0); myDiffs.add(5.0); myDiffs.add(17.0); myDiffs.add(2.0); myDiffs.add(16.0); myDiffs.add(19.0); myDiffs.add(2.0); myDiffs.add(31.0); DataPanel myPP = new DataPanel(myDiffs,this.getHeight(),this.getWidth()); this.add(myPP); this.setVisible(true);// Display the panel. } public static void main(String[] args){ DataGUI myDataGUI = new DataGUI(); myDataGUI.setVisible(true); } } 

DataPanel.java (Nota: edité el código a continuación para incluir las sugerencias de trashgod, pero todavía no funciona).

 import java.awt.*; import java.awt.geom.AffineTransform; import javax.swing.*; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.*; class DataPanel extends JPanel { Insets ins; // holds the panel's insets ArrayList myDiffs; double maxDiff = Double.NEGATIVE_INFINITY; double minDiff = Double.POSITIVE_INFINITY; double maxPlot; DataPanel(ArrayList Diffs, int h, int w){ setOpaque(true);// Ensure that panel is opaque. setPreferredSize(new Dimension(w, h)); setMinimumSize(new Dimension(w, h)); setMaximumSize(new Dimension(w, h)); myDiffs = Diffs; repaint(); this.setVisible(true); } protected void paintComponent(Graphics g){// Override paintComponent() method. super.paintComponent(g); //get data about plotting environment and about text int height = getHeight(); int width = getWidth(); ins = getInsets(); Graphics2D g2d = (Graphics2D)g; FontMetrics fontMetrics = g2d.getFontMetrics(); String xString = ("x-axis label"); int xStrWidth = fontMetrics.stringWidth(xString); int xStrHeight = fontMetrics.getHeight(); String yString = "y-axis label"; int yStrWidth = fontMetrics.stringWidth(yString); int yStrHeight = fontMetrics.getHeight(); String titleString ="Title of Graphic"; int titleStrWidth = fontMetrics.stringWidth(titleString); int titleStrHeight = fontMetrics.getHeight(); int leftMargin = ins.left; //set parameters for inner rectangle int hPad=10; int vPad = 6; int testLeftStartPlotWindow = ins.left+5+(3*yStrHeight); int testInnerWidth = width-testLeftStartPlotWindow-ins.right-hPad; getMaxMinDiffs(); getMaxPlotVal(); double increment = 5.0; int numTicks = (int)(maxPlot/increment);//will use numTicks for: remainder, leftStartPlotWindow, innerRectangle+labels+tickmarks int remainder = testInnerWidth%numTicks; int leftStartPlotWindow = testLeftStartPlotWindow-remainder; System.out.println("remainder is: "+remainder); int bottomPad = (3*xStrHeight)-vPad; int blueTop = ins.bottom+(vPad/2)+titleStrHeight; int blueHeight = height-bottomPad-blueTop; int blueWidth = blueHeight; int blueBottom = blueHeight+blueTop; //plot outer rectangle g.setColor(Color.red); int redWidth = width-leftMargin-1; g.drawRect(leftMargin, ins.bottom, redWidth, height-ins.bottom-1); //write top label g.setColor(Color.black); g.drawString(titleString, leftStartPlotWindow+((blueWidth/2)-(titleStrWidth/2)), titleStrHeight); // fill, then plot, inner rectangle g.setColor(Color.white); g.fillRect(leftStartPlotWindow, blueTop, blueWidth, blueHeight); g.setColor(Color.blue); g.drawRect(leftStartPlotWindow, blueTop, blueWidth, blueHeight); //scale the diffs to fit window double Scalar = blueWidth/maxPlot; ArrayList scaledDiffs = new ArrayList(); for(int e = 0;e<myDiffs.size();e++){scaledDiffs.add(myDiffs.get(e)*Scalar);} //plot the scaled Diffs AffineTransform at = g2d.getTransform();//save the graphics context's transform g2d.translate(leftStartPlotWindow, blueTop);//translate origin to bottom-left corner of blue rectangle g2d.scale(1, -1);//invert the y-axis for(int w = 0;w0){ double prior = scaledDiffs.get(w-1); int priorInt = (int)prior; double current = scaledDiffs.get(w); int currentInt = (int)current; g2d.drawOval(priorInt, currentInt, 4, 4); } } g2d.setTransform(at);//restre the transform for conventional rendering //write x-axis label g.setColor(Color.red); g.drawString(xString, leftStartPlotWindow+((blueWidth/2)-(xStrWidth/2)), height-ins.bottom-vPad); //write y-axis label g2d.rotate(Math.toRadians(-90), 0, 0);//rotate text 90 degrees counter-clockwise g.drawString(yString, -(height/2)-(yStrWidth/2), yStrHeight); g2d.rotate(Math.toRadians(+90), 0, 0);//rotate text 90 degrees clockwise // draw tick marks on x-axis NumberFormat formatter = new DecimalFormat("#0.0"); double k = (double)blueWidth/(double)numTicks; double iteration = 0; for(int h=0;h<=numTicks;h++){ int xval = (int)(h*k); g.setColor(Color.red); g.drawLine(leftStartPlotWindow+xval, blueBottom+2, leftStartPlotWindow+xval, blueBottom+(xStrHeight/2));//draw tick marks g.drawString(formatter.format(iteration),leftStartPlotWindow+xval-(fontMetrics.stringWidth(Double.toString(iteration))/2),blueBottom+(xStrHeight/2)+13); iteration+=increment; } // draw tick marks on y-axis iteration = 0; for(int h=0;h<=numTicks;h++){ int yval = (int)(h*k); g.setColor(Color.red); g.drawLine(leftStartPlotWindow-2, blueBottom-yval, leftStartPlotWindow-(yStrHeight/2), blueBottom-yval);//draw tick marks g2d.rotate(Math.toRadians(-90), 0, 0);//rotate text 90 degrees counter-clockwise g.drawString(formatter.format(iteration),leftStartPlotWindow-2,blueBottom-(fontMetrics.stringWidth(Double.toString(iteration))/2)); g2d.rotate(Math.toRadians(+90), 0, 0);//rotate text 90 degrees clockwise iteration+=increment; } } void getMaxMinDiffs(){// get max and min of Diffs for(int u = 0;umaxDiff){maxDiff = myDiffs.get(u);} if(myDiffs.get(u)<minDiff){minDiff = myDiffs.get(u);} } } void getMaxPlotVal(){ maxPlot = maxDiff; maxPlot += 1;//make sure maxPlot is bigger than the max data value while(maxPlot%5!=0){maxPlot+=1;}//make sure maxPlot is a multiple of 5 } } 

Además, como siempre, los enlaces a artículos o tutoriales sobre el tema son muy apreciados.

Un enfoque se muestra en SineTest . En resumen,

  1. Guarde la transformación del contexto de gráficos.

     Graphics2D g2d = (Graphics2D) g; AffineTransform at = g2d.getTransform(); 
  2. Traduzca el origen al centro.

     g2d.translate(w / 2, h / 2); 
  3. Invierta el eje y .

     g2d.scale(1, -1); 
  4. Render usando coordenadas cartesianas.

  5. Restaure la transformación para renderizado convencional.

     g2d.setTransform(at); 

enter image description here

Disculpas por una respuesta algo incompleta, pero esto puede hacer que tus engranajes giren. Java dibuja las cosas de la forma en que las describió: considera que la esquina superior izquierda de la pantalla es 0, 0 y dibuja x aumentando a la derecha ey aumentando hacia abajo. Si haces la línea que indica

 g2d.drawOval(priorInt, currentInt, 4, 4); 

dentro

 g2d.drawOval(blueWidth - priorInt, blueHeight - currentInt, 4, 4); 

debería arrojar los resultados correctos para su primer problema. Sin embargo, necesito un poco más de información sobre el segundo problema para ayudarte con eso. ¿Están fuera de la pantalla o son atraídos por otra cosa? Intente voltear + sy -s alrededor para ver si puede obtener el resultado correcto si ese es el caso.

    Intereting Posts