Rotate the coordinate plane of data and text with Java
I need it:
The following code sets this problem It works except for two problems: 1.) Draw the data point, the upper left corner is the origin, and the y value decreases by 2.) The mark on the y-axis is not drawn on the screen
Anyone can tell me how to fix the following code so that it can fix these two problems and do what is described in the first paragraph above?
The code is in the following two java files:
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<Double> myDiffs = new ArrayList<Double>(); 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 (Note: I edited the following code to include the suggestion of trashgod, but it still doesn't work.)
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<Double> myDiffs; double maxDiff = Double.NEGATIVE_INFINITY; double minDiff = Double.POSITIVE_INFINITY; double maxPlot; DataPanel(ArrayList<Double> 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,blueHeight); //scale the diffs to fit window double Scalar = blueWidth/maxPlot; ArrayList<Double> scaledDiffs = new ArrayList<Double>(); 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;w<scaledDiffs.size();w++){ if(w>0){ 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);//rotate text 90 degrees counter-clockwise g.drawString(yString,-(height/2)-(yStrWidth/2),yStrHeight); g2d.rotate(Math.toradians(+90),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);//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);//rotate text 90 degrees clockwise iteration+=increment; } } void getmaxmindiffs(){// get max and min of Diffs for(int u = 0;u<myDiffs.size();u++){ if(myDiffs.get(u)>maxDiff){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 } }
Also, as always, thank you for links to articles or tutorials on this topic
Solution
A method is displayed in sinetest In summary,
>Saves the transformation of the drawing context
Graphics2D g2d = (Graphics2D) g; AffineTransform at = g2d.getTransform();
>Convert the origin to the center
g2d.translate(w / 2,h / 2);
>Reverse the y-axis
g2d.scale(1,-1);
>Render using Cartesian coordinates. > Restores the transformation of a regular render
g2d.setTransform(at);