2011-12-20 163 views
3

下面的代码绘制了一些简单的x-y数据,但它有两个问题,我不知道如何解决。x-y坐标轴和标签的旋转文本

首先,它绘制了一些数据点的负值,这意味着在x轴下向南延伸的线。由于数据点是随机选择的,因此您可能需要稍微调整一下框架的大小,以查看以显示此错误的方式绘制的新随机数。所有的数据值都是正值,所以我希望所有的偏差都能在蓝色底部标记线以上向北投影,并且我需要确保没有偏差向南延伸到蓝色底部标记线以下。

其次,y轴标签在屏幕上占用太多空间。它需要旋转-90度。但是,我所看到的所有示例都涉及使用graphics2d对象旋转整个面板。我不想旋转整个面板。相反,我只是想旋转y轴标签的文字。

任何人都可以告诉我如何更改下面的代码来解决这两个具体问题?

的代码在以下两个文件:

GUI.java

import java.awt.*; 
import javax.swing.*; 

class GUI{ 

GUI() { 
    // Create a new JFrame container. 
    JFrame jfrm = new JFrame("X-Y Plot"); 
    // Specify FlowLayout for the layout manager. 
    jfrm.getContentPane().setLayout(new FlowLayout()); 
    int frameHeight = 400; 
    int frameWidth = 300; 
    // Give the frame an initial size. 
    jfrm.setSize(frameWidth, frameHeight); 

    // Terminate the program when the user closes the application. 
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    // Create a text-based label. 
    JVertLabel myVLabel = new JVertLabel("y-axis label"); 
    int width = myVLabel.WIDTH; 

    PaintPanel myPP = new PaintPanel(frameWidth-width-50-20,frameHeight-70); 
    jfrm.add(myPP); 

    jfrm.add(myVLabel);// Add the label to the frame. 

    // Display the frame. 
    jfrm.setVisible(true); 
} 

public static void main(String args[]) { 
    // Create the frame on the event dispatching thread. 
    SwingUtilities.invokeLater(new Runnable() {public void run(){new GUI();}}); 
} 

    public class JVertLabel extends JComponent { 

     private String text; 

     public JVertLabel(String s) { 
      text = s; 
     }//constructor 

     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 
      g2d.rotate(Math.toRadians(-90)); 
      g2d.drawString(text, 0, 0); 
     } 
    } 
} 

PaintPanel.java

import java.awt.*; 
import javax.swing.*; 
import java.util.*; 

class PaintPanel extends JPanel { 

    Insets ins; // holds the panel's insets 
    Random rand; // used to generate random numbers 

    PaintPanel(int w, int h) { 
     setOpaque(true);// Ensure that panel is opaque. 
     setPreferredSize(new Dimension(w, h));// Set preferred dimension as specfied. 
     rand = new Random(); 
    } 

    protected void paintComponent(Graphics g) {// Override paintComponent() method. 
     super.paintComponent(g);// Always call superclass method first. 
     int height = getHeight();// Get height of component. 
     int width = getWidth();// Get width of component. 
     ins = getInsets();// Get the insets. 
     // Get dimensions of text 
     Graphics2D g2d = (Graphics2D) g; 
     Font font = new Font("Serif", Font.PLAIN, 12); 
     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(); 
     int leftStartPlotWindow = ins.left + 5 + yStrWidth; 
     int hPad = 3; 

     // Fill panel by plotting random data in a bar graph. 
     for (int i = leftStartPlotWindow + hPad; i <= width - leftStartPlotWindow - hPad + yStrWidth + 1; i += 4) { 
      int h = Math.abs(rand.nextInt(height - ins.bottom));//Get rand# betw/0 and max height of drawing area. 
      // If generated value w/in or too close to border, change it to just outside border. 
      if (h <= ins.top) { 
       h = ins.top + 1; 
      } 
      g.drawLine(i, Math.abs(height - ins.bottom - xStrHeight - 5), i, h);// Draw a line that represents data. 
     } 
     g.setColor(Color.blue); 
     g.drawRect(leftStartPlotWindow, ins.bottom + 2, width - leftStartPlotWindow - ins.right - hPad, height - xStrHeight - 6); 
     g.setColor(Color.red); 
     g.drawRect(ins.left, ins.bottom, width - ins.left - 1, height - ins.bottom - 1); 
     g.drawString(xString, (width/2) - (xStrWidth/2), height - ins.bottom - 6); 
     g.drawString(yString, ins.left, height/2); 
    } 
} 
+0

+1 [sscce](http://sscce.org/)。 – trashgod 2011-12-20 03:53:43

回答

3

所有数据值都将是积极的,所以我希望所有的挠度项目向北上述蓝底标记线,我需要确保没有变形向南延伸的下方底部的蓝色标记线。

您需要计算随机高度,以便所有值都适合可用空间。所以计算会是这样的:

int randomHeight = panelHeight - offset.top - offset.bottom - heightForTheXAxisText; 

然后,你不必担心负值或面板边界外的延伸线的顶部。

我所见过的所有例子都涉及到使用graphics2d对象旋转整个面板。我不想旋转整个面板。相反,我只是想旋转y轴标签的文字。

图形集的旋转反对,绘制文本,然后恢复图形的旋转对象返回0。

或者,您从图形对象的当前创建一个新的Graphcis对象,然后应用旋转,绘制文本,然后处理临时图形对象。

+0

+1正确回答我的问题。 – CodeMed 2011-12-20 05:34:59

2

JFreeChart默认地址这两个问题,在本example所示。

在你的榜样,

  1. 你必须努力使其之前创建的数据模型。然后,您可以扫描它以确定range轴的极限。 List<Double>可能是一个合适的选择。

  2. 您可以通过更改图形上下文的AffineTransform来旋转范围标签,如RotateText所示。

+0

+1试图帮助。我没有将JFreeChart用于许可原因。但我确实阅读过您发送的文章。谢谢。 – CodeMed 2011-12-20 05:35:58