Use bounds

This commit is contained in:
Andrea Cavalli 2022-09-15 19:08:02 +02:00
parent 7802386392
commit e3f579f38c
5 changed files with 63 additions and 32 deletions

View File

@ -6,13 +6,13 @@ import java.awt.image.BufferedImage;
public class AWTBufferedGraphRenderer implements IGraphRenderer<BufferedImage> {
@Override
public BufferedImage renderGraph(Graph graph, RasterSize totalSize) {
BufferedImage image = new BufferedImage((int) totalSize.width(),
(int) totalSize.height(),
public BufferedImage renderGraph(Graph graph, GraphBounds bounds) {
BufferedImage image = new BufferedImage((int) bounds.maxX(),
(int) bounds.maxY(),
BufferedImage.TYPE_INT_ARGB
);
Graphics2D graphics2D = image.createGraphics();
AWTGraphRenderer.renderGraph(graphics2D, graph, totalSize);
AWTGraphRenderer.renderGraph(graphics2D, graph, bounds);
return image;
}

View File

@ -95,8 +95,8 @@ public class AWTGraphExample {
new SeriesStyle(new Color(0.5f, 1f, 0.5f, 1f), 0, 1, 0.3, 1d),
new SeriesStyle(new Color(1f, 1f, 0.7f, 1f), 1.5, 2, 0, 1d)
),
new GraphAxisStyle("X axis", false, AxisMode.SHOW_WITH_VALUES, "%.2fs"::formatted),
new GraphAxisStyle("Y axis", false, AxisMode.SHOW_WITH_VALUES, "%.2fm"::formatted),
new GraphAxisStyle("X axis", true, AxisMode.SHOW_WITH_VALUES, "%.2fs"::formatted),
new GraphAxisStyle("Y axis", true, AxisMode.SHOW_WITH_VALUES, "%.2fm"::formatted),
GRAPH_COLOR,
new GraphFonts(10f, 18f, 12f, 12f),
2f,
@ -104,6 +104,6 @@ public class AWTGraphExample {
1
));
var r = new AWTGraphRenderer();
r.renderGraph(g, new RasterSize(w, h)).drawTo(g2d);
r.renderGraph(g, new GraphBounds(0, 0, w, h)).drawTo(g2d);
}
}

View File

