以图形方式显示图形中两个顶点之间的最短路径

时间:2023-02-01 16:17:52

I wrote a program that collects at least 500 Wikipedia pages and links from these pages to other Wikipedia pages. It collects word frequencies from each webpage in order to determine the cost between two vertices(webpages) in a graph.

我写了一个程序,收集至少500个*页面和从这些页面到其他*页面的链接。它从每个网页收集单词频率,以确定图表中两个顶点(网页)之间的成本。

I am now trying to create a second program. I'm creating a GUI in NeatBeans using Swing where the user can select two webpages and then graphically see the shortest path between them. I am not sure how to visually display the graph. I have been looking into using JFreeChart or JUNG but neither seem to be capable of creating the kind of graph that I want.

我现在正在尝试创建第二个程序。我正在使用Swing在NeatBeans中创建GUI,用户可以选择两个网页,然后以图形方式查看它们之间的最短路径。我不确定如何直观地显示图表。我一直在研究使用JFreeChart或JUNG,但似乎都无法创建我想要的那种图形。

Here is an example of what I am trying to create:

以下是我要创建的示例:

以图形方式显示图形中两个顶点之间的最短路径

1 个解决方案

#1


I made something using only custom painting. If you do not know how to use cutom painting, the tutorial is a good place to start, see Performing Custom Painting and 2D Graphics.

我只使用自定义绘画制作了一些东西如果您不知道如何使用cutom绘画,那么教程是一个很好的起点,请参阅执行自定义绘画和2D图形。

以图形方式显示图形中两个顶点之间的最短路径

public class Example extends JPanel {

    final static int GRID_SIZE = 4;
    final static int CELL_SIZE = 150;
    final static int CIRCLE_RAD = 20;
    final static int HALF_CIRCLE_WIDTH = 4;

    final static Color BACKGROUND = Color.WHITE;
    final static Color CIRCLE_FILL = new Color(185, 42, 42);
    final static Color CIRCLE_EDGE = Color.BLACK;
    final static Color LINK_FILL = Color.BLUE;
    final static Color NOLINK_FILL = new Color(150, 75, 0);

    final static BasicStroke LINK_STROKE = new BasicStroke(10);
    final static BasicStroke NOLINK_STROKE = new BasicStroke(2);
    final static BasicStroke CIRCLE_STROKE = new BasicStroke(HALF_CIRCLE_WIDTH);


    boolean[][][] links = new boolean[GRID_SIZE][GRID_SIZE][2];

    Example() {

        setBackground(BACKGROUND);

        Random rand = new Random();
        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                links[i][j][0] = rand.nextBoolean(); // isLinkingtoRight
                links[i][j][1] = rand.nextBoolean(); // isLinkingtoDown
            }
        }
    }

    @Override
    public Dimension getPreferredSize() {

        int dim = CIRCLE_RAD * 2 + CELL_SIZE * (GRID_SIZE - 1) + HALF_CIRCLE_WIDTH * 2;
        return new Dimension(dim, dim);
    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {

                if (j != GRID_SIZE - 1) {
                    if (links[i][j][0]) {
                        g2d.setColor(LINK_FILL);
                        g2d.setStroke(LINK_STROKE);
                    }
                    else {
                        g2d.setColor(NOLINK_FILL);
                        g2d.setStroke(NOLINK_STROKE);
                    }
                    g2d.drawLine(i * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, j * CELL_SIZE  + CIRCLE_RAD + HALF_CIRCLE_WIDTH,
                                 i * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, (j + 1) * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH);
                }
                if (i != GRID_SIZE - 1) {
                    if (links[i][j][1]) {
                        g2d.setColor(LINK_FILL);
                        g2d.setStroke(LINK_STROKE);
                    }
                    else {
                        g2d.setColor(NOLINK_FILL);
                        g2d.setStroke(NOLINK_STROKE);
                    }
                    g2d.drawLine(i * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, j * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH,
                                 (i + 1) * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, j * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH);
                }
            }
        }

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setStroke(CIRCLE_STROKE);
        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                g2d.setColor(CIRCLE_FILL);
                g2d.fillOval(i * CELL_SIZE + HALF_CIRCLE_WIDTH, j * CELL_SIZE + HALF_CIRCLE_WIDTH, CIRCLE_RAD * 2, CIRCLE_RAD * 2);
                g2d.setColor(CIRCLE_EDGE);
                g2d.drawOval(i * CELL_SIZE + HALF_CIRCLE_WIDTH, j * CELL_SIZE + HALF_CIRCLE_WIDTH, CIRCLE_RAD * 2, CIRCLE_RAD * 2);
            }
        }
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.add(new Example());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

Notes:

  • It is by no means an efficient (performance-wise) painting method. The loops runs twice, I turned on anti-aliasing etc.
  • 它绝不是一种有效的(表现方面)绘画方法。循环运行两次,我打开抗锯齿等。

  • The pixel calculations could be off (positions, sizes...).
  • 像素计算可能是关闭的(位置,大小......)。

  • The styles (colors, sizes...) are at your discretion.
  • 款式(颜色,尺寸......)由您自行决定。

  • The link grid is a simple but stupid implementation.
  • 链接网格是一个简单但愚蠢的实现。

#1


I made something using only custom painting. If you do not know how to use cutom painting, the tutorial is a good place to start, see Performing Custom Painting and 2D Graphics.

我只使用自定义绘画制作了一些东西如果您不知道如何使用cutom绘画,那么教程是一个很好的起点,请参阅执行自定义绘画和2D图形。

以图形方式显示图形中两个顶点之间的最短路径

public class Example extends JPanel {

    final static int GRID_SIZE = 4;
    final static int CELL_SIZE = 150;
    final static int CIRCLE_RAD = 20;
    final static int HALF_CIRCLE_WIDTH = 4;

    final static Color BACKGROUND = Color.WHITE;
    final static Color CIRCLE_FILL = new Color(185, 42, 42);
    final static Color CIRCLE_EDGE = Color.BLACK;
    final static Color LINK_FILL = Color.BLUE;
    final static Color NOLINK_FILL = new Color(150, 75, 0);

    final static BasicStroke LINK_STROKE = new BasicStroke(10);
    final static BasicStroke NOLINK_STROKE = new BasicStroke(2);
    final static BasicStroke CIRCLE_STROKE = new BasicStroke(HALF_CIRCLE_WIDTH);


    boolean[][][] links = new boolean[GRID_SIZE][GRID_SIZE][2];

    Example() {

        setBackground(BACKGROUND);

        Random rand = new Random();
        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                links[i][j][0] = rand.nextBoolean(); // isLinkingtoRight
                links[i][j][1] = rand.nextBoolean(); // isLinkingtoDown
            }
        }
    }

    @Override
    public Dimension getPreferredSize() {

        int dim = CIRCLE_RAD * 2 + CELL_SIZE * (GRID_SIZE - 1) + HALF_CIRCLE_WIDTH * 2;
        return new Dimension(dim, dim);
    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {

                if (j != GRID_SIZE - 1) {
                    if (links[i][j][0]) {
                        g2d.setColor(LINK_FILL);
                        g2d.setStroke(LINK_STROKE);
                    }
                    else {
                        g2d.setColor(NOLINK_FILL);
                        g2d.setStroke(NOLINK_STROKE);
                    }
                    g2d.drawLine(i * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, j * CELL_SIZE  + CIRCLE_RAD + HALF_CIRCLE_WIDTH,
                                 i * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, (j + 1) * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH);
                }
                if (i != GRID_SIZE - 1) {
                    if (links[i][j][1]) {
                        g2d.setColor(LINK_FILL);
                        g2d.setStroke(LINK_STROKE);
                    }
                    else {
                        g2d.setColor(NOLINK_FILL);
                        g2d.setStroke(NOLINK_STROKE);
                    }
                    g2d.drawLine(i * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, j * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH,
                                 (i + 1) * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, j * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH);
                }
            }
        }

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setStroke(CIRCLE_STROKE);
        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                g2d.setColor(CIRCLE_FILL);
                g2d.fillOval(i * CELL_SIZE + HALF_CIRCLE_WIDTH, j * CELL_SIZE + HALF_CIRCLE_WIDTH, CIRCLE_RAD * 2, CIRCLE_RAD * 2);
                g2d.setColor(CIRCLE_EDGE);
                g2d.drawOval(i * CELL_SIZE + HALF_CIRCLE_WIDTH, j * CELL_SIZE + HALF_CIRCLE_WIDTH, CIRCLE_RAD * 2, CIRCLE_RAD * 2);
            }
        }
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.add(new Example());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

Notes:

  • It is by no means an efficient (performance-wise) painting method. The loops runs twice, I turned on anti-aliasing etc.
  • 它绝不是一种有效的(表现方面)绘画方法。循环运行两次,我打开抗锯齿等。

  • The pixel calculations could be off (positions, sizes...).
  • 像素计算可能是关闭的(位置,大小......)。

  • The styles (colors, sizes...) are at your discretion.
  • 款式(颜色,尺寸......)由您自行决定。

  • The link grid is a simple but stupid implementation.
  • 链接网格是一个简单但愚蠢的实现。