You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Java Swing中实现统计数据(中位数、最值、均值)线型展示的技术求助

嘿,这个需求我太懂了!你要的其实是简化版的统计参考线组件——有点像箱线图的极简形态,但只保留关键统计值的标记,很多可视化场景里会把它叫“单轴统计里程碑线”,因为名字太小众,确实很难直接搜到现成组件。下面给你两个可行的方案:

方案一:用原生Swing API自己画(最灵活)

Swing的JComponent绘图能力完全能搞定这个需求,而且自定义程度拉满,步骤也很简单:

  • 继承JComponent,重写paintComponent方法
  • 先画一条贯穿的主线,代表数据的整体范围(从最小值到最大值)
  • 在对应比例位置标记出中位数、平均值的点,用不同颜色/形状区分
  • 加上文字标签让数据更直观

给你写了个极简示例代码,直接就能跑:

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

public class StatsMilestoneLine extends JComponent {
    private final double min, max, avg, median;
    private final int padding = 40;

    public StatsMilestoneLine(double min, double max, double avg, double median) {
        this.min = min;
        this.max = max;
        this.avg = avg;
        this.median = median;
        setPreferredSize(new Dimension(450, 180));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 计算主线的坐标范围
        int lineY = getHeight() / 2;
        int startX = padding;
        int endX = getWidth() - padding;
        double valueRange = max - min;

        // 绘制基础主线
        g2d.setColor(Color.DARK_GRAY);
        g2d.drawLine(startX, lineY, endX, lineY);

        // 计算每个统计点的X坐标(按比例映射)
        int minX = startX;
        int maxX = endX;
        int avgX = startX + (int) ((avg - min) / valueRange * (endX - startX));
        int medianX = startX + (int) ((median - min) / valueRange * (endX - startX));

        // 标记各个统计点并添加标签
        drawMarker(g2d, minX, lineY, Color.RED, "Min: " + min);
        drawMarker(g2d, maxX, lineY, Color.BLUE, "Max: " + max);
        drawMarker(g2d, avgX, lineY, Color.GREEN, "Avg: " + String.format("%.1f", avg));
        drawMarker(g2d, medianX, lineY, Color.ORANGE, "Median: " + String.format("%.1f", median));
    }

    private void drawMarker(Graphics2D g2d, int x, int y, Color color, String label) {
        g2d.setColor(color);
        // 画实心圆作为标记点
        g2d.fillOval(x - 6, y - 6, 12, 12);
        // 把标签放在点的下方,居中对齐
        FontMetrics metrics = g2d.getFontMetrics();
        int labelX = x - metrics.stringWidth(label) / 2;
        g2d.drawString(label, labelX, y + 25);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("统计里程碑线");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new StatsMilestoneLine(15, 88, 49.2, 46));
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
方案二:用成熟的Swing可视化库(省时间)

如果不想自己写绘图逻辑,推荐两个常用的Swing图表库,都能快速组合出你要的效果:

  • JFreeChart:Swing生态最流行的可视化库,你可以创建一个XYPlot,先添加一条XYLineAnnotation作为主线,再用XYDotAnnotation和XYTextAnnotation分别标记四个统计值,配置起来很灵活。
  • XChart:轻量级的Java图表库,支持Swing渲染,你可以创建一个极简的XY图表,只保留一条数据线,然后在对应位置添加标记点和标签,代码比JFreeChart简洁很多。
搜索提示

以后搜这类组件的时候,别用“里程碑时间线”这种偏业务的词,试试英文关键词:swing statistical line marker、single axis stats plot,更容易找到相关的实现思路或组件片段。

内容的提问来源于stack exchange,提问作者user3227576

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:43:16