@ -26,11 +26,12 @@ public class AWTGraphRenderer implements IGraphRenderer<AWTDrawer> {
private static final int MAX_LABELS = 1000;
@Override
public AWTDrawer renderGraph(Graph graph, RasterSize totalSize) {
return graphics2D -> renderGraph(graphics2D, graph, totalSize);
public AWTDrawer renderGraph(Graph graph, GraphBounds bounds) {
return graphics2D -> renderGraph(graphics2D, graph, bounds);
}
public static void renderGraph(Graphics2D graphics2D, Graph graph, RasterSize totalSize) {
public static void renderGraph(Graphics2D g2d, Graph graph, GraphBounds bounds) {
var graphics2D = (Graphics2D) g2d.create();
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
@ -76,7 +77,7 @@ public class AWTGraphRenderer implements IGraphRenderer<AWTDrawer> {
var graphHeight
// Start with total height
= totalSize.height()
= bounds.height()
// Remove the padding on top
- topPadding
// Remove the x value lines length
@ -90,16 +91,16 @@ public class AWTGraphRenderer implements IGraphRenderer<AWTDrawer> {
// Remove the padding on bottom
- bottomPadding;
var xValueLineOffset = topPadding + graphHeight;
var xValueLineOffset = bounds.minY() + topPadding + graphHeight;
var yLabels = getYLabels(graph, graphHeight, valuesFontMetrics, scaleY, y.mode());
var yLabels = getYLabels(graph, bounds.minY(), graphHeight, valuesFontMetrics, scaleY, y.mode());
RasterSize yLabelsAreaSize = computeYLabelsAreaSize(y.mode(), graphHeight, valuesFontMetrics, yLabels);
var yValuesWidth = yLabelsAreaSize.width();
var yValueLineOffset = leftPadding + yAxisNameWidth + yValuesToYAxisNamePadding + yValuesWidth;
var yValueLineOffset = bounds.minX() + leftPadding + yAxisNameWidth + yValuesToYAxisNamePadding + yValuesWidth;
var graphWidth
// Start with total width
= totalSize.width()
= bounds.width()
// Remove the padding on left
- leftPadding
// Remove y-axis name "90deg height"
@ -133,32 +134,39 @@ public class AWTGraphRenderer implements IGraphRenderer<AWTDrawer> {
}
}
var xLabels = getXLabels(graph, graphWidth, valuesFontMetrics, scaleX, x.mode());
var xLabels = getXLabels(graph, bounds.minX(), graphWidth, valuesFontMetrics, scaleX, x.mode());
RasterSize yAxisNameCenterOffset = new RasterSize(leftPadding + valuesFontMetrics.getHeight() / 2d, valuesFontMetrics.getHeight()
RasterSize yAxisNameCenterOffset = new RasterSize(bounds.minX()
+ leftPadding
+ valuesFontMetrics.getHeight() / 2d, bounds.minY()
+ valuesFontMetrics.getHeight()
// Add half of graph height
+ graphHeight / 2 + topPadding);
RasterSize yValuesOffset = new RasterSize(leftPadding
RasterSize yValuesOffset = new RasterSize(bounds.minX()
+ leftPadding
// Add y axis name "90deg height"
+ yAxisNameWidth
// Add the space between the values and the axis name
+ yValuesToYAxisNamePadding, topPadding);
+ yValuesToYAxisNamePadding, bounds.minY() + topPadding);
RasterSize graphOffset = new RasterSize(leftPadding
RasterSize graphOffset = new RasterSize(bounds.minX()
+ leftPadding
+ yAxisNameWidth
+ yValuesToYAxisNamePadding
+ yValuesWidth
+ yValueLineLength, topPadding);
+ yValueLineLength, bounds.minY() + topPadding);
RasterSize xValuesOffset = new RasterSize(graphOffset.width(), xValueLineOffset + xValueLineLength);
RasterSize xAxisNameCenterOffset = new RasterSize(leftPadding
RasterSize xAxisNameCenterOffset = new RasterSize(bounds.minX()
+ leftPadding
+ yAxisNameWidth
+ yValuesToYAxisNamePadding
+ yValuesWidth
+ yValueLineLength
// Add half of graph width
+ graphWidth / 2, topPadding
+ graphWidth / 2, bounds.minY()
+ topPadding
// Add graph height
+ graphHeight
// Add the x value lines length
@ -179,7 +187,11 @@ public class AWTGraphRenderer implements IGraphRenderer<AWTDrawer> {
try {
graphics2D.setBackground(bgColor);
graphics2D.clearRect(0, 0, (int) totalSize.width(), (int) totalSize.height());
graphics2D.clearRect((int) Math.floor(bounds.minX()),
(int) Math.floor(bounds.minY()),
(int) Math.ceil(bounds.width()),
(int) Math.ceil(bounds.height())
);
if (graphHeight < 0) {
return;
@ -188,7 +200,7 @@ public class AWTGraphRenderer implements IGraphRenderer<AWTDrawer> {
return;
}
renderGraphBorders(graphics2D, graph, graphOffset, graphSize, defaultStroke, totalSize);
renderGraphBorders(graphics2D, graph, graphOffset, graphSize, defaultStroke, bounds);
if (y.showName()) {
renderYAxisName(graphics2D, graph, yAxisNameCenterOffset, axisNameFont, axisNameFontMetrics);
}
@ -710,12 +722,12 @@ public class AWTGraphRenderer implements IGraphRenderer<AWTDrawer> {
RasterSize graphOffset,
RasterSize graphSize,
BasicStroke defaultStroke,
RasterSize totalSize) {
GraphBounds bounds) {
// Do not draw the border if the graph is fullscreen
if (graphOffset.width() <= 0
&& graphOffset.height() <= 0
&& graphSize.width() >= totalSize.width()
&& graphSize.height() >= totalSize.height()) {
if (graphOffset.width() <= bounds.minX()
&& graphOffset.height() <= bounds.minY()
&& graphSize.width() >= bounds.width()
&& graphSize.height() >= bounds.height()) {
return;
}
var fgColor = graph.style().colors().foreground().toColor();
@ -750,6 +762,7 @@ public class AWTGraphRenderer implements IGraphRenderer<AWTDrawer> {
* @return rendered labels
*/
private static List<LabelWithOffset> getXLabels(Graph graph,
double labelsAreaOffset,
double labelsAreaWidth,
FontMetrics valuesFontMetrics,
NiceScale scaleX,
@ -767,7 +780,7 @@ public class AWTGraphRenderer implements IGraphRenderer<AWTDrawer> {
int i = 0;
double prevRasterLabelEndOffset = -Double.MAX_VALUE;
double currentRasterOffset = 0;
double currentRasterOffset = labelsAreaOffset;
double currentValue = minX;
while (currentValue <= maxX && i < MAX_LABELS && (scaleX.getTickSpacing() > 0)) {
if (mode.showLabels()) {
@ -794,6 +807,7 @@ public class AWTGraphRenderer implements IGraphRenderer<AWTDrawer> {
* @return rendered labels
*/
private static List<LabelWithOffset> getYLabels(Graph graph,
double labelsAreaOffset,
double labelsAreaHeight,
FontMetrics valuesFontMetrics,
NiceScale scaleY,

View File

@ -6,6 +6,15 @@ public record GraphBounds(double minX, double minY, double maxX, double maxY) {
private static final GraphBounds EMPTY = new GraphBounds(0, 0, 0, 0);
public static GraphBounds fromRasterSize(RasterSize size) {
return fromRasterSize(RasterSize.EMPTY, size);
}
public static GraphBounds fromRasterSize(RasterSize offset, RasterSize size) {
return new GraphBounds(offset.width(), offset.height(),
offset.width() + size.width(), offset.height() + size.height());
}
public static GraphBounds fromSeriesData(List<SeriesData> seriesDataList,
boolean includeOriginX,
boolean includeOriginY) {
@ -91,4 +100,12 @@ public record GraphBounds(double minX, double minY, double maxX, double maxY) {
return adjustZero(new GraphBounds(minX, minY, maxX, maxY), showZeroX, showZeroY);
}
}
public double height() {
return maxY - minY;
}
public double width() {
return maxX - minX;
}
}

View File

@ -2,5 +2,5 @@ package it.cavallium.jlinegraph;
public interface IGraphRenderer<T> {
T renderGraph(Graph graph, RasterSize size);
T renderGraph(Graph graph, GraphBounds bounds);
}