使用JFreeChart排名图表

时间:2014-06-23 20:21:13

标签: 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();
    }
}
}

1 个答案:

答案 0 :(得分:1)

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

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);
    }

}