public static JFreeChart createScatterChart(ScatterChartData[] data, long[] xyRange) {
NumberAxis xAxis = new NumberAxis();
xAxis.setAutoRange(false);
xAxis.setVisible(false);
xAxis.setRange(xyRange[0], xyRange[1]);
XYSeriesCollection dataset = new XYSeriesCollection();
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(false, true);
//扩展的y轴 支持 \n 换行 label
NumberAxis yAxis = new NumberAxis();
yAxis.setAutoRange(false);
yAxis.setVisible(false);
yAxis.setRange(xyRange[2], xyRange[3]);
for (int i = 0; i < data.length; i++) {
XYSeries xySeries = new XYSeries(i);
data[i].getData().forEach(value -> xySeries.add(value[0].doubleValue(), value[1].doubleValue()));
dataset.addSeries(xySeries);
setRenderer(renderer, i, CommonUtil.getJavaColor(data[i].getColor()), true);
}
XYPlot xyPlot = new XYPlot(dataset, xAxis, yAxis, renderer);
setPlot(xyPlot);
JFreeChart chart = new JFreeChart(null, JFreeChart.DEFAULT_TITLE_FONT,
xyPlot, false);
setChart("", chart);
return chart;
}
/**
* 设置折线线段
*/
private static void setRenderer(XYLineAndShapeRenderer renderer, int index, Color color, boolean showShape) {
//要求单点也要显示
renderer.setSeriesShape(index, new Ellipse2D.Double(-0.25, -0.25, 0.5, 0.5));
renderer.setSeriesShapesVisible(index, showShape);
//设置折线颜色
if (null != color) {
renderer.setSeriesPaint(index, color);
}
}
/**
* 设置画图数据区域
*/
private static void setPlot(XYPlot xyPlot) {
//要求不显示边框
xyPlot.setOutlineVisible(false);
}
/**
* 设置图表样式
*/
private static void setChart(String title, JFreeChart chart) {
chart.setBackgroundPaint(Color.white);
if (chart.getLegend() != null) {
chart.getLegend().setItemFont(new Font("宋体", Font.PLAIN, 8));
//防止A4打印时,底部无墨
chart.getLegend().setPadding(new RectangleInsets(1, 1, 20, 1));
}
if (StrUtil.isNotEmpty(title)) {
chart.setTitle(new TextTitle(
title,
new Font("宋体", Font.PLAIN, 12),
TextTitle.DEFAULT_TEXT_PAINT, Title.DEFAULT_POSITION,
Title.DEFAULT_HORIZONTAL_ALIGNMENT,
Title.DEFAULT_VERTICAL_ALIGNMENT,
//防止A4打印时,顶部无墨
new RectangleInsets(20, 1, 1, 1)
));
}
}
/**
* 图表数据封装
*
* @author liaozesong
*/
@Data
public class ScatterChartData {
/**
* 折线颜色
*/
private String color;
/**
* 折线数据
*/
private List<Number[]> data = new ArrayList<>();
/**
* 除data外所有属性复制
*/
public ScatterChartData copyBase() {
ScatterChartData chartData = new ScatterChartData();
chartData.setColor(color);
return chartData;
}
}
demo
import java.util.ArrayList;
/**
* @author liaozesong
*/
public class ScatterBackground {
public static final ScatterChartData SCATTER_CHART_DATA = new ScatterChartData();
static {
SCATTER_CHART_DATA.setColor("#000000");
ArrayList<Number[]> objects = new ArrayList<>();
// 右上
objects.add(new Number[]{0, 2129 + 1982});
objects.add(new Number[]{353, 2129 + 1982});
objects.add(new Number[]{511, 2117 + 1982});
objects.add(new Number[]{724, 2044 + 1982});
objects.add(new Number[]{921, 1947 + 1982});
objects.add(new Number[]{964, 1798 + 1982});
objects.add(new Number[]{1236, 1709 + 1982});
objects.add(new Number[]{1408, 1600 + 1982});
objects.add(new Number[]{1465, 1565 + 1982});
objects.add(new Number[]{1656, 1389 + 1982});
objects.add(new Number[]{1670, 1261 + 1982});
objects.add(new Number[]{1700, 1260 + 1982});
objects.add(new Number[]{1705, 897 + 1982});
objects.add(new Number[]{1675, 897 + 1982});
//右下
objects.add(new Number[]{1825, -96 + 1982});
objects.add(new Number[]{1744, -839 + 1982});
objects.add(new Number[]{1744, -1346 + 1982});
objects.add(new Number[]{1649, -1687 + 1982});
objects.add(new Number[]{1493, -1982 + 1982});
objects.add(new Number[]{700, -1982 + 1982});
objects.add(new Number[]{0, -1982 + 1982});
//左下
objects.add(new Number[]{-700, -1982 + 1982});
objects.add(new Number[]{-1493, -1982 + 1982});
objects.add(new Number[]{-1649, -1687 + 1982});
objects.add(new Number[]{-1744, -1346 + 1982});
objects.add(new Number[]{-1744, -839 + 1982});
objects.add(new Number[]{-1825, -96 + 1982});
objects.add(new Number[]{-1675, 897 + 1982});
objects.add(new Number[]{-1705, 897 + 1982});
objects.add(new Number[]{-1700, 1260 + 1982});
objects.add(new Number[]{-1670, 1261 + 1982});
objects.add(new Number[]{-1656, 1389 + 1982});
objects.add(new Number[]{-1465, 1565 + 1982});
objects.add(new Number[]{-1408, 1600 + 1982});
objects.add(new Number[]{-1236, 1709 + 1982});
objects.add(new Number[]{-964, 1798 + 1982});
objects.add(new Number[]{-921, 1947 + 1982});
objects.add(new Number[]{-724, 2044 + 1982});
objects.add(new Number[]{-511, 2117 + 1982});
objects.add(new Number[]{-353, 2129 + 1982});
objects.add(new Number[]{0, 2129 + 1982});
ArrayList<Number[]> lines = new ArrayList<>();
for (int i = 0; i < objects.size() - 1; i++) {
Number[] numbers = objects.get(i);
Number[] numbers1 = objects.get(i + 1);
int i1 = numbers1[0].intValue() - numbers[0].intValue();
int i2 = numbers1[1].intValue() - numbers[1].intValue();
for (int j = 0; j < 100; j++) {
lines.add(new Number[]{numbers[0].intValue() + j * i1 / 100, numbers[1].intValue() + j * i2 / 100});
}
}
SCATTER_CHART_DATA.getData().addAll(objects);
SCATTER_CHART_DATA.getData().addAll(lines);
}
}