Skip to content
Snippets Groups Projects
Commit f38ed5b6 authored by Tim Molter's avatar Tim Molter
Browse files

new feature: save as a high res png by specifying DPI

parent ce94d5d2
Branches
No related tags found
No related merge requests found
Showing
with 192 additions and 72 deletions
......@@ -3,4 +3,5 @@ target/
.project
.settings/
*.png
*.jpg
CSV/
\ No newline at end of file
......@@ -83,9 +83,13 @@ public class LineChart03 implements ExampleChart {
chart.getStyleManager().setChartTitleBoxVisible(true);
chart.getStyleManager().setChartTitleBoxBorderColor(Color.BLACK);
chart.getStyleManager().setPlotGridLinesVisible(false);
chart.getStyleManager().setAxisTickPadding(20);
chart.getStyleManager().setAxisTickMarkLength(15);
chart.getStyleManager().setPlotPadding(20);
chart.getStyleManager().setChartTitleFont(new Font(Font.MONOSPACED, Font.BOLD, 24));
chart.getStyleManager().setLegendFont(new Font(Font.SERIF, Font.PLAIN, 18));
chart.getStyleManager().setLegendPosition(LegendPosition.InsideSE);
......
......@@ -35,6 +35,7 @@ public class Example1 {
chart.addSeries("y(x)", null, yData);
BitmapEncoder.savePNG(chart, "./Sample_Chart.png");
BitmapEncoder.savePNGWithDPI(chart, "./Sample_Chart_300_DPI.png", 300);
BitmapEncoder.saveJPG(chart, "./Sample_Chart.jpg", 0.95f);
}
......
......@@ -16,6 +16,7 @@
package com.xeiam.xchart;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
......@@ -26,8 +27,12 @@ import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.FileImageOutputStream;
/**
......@@ -63,6 +68,79 @@ public final class BitmapEncoder {
out.close();
}
/**
* Save a chart as a PNG with a custom DPI. The default DPI is 72, which is fine for displaying charts on a computer monitor, but for printing charts, a DPI of around 300 is much better.
*
* @param chart
* @param fileName
* @param DPI
* @throws IOException
*/
public static void savePNGWithDPI(Chart chart, String fileName, int DPI) throws IOException {
double scaleFactor = DPI / 72.0;
BufferedImage bufferedImage = new BufferedImage((int) (chart.getWidth() * scaleFactor), (int) (chart.getHeight() * scaleFactor), BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = bufferedImage.createGraphics();
AffineTransform at = graphics2D.getTransform();
at.scale(scaleFactor, scaleFactor);
graphics2D.setTransform(at);
chart.paint(graphics2D, chart.getWidth(), chart.getHeight());
for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName("png"); iw.hasNext();) {
ImageWriter writer = iw.next();
// instantiate an ImageWriteParam object with default compression options
ImageWriteParam iwp = writer.getDefaultWriteParam();
ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, iwp);
if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
continue;
}
setDPIforPNG(metadata, DPI);
File file = new File(fileName);
FileImageOutputStream output = new FileImageOutputStream(file);
writer.setOutput(output);
IIOImage image = new IIOImage(bufferedImage, null, metadata);
writer.write(null, image, iwp);
writer.dispose();
break;
}
}
/**
* Sets the metadata correctly
*
* @param metadata
* @param DPI
* @throws IIOInvalidTreeException
*/
private static void setDPIforPNG(IIOMetadata metadata, int DPI) throws IIOInvalidTreeException {
// for PNG, it's dots per millimeter
double dotsPerMilli = 1.0 * DPI / 10 / 2.54;
IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
horiz.setAttribute("value", Double.toString(dotsPerMilli));
IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
vert.setAttribute("value", Double.toString(dotsPerMilli));
IIOMetadataNode dim = new IIOMetadataNode("Dimension");
dim.appendChild(horiz);
dim.appendChild(vert);
IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
root.appendChild(dim);
metadata.mergeTree("javax_imageio_1.0", root);
}
/**
* Save a Chart as a JPEG file
*
......@@ -92,4 +170,12 @@ public final class BitmapEncoder {
writer.dispose();
}
public static void main(String[] args) {
for (String format : ImageIO.getWriterFormatNames()) {
System.out.println(format);
// ImageIO.write(bufferedImage, format, new File("C:\\image_new." + format));
}
}
}
......@@ -19,6 +19,7 @@ import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.math.BigDecimal;
import com.xeiam.xchart.StyleManager.LegendPosition;
......@@ -128,7 +129,7 @@ public class Axis implements ChartPart {
double titleHeight = 0.0;
if (axisTitle.getText() != null && !axisTitle.getText().trim().equalsIgnoreCase("") && getChartPainter().getStyleManager().isXAxisTitleVisible()) {
TextLayout textLayout = new TextLayout(axisTitle.getText(), getChartPainter().getStyleManager().getAxisTitleFont(), new FontRenderContext(null, true, false));
Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0);
Rectangle2D rectangle = textLayout.getBounds();
titleHeight = rectangle.getHeight() + getChartPainter().getStyleManager().getAxisTitlePadding();
}
......@@ -136,9 +137,8 @@ public class Axis implements ChartPart {
double axisTickLabelsHeight = 0.0;
if (getChartPainter().getStyleManager().isXAxisTicksVisible()) {
TextLayout textLayout = new TextLayout("0", getChartPainter().getStyleManager().getAxisTickLabelsFont(), new FontRenderContext(null, true, false));
Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0);
axisTickLabelsHeight = rectangle.getHeight() + getChartPainter().getStyleManager().getAxisTickPadding() + getChartPainter().getStyleManager().getAxisTickMarkLength()
+ getChartPainter().getStyleManager().getPlotPadding();
Rectangle2D rectangle = textLayout.getBounds();
axisTickLabelsHeight = rectangle.getHeight() + getChartPainter().getStyleManager().getAxisTickPadding() + getChartPainter().getStyleManager().getAxisTickMarkLength();
}
return (int) (titleHeight + axisTickLabelsHeight);
} else { // Y-Axis
......@@ -165,7 +165,9 @@ public class Axis implements ChartPart {
int xOffset = getChartPainter().getStyleManager().getChartPadding();
int yOffset = getChartPainter().getChartTitle().getSizeHint();
int width = 80; // arbitrary, final width depends on Axis tick labels
int height = getChartPainter().getHeight() - yOffset - axisPair.getxAxis().getSizeHint() - getChartPainter().getStyleManager().getChartPadding();
int height = getChartPainter().getHeight() - yOffset - axisPair.getxAxis().getSizeHint() - getChartPainter().getStyleManager().getPlotPadding()
- getChartPainter().getStyleManager().getChartPadding();
Rectangle yAxisRectangle = new Rectangle(xOffset, yOffset, width, height);
this.paintZone = yAxisRectangle;
// g.setColor(Color.green);
......@@ -190,9 +192,9 @@ public class Axis implements ChartPart {
int xOffset = (int) (axisPair.getyAxis().getBounds().getWidth() + (getChartPainter().getStyleManager().isYAxisTicksVisible() ? getChartPainter().getStyleManager().getPlotPadding() : 0) + getChartPainter()
.getStyleManager().getChartPadding());
int yOffset = (int) (axisPair.getyAxis().getBounds().getY() + axisPair.getyAxis().getBounds().getHeight());
int yOffset = (int) (axisPair.getyAxis().getBounds().getY() + axisPair.getyAxis().getBounds().getHeight() + getChartPainter().getStyleManager().getPlotPadding());
int chartLegendWidth = 0;
double chartLegendWidth = 0;
if (getChartPainter().getStyleManager().getLegendPosition() == LegendPosition.OutsideE) {
chartLegendWidth = getChartPainter().getChartLegend().getSizeHint()[0];
}
......
......@@ -19,6 +19,7 @@ import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
/**
* Axis tick labels
......@@ -69,7 +70,7 @@ public class AxisTickLabels implements ChartPart {
FontRenderContext frc = g.getFontRenderContext();
// TextLayout layout = new TextLayout(tickLabel, font, new FontRenderContext(null, true, false));
TextLayout layout = new TextLayout(tickLabel, getChartPainter().getStyleManager().getAxisTickLabelsFont(), frc);
Rectangle tickLabelBounds = layout.getPixelBounds(null, 0, 0);
Rectangle2D tickLabelBounds = layout.getBounds();
layout.draw(g, xOffset, (int) (yOffset + axisTick.getAxis().getPaintZone().getHeight() - tickLocation + tickLabelBounds.getHeight() / 2.0));
if (tickLabelBounds.getWidth() > maxTickLabelWidth) {
......@@ -96,7 +97,7 @@ public class AxisTickLabels implements ChartPart {
if (tickLabel != null) { // some are null for logarithmic axes
FontRenderContext frc = g.getFontRenderContext();
TextLayout layout = new TextLayout(tickLabel, getChartPainter().getStyleManager().getAxisTickLabelsFont(), frc);
Rectangle tickLabelBounds = layout.getPixelBounds(null, 0, 0);
Rectangle2D tickLabelBounds = layout.getBounds();
layout.draw(g, (int) (xOffset + tickLocation - tickLabelBounds.getWidth() / 2.0), yOffset);
if (tickLabelBounds.getHeight() > maxTickLabelHeight) {
......
......@@ -20,6 +20,7 @@ import java.awt.Rectangle;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
/**
* AxisTitle
......@@ -65,31 +66,19 @@ public class AxisTitle implements ChartPart {
FontRenderContext frc = g.getFontRenderContext();
TextLayout nonRotatedTextLayout = new TextLayout(text, getChartPainter().getStyleManager().getAxisTitleFont(), frc);
Rectangle nonRotatedRectangle = nonRotatedTextLayout.getPixelBounds(null, 0, 0);
// System.out.println(nonRotatedRectangle);
Rectangle2D nonRotatedRectangle = nonRotatedTextLayout.getBounds();
// ///////////////////////////////////////////////
// AffineTransform at = new AffineTransform();
// // Tx.translate(anchorx, anchory); // S3: final translation
// double theta = Math.PI / -2.0;
// at.rotate(theta); // S2: rotate around anchor
// // Tx.translate(-anchorx, -anchory); // S1: translate anchor to origin
// Font derivedFont = font.deriveFont(at);
// TextLayout rotatedTextLayout = new TextLayout(text, derivedFont, frc);
// // TextLayout rotatedTextLayout = new TextLayout(text, font.deriveFont(AffineTransform.getRotateInstance(Math.PI / -2.0, 0, 0)), frc);
// // Rectangle rotatedRectangle = rotatedTextLayout.getPixelBounds(null, 0, 0);
// // System.out.println(rotatedRectangle);
//
int xOffset = (int) (axis.getPaintZone().getX() + nonRotatedRectangle.getHeight());
int yOffset = (int) ((axis.getPaintZone().getHeight() + nonRotatedRectangle.getWidth()) / 2.0 + axis.getPaintZone().getY());
AffineTransform orig = g.getTransform();
g.transform(AffineTransform.getRotateInstance(Math.PI / -2.0, xOffset, yOffset));
g.drawString(text, xOffset, yOffset);
// rotatedTextLayout.draw(g, xOffset, yOffset);
// ///////////////////////////////////////////////
g.setTransform(orig);
// System.out.println(nonRotatedRectangle.getHeight());
// bounds
bounds = new Rectangle((int) (xOffset - nonRotatedRectangle.getHeight()), (int) (yOffset - nonRotatedRectangle.getWidth()), (int) nonRotatedRectangle.getHeight()
......@@ -106,7 +95,7 @@ public class AxisTitle implements ChartPart {
FontRenderContext frc = g.getFontRenderContext();
TextLayout textLayout = new TextLayout(text, getChartPainter().getStyleManager().getAxisTitleFont(), frc);
Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0);
Rectangle2D rectangle = textLayout.getBounds();
// System.out.println(rectangle);
int xOffset = (int) (axis.getPaintZone().getX() + (axis.getPaintZone().getWidth() - rectangle.getWidth()) / 2.0);
......
......@@ -20,6 +20,7 @@ import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
/**
* Chart Title
......@@ -70,7 +71,7 @@ public class ChartTitle implements ChartPart {
if (chartPainter.getStyleManager().isChartTitleVisible()) {
TextLayout textLayout = new TextLayout(text, chartPainter.getStyleManager().getChartTitleFont(), new FontRenderContext(null, true, false));
Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0);
Rectangle2D rectangle = textLayout.getBounds();
int titleHeight = (int) ((chartPainter.getStyleManager().isChartTitleVisible() ? rectangle.getHeight() : 0));
return chartPainter.getStyleManager().getChartPadding() + 2 * chartPainter.getStyleManager().getChartTitlePadding() + titleHeight;
} else {
......@@ -89,7 +90,7 @@ public class ChartTitle implements ChartPart {
// create rectangle first for sizing
FontRenderContext frc = g.getFontRenderContext();
TextLayout textLayout = new TextLayout(text, chartPainter.getStyleManager().getChartTitleFont(), frc);
Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0);
Rectangle2D rectangle = textLayout.getBounds();
int xOffset = (int) chartPainter.getPlot().getBounds().getX();
int yOffset = chartPainter.getStyleManager().getChartPadding();
......@@ -111,7 +112,7 @@ public class ChartTitle implements ChartPart {
xOffset = (int) (chartPainter.getPlot().getBounds().getX() + (chartPainter.getPlot().getBounds().getWidth() - rectangle.getWidth()) / 2.0);
yOffset = (int) (chartPainter.getStyleManager().getChartPadding() - rectangle.getY() + chartPainter.getStyleManager().getChartTitlePadding());
// bounds = new Rectangle(xOffset, yOffset + ((int) rectangle.getY()), (int) rectangle.getWidth(), (int) (rectangle.getHeight()));
bounds = new Rectangle(xOffset, yOffset + ((int) rectangle.getY()), (int) rectangle.getWidth(), (int) (rectangle.getHeight()));
// g.setColor(Color.green);
// g.draw(bounds);
......
......@@ -18,8 +18,12 @@ package com.xeiam.xchart.internal.chartpart;
import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.Map;
import com.xeiam.xchart.Series;
......@@ -55,51 +59,51 @@ public class Legend implements ChartPart {
*
* @return
*/
protected int[] getSizeHint() {
protected double[] getSizeHint() {
if (chartPainter.getStyleManager().isLegendVisible()) {
Map<Integer, Series> seriesMap = chartPainter.getAxisPair().getSeriesMap();
// determine legend text content max width
int legendTextContentMaxWidth = 0;
int legendTextContentMaxHeight = 0;
double legendTextContentMaxWidth = 0;
double legendTextContentMaxHeight = 0;
for (Integer seriesId : seriesMap.keySet()) {
Series series = seriesMap.get(seriesId);
TextLayout textLayout = new TextLayout(series.getName(), chartPainter.getStyleManager().getLegendFont(), new FontRenderContext(null, true, false));
Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0);
Rectangle2D rectangle = textLayout.getBounds();
// System.out.println(rectangle);
if (rectangle.getWidth() > legendTextContentMaxWidth) {
legendTextContentMaxWidth = (int) rectangle.getWidth();
legendTextContentMaxWidth = rectangle.getWidth();
}
if (rectangle.getHeight() > legendTextContentMaxHeight) {
legendTextContentMaxHeight = (int) rectangle.getHeight();
legendTextContentMaxHeight = rectangle.getHeight();
}
}
// determine legend content height
int maxContentHeight = 0;
double maxContentHeight = 0;
if (getChartPainter().getStyleManager().getChartType() != ChartType.Bar) {
maxContentHeight = Math.max(legendTextContentMaxHeight, Marker.SIZE);
} else {
maxContentHeight = Math.max(legendTextContentMaxHeight, BOX_SIZE);
}
int legendContentHeight = maxContentHeight * seriesMap.size() + chartPainter.getStyleManager().getLegendPadding() * (seriesMap.size() - 1);
double legendContentHeight = maxContentHeight * seriesMap.size() + chartPainter.getStyleManager().getLegendPadding() * (seriesMap.size() - 1);
// determine legend content width
int legendContentWidth = 0;
double legendContentWidth = 0;
if (getChartPainter().getStyleManager().getChartType() != ChartType.Bar) {
legendContentWidth = (int) (3.0 * Marker.SIZE + chartPainter.getStyleManager().getLegendPadding() + legendTextContentMaxWidth);
} else {
legendContentWidth = BOX_SIZE + chartPainter.getStyleManager().getLegendPadding() + legendTextContentMaxWidth;
}
// Legend Box
int legendBoxWidth = legendContentWidth + 2 * chartPainter.getStyleManager().getLegendPadding();
int legendBoxHeight = legendContentHeight + 2 * chartPainter.getStyleManager().getLegendPadding();
return new int[] { legendBoxWidth, legendBoxHeight, maxContentHeight };
double legendBoxWidth = legendContentWidth + 2 * chartPainter.getStyleManager().getLegendPadding();
double legendBoxHeight = legendContentHeight + 2 * chartPainter.getStyleManager().getLegendPadding();
return new double[] { legendBoxWidth, legendBoxHeight, maxContentHeight };
} else {
return new int[] { 0, 0, 0 };
return new double[] { 0, 0, 0 };
}
}
......@@ -113,16 +117,19 @@ public class Legend implements ChartPart {
Map<Integer, Series> seriesMap = chartPainter.getAxisPair().getSeriesMap();
int legendBoxWidth = getSizeHint()[0];
int legendBoxHeight = getSizeHint()[1];
int maxContentHeight = getSizeHint()[2];
double legendBoxWidth = getSizeHint()[0];
double legendBoxHeight = getSizeHint()[1];
double maxContentHeight = getSizeHint()[2];
// System.out.println(legendBoxWidth);
// System.out.println(legendBoxHeight);
// System.out.println(maxContentHeight);
// legend draw position
int xOffset = 0;
int yOffset = 0;
switch (chartPainter.getStyleManager().getLegendPosition()) {
case OutsideE:
xOffset = chartPainter.getWidth() - legendBoxWidth - chartPainter.getStyleManager().getChartPadding();
xOffset = (int) (chartPainter.getWidth() - legendBoxWidth - chartPainter.getStyleManager().getChartPadding());
yOffset = (int) (chartPainter.getPlot().getBounds().getY() + (chartPainter.getPlot().getBounds().getHeight() - legendBoxHeight) / 2.0);
break;
case InsideNW:
......@@ -146,10 +153,11 @@ public class Legend implements ChartPart {
break;
}
g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
g.setColor(chartPainter.getStyleManager().getLegendBorderColor());
g.drawRect(xOffset, yOffset, legendBoxWidth, legendBoxHeight);
Rectangle2D rect = new Rectangle2D.Double(xOffset + 1, yOffset + 1, (int) (legendBoxWidth - 2), (int) (legendBoxHeight - 2));
g.setColor(chartPainter.getStyleManager().getLegendBackgroundColor());
g.fillRect(xOffset + 1, yOffset + 1, legendBoxWidth - 1, legendBoxHeight - 1);
g.fill(rect);
g.setColor(chartPainter.getStyleManager().getLegendBorderColor());
g.draw(rect);
// Draw legend content inside legend box
int startx = xOffset + chartPainter.getStyleManager().getLegendPadding();
......@@ -161,15 +169,18 @@ public class Legend implements ChartPart {
// paint line
if (getChartPainter().getStyleManager().getChartType() != ChartType.Scatter && series.getStroke() != null) {
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g.setColor(series.getStrokeColor());
g.setStroke(series.getStroke());
g.drawLine(startx, starty + (int) (maxContentHeight / 2.0), (int) (startx + Marker.SIZE * 3.0), starty + (int) (maxContentHeight / 2.0));
Shape line = new Line2D.Double(startx, (int) (starty + maxContentHeight / 2.0), (startx + Marker.SIZE * 3.0), (starty + maxContentHeight / 2.0));
g.draw(line);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
}
// paint marker
if (series.getMarker() != null) {
g.setColor(series.getMarkerColor());
series.getMarker().paint(g, (int) (startx + (Marker.SIZE * 1.5)), starty + (int) (maxContentHeight / 2.0));
series.getMarker().paint(g, (int) (startx + (Marker.SIZE * 1.5)), (int) (starty + maxContentHeight / 2.0));
}
} else {
// paint little box
......@@ -182,19 +193,20 @@ public class Legend implements ChartPart {
}
// paint series name
g.setColor(chartPainter.getStyleManager().getChartFontColor());
TextLayout layout = new TextLayout(series.getName(), chartPainter.getStyleManager().getLegendFont(), new FontRenderContext(null, true, false));
if (getChartPainter().getStyleManager().getChartType() != ChartType.Bar) {
layout.draw(g, (float) (startx + Marker.SIZE + (Marker.SIZE * 1.5) + chartPainter.getStyleManager().getLegendPadding()), starty
+ (int) ((maxContentHeight + layout.getPixelBounds(null, 0, 0).getHeight()) / 2.0));
+ (int) ((maxContentHeight - 1 + layout.getBounds().getHeight()) / 2.0));
} else {
layout.draw(g, startx + BOX_SIZE + chartPainter.getStyleManager().getLegendPadding(), starty + (int) ((maxContentHeight + layout.getPixelBounds(null, 0, 0).getHeight()) / 2.0));
layout.draw(g, startx + BOX_SIZE + chartPainter.getStyleManager().getLegendPadding(), starty + (int) ((maxContentHeight + layout.getBounds().getHeight()) / 2.0));
}
starty = starty + maxContentHeight + chartPainter.getStyleManager().getLegendPadding();
starty = (int) (starty + maxContentHeight + chartPainter.getStyleManager().getLegendPadding());
}
// bounds
bounds = new Rectangle(xOffset, yOffset, legendBoxWidth, legendBoxHeight);
bounds = new Rectangle(xOffset, yOffset, (int) (legendBoxWidth), (int) (legendBoxHeight));
// g.setColor(Color.blue);
// g.draw(bounds);
}
......
......@@ -16,6 +16,9 @@
package com.xeiam.xchart.internal.markers;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
/**
* @author timmolter
......@@ -26,7 +29,10 @@ public class Circle extends Marker {
public void paint(Graphics2D g, int xOffset, int yOffset) {
g.setStroke(stroke);
g.fillOval(xOffset + Marker.X_OFFSET, yOffset + Marker.Y_OFFSET, Marker.SIZE, Marker.SIZE);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Shape circle = new Ellipse2D.Double(xOffset + Marker.X_OFFSET, yOffset + Marker.Y_OFFSET, Marker.SIZE, Marker.SIZE);
g.fill(circle);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
}
......
......@@ -17,6 +17,8 @@ package com.xeiam.xchart.internal.markers;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Shape;
/**
* @author timmolter
......@@ -36,16 +38,18 @@ public class Diamond extends Marker {
int halfSize = (int) (Math.ceil((Marker.SIZE + 3) / 2.0));
x[0] = xOffset - halfSize + 0;
x[1] = xOffset - halfSize + halfSize;
x[2] = xOffset - halfSize + Marker.SIZE + 3;
x[2] = (int) (xOffset - halfSize + Marker.SIZE + 3);
x[3] = xOffset - halfSize + halfSize;
y[0] = 1 + yOffset - halfSize + halfSize;
y[1] = 1 + yOffset - halfSize + Marker.SIZE + 3;
y[1] = (int) (1 + yOffset - halfSize + Marker.SIZE + 3);
y[2] = 1 + yOffset - halfSize + halfSize;
y[3] = 1 + yOffset - halfSize + 0;
Polygon diamond = new Polygon(x, y, n);
g.fillPolygon(diamond);
Shape diamond = new Polygon(x, y, n);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g.fill(diamond);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
}
......
......@@ -25,10 +25,10 @@ public abstract class Marker {
protected BasicStroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL);
public static final int SIZE = 7; // make this an odd number!
public static final double SIZE = 8;
public static final int X_OFFSET = (int) (-1.0 * (SIZE / 2.0));
public static final int Y_OFFSET = (int) (-1.0 * (SIZE / 2.0));
public static final double X_OFFSET = (int) (-1.0 * (SIZE / 2.0));
public static final double Y_OFFSET = (int) (-1.0 * (SIZE / 2.0));
public abstract void paint(Graphics2D g, int xOffset, int yOffset);
}
......@@ -16,7 +16,9 @@
package com.xeiam.xchart.internal.markers;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
/**
* @author timmolter
......@@ -27,7 +29,10 @@ public class Square extends Marker {
public void paint(Graphics2D g, int xOffset, int yOffset) {
g.setStroke(stroke);
g.fill(new Rectangle(xOffset + Marker.X_OFFSET, yOffset + Marker.Y_OFFSET, Marker.SIZE, Marker.SIZE));
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Shape square = new Rectangle2D.Double(xOffset + Marker.X_OFFSET, yOffset + Marker.Y_OFFSET, Marker.SIZE, Marker.SIZE);
g.fill(square);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
}
......
......@@ -17,6 +17,8 @@ package com.xeiam.xchart.internal.markers;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Shape;
/**
* @author timmolter
......@@ -36,14 +38,16 @@ public class TriangleDown extends Marker {
int halfSize = (int) (Math.ceil((Marker.SIZE + 1) / 2.0));
x[0] = xOffset - halfSize + 0;
x[1] = xOffset - halfSize + halfSize;
x[2] = xOffset - halfSize + Marker.SIZE + 1;
x[2] = (int) (xOffset - halfSize + Marker.SIZE + 1);
y[0] = 1 + yOffset - halfSize + 0;
y[1] = 1 + yOffset - halfSize + Marker.SIZE + 1;
y[1] = (int) (1 + yOffset - halfSize + Marker.SIZE + 1);
y[2] = 1 + yOffset - halfSize + 0;
Polygon triangle = new Polygon(x, y, n);
g.fillPolygon(triangle);
Shape triangle = new Polygon(x, y, n);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g.fill(triangle);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
}
}
......@@ -17,6 +17,8 @@ package com.xeiam.xchart.internal.markers;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Shape;
/**
* @author timmolter
......@@ -35,15 +37,17 @@ public class TriangleUp extends Marker {
// Make a triangle
int halfSize = (int) (Math.ceil((Marker.SIZE + 1) / 2.0));
x[0] = xOffset - halfSize + 0;
x[1] = xOffset - halfSize + Marker.SIZE + 1;
x[1] = (int) (xOffset - halfSize + Marker.SIZE + 1);
x[2] = xOffset - halfSize + halfSize;
y[0] = yOffset - halfSize + Marker.SIZE + 1;
y[1] = yOffset - halfSize + Marker.SIZE + 1;
y[0] = (int) (yOffset - halfSize + Marker.SIZE + 1);
y[1] = (int) (yOffset - halfSize + Marker.SIZE + 1);
y[2] = yOffset - halfSize + 0;
Polygon triangle = new Polygon(x, y, n);
g.fillPolygon(triangle);
Shape triangle = new Polygon(x, y, n);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g.fill(triangle);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment