piano di coordinate rotanti per dati e testo in Java

Ho bisogno di:
1.) spostare l’origine e ruotare anche il piano delle coordinate in modo che i valori x avanzino verso destra e i valori y avanzino verso l’alto dalla nuova origine (che deve essere l’angolo in basso a sinistra del rettangolo interno, blu nel codice sottostante). Questo mi consentirà di tracciare punti in coppie di coordinate x, y nel codice qui sotto.
2.) traccia le etichette ruotate per i segni di graduazione sull’asse y del grafico dei dati.

Il seguente codice imposta questo problema. Funziona, tranne per due problemi:
1.) i punti dati vengono tracciati con l’angolo in alto a sinistra come valori di origine e y discendenti verso il basso
2.) le etichette per i segni di tic sull’asse y non vengono disegnate sullo schermo

Qualcuno può mostrarmi come risolvere il codice qui sotto in modo che corregge questi due problemi e fa ciò che descrive il primo paragrafo sopra?

Il codice è nei seguenti due file 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: ho modificato il codice qui sotto per includere i suggerimenti di trashgod, ma non funziona ancora.)

 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);//restore 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 } } 

Inoltre, come sempre, i link ad articoli o tutorial sull’argomento sono molto apprezzati.

Un approccio è mostrato in SineTest . In linea generale,

  1. Salva la trasformazione del contesto grafico.

     Graphics2D g2d = (Graphics2D) g; AffineTransform at = g2d.getTransform(); 
  2. Tradurre l’origine al centro.

     g2d.translate(w / 2, h / 2); 
  3. Invertire l’asse y .

     g2d.scale(1, -1); 
  4. Rendering mediante coordinate cartesiane.

  5. Ripristina la trasformazione per il rendering convenzionale.

     g2d.setTransform(at); 

inserisci la descrizione dell'immagine qui

Ci scusiamo per una risposta un po ‘incompleta, ma questo potrebbe far girare il tuo ingranaggio. Java disegna le cose come le hai descritte: considera l’angolo in alto a sinistra dello schermo come 0, 0 e disegna x crescente verso destra e y crescente verso il basso. Se fai la linea che dice

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

in

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

dovrebbe produrre i risultati corretti per il tuo primo numero. Ho bisogno di qualche informazione in più sul secondo problema per aiutarti con quello. Sono appena fuori dallo schermo o sono attratti da qualcos’altro? Prova a girare + se e -s in giro per vedere se riesci a ottenere il risultato corretto, se così fosse.