JFreeChart柱状图中单组柱子根据不同数据显示不同颜色的方法:首先需要自定义一个Renderer,然后继承BarRenderer类,最后再重写getItemPaint(int i,int j)方法。
我这里需求为分数大于89的显示绿色,大于79的显示橙色,其他的显示红色
第一步创建Renderer类并继承BarRenderer类,重写getItemPaint(int i,int j)方法
import lombok.Data;
import java.awt.*;
import java.util.ArrayList;
/**
* 类描述: 重写BarRenderer类
*
* @author Jack_Liberty
* @version 1.0
* @date 2021-04-01 11:30
*/
@Data
public class CustomRenderer extends org.jfree.chart.renderer.category.BarRenderer {
/**
* 分值
*/
private static final Double EIGHTY_NINE = 89D;
/**
* 分值
*/
private static final Double SEVENTY_NINE = 79D;
/**
* 柱子颜色
*/
private Paint[] colors;
/**
* 柱子分数
*/
private ArrayList<Double> scores;
public CustomRenderer() {
/**
* 初始化柱子颜色
*/
String[] colorValues = {"#9BBE62", "#F59A23", "#E84614"};
colors = new Paint[colorValues.length];
for (int i = 0; i < colorValues.length; i++) {
colors[i] = Color.decode(colorValues[i]);
}
}
@Override
public Paint getItemPaint(int i, int j) {
Double score = this.scores.get(j);
if (score > EIGHTY_NINE) {
return colors[0];
} else if (score > SEVENTY_NINE) {
return colors[1];
} else {
return colors[2];
}
}
}
第二步、创建一个CategoryDataset对象
/**
* 功能描述: 创建CategoryDataset对象
*
* @return org.jfree.data.category.CategoryDataset
* @author Jack_Liberty
* @date 2021-04-01 16:20
*/
public static CategoryDataset createDataset() {
double[][] data = new double[][]{{99, 87, 89, 45, 78, 92, 98, 80}};
String[] rowKeys = {""};
String[] columnKeys = {"张三", "李四", "王五", "马六", "陈七", "赵八", "测试1", "测试二"};
return DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);
}
第三步、再根据CategoryDataset对象生成JFreeChart对象,并设置相应的样式(使用自定义渲染器)
/**
* 功能描述: 创建JFreeChart对象并设置样式
*
* @param categoryDataset 类别数据集
* @return org.jfree.chart.JFreeChart
* @author Jack_Liberty
* @date 2021-04-01 11:16
*/
public static JFreeChart createChart(CategoryDataset categoryDataset) {
JFreeChart jfreechart = ChartFactory.createBarChart("学生统计图", "学生姓名", "年龄", categoryDataset,
PlotOrientation.VERTICAL, false, false, false);
Font labelFont = new Font("SansSerif", Font.TRUETYPE_FONT, 12);
jfreechart.setTextAntiAlias(false);
jfreechart.setBackgroundPaint(Color.white);
// 获得图表区域对象
CategoryPlot plot = jfreechart.getCategoryPlot();
// 设置横虚线可见
plot.setRangeGridlinesVisible(true);
// 虚线色彩
plot.setRangeGridlinePaint(Color.gray);
// 数据轴精度
NumberAxis vn = (NumberAxis) plot.getRangeAxis();
DecimalFormat df = new DecimalFormat("#0.0");
// 数据轴数据标签的显示格式
vn.setNumberFormatOverride(df);
// x轴设置
CategoryAxis domainAxis = plot.getDomainAxis();
// 轴标题
domainAxis.setLabelFont(labelFont);
// 轴数值
domainAxis.setTickLabelFont(labelFont);
// X轴标题过长可设置倾斜度
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 3.0));
// 横轴上的 Label
domainAxis.setMaximumCategoryLabelWidthRatio(6.00f);
// 是否完整显示
// 设置距离图片左端距离
domainAxis.setLowerMargin(0.1);
// 设置距离图片右端距离
domainAxis.setUpperMargin(0.1);
// 设置 columnKey 是否间隔显示
plot.setDomainAxis(domainAxis);
// 设置柱图背景色(注意,系统取色的时候要使用16位的模式来查看颜色编码,这样比较准确)
plot.setBackgroundPaint(new Color(255, 255, 204));
// y轴设置
ValueAxis rangeAxis = plot.getRangeAxis();
rangeAxis.setLabelFont(labelFont);
rangeAxis.setTickLabelFont(labelFont);
// 设置最高的一个 Item 与图片顶端的距离
rangeAxis.setUpperMargin(0.15);
// 设置最低的一个 Item 与图片底端的距离
rangeAxis.setLowerMargin(0.15);
plot.setRangeAxis(rangeAxis);
// 解决中文乱码问题(关键)
TextTitle textTitle = jfreechart.getTitle();
textTitle.setFont(new Font("黑体", Font.PLAIN, 20));
domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 11));
domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));
vn.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 12));
vn.setLabelFont(new Font("黑体", Font.PLAIN, 12));
// 使用自定义的渲染器
CustomRenderer renderer = new CustomRenderer();
ArrayList<Double> data = new ArrayList<Double>();
data.add(99D);
data.add(87D);
data.add(89D);
data.add(45D);
data.add(78D);
data.add(92D);
data.add(98D);
data.add(80D);
renderer.setScores(data);
// 设置柱子宽度
renderer.setMaximumBarWidth(0.2);
// 设置柱子高度
renderer.setMinimumBarLength(0.2);
// 设置柱子边框颜色
renderer.setBaseOutlinePaint(Color.BLACK);
// 设置柱子边框可见
renderer.setDrawBarOutline(true);
// 设置每个地区所包含的平行柱的之间距离
renderer.setItemMargin(0.5);
jfreechart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
// 显示每个柱的数值,并修改该数值的字体属性
renderer.setIncludeBaseInRange(true);
renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setBaseItemLabelsVisible(true);
plot.setRenderer(renderer);
// 设置柱的透明度
plot.setForegroundAlpha(1.0f);
// 背景色 透明度
plot.setBackgroundAlpha(0.5f);
return jfreechart;
}
第三步、也就是最后一步将JFreeChart对象输出
/**
* 功能描述: 输出为文件
*
* @param chart JFreeChart对象
* @param outputPath 输出路径
* @param weight 图片宽度
* @param height 图片高度
* @author Jack_Liberty
* @date 2021-04-01 16:11
*/
public static void saveAsFile(JFreeChart chart, String outputPath, int weight, int height) {
FileOutputStream out = null;
try {
File outFile = new File(outputPath);
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}
out = new FileOutputStream(outputPath);
// 保存为PNG文件
ChartUtilities.writeChartAsPNG(out, chart, weight, height);
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
最后做个简单测试
@Test
public void CreateHistogram() {
// 创建CategoryDataset对象
CategoryDataset dataset = createDataset();
// 根据Dataset 生成JFreeChart对象,并设置相应的样式
JFreeChart freeChart = createChart(dataset);
// 输出到文件
saveAsFile(freeChart, "F:\\histogram.png", 800, 500);
}
效果如图所示: