【问题标题】:x-y plot and rotating text of axis-label轴标签的 x-y 绘图和旋转文本
【发布时间】:2011-12-20 01:01:57
【问题描述】:

下面的代码绘制了一些简单的 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);
    }
}

【问题讨论】:

标签: java swing graph plot awt


【解决方案1】:

所有数据值都是正数,因此我希望所有偏转都向北投影到蓝色底部标记线上方,并且我需要确保没有偏转向南延伸到蓝色底部标记线下方。

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

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

那么您不必担心负值或超出面板边界的行的顶部。

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

设置 Graphics 对象的旋转,绘制文本,然后将 Graphics 对象的旋转恢复为 0。

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

【讨论】:

    【解决方案2】:

    JFreeChart 默认解决这两个问题,如example 所示。

    在你的例子中,

    1. 您必须先创建数据模型,然后再尝试呈现它。然后您可以扫描它的 minmax 以确定您的 range 轴的限制。 List&lt;Double&gt; 可能是一个合适的选择。

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

    【讨论】:

    • +1 试图提供帮助。出于许可原因,我不使用 JFreeChart。但我确实读过你发来的文章。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    • 1970-01-01
    • 2014-07-07
    • 2014-07-30
    相关资源
    最近更新 更多