algorithm - 使用 JFreeChart 的排名图表

标签 algorithm jfreechart bar-chart

我想制作一个条形图来说明用户的整数排名。纵轴是用户总数中的排名。我认为堆叠条形图是正确的选择,但我不知道该怎么做,特别是因为#1 位于条形图的顶部,而#last 位于条形图的底部。例如,如果用户在 100 人中排在第 25 位,则该条将在四分之一的上方显示一种颜色,然后另一种颜色代表其上方的所有其他用户。 #1 用户的栏将全部是一种颜色,#last 用户将是所有其他颜色。

我的主要问题是我无法找出确定条形高度的算法。

感谢您的帮助!

编辑:对于任何感兴趣的人,我自己编写了一个图形例程来解决这个问题。

package test2;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Test2 {

public static void main(String[] args) {
    int rank=75;
    int totalUsers=100;
    int barWidth=400;
    int barHeight=717;
    double intervalTotal = (double)totalUsers-1.0;
    double intervalPixelSize = (double)barHeight/intervalTotal;        
    int aboveRankBarHeight=(int)Math.round(intervalPixelSize*((double)rank-1.0));
    int belowRankBarHeight=barHeight-aboveRankBarHeight;
    if (rank==1){aboveRankBarHeight=0;}
    if (rank==totalUsers){belowRankBarHeight=0;}

    //Axis and chart labels.
    String topRank = "#1";
    String myRank = "Your Rank #"+Integer.toString(rank);
    String bottomRank = "#"+Integer.toString(totalUsers);

    Color imageBackground=Color.white;
    Color axisLines=new Color(128,128,128); //Medium Gray axis lines.
    Color graphOutline=new Color(96,96,96); //Darker Gray graph outline.
    Color graphBackground=new Color(192,192,192); //Lighter Gray graph background.
    Color belowRank=new Color(85,85,255);   //Blue for bar below user rank.
    Color aboveRank=new Color(255,85,85);   //Red for bar above user rank.
    Color rankLine=Color.black;

    BufferedImage image = new BufferedImage(1200, 900, BufferedImage.TYPE_INT_RGB);
    Graphics g = image.getGraphics();
    g.setColor(imageBackground);    //White image background.
    g.fillRect(0,0,1200,900);       //Draw the white.
    g.setColor(axisLines);          //Medium Gray axis lines.
    g.drawLine(46, 35, 46, 788);    //Draw y-axis.
    g.drawLine(50, 792, 1189, 792); //Draw x-axis.
    g.setColor(graphOutline);       //Darker Gray graph outline.
    g.drawRect(50, 35, 1139, 753);  //Draw graph outline.
    g.setColor(graphBackground);    //Lighter Gray graph background.
    g.fillRect(51,36,1138,752);     //Draw the graph background.
    g.setColor(aboveRank);          //Red bar for above rank.
    g.fillRect(419,70,barWidth,aboveRankBarHeight);     //Draw the above rank bar.
    g.setColor(belowRank);          //Blue bar for below rank.
    g.fillRect(419,70+aboveRankBarHeight,barWidth,belowRankBarHeight);     //Draw the below rank bar.
    g.setColor(rankLine);           //Black line for rank.
    g.fillRect(419,70+aboveRankBarHeight-5,barWidth,10);    //Draw the rank line 10 pixels wide, 5 on either side of the border.
    g.setFont(new Font(null, Font.PLAIN, 10));  //Plain 10-point default font for axis ticks.
    g.drawString(topRank, 30, 70);  //Draw top rank label.
    g.drawString(bottomRank, 15, 788);   //Draw bottom rank label.
    g.setFont(new Font(null, Font.BOLD, 20));  //Bold 20-point default font for user rank label.
    g.drawString(myRank, 250, 70+aboveRankBarHeight);   //Draw user rank label.
    g.setFont(new Font(null, Font.BOLD, 20));  //Bold 20-point default font for graph title.
    g.drawString("Rank",575,30);    //Draw graph title.
    g.setFont(new Font(null, Font.BOLD, 20));  //Bold 20-point default font for axis labels.
    g.drawString("Contributors",565,815);    //Draw x-axis label.

    //Draw vertical y-axis label.
    Graphics2D g2= (Graphics2D)g;
    AffineTransform fontAT = new AffineTransform(); //Create a rotation transformation for the font.
    Font theFont = g2.getFont();                    //Get the current font.
    fontAT.rotate(270 * Math.PI/180);               //Derive a new font using a rotatation transform.
    Font theDerivedFont = theFont.deriveFont(fontAT);   //Apply the transform to a new font.
    g2.setFont(theDerivedFont);                     //Set the derived font in the Graphics2D context.
    g2.drawString("Number of Edits Made", 25, 488);  //Draw y-axis label.
    g2.setFont(theFont); //Put the original font back.

    try {
        ImageIO.write(image, "png", new File("CustomImage.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

最佳答案

只需为每个用户和两行创建一个数据集(一行包含排名较高的用户数,另一行包含排名低于该列中用户的用户数)。然后你可以创建一个堆叠条形图,例如:

public class BarChartDemo2 extends JFrame {

    public BarChartDemo2(String title) {
        super(title);
        CategoryDataset dataset = createDataset();
        JFreeChart chart = createChart(dataset);
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(500, 270));
        setContentPane(chartPanel);
    }

    private static CategoryDataset createDataset() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        dataset.addValue(100, "Users with lower rank", "Mary");
        dataset.addValue(0, "Users With higher rank", "Mary");
        dataset.addValue(70, "Users with lower rank", "John");
        dataset.addValue(30, "Users With higher rank", "John");
        dataset.addValue(0, "Users with lower rank", "Bill");
        dataset.addValue(100, "Users With higher rank", "Bill");
        return dataset;
    }

    private static JFreeChart createChart(CategoryDataset dataset) {
        JFreeChart chart = ChartFactory.createStackedBarChart("User Ranking", 
                "User", "Rank",  dataset);
        chart.setBackgroundPaint(Color.white);
        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        BarRenderer renderer = (BarRenderer) plot.getRenderer();
        renderer.setBarPainter(new StandardBarPainter());
        renderer.setSeriesPaint(0, new Color(50, 240, 50));
        renderer.setSeriesPaint(1, new Color(240, 50, 50));
        renderer.setDrawBarOutline(false);
        return chart;
    }

    public static void main(String[] args) {
        BarChartDemo2 demo = new BarChartDemo2("JFreeChart: Stack Overflow Question");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }

} 

关于algorithm - 使用 JFreeChart 的排名图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24374662/

相关文章:

algorithm - 从混合波(或其他音乐格式)文件中提取特定乐器的特定旋律/节拍/节奏

php - 生成 Luhn 校验和

java - 如何提高jfree图表的质量(分辨率)

r - 基本 R 中每个条形的不同颜色的堆叠条形图

c# - 如何在对象列表中递归搜索字符串项

swing - 如何在矩形上创建和分布对角条纹?

java - JFreechart:将图表面板的所有组件保存在 png 文件中

r - 使用 dygraphs 包在 R 中创建条形图

r - 在 ggplot2 中创建填充标志(或图像)的条形图

c++ - 实现洗牌的逻辑