我希望制作一个条形图,说明用户的整数排名。垂直轴将是用户总数的排名。我在想一个堆积的条形图是正确的东西,但我无法绕过如何做到这一点,特别是因为#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();
}
}
}
答案 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);
}
}