如何在java中绘制热图,显示圆圈而不是颜色

时间:2017-10-12 18:19:16

标签: java heatmap

我正在生成一个热图,使用Jtable并用数字填充,然后用颜色填充 enter image description here。而不是颜色,我想显示圆圈或其他图形图像,这些图像的大小相对较大,如enter image description here。 我在R中找到了一个库来做geom_tile,但是无法在Javs中找到任何方法。你们有任何想法或如何做的例子吗?

1 个答案:

答案 0 :(得分:1)

要绘制自定义表格单元格,您需要提供自己的TableCellRenderer实现。

您的自定义TableCellRenderer必须只实现一个方法:getTableCellRendererComponent,该方法必须返回ComponentJComponent

然后,您的TableCellRenderer可以返回一个自定义JComponent,它根据预先设置的单元格值绘制圆形。

以下是一个示例代码,演示如何设置自定义HeatmapCellRenderer,该代码使用DotRenderer作为组件来呈现单个单元格:

public class TableHeatmap {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        // create a demo table 10 x 10 cells
        JTable table = new JTable(10, 10);
        frame.setContentPane(table);

        // fill in some random data
        for (int row = 0; row < 10; row++) {
            for (int col = 0; col < 10; col++) {
                table.setValueAt((int) (Math.random() * 10), row, col);
            }
        }

        // set our custom TableCellRenderer
        table.setDefaultRenderer(Object.class, new HeatmapCellRenderer());
        table.setRowHeight(30);

        // show the window
        frame.pack();
        frame.setVisible(true);
    }

    private static class HeatmapCellRenderer implements TableCellRenderer {

        private final DotRenderer renderer = new DotRenderer();

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (value instanceof Integer) {
                this.renderer.setValue((Integer) value);
                return this.renderer;
            }
            return null;
        }
    }

    private static class DotRenderer extends JComponent {
        private int value;

        public void setValue(int value) {
            this.value = value;
        }

        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(Color.BLUE);
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
            g.setColor(Color.RED);
            int centerX = this.getWidth() / 2;
            int centerY = this.getHeight() / 2;
            g.fillOval(centerX - this.value, centerY - this.value, this.value * 2, this.value * 2);
        }

    }

}

上面的代码应生成一个类似于以下屏幕截图的表:

example screenshot

通过为单元格使用比Integer更复杂的对象,可以实现更复杂的渲染器。如果您有一个简单的数据类class MyData { int value1; int value2; }并将这些值插入表中,您可以实现一个Renderer,它根据value1设置背景颜色,并根据{{设置点的大小。 1}}单元格值。在课程中添加value2可以进一步根据这些值对点进行着色,非常接近您的示例图像。