diff --git a/pom.xml b/pom.xml index c96eb763e710c42808a7bf4fe51ce29bb6113160..1931ddfc7e6140a440eee5e5e0e51f448dfbe280 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>com.xeiam.xchart</groupId> - <artifactId>xchart</artifactId> + <artifactId>xchart-parent</artifactId> <version>1.3.0-SNAPSHOT</version> <packaging>pom</packaging> <name>XChart</name> diff --git a/xchange-core/pom.xml b/xchange-core/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..be1e537a1a12334cb6f0501d16f4d7a69e792bad --- /dev/null +++ b/xchange-core/pom.xml @@ -0,0 +1,19 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.xeiam.xchart</groupId> + <artifactId>xchart-parent</artifactId> + <version>1.3.0-SNAPSHOT</version> + </parent> + + <artifactId>xchart-core</artifactId> + <!-- This version is tied to the version of the parent --> + <version>1.3.0-SNAPSHOT</version> + + <name>XChart Core</name> + <description> + </description> + +</project> diff --git a/src/main/java/com/xeiam/xchart/BitmapEncoder.java b/xchange-core/src/main/java/com/xeiam/xchart/BitmapEncoder.java similarity index 100% rename from src/main/java/com/xeiam/xchart/BitmapEncoder.java rename to xchange-core/src/main/java/com/xeiam/xchart/BitmapEncoder.java diff --git a/src/main/java/com/xeiam/xchart/Chart.java b/xchange-core/src/main/java/com/xeiam/xchart/Chart.java similarity index 100% rename from src/main/java/com/xeiam/xchart/Chart.java rename to xchange-core/src/main/java/com/xeiam/xchart/Chart.java diff --git a/src/main/java/com/xeiam/xchart/ChartColor.java b/xchange-core/src/main/java/com/xeiam/xchart/ChartColor.java similarity index 100% rename from src/main/java/com/xeiam/xchart/ChartColor.java rename to xchange-core/src/main/java/com/xeiam/xchart/ChartColor.java diff --git a/src/main/java/com/xeiam/xchart/QuickChart.java b/xchange-core/src/main/java/com/xeiam/xchart/QuickChart.java similarity index 100% rename from src/main/java/com/xeiam/xchart/QuickChart.java rename to xchange-core/src/main/java/com/xeiam/xchart/QuickChart.java diff --git a/src/main/java/com/xeiam/xchart/Series.java b/xchange-core/src/main/java/com/xeiam/xchart/Series.java similarity index 100% rename from src/main/java/com/xeiam/xchart/Series.java rename to xchange-core/src/main/java/com/xeiam/xchart/Series.java diff --git a/src/main/java/com/xeiam/xchart/SeriesColor.java b/xchange-core/src/main/java/com/xeiam/xchart/SeriesColor.java similarity index 100% rename from src/main/java/com/xeiam/xchart/SeriesColor.java rename to xchange-core/src/main/java/com/xeiam/xchart/SeriesColor.java diff --git a/src/main/java/com/xeiam/xchart/SeriesLineStyle.java b/xchange-core/src/main/java/com/xeiam/xchart/SeriesLineStyle.java similarity index 100% rename from src/main/java/com/xeiam/xchart/SeriesLineStyle.java rename to xchange-core/src/main/java/com/xeiam/xchart/SeriesLineStyle.java diff --git a/src/main/java/com/xeiam/xchart/SeriesMarker.java b/xchange-core/src/main/java/com/xeiam/xchart/SeriesMarker.java similarity index 100% rename from src/main/java/com/xeiam/xchart/SeriesMarker.java rename to xchange-core/src/main/java/com/xeiam/xchart/SeriesMarker.java diff --git a/src/main/java/com/xeiam/xchart/SwingWrapper.java b/xchange-core/src/main/java/com/xeiam/xchart/SwingWrapper.java similarity index 100% rename from src/main/java/com/xeiam/xchart/SwingWrapper.java rename to xchange-core/src/main/java/com/xeiam/xchart/SwingWrapper.java diff --git a/src/main/java/com/xeiam/xchart/XChartPanel.java b/xchange-core/src/main/java/com/xeiam/xchart/XChartPanel.java similarity index 100% rename from src/main/java/com/xeiam/xchart/XChartPanel.java rename to xchange-core/src/main/java/com/xeiam/xchart/XChartPanel.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/Axis.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/Axis.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/Axis.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/Axis.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickMarks.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickMarks.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickMarks.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickMarks.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTitle.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTitle.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/AxisTitle.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTitle.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/ChartTitle.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/ChartTitle.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/ChartTitle.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/ChartTitle.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/Plot.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/Plot.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/Plot.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/Plot.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContent.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContent.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/PlotContent.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContent.java diff --git a/src/main/java/com/xeiam/xchart/internal/chartpart/PlotSurface.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/PlotSurface.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/chartpart/PlotSurface.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/chartpart/PlotSurface.java diff --git a/src/main/java/com/xeiam/xchart/internal/interfaces/IChartPart.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/interfaces/IChartPart.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/interfaces/IChartPart.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/interfaces/IChartPart.java diff --git a/src/main/java/com/xeiam/xchart/internal/interfaces/IHideable.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/interfaces/IHideable.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/interfaces/IHideable.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/interfaces/IHideable.java diff --git a/src/main/java/com/xeiam/xchart/internal/markers/Circle.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/markers/Circle.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/markers/Circle.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/markers/Circle.java diff --git a/src/main/java/com/xeiam/xchart/internal/markers/Diamond.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/markers/Diamond.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/markers/Diamond.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/markers/Diamond.java diff --git a/src/main/java/com/xeiam/xchart/internal/markers/Marker.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/markers/Marker.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/markers/Marker.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/markers/Marker.java diff --git a/src/main/java/com/xeiam/xchart/internal/markers/Square.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/markers/Square.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/markers/Square.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/markers/Square.java diff --git a/src/main/java/com/xeiam/xchart/internal/markers/TriangleDown.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/markers/TriangleDown.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/markers/TriangleDown.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/markers/TriangleDown.java diff --git a/src/main/java/com/xeiam/xchart/internal/markers/TriangleUp.java b/xchange-core/src/main/java/com/xeiam/xchart/internal/markers/TriangleUp.java similarity index 100% rename from src/main/java/com/xeiam/xchart/internal/markers/TriangleUp.java rename to xchange-core/src/main/java/com/xeiam/xchart/internal/markers/TriangleUp.java diff --git a/src/test/java/com/xeiam/xchart/example/Example0.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example0.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example0.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example0.java diff --git a/src/test/java/com/xeiam/xchart/example/Example1.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example1.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example1.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example1.java diff --git a/src/test/java/com/xeiam/xchart/example/Example10.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example10.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example10.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example10.java diff --git a/src/test/java/com/xeiam/xchart/example/Example11.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example11.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example11.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example11.java diff --git a/src/test/java/com/xeiam/xchart/example/Example2.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example2.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example2.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example2.java diff --git a/src/test/java/com/xeiam/xchart/example/Example3.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example3.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example3.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example3.java diff --git a/src/test/java/com/xeiam/xchart/example/Example4.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example4.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example4.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example4.java diff --git a/src/test/java/com/xeiam/xchart/example/Example5.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example5.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example5.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example5.java diff --git a/src/test/java/com/xeiam/xchart/example/Example6.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example6.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example6.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example6.java diff --git a/src/test/java/com/xeiam/xchart/example/Example7.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example7.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example7.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example7.java diff --git a/src/test/java/com/xeiam/xchart/example/Example8.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example8.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example8.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example8.java diff --git a/src/test/java/com/xeiam/xchart/example/Example9.java b/xchange-core/src/test/java/com/xeiam/xchart/example/Example9.java similarity index 100% rename from src/test/java/com/xeiam/xchart/example/Example9.java rename to xchange-core/src/test/java/com/xeiam/xchart/example/Example9.java diff --git a/xchange-examples/pom.xml b/xchange-examples/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..dc4aec31235f643e5b394ab2c3d12c5e39b98dc8 --- /dev/null +++ b/xchange-examples/pom.xml @@ -0,0 +1,19 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.xeiam.xchart</groupId> + <artifactId>xchart-parent</artifactId> + <version>1.3.0-SNAPSHOT</version> + </parent> + + <artifactId>xchart-examples</artifactId> + <!-- This version is tied to the version of the parent --> + <version>1.3.0-SNAPSHOT</version> + + <name>XChart Examples</name> + <description> + </description> + +</project> diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/BitmapEncoder.java b/xchange-examples/src/main/java/com/xeiam/xchart/BitmapEncoder.java new file mode 100644 index 0000000000000000000000000000000000000000..463f10d6c20df269fcdeb920066ec0ba5bf55e6a --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/BitmapEncoder.java @@ -0,0 +1,95 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; + +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.FileImageOutputStream; + +/** + * A helper class with static methods for saving Charts as bitmaps + * + * @author timmolter + */ +public final class BitmapEncoder { + + /** + * Constructor - Private constructor to prevent instantiation + */ + private BitmapEncoder() { + + } + + /** + * Save a Chart as a PNG file + * + * @param chart + * @param fileName + * @throws IOException + */ + public static void savePNG(Chart chart, String fileName) throws IOException { + + BufferedImage bufferedImage = new BufferedImage(chart.width, chart.height, BufferedImage.TYPE_INT_RGB); + Graphics2D lGraphics2D = bufferedImage.createGraphics(); + chart.paint(lGraphics2D); + + // Save chart as PNG + OutputStream out = new FileOutputStream(fileName); + ImageIO.write(bufferedImage, "png", out); + out.close(); + } + + /** + * Save a Chart as a JPEG file + * + * @param chart + * @param fileName + * @param quality - // a float between 0 and 1 (1 = maximum quality) + * @throws FileNotFoundException + * @throws IOException + */ + public static void saveJPG(Chart chart, String fileName, float quality) throws FileNotFoundException, IOException { + + BufferedImage bufferedImage = new BufferedImage(chart.width, chart.height, BufferedImage.TYPE_INT_RGB); + Graphics2D lGraphics2D = bufferedImage.createGraphics(); + chart.paint(lGraphics2D); + + Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg"); + ImageWriter writer = iter.next(); + // instantiate an ImageWriteParam object with default compression options + ImageWriteParam iwp = writer.getDefaultWriteParam(); + iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + iwp.setCompressionQuality(quality); + File file = new File(fileName); + FileImageOutputStream output = new FileImageOutputStream(file); + writer.setOutput(output); + IIOImage image = new IIOImage(bufferedImage, null, null); + writer.write(null, image, iwp); + writer.dispose(); + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/Chart.java b/xchange-examples/src/main/java/com/xeiam/xchart/Chart.java new file mode 100644 index 0000000000000000000000000000000000000000..a63b0d37f352eaa07517dc573c4950e78ebdf201 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/Chart.java @@ -0,0 +1,345 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Locale; + +import com.xeiam.xchart.internal.chartpart.AxisPair; +import com.xeiam.xchart.internal.chartpart.ChartTitle; +import com.xeiam.xchart.internal.chartpart.Legend; +import com.xeiam.xchart.internal.chartpart.Plot; + +/** + * An XChart Chart + * + * @author timmolter + */ +public class Chart { + + public int width; + public int height; + private Color backgroundColor; + public Color bordersColor; + public Color fontColor; + + public final static int CHART_PADDING = 10; + + public ChartTitle chartTitle = new ChartTitle(this); + public Legend chartLegend = new Legend(this); + public AxisPair axisPair = new AxisPair(this); + protected Plot plot = new Plot(this); + + /** + * Constructor + * + * @param width + * @param height + */ + public Chart(int width, int height) { + + this.width = width; + this.height = height; + backgroundColor = ChartColor.getAWTColor(ChartColor.GREY); + bordersColor = ChartColor.getAWTColor(ChartColor.DARK_GREY); + fontColor = ChartColor.getAWTColor(ChartColor.BLACK); + } + + /** + * @param g + * @param width + * @param height + */ + public void paint(Graphics2D g, int width, int height) { + + this.width = width; + this.height = height; + + paint(g); + } + + /** + * @param g + */ + public void paint(Graphics2D g) { + + // Sanity check + if (axisPair.seriesMap.isEmpty()) { + throw new RuntimeException("No series defined for Chart!!!"); + } + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // global rendering hint + g.setColor(backgroundColor); + g.fillRect(0, 0, width, height); + + chartTitle.paint(g); + chartLegend.paint(g); + axisPair.paint(g); + plot.paint(g); + + g.dispose(); + + // reset static Ids + SeriesColor.resetId(); + SeriesLineStyle.resetId(); + SeriesMarker.resetId(); + + } + + // PUBLIC SETTERS + + /** + * @param seriesName + * @param xData + * @param yData + */ + public Series addDateSeries(String seriesName, Collection<Date> xData, Collection<Number> yData) { + + return axisPair.addSeries(seriesName, xData, yData, null); + } + + public Series addDateSeries(String seriesName, Collection<Date> xData, Collection<Number> yData, Collection<Number> errorBars) { + + return axisPair.addSeries(seriesName, xData, yData, errorBars); + } + + /** + * Add series data as Collection<Number> + * + * @param seriesName + * @param xData Collection<Number> + * @param yData Collection<Number> + * @return A Series object that you can set properties on + */ + public Series addSeries(String seriesName, Collection<Number> xData, Collection<Number> yData) { + + return axisPair.addSeries(seriesName, xData, yData, null); + } + + public Series addSeries(String seriesName, Collection<Number> xData, Collection<Number> yData, Collection<Number> errorBars) { + + return axisPair.addSeries(seriesName, xData, yData, errorBars); + } + + /** + * Convenience Method - Add series data as double arrays + * + * @param seriesName + * @param xData double[] + * @param yData double[] + * @return A Series object that you can set properties on + */ + public Series addSeries(String seriesName, double[] xData, double[] yData) { + + return addSeries(seriesName, xData, yData, null); + } + + /** + * Convenience Method - Add series data as double arrays with errorbars + * + * @param seriesName + * @param xData + * @param yData + * @param errorBars + * @return A Series object that you can set properties on + */ + public Series addSeries(String seriesName, double[] xData, double[] yData, double[] errorBars) { + + Collection<Number> xDataNumber = null; + if (xData != null) { + xDataNumber = new ArrayList<Number>(); + for (double d : xData) { + xDataNumber.add(new Double(d)); + } + } + Collection<Number> yDataNumber = new ArrayList<Number>(); + for (double d : yData) { + yDataNumber.add(new Double(d)); + } + Collection<Number> errorBarDataNumber = null; + if (errorBars != null) { + errorBarDataNumber = new ArrayList<Number>(); + for (double d : errorBars) { + errorBarDataNumber.add(new Double(d)); + } + } + + return axisPair.addSeries(seriesName, xDataNumber, yDataNumber, errorBarDataNumber); + } + + public void setTitle(String title) { + + this.chartTitle.setText(title); + } + + public void setXAxisTitle(String title) { + + this.axisPair.xAxis.axisTitle.setText(title); + } + + public void setYAxisTitle(String title) { + + this.axisPair.yAxis.axisTitle.setText(title); + } + + // ChartPart visibility //////////////////////////////// + + public void setTitleVisible(boolean isVisible) { + + this.chartTitle.setVisible(isVisible); + } + + public void setAxisTitlesVisible(boolean isVisible) { + + this.axisPair.xAxis.getAxisTitle().setVisible(isVisible); + this.axisPair.yAxis.getAxisTitle().setVisible(isVisible); + } + + public void setXAxisTitleVisible(boolean isVisible) { + + this.axisPair.xAxis.getAxisTitle().setVisible(isVisible); + } + + public void setYAxisTitleVisible(boolean isVisible) { + + this.axisPair.yAxis.getAxisTitle().setVisible(isVisible); + } + + public void setLegendVisible(boolean isVisible) { + + this.chartLegend.setVisible(isVisible); + } + + public void setAxisTicksVisible(boolean isVisible) { + + this.axisPair.xAxis.axisTick.setVisible(isVisible); + this.axisPair.yAxis.axisTick.setVisible(isVisible); + } + + public void setXAxisTicksVisible(boolean isVisible) { + + this.axisPair.xAxis.axisTick.setVisible(isVisible); + } + + public void setYAxisTicksVisible(boolean isVisible) { + + this.axisPair.yAxis.axisTick.setVisible(isVisible); + } + + public void setGridlinesVisible(boolean isVisible) { + + this.plot.plotSurface.setVisible(isVisible); + } + + public void setBackgroundColor(Color color) { + + this.backgroundColor = color; + } + + public void setForegroundColor(Color color) { + + this.plot.plotSurface.setForegroundColor(color); + } + + public void setGridLinesColor(Color color) { + + this.plot.plotSurface.setGridLinesColor(color); + } + + public void setLegendBackgroundColor(Color color) { + + this.chartLegend.backgroundColor = color; + } + + /** + * Sets the color of the plot border, legend border, tick marks, and error bars + * + * @param color + */ + public void setLinesColor(Color color) { + + this.bordersColor = color; + } + + public void setFontColor(Color color) { + + this.fontColor = color; + } + + public void setTitleFont(Font font) { + + this.chartTitle.font = font; + } + + public void setLegendFont(Font font) { + + this.chartLegend.font = font; + } + + public void setAxisTitleFont(Font font) { + + this.axisPair.xAxis.axisTitle.font = font; + this.axisPair.yAxis.axisTitle.font = font; + } + + public void setTickLabelFont(Font font) { + + this.axisPair.xAxis.axisTick.axisTickLabels.font = font; + this.axisPair.yAxis.axisTick.axisTickLabels.font = font; + } + + /** + * @param pattern - the pattern describing the date and time format + */ + public void setDateFormatter(String pattern) { + + this.axisPair.xAxis.axisTick.datePattern = pattern; + } + + /** + * @param pattern - the pattern describing the decimal format + */ + public void setDecmialFormatter(String pattern) { + + this.axisPair.xAxis.axisTick.normalDecimalPattern = pattern; + this.axisPair.yAxis.axisTick.normalDecimalPattern = pattern; + } + + /** + * @param pattern - the pattern describing the scientific notation format + */ + public void setDecmialScientificFormatter(String pattern) { + + this.axisPair.xAxis.axisTick.scientificDecimalPattern = pattern; + this.axisPair.yAxis.axisTick.scientificDecimalPattern = pattern; + } + + /** + * @param locale - the locale to use when drawing the chart + */ + public void setLocale(Locale locale) { + + this.axisPair.xAxis.axisTick.locale = locale; + this.axisPair.yAxis.axisTick.locale = locale; + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/ChartColor.java b/xchange-examples/src/main/java/com/xeiam/xchart/ChartColor.java new file mode 100644 index 0000000000000000000000000000000000000000..36a967ea513519490ef0a42456fce6638fefd679 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/ChartColor.java @@ -0,0 +1,65 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart; + +import java.awt.Color; + +/** + * Pre-defined Colors used for various Chart Elements + * + * @author timmolter + */ +public enum ChartColor { + + /** BLACK */ + BLACK(new Color(0, 0, 0)), + + /** DARK_GREY */ + DARK_GREY(new Color(22, 22, 22)), + + /** GREY */ + GREY(new Color(200, 200, 200)), + + /** LIGHT_GREY */ + LIGHT_GREY(new Color(252, 252, 252)), + + /** WHITE */ + WHITE(new Color(255, 255, 255)); + + Color color; + + /** + * Get a AWT Color Object + * + * @param chartColor + * @return a AWT Color Object + */ + public static Color getAWTColor(ChartColor chartColor) { + + return chartColor.color; + } + + /** + * Constructor + * + * @param color + */ + private ChartColor(Color color) { + + this.color = color; + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/QuickChart.java b/xchange-examples/src/main/java/com/xeiam/xchart/QuickChart.java new file mode 100644 index 0000000000000000000000000000000000000000..75931dec117ecadfa5ea1e84efb5823c6d3b6cb7 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/QuickChart.java @@ -0,0 +1,122 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart; + +import java.util.Collection; + +/** + * A convenience class for making Charts with one line of code + * + * @author timmolter + */ +public final class QuickChart { + + private final static int WIDTH = 600; + private final static int HEIGHT = 400; + + /** + * private Constructor + */ + private QuickChart() { + + } + + /** + * Creates a Chart with default style + * + * @param chartTitle the Chart title + * @param xTitle The X-Axis title + * @param yTitle The Y-Axis title + * @param seriesNames The name of the series + * @param xData An array containing the X-Axis data + * @param yData An array containing Y-Axis data + * @return a Chart Object + */ + public static Chart getChart(String chartTitle, String xTitle, String yTitle, String seriesName, double[] xData, double[] yData) { + + double[][] yData2d = { yData }; + if (seriesName == null) { + return getChart(chartTitle, xTitle, yTitle, null, xData, yData2d); + } else { + return getChart(chartTitle, xTitle, yTitle, new String[] { seriesName }, xData, yData2d); + } + } + + /** + * Creates a Chart with multiple Series for the same X-Axis data with default style + * + * @param chartTitle the Chart title + * @param xTitle The X-Axis title + * @param yTitle The Y-Axis title + * @param seriesNames An array of the name of the multiple series + * @param xData An array containing the X-Axis data + * @param yData An array of double arrays containing multiple Y-Axis data + * @return a Chart Object + */ + public static Chart getChart(String chartTitle, String xTitle, String yTitle, String[] seriesNames, double[] xData, double[][] yData) { + + // Create Chart + Chart chart = new Chart(WIDTH, HEIGHT); + + // Customize Chart + chart.setTitle(chartTitle); + chart.setXAxisTitle(xTitle); + chart.setYAxisTitle(yTitle); + + // Series + for (int i = 0; i < yData.length; i++) { + Series series; + if (seriesNames != null) { + series = chart.addSeries(seriesNames[i], xData, yData[i]); + } else { + chart.setLegendVisible(false); + series = chart.addSeries(" " + i, xData, yData[i]); + } + series.setMarker(SeriesMarker.NONE); + } + + return chart; + } + + /** + * Creates a Chart with default style + * + * @param chartTitle the Chart title + * @param xTitle The X-Axis title + * @param yTitle The Y-Axis title + * @param seriesNames The name of the series + * @param xData A Collection containing the X-Axis data + * @param yData A Collection containing Y-Axis data + * @return a Chart Object + */ + public static Chart getChart(String chartTitle, String xTitle, String yTitle, String seriesName, Collection<Number> xData, Collection<Number> yData) { + + // Create Chart + Chart chart = new Chart(WIDTH, HEIGHT); + + // Customize Chart + chart.setTitle(chartTitle); + chart.setXAxisTitle(xTitle); + chart.setYAxisTitle(yTitle); + + Series series = chart.addSeries(seriesName, xData, yData); + series.setMarker(SeriesMarker.NONE); + + return chart; + + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/Series.java b/xchange-examples/src/main/java/com/xeiam/xchart/Series.java new file mode 100644 index 0000000000000000000000000000000000000000..8997902cfec941e7e6eb650932cd94dc2ac4bd2a --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/Series.java @@ -0,0 +1,204 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.math.BigDecimal; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; + +import com.xeiam.xchart.internal.chartpart.Axis.AxisType; +import com.xeiam.xchart.internal.markers.Marker; + +/** + * A Series containing X and Y data to be plotted on a Chart + * + * @author timmolter + */ +public class Series { + + public String name = ""; + + public Collection<?> xData; + + public Collection<Number> yData; + + public Collection<Number> errorBars; + + /** the minimum value of axis range */ + public BigDecimal xMin; + + /** the maximum value of axis range */ + public BigDecimal xMax; + + /** the minimum value of axis range */ + public BigDecimal yMin; + + /** the maximum value of axis range */ + public BigDecimal yMax; + + /** Line Style */ + public BasicStroke stroke; + + /** Line Color */ + public Color strokeColor; + + /** Marker Style */ + public Marker marker; + + /** Marker Color */ + public Color markerColor; + + /** + * Constructor + * + * @param name + * @param xData + * @param xAxisType + * @param yData + * @param yAxisType + * @param errorBars + */ + public Series(String name, Collection<?> xData, AxisType xAxisType, Collection<Number> yData, AxisType yAxisType, Collection<Number> errorBars) { + + this.name = name; + this.xData = xData; + this.yData = yData; + this.errorBars = errorBars; + + // xData + BigDecimal[] xMinMax = findMinMax(xData, xAxisType); + xMin = xMinMax[0]; + xMax = xMinMax[1]; + + // yData + BigDecimal[] yMinMax = null; + if (errorBars == null) { + yMinMax = findMinMax(yData, yAxisType); + } else { + yMinMax = findMinMaxWithErrorBars(yData, errorBars); + } + yMin = yMinMax[0]; + yMax = yMinMax[1]; + // System.out.println(yMin); + // System.out.println(yMax); + + Color color = SeriesColor.getNextAWTColor(); + strokeColor = color; + markerColor = color; + + marker = SeriesMarker.getNextMarker(); + stroke = SeriesLineStyle.getNextBasicStroke(); + + } + + /** + * Finds the min and max of a dataset + * + * @param data + * @return + */ + private BigDecimal[] findMinMax(Collection<?> data, AxisType axisType) { + + BigDecimal min = null; + BigDecimal max = null; + + for (Object dataPoint : data) { + + BigDecimal bigDecimal = null; + + if (axisType == AxisType.NUMBER) { + bigDecimal = new BigDecimal(((Number) dataPoint).toString()); + + } else if (axisType == AxisType.DATE) { + Date date = (Date) dataPoint; + bigDecimal = new BigDecimal(date.getTime()); + } + if (min == null || bigDecimal.compareTo(min) < 0) { + min = bigDecimal; + } + if (max == null || bigDecimal.compareTo(max) > 0) { + max = bigDecimal; + } + } + + return new BigDecimal[] { min, max }; + } + + /** + * Finds the min and max of a dataset accounting for error bars + * + * @param data + * @return + */ + private BigDecimal[] findMinMaxWithErrorBars(Collection<Number> data, Collection<Number> errorBars) { + + BigDecimal min = null; + BigDecimal max = null; + + Iterator<Number> itr = data.iterator(); + Iterator<Number> ebItr = errorBars.iterator(); + while (itr.hasNext()) { + BigDecimal bigDecimal = new BigDecimal(itr.next().doubleValue()); + BigDecimal eb = new BigDecimal(ebItr.next().doubleValue()); + if (min == null || (bigDecimal.subtract(eb)).compareTo(min) < 0) { + min = bigDecimal.subtract(eb); + } + if (max == null || (bigDecimal.add(eb)).compareTo(max) > 0) { + max = bigDecimal.add(eb); + } + } + return new BigDecimal[] { min, max }; + } + + public void setLineStyle(SeriesLineStyle lineStyle) { + + stroke = SeriesLineStyle.getBasicStroke(lineStyle); + } + + public void setLineStyle(BasicStroke lineStyle) { + + stroke = lineStyle; + } + + public void setLineColor(SeriesColor lineColor) { + + strokeColor = SeriesColor.getAWTColor(lineColor); + } + + public void setLineColor(java.awt.Color lineColor) { + + strokeColor = lineColor; + } + + public void setMarker(SeriesMarker marker) { + + this.marker = SeriesMarker.getMarker(marker); + } + + public void setMarkerColor(SeriesColor lineColor) { + + this.markerColor = SeriesColor.getAWTColor(lineColor); + } + + public void setMarkerColor(java.awt.Color lineColor) { + + this.markerColor = lineColor; + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/SeriesColor.java b/xchange-examples/src/main/java/com/xeiam/xchart/SeriesColor.java new file mode 100644 index 0000000000000000000000000000000000000000..993692ece059b272c58c59abb5e78db207d8aff2 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/SeriesColor.java @@ -0,0 +1,118 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart; + +import java.awt.Color; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +/** + * Pre-defined Colors used for Series Lines and Markers + * + * @author timmolter + */ +public enum SeriesColor { + + /** BLUE */ + BLUE(0, new Color(0, 55, 255)), + + /** ORANGE */ + ORANGE(1, new Color(255, 172, 0)), + + /** PURPLE */ + PURPLE(2, new Color(128, 0, 255)), + + /** GREEN */ + GREEN(3, new Color(0, 205, 0)), + + /** RED */ + RED(4, new Color(205, 0, 0)), + + /** YELLOW */ + YELLOW(5, new Color(255, 215, 0)), + + /** MAGENTA */ + MAGENTA(6, new Color(255, 0, 255)), + + /** PINK */ + PINK(7, new Color(255, 166, 201)), + + /** LIGHT_GREY */ + LIGHT_GREY(8, new Color(207, 207, 207)), + + /** CYAN */ + CYAN(9, new Color(0, 255, 255)), + + /** BROWN */ + BROWN(10, new Color(150, 74, 0)), + + /** BLACK */ + BLACK(11, new Color(0, 0, 0)), + + /** RANDOM */ + RANDOM(12, new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255))); + + int id; + Color color; + + private static int nextId = 0; + + private static final Map<Integer, SeriesColor> idLookup = new HashMap<Integer, SeriesColor>(); + static { + for (SeriesColor seriesColor : EnumSet.allOf(SeriesColor.class)) { + idLookup.put(seriesColor.getId(), seriesColor); + } + } + + private Integer getId() { + + return id; + } + + protected static void resetId() { + + nextId = 0; + } + + protected static Color getAWTColor(SeriesColor seriesColor) { + + return seriesColor.color; + } + + protected static Color getNextAWTColor() { + + SeriesColor seriesColor = idLookup.get(nextId); + if (seriesColor == null) { + // rotate thru from beginning + resetId(); + } + return idLookup.get(nextId++).color; + } + + /** + * Constructor + * + * @param id + * @param color + */ + private SeriesColor(int id, Color color) { + + this.id = id; + this.color = color; + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/SeriesLineStyle.java b/xchange-examples/src/main/java/com/xeiam/xchart/SeriesLineStyle.java new file mode 100644 index 0000000000000000000000000000000000000000..cc17433d20f5e32193711600010ea801a096228b --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/SeriesLineStyle.java @@ -0,0 +1,106 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart; + +import java.awt.BasicStroke; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +/** + * Pre-defined Line Styles used for Series Lines + * + * @author timmolter + */ +public enum SeriesLineStyle { + + /** NONE */ + NONE(-1, null), + + /** SOLID */ + SOLID(0, new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)), + + /** DASH_DOT */ + DASH_DOT(1, new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10.0f, new float[] { 3.0f, 1.0f }, 0.0f)), + + /** DASH_DASH */ + DASH_DASH(2, new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10.0f, new float[] { 3.0f, 3.0f }, 0.0f)), + + /** DOT_DOT */ + DOT_DOT(3, new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10.0f, new float[] { 1.0f, 1.0f }, 0.0f)); + + int id; + + BasicStroke basicStroke; + + private static int nextId = 0; + + /** + * Constructor + * + * @param id + * @param color + */ + private SeriesLineStyle(int id, BasicStroke basicStroke) { + + this.id = id; + this.basicStroke = basicStroke; + } + + private static final Map<Integer, SeriesLineStyle> idLookup = new HashMap<Integer, SeriesLineStyle>(); + static { + for (SeriesLineStyle seriesLineStyle : EnumSet.allOf(SeriesLineStyle.class)) { + idLookup.put(seriesLineStyle.getId(), seriesLineStyle); + } + } + + private Integer getId() { + + return id; + } + + protected static void resetId() { + + nextId = 0; + } + + /** + * Get an AWT Stroke + * + * @param seriesMarker + * @return an AWT Stroke + */ + protected static BasicStroke getBasicStroke(SeriesLineStyle seriesMarker) { + + return seriesMarker.basicStroke; + } + + /** + * Gets the next BasicStroke + * + * @return the next BasicStroke + */ + protected static BasicStroke getNextBasicStroke() { + + SeriesLineStyle seriesLineStyle = idLookup.get(nextId); + if (seriesLineStyle == null) { + // rotate thru from beginning + resetId(); + } + return idLookup.get(nextId++).basicStroke; + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/SeriesMarker.java b/xchange-examples/src/main/java/com/xeiam/xchart/SeriesMarker.java new file mode 100644 index 0000000000000000000000000000000000000000..a380236822ec29b5c7c75556319dc9fb2a501c3f --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/SeriesMarker.java @@ -0,0 +1,102 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +import com.xeiam.xchart.internal.markers.Circle; +import com.xeiam.xchart.internal.markers.Diamond; +import com.xeiam.xchart.internal.markers.Marker; +import com.xeiam.xchart.internal.markers.Square; +import com.xeiam.xchart.internal.markers.TriangleDown; +import com.xeiam.xchart.internal.markers.TriangleUp; + +/** + * Pre-defined Markers used for Series Lines + * + * @author timmolter + */ +public enum SeriesMarker { + + /** NONE */ + NONE(-1, null), + + /** CIRCLE */ + CIRCLE(0, new Circle()), + + /** DIAMOND */ + DIAMOND(1, new Diamond()), + + /** SQUARE */ + SQUARE(2, new Square()), + + /** TRIANGLE_DOWN */ + TRIANGLE_DOWN(3, new TriangleDown()), + + /** TRIANGLE_UP */ + TRIANGLE_UP(4, new TriangleUp()); + + int id; + Marker marker; + private static int nextId = 0; + + private static final Map<Integer, SeriesMarker> idLookup = new HashMap<Integer, SeriesMarker>(); + static { + for (SeriesMarker seriesMarker : EnumSet.allOf(SeriesMarker.class)) { + idLookup.put(seriesMarker.getId(), seriesMarker); + } + } + + private Integer getId() { + + return id; + } + + protected static void resetId() { + + nextId = 0; + } + + protected static Marker getMarker(SeriesMarker seriesMarker) { + + return seriesMarker.marker; + } + + protected static Marker getNextMarker() { + + SeriesMarker seriesMarker = idLookup.get(nextId); + if (seriesMarker == null) { + // rotate thru from beginning + resetId(); + } + return idLookup.get(nextId++).marker; + } + + /** + * Constructor + * + * @param id + * @param color + */ + private SeriesMarker(int id, Marker marker) { + + this.id = id; + this.marker = marker; + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/SwingWrapper.java b/xchange-examples/src/main/java/com/xeiam/xchart/SwingWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..109ff8e5f6bb28cc407ed715015801c2580c2d57 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/SwingWrapper.java @@ -0,0 +1,133 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart; + +import java.awt.GridLayout; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +/** + * A convenience class used to display a Chart in a barebones Swing application + * + * @author timmolter + */ +public class SwingWrapper { + + private List<Chart> charts = new ArrayList<Chart>(); + private int numRows; + private int numColumns; + + /** + * Constructor + * + * @param chart + */ + public SwingWrapper(Chart chart) { + + this.charts.add(chart); + } + + /** + * Constructor - The number of rows and columns will be calculated automatically Constructor + * + * @param charts + */ + public SwingWrapper(List<Chart> charts) { + + this.charts = charts; + + this.numRows = (int) (Math.sqrt(charts.size()) + .5); + this.numColumns = (int) ((double) charts.size() / this.numRows + 1); + } + + /** + * Constructor + * + * @param charts + * @param numRows - the number of rows + * @param numColumns - the number of columns + */ + public SwingWrapper(List<Chart> charts, int numRows, int numColumns) { + + this.charts = charts; + this.numRows = numRows; + this.numColumns = numColumns; + } + + /** + * Display the chart in a Swing JFrame + */ + public void displayChart() { + + // Schedule a job for the event-dispatching thread: + // creating and showing this application's GUI. + javax.swing.SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + // Create and set up the window. + JFrame frame = new JFrame("XChart"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + JPanel chartPanel = new XChartPanel(charts.get(0)); + frame.add(chartPanel); + + // Display the window. + frame.pack(); + frame.setVisible(true); + } + }); + } + + /** + * Display the chart in a Swing JFrame + */ + public void displayChartMatrix() { + + // Schedule a job for the event-dispatching thread: + // creating and showing this application's GUI. + javax.swing.SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + // Create and set up the window. + JFrame frame = new JFrame("XChart"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().setLayout(new GridLayout(numRows, numColumns)); + + for (Chart chart : charts) { + if (chart != null) { + JPanel chartPanel = new XChartPanel(chart); + frame.add(chartPanel); + } else { + JPanel chartPanel = new JPanel(); + frame.getContentPane().add(chartPanel); + } + + } + + // Display the window. + frame.pack(); + frame.setVisible(true); + } + }); + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/XChartPanel.java b/xchange-examples/src/main/java/com/xeiam/xchart/XChartPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..76688bd85014d09528258bcbbfbe21a50f01cd2f --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/XChartPanel.java @@ -0,0 +1,57 @@ +/** + * Copyright 2012 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; + +import javax.swing.JPanel; + +/** + * A Swing JPanel that contains a Chart + * + * @author timmolter + */ +public class XChartPanel extends JPanel { + + private final Chart chart; + + /** + * Constructor + * + * @param chart + */ + public XChartPanel(final Chart chart) { + + this.chart = chart; + + } + + @Override + protected void paintComponent(Graphics g) { + + super.paintComponent(g); + + chart.paint((Graphics2D) g, getWidth(), getHeight()); + } + + @Override + public Dimension getPreferredSize() { + + return new Dimension(chart.width, chart.height); + } +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/Axis.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/Axis.java new file mode 100644 index 0000000000000000000000000000000000000000..7eacf787be4859cfbf2f4030bf4dae7e599e665c --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/Axis.java @@ -0,0 +1,230 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; +import java.math.BigDecimal; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.internal.interfaces.IChartPart; + +/** + * Axis + * + * @author timmolter + */ +public class Axis implements IChartPart { + + public enum AxisType { + + NUMBER, DATE; + } + + /** parent */ + protected AxisPair axisPair; + + /** the axisType */ + protected AxisType axisType; + + /** the axis title */ + public AxisTitle axisTitle; + + /** the axis tick */ + public AxisTick axisTick; + + /** the axis direction */ + protected Direction direction; + + protected BigDecimal min = null; + + protected BigDecimal max = null; + + /** the bounds */ + private Rectangle bounds; + + /** the paint zone */ + private Rectangle paintZone; + + /** An axis direction */ + protected enum Direction { + + /** the constant to represent X axis */ + X, + + /** the constant to represent Y axis */ + Y + } + + /** + * Constructor + * + * @param direction the axis direction (X or Y) + * @param chart the chart + */ + protected Axis(AxisPair axisPair, Direction direction) { + + this.axisPair = axisPair; + this.direction = direction; + + axisTitle = new AxisTitle(this); + axisTick = new AxisTick(this); + } + + /** + * @param min + * @param max + */ + protected void addMinMax(BigDecimal min, BigDecimal max) { + + // System.out.println(min); + // System.out.println(max); + if (this.min == null || min.compareTo(this.min) < 0) { + this.min = min; + } + if (this.max == null || max.compareTo(this.max) > 0) { + this.max = max; + } + + // System.out.println(this.min); + // System.out.println(this.max); + } + + protected void setAxisType(AxisType axisType) { + + if (this.axisType != null && this.axisType != axisType) { + throw new IllegalArgumentException("Date and Number Axes cannot be mixed on the same chart!! "); + } + this.axisType = axisType; + } + + @Override + public Rectangle getBounds() { + + return bounds; + } + + protected Rectangle getPaintZone() { + + return paintZone; + } + + public AxisTitle getAxisTitle() { + + return axisTitle; + } + + protected void setAxisTitle(AxisTitle axisTitle) { + + this.axisTitle = axisTitle; + } + + /** + * @return + */ + protected int getSizeHint() { + + if (direction == Direction.X) { // X-Axis + + // Axis title + double titleHeight = 0.0; + if (axisTitle.isVisible) { + TextLayout textLayout = new TextLayout(axisTitle.getText(), axisTitle.getFont(), new FontRenderContext(null, true, false)); + Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0); + titleHeight = rectangle.getHeight() + AxisTitle.AXIS_TITLE_PADDING; + } + + // Axis tick labels + double axisTickLabelsHeight = 0.0; + if (axisTick.isVisible) { + TextLayout textLayout = new TextLayout("0", axisTick.axisTickLabels.font, new FontRenderContext(null, true, false)); + Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0); + axisTickLabelsHeight = rectangle.getHeight() + AxisTick.AXIS_TICK_PADDING + AxisTickMarks.TICK_LENGTH + Plot.PLOT_PADDING; + } + return (int) (titleHeight + axisTickLabelsHeight); + } else { // Y-Axis + return 0; // We layout the yAxis first depending in the xAxis height hint. We don't care about the yAxis height hint + } + } + + @Override + public void paint(Graphics2D g) { + + paintZone = new Rectangle(); + bounds = new Rectangle(); + + // determine Axis bounds + if (direction == Direction.Y) { // Y-Axis + + // calculate paint zone + // ---- + // | + // | + // | + // | + // ---- + int xOffset = Chart.CHART_PADDING; + int yOffset = (int) (axisPair.getChartTitleBounds().getY() + axisPair.getChartTitleBounds().getHeight() + Chart.CHART_PADDING); + int width = 80; // arbitrary, final width depends on Axis tick labels + int height = axisPair.chart.height - yOffset - axisPair.xAxis.getSizeHint() - Chart.CHART_PADDING; + Rectangle yAxisRectangle = new Rectangle(xOffset, yOffset, width, height); + this.paintZone = yAxisRectangle; + // g.setColor(Color.green); + // g.draw(yAxisRectangle); + + // fill in Axis with sub-components + axisTitle.paint(g); + axisTick.paint(g); + + xOffset = (int) paintZone.getX(); + yOffset = (int) paintZone.getY(); + width = (int) (axisTitle.isVisible ? axisTitle.getBounds().getWidth() : 0) + (int) axisTick.getBounds().getWidth(); + height = (int) paintZone.getHeight(); + bounds = new Rectangle(xOffset, yOffset, width, height); + // g.setColor(Color.yellow); + // g.draw(bounds); + + } else { // X-Axis + + // calculate paint zone + // |____________________| + + int xOffset = (int) (axisPair.yAxis.getBounds().getWidth() + (axisPair.yAxis.axisTick.isVisible ? Plot.PLOT_PADDING : 0) + Chart.CHART_PADDING); + int yOffset = (int) (axisPair.yAxis.getBounds().getY() + axisPair.yAxis.getBounds().getHeight()); + int width = (int) (axisPair.chart.width - axisPair.yAxis.getBounds().getWidth() - axisPair.getChartLegendBounds().getWidth() - (axisPair.chart.chartLegend.isVisible ? 3 : 2) * Chart.CHART_PADDING); + int height = this.getSizeHint(); + Rectangle xAxisRectangle = new Rectangle(xOffset, yOffset, width, height); + this.paintZone = xAxisRectangle; + // g.setColor(Color.green); + // g.draw(xAxisRectangle); + + axisTitle.paint(g); + axisTick.paint(g); + + xOffset = (int) paintZone.getX(); + yOffset = (int) paintZone.getY(); + width = (int) paintZone.getWidth(); + height = (int) ((axisTitle.isVisible ? axisTitle.getBounds().getHeight() : 0) + (int) axisTick.getBounds().getHeight()); + bounds = new Rectangle(xOffset, yOffset, width, height); + bounds = new Rectangle(xOffset, yOffset, width, height); + // g.setColor(Color.yellow); + // g.draw(bounds); + } + + } +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java new file mode 100644 index 0000000000000000000000000000000000000000..e51aec8c4ddd0e178e085d4cdceb462aa88eff56 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java @@ -0,0 +1,156 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.Series; +import com.xeiam.xchart.internal.chartpart.Axis.AxisType; +import com.xeiam.xchart.internal.interfaces.IChartPart; + +/** + * @author timmolter + */ +public class AxisPair implements IChartPart { + + /** parent */ + protected Chart chart; + + public Map<Integer, Series> seriesMap = new LinkedHashMap<Integer, Series>(); + + private int seriesCount; + + public Axis xAxis; + public Axis yAxis; + + /** + * Constructor. + * + * @param chart the chart + */ + public AxisPair(Chart chart) { + + this.chart = chart; + seriesCount = 0; + + // add axes + xAxis = new Axis(this, Axis.Direction.X); + yAxis = new Axis(this, Axis.Direction.Y); + } + + /** + * @param <T> + * @param xData + * @param yData + */ + public <T> Series addSeries(String seriesName, Collection<T> xData, Collection<Number> yData, Collection<Number> errorBars) { + + // Sanity checks + if (seriesName == null) { + throw new IllegalArgumentException("Series Name cannot be null!!!"); + } + if (yData == null) { + throw new IllegalArgumentException("Y-Axis data cannot be null!!!"); + } + if (yData.size() == 0) { + throw new IllegalArgumentException("Y-Axis data cannot be empty!!!"); + } + if (xData != null && xData.size() == 0) { + throw new IllegalArgumentException("X-Axis data cannot be empty!!!"); + } + + Series series = null; + if (xData != null) { + // Check if xAxis series contains Number or Date data + Iterator<?> itr = xData.iterator(); + Object dataPoint = itr.next(); + if (dataPoint instanceof Number) { + xAxis.setAxisType(AxisType.NUMBER); + } else if (dataPoint instanceof Date) { + xAxis.setAxisType(AxisType.DATE); + } + yAxis.setAxisType(AxisType.NUMBER); + series = new Series(seriesName, xData, xAxis.axisType, yData, yAxis.axisType, errorBars); + } else { // generate xData + Collection<Number> generatedXData = new ArrayList<Number>(); + for (int i = 1; i < yData.size(); i++) { + generatedXData.add(i); + } + xAxis.setAxisType(AxisType.NUMBER); + yAxis.setAxisType(AxisType.NUMBER); + series = new Series(seriesName, generatedXData, xAxis.axisType, yData, yAxis.axisType, errorBars); + } + + // Sanity check + if (xData != null && xData.size() != yData.size()) { + throw new IllegalArgumentException("X and Y-Axis sizes are not the same!!! "); + } + if (errorBars != null && errorBars.size() != yData.size()) { + throw new IllegalArgumentException("errorbars and Y-Axis sizes are not the same!!! "); + } + + seriesMap.put(seriesCount++, series); + + // add min/max to axis + xAxis.addMinMax(series.xMin, series.xMax); + yAxis.addMinMax(series.yMin, series.yMax); + + return series; + } + + protected Rectangle getChartTitleBounds() { + + return chart.chartTitle.getBounds(); + } + + protected Rectangle getChartLegendBounds() { + + return chart.chartLegend.getBounds(); + } + + protected static int getTickSpace(int workingSpace) { + + return (int) (workingSpace * 0.95); + } + + protected static int getMargin(int workingSpace, int tickSpace) { + + int marginSpace = workingSpace - tickSpace; + return (int) (marginSpace / 2.0); + } + + @Override + public void paint(Graphics2D g) { + + yAxis.paint(g); + xAxis.paint(g); + } + + @Override + public Rectangle getBounds() { + + return null; // should never be called + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java new file mode 100644 index 0000000000000000000000000000000000000000..4004eb8f2d5fdd05d664c2c7d339428cc3ee3432 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java @@ -0,0 +1,286 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; + +import com.xeiam.xchart.internal.chartpart.Axis.AxisType; +import com.xeiam.xchart.internal.chartpart.Axis.Direction; +import com.xeiam.xchart.internal.interfaces.IChartPart; +import com.xeiam.xchart.internal.interfaces.IHideable; + +/** + * An axis tick. + */ +public class AxisTick implements IChartPart, IHideable { + + /** the default tick mark step hint for x axis */ + private static final int DEFAULT_TICK_MARK_STEP_HINT_X = 74; + + /** the default tick mark step hint for y axis */ + private static final int DEFAULT_TICK_MARK_STEP_HINT_Y = 44; + + /** the padding between the tick labels and the tick marks */ + protected final static int AXIS_TICK_PADDING = 4; + + /** parent */ + protected Axis axis; + + /** the axisticklabels */ + public AxisTickLabels axisTickLabels; + + /** the axistickmarks */ + protected AxisTickMarks axisTickMarks; + + /** the arraylist of tick label position in pixels */ + protected List<Integer> tickLocations; + + /** the arraylist of tick label values */ + protected List<String> tickLabels; + + private int workingSpace; + + /** the Locale for Date tick labels */ + public Locale locale; + + public String normalDecimalPattern; + public String scientificDecimalPattern; + public String datePattern; + + /** the bounds */ + private Rectangle bounds; + + /** the visibility state of axistick */ + protected boolean isVisible = true; // default to true + + /** + * Constructor + * + * @param axis the axis + */ + protected AxisTick(Axis axis) { + + this.axis = axis; + axisTickLabels = new AxisTickLabels(this); + axisTickMarks = new AxisTickMarks(this); + + // formatting + locale = Locale.getDefault(); + normalDecimalPattern = "#.####"; + scientificDecimalPattern = "0.##E0"; + datePattern = "HHmmss"; + + } + + @Override + public Rectangle getBounds() { + + return bounds; + } + + @Override + public void paint(Graphics2D g) { + + bounds = new Rectangle(); + + if (axis.direction == Axis.Direction.Y) { + workingSpace = (int) axis.getPaintZone().getHeight(); // number of pixels the axis has to work with for drawing AxisTicks + // System.out.println("workingspace= " + workingSpace); + } else { + workingSpace = (int) axis.getPaintZone().getWidth(); // number of pixels the axis has to work with for drawing AxisTicks + // System.out.println("workingspace= " + workingSpace); + } + + determineAxisTick(); + + // for (Integer position : tickLocations) { + // System.out.println(position); + // } + // for (String label : tickLabels) { + // System.out.println(label); + // } + + if (isVisible) { + axisTickLabels.paint(g); + axisTickMarks.paint(g); + + if (axis.direction == Axis.Direction.Y) { + bounds = new Rectangle((int) axisTickLabels.getBounds().getX(), (int) (axisTickLabels.getBounds().getY()), (int) (axisTickLabels.getBounds().getWidth() + AXIS_TICK_PADDING + axisTickMarks + .getBounds().getWidth()), (int) (axisTickMarks.getBounds().getHeight())); + // g.setColor(Color.red); + // g.draw(bounds); + } else { + bounds = new Rectangle((int) axisTickMarks.getBounds().getX(), (int) (axisTickMarks.getBounds().getY()), (int) axisTickLabels.getBounds().getWidth(), (int) (axisTickMarks.getBounds() + .getHeight() + + AXIS_TICK_PADDING + axisTickLabels.getBounds().getHeight())); + // g.setColor(Color.red); + // g.draw(bounds); + } + } + + } + + /** + * + */ + private void determineAxisTick() { + + tickLocations = new LinkedList<Integer>(); + tickLabels = new LinkedList<String>(); + + // System.out.println("workingSpace= " + workingSpace); + + int tickSpace = AxisPair.getTickSpace(workingSpace); + // System.out.println("tickSpace= " + tickSpace); + + int margin = AxisPair.getMargin(workingSpace, tickSpace); + + // a check if all axis data are the exact same values + if (axis.max == axis.min) { + tickLabels.add(format(axis.max)); + tickLocations.add((int) (margin + tickSpace / 2.0)); + } else { + + final BigDecimal min = new BigDecimal(axis.min.doubleValue()); + BigDecimal firstPosition; + BigDecimal gridStep = getGridStep(tickSpace); + + double xyz = min.remainder(gridStep).doubleValue(); + if (xyz <= 0.0) { + firstPosition = min.subtract(min.remainder(gridStep)); + } else { + firstPosition = min.subtract(min.remainder(gridStep)).add(gridStep); + } + + for (BigDecimal b = firstPosition; b.compareTo(axis.max) <= 0; b = b.add(gridStep)) { + + // System.out.println("b= " + b); + tickLabels.add(format(b)); + int tickLabelPosition = (int) (margin + ((b.subtract(axis.min)).doubleValue() / (axis.max.subtract(axis.min)).doubleValue() * tickSpace)); + // System.out.println("tickLabelPosition= " + tickLabelPosition); + + tickLocations.add(tickLabelPosition); + } + } + } + + private BigDecimal getGridStep(int tickSpace) { + + double length = Math.abs(axis.max.subtract(axis.min).doubleValue()); + // System.out.println(axis.getMax()); + // System.out.println(axis.min); + // System.out.println(length); + int tickMarkSpaceHint = (axis.direction == Direction.X ? DEFAULT_TICK_MARK_STEP_HINT_X : DEFAULT_TICK_MARK_STEP_HINT_Y); + double gridStepHint = length / tickSpace * tickMarkSpaceHint; + + // gridStepHint --> mantissa * 10 ** exponent + // e.g. 724.1 --> 7.241 * 10 ** 2 + double mantissa = gridStepHint; + int exponent = 0; + if (mantissa == 0) { + exponent = 1; + } else if (mantissa < 1) { + while (mantissa < 1) { + mantissa *= 10.0; + exponent--; + } + } else { + while (mantissa >= 10) { + mantissa /= 10.0; + exponent++; + } + } + + // calculate the grid step with hint. + BigDecimal gridStep; + if (mantissa > 7.5) { + // gridStep = 10.0 * 10 ** exponent + gridStep = BigDecimal.TEN.multiply(pow(10, exponent)); + } else if (mantissa > 3.5) { + // gridStep = 5.0 * 10 ** exponent + gridStep = new BigDecimal(new Double(5).toString()).multiply(pow(10, exponent)); + } else if (mantissa > 1.5) { + // gridStep = 2.0 * 10 ** exponent + gridStep = new BigDecimal(new Double(2).toString()).multiply(pow(10, exponent)); + } else { + // gridStep = 1.0 * 10 ** exponent + gridStep = pow(10, exponent); + } + return gridStep; + } + + /** + * Calculates the value of the first argument raised to the power of the second argument. + * + * @param base the base + * @param exponent the exponent + * @return the value <tt>a<sup>b</sup></tt> in <tt>BigDecimal</tt> + */ + private BigDecimal pow(double base, int exponent) { + + BigDecimal value; + if (exponent > 0) { + value = new BigDecimal(new Double(base).toString()).pow(exponent); + } else { + value = BigDecimal.ONE.divide(new BigDecimal(new Double(base).toString()).pow(-exponent)); + } + return value; + } + + private String format(BigDecimal value) { + + if (axis.axisType == AxisType.NUMBER) { + + NumberFormat nf = NumberFormat.getNumberInstance(locale); + + if (Math.abs(value.doubleValue()) <= 9999 && Math.abs(value.doubleValue()) > .01 || value.doubleValue() == 0) { + + DecimalFormat normalFormat = (DecimalFormat) nf; + normalFormat.applyPattern(normalDecimalPattern); + return normalFormat.format(value.doubleValue()); + + } else { + + DecimalFormat scientificFormat = (DecimalFormat) nf; + scientificFormat.applyPattern(scientificDecimalPattern); + return scientificFormat.format(value.doubleValue()); + + } + } else { + + // TODO set this more intelligently + SimpleDateFormat simpleDateformat = new SimpleDateFormat(datePattern, locale); + simpleDateformat.applyPattern(datePattern); + return simpleDateformat.format(value.longValueExact()); + + } + + } + + @Override + public void setVisible(boolean isVisible) { + + this.isVisible = isVisible; + } +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java new file mode 100644 index 0000000000000000000000000000000000000000..74dbd943f4a06f932bf0a90f8f53a24173572080 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java @@ -0,0 +1,120 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; + +import com.xeiam.xchart.internal.interfaces.IChartPart; + +/** + * Axis tick labels + */ +public class AxisTickLabels implements IChartPart { + + /** parent */ + private final AxisTick axisTick; + + /** the font */ + public Font font; + + /** the bounds */ + private Rectangle bounds; + + /** + * Constructor + * + * @param axisTick + */ + protected AxisTickLabels(AxisTick axisTick) { + + this.axisTick = axisTick; + font = new Font(Font.SANS_SERIF, Font.BOLD, 12); // default font + } + + @Override + public Rectangle getBounds() { + + return bounds; + } + + @Override + public void paint(Graphics2D g) { + + bounds = new Rectangle(); + g.setFont(font); + + g.setColor(axisTick.axis.axisPair.chart.fontColor); + + if (axisTick.axis.direction == Axis.Direction.Y) { // Y-Axis + + int xOffset = (int) (axisTick.axis.getAxisTitle().getBounds().getX() + axisTick.axis.getAxisTitle().getBounds().getWidth()); + int yOffset = (int) (axisTick.axis.getPaintZone().getY()); + int maxTickLabelWidth = 0; + for (int i = 0; i < axisTick.tickLabels.size(); i++) { + + String tickLabel = axisTick.tickLabels.get(i); + // System.out.println(tickLabel); + int tickLocation = axisTick.tickLocations.get(i); + + FontRenderContext frc = g.getFontRenderContext(); + // TextLayout layout = new TextLayout(tickLabel, font, new FontRenderContext(null, true, false)); + TextLayout layout = new TextLayout(tickLabel, font, frc); + Rectangle tickLabelBounds = layout.getPixelBounds(null, 0, 0); + layout.draw(g, xOffset, (int) (yOffset + axisTick.axis.getPaintZone().getHeight() - tickLocation + tickLabelBounds.getHeight() / 2.0)); + + if (tickLabelBounds.getWidth() > maxTickLabelWidth) { + maxTickLabelWidth = (int) tickLabelBounds.getWidth(); + } + } + + // bounds + bounds = new Rectangle(xOffset, yOffset, maxTickLabelWidth, (int) axisTick.axis.getPaintZone().getHeight()); + // g.setColor(Color.blue); + // g.draw(bounds); + + } else { // X-Axis + + int xOffset = (int) (axisTick.axis.getPaintZone().getX()); + int yOffset = (int) (axisTick.axis.getAxisTitle().getBounds().getY()); + int maxTickLabelHeight = 0; + for (int i = 0; i < axisTick.tickLabels.size(); i++) { + + String tickLabel = axisTick.tickLabels.get(i); + int tickLocation = axisTick.tickLocations.get(i); + + FontRenderContext frc = g.getFontRenderContext(); + TextLayout layout = new TextLayout(tickLabel, font, frc); + Rectangle tickLabelBounds = layout.getPixelBounds(null, 0, 0); + layout.draw(g, (int) (xOffset + tickLocation - tickLabelBounds.getWidth() / 2.0), yOffset); + + if (tickLabelBounds.getHeight() > maxTickLabelHeight) { + maxTickLabelHeight = (int) tickLabelBounds.getHeight(); + } + } + + // bounds + bounds = new Rectangle(xOffset, yOffset - maxTickLabelHeight, (int) axisTick.axis.getPaintZone().getWidth(), maxTickLabelHeight); + // g.setColor(Color.blue); + // g.draw(bounds); + + } + + } +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickMarks.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickMarks.java new file mode 100644 index 0000000000000000000000000000000000000000..9aca4a0e2517fe29b1b8fb82639b7396fff04495 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickMarks.java @@ -0,0 +1,113 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.BasicStroke; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Stroke; + +import com.xeiam.xchart.internal.interfaces.IChartPart; + +/** + * Axis tick marks. + */ +public class AxisTickMarks implements IChartPart { + + /** the tick length */ + public static final int TICK_LENGTH = 3; + + /** parent */ + private AxisTick axisTick; + + /** the line style */ + private Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); + + /** the bounds */ + private Rectangle bounds; + + /** + * Constructor + * + * @param axisTick + */ + protected AxisTickMarks(AxisTick axisTick) { + + this.axisTick = axisTick; + } + + @Override + public Rectangle getBounds() { + + return bounds; + } + + @Override + public void paint(Graphics2D g) { + + bounds = new Rectangle(); + + g.setColor(axisTick.axis.axisPair.chart.bordersColor); + + if (axisTick.axis.direction == Axis.Direction.Y) { // Y-Axis + + int xOffset = (int) (axisTick.axisTickLabels.getBounds().getX() + axisTick.axisTickLabels.getBounds().getWidth() + AxisTick.AXIS_TICK_PADDING); + int yOffset = (int) (axisTick.axis.getPaintZone().getY()); + + // tick marks + for (int i = 0; i < axisTick.tickLabels.size(); i++) { + + int tickLocation = axisTick.tickLocations.get(i); + + g.setColor(axisTick.axis.axisPair.chart.bordersColor); + g.setStroke(stroke); + + g.drawLine(xOffset, yOffset + (int) (axisTick.axis.getPaintZone().getHeight() - tickLocation), xOffset + TICK_LENGTH, yOffset + (int) (axisTick.axis.getPaintZone().getHeight() - tickLocation)); + + } + // Line + g.drawLine(xOffset + TICK_LENGTH, yOffset, xOffset + TICK_LENGTH, yOffset + (int) axisTick.axis.getPaintZone().getHeight()); + + // bounds + bounds = new Rectangle(xOffset, yOffset, TICK_LENGTH, (int) axisTick.axis.getPaintZone().getHeight()); + // g.setColor(Color.yellow); + // g.draw(bounds); + + } else { // X-Axis + + int xOffset = (int) (axisTick.axis.getPaintZone().getX()); + int yOffset = (int) (axisTick.axisTickLabels.getBounds().getY() - AxisTick.AXIS_TICK_PADDING); + + // tick marks + for (int i = 0; i < axisTick.tickLabels.size(); i++) { + + int tickLocation = axisTick.tickLocations.get(i); + + g.setColor(axisTick.axis.axisPair.chart.bordersColor); + g.setStroke(stroke); + + g.drawLine(xOffset + tickLocation, yOffset, xOffset + tickLocation, yOffset - TICK_LENGTH); + } + // Line + g.drawLine(xOffset, yOffset - TICK_LENGTH, xOffset + (int) axisTick.axis.getPaintZone().getWidth(), yOffset - TICK_LENGTH); + + // bounds + bounds = new Rectangle(xOffset, yOffset - TICK_LENGTH, (int) axisTick.axis.getPaintZone().getWidth(), TICK_LENGTH); + // g.setColor(Color.yellow); + // g.draw(bounds); + } + } +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTitle.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTitle.java new file mode 100644 index 0000000000000000000000000000000000000000..4c9f84e7777cf6b17aea2c2dc22ad83bbc676bb3 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTitle.java @@ -0,0 +1,172 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; + +import com.xeiam.xchart.internal.interfaces.IChartPart; +import com.xeiam.xchart.internal.interfaces.IHideable; + +/** + * AxisTitle + */ +public class AxisTitle implements IChartPart, IHideable { + + protected final static int AXIS_TITLE_PADDING = 10; + + /** parent */ + private final Axis axis; + + /** the title text */ + protected String text = ""; // default to "" + + /** the visibility state of title */ + protected boolean isVisible = false; // default to false, set true if text is set + + /** the font */ + public Font font; + + /** the bounds */ + private Rectangle bounds; + + /** + * Constructor + * + * @param axis the axis + */ + protected AxisTitle(Axis axis) { + + this.axis = axis; + font = new Font(Font.SANS_SERIF, Font.BOLD, 12); // default font + } + + protected String getText() { + + return text; + } + + public void setText(String text) { + + if (text.trim().equalsIgnoreCase("")) { + this.isVisible = false; + } else { + this.isVisible = true; + } + this.text = text; + } + + protected Font getFont() { + + return font; + } + + @Override + public void setVisible(boolean isVisible) { + + if (!text.trim().equalsIgnoreCase("")) { + this.isVisible = isVisible; + } else { + // don't allow a set to true if text is empty! + this.isVisible = false; // set to false for good measure + } + } + + @Override + public Rectangle getBounds() { + + return bounds; + } + + @Override + public void paint(Graphics2D g) { + + bounds = new Rectangle(); + + g.setColor(axis.axisPair.chart.fontColor); + g.setFont(font); + + if (axis.direction == Axis.Direction.Y) { + if (isVisible) { + + FontRenderContext frc = g.getFontRenderContext(); + TextLayout nonRotatedTextLayout = new TextLayout(text, font, frc); + Rectangle nonRotatedRectangle = nonRotatedTextLayout.getPixelBounds(null, 0, 0); + // System.out.println(nonRotatedRectangle); + + // /////////////////////////////////////////////// + + // 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); + + // bounds + bounds = new Rectangle((int) (xOffset - nonRotatedRectangle.getHeight()), (int) (yOffset - nonRotatedRectangle.getWidth()), (int) nonRotatedRectangle.getHeight() + AXIS_TITLE_PADDING, + (int) nonRotatedRectangle.getWidth()); + // g.setColor(Color.blue); + // g.draw(bounds); + } else { + bounds = new Rectangle((int) axis.getPaintZone().getX(), (int) axis.getPaintZone().getY(), 0, (int) axis.getPaintZone().getHeight()); + } + + } else { + + if (isVisible) { + + FontRenderContext frc = g.getFontRenderContext(); + TextLayout textLayout = new TextLayout(text, font, frc); + Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0); + // System.out.println(rectangle); + + int xOffset = (int) (axis.getPaintZone().getX() + (axis.getPaintZone().getWidth() - rectangle.getWidth()) / 2.0); + int yOffset = (int) (axis.getPaintZone().getY() + axis.getPaintZone().getHeight() - rectangle.getHeight()); + + textLayout.draw(g, xOffset, (float) (yOffset - rectangle.getY())); + + bounds = new Rectangle(xOffset, yOffset - AXIS_TITLE_PADDING, (int) rectangle.getWidth(), (int) rectangle.getHeight() + AXIS_TITLE_PADDING); + // g.setColor(Color.blue); + // g.draw(bounds); + + } else { + bounds = new Rectangle((int) axis.getPaintZone().getX(), (int) (axis.getPaintZone().getY() + axis.getPaintZone().getHeight()), (int) axis.getPaintZone().getWidth(), 0); + // g.setColor(Color.blue); + // g.draw(bounds); + + } + } + } +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/ChartTitle.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/ChartTitle.java new file mode 100644 index 0000000000000000000000000000000000000000..480ea6061392082b3798bb3a9595980ae797497c --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/ChartTitle.java @@ -0,0 +1,104 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.internal.interfaces.IChartPart; +import com.xeiam.xchart.internal.interfaces.IHideable; + +/** + * Chart Title + */ +public class ChartTitle implements IChartPart, IHideable { + + /** parent */ + private final Chart chart; + + /** the title text */ + protected String text = ""; // default to "" + + /** the visibility state of title */ + protected boolean isVisible = false; // default to false + + /** the font */ + public Font font; + + /** the bounds */ + private Rectangle bounds; + + /** + * Constructor + * + * @param chart + */ + public ChartTitle(Chart chart) { + + this.chart = chart; + font = new Font(Font.SANS_SERIF, Font.BOLD, 14); // default font + } + + public void setText(String text) { + + if (text.trim().equalsIgnoreCase("")) { + this.isVisible = false; + } else { + this.isVisible = true; + } + this.text = text; + } + + @Override + public void setVisible(boolean isVisible) { + + this.isVisible = isVisible; + } + + @Override + public void paint(Graphics2D g) { + + bounds = new Rectangle(); + g.setFont(font); + + if (isVisible) { + + FontRenderContext frc = g.getFontRenderContext(); + TextLayout textLayout = new TextLayout(text, font, frc); + Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0); + int xOffset = (int) ((chart.width - rectangle.getWidth()) / 2.0); + int yOffset = (int) ((isVisible ? (Chart.CHART_PADDING - rectangle.getY()) : 0)); + + bounds = new Rectangle(xOffset, yOffset + (isVisible ? (int) rectangle.getY() : 0), (int) rectangle.getWidth(), (int) (isVisible ? rectangle.getHeight() : 0)); + // g.setColor(Color.green); + // g.draw(bounds); + + g.setColor(chart.fontColor); + textLayout.draw(g, xOffset, yOffset); + } + + } + + @Override + public Rectangle getBounds() { + + return bounds; + } +} \ No newline at end of file diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java new file mode 100644 index 0000000000000000000000000000000000000000..a1260406cf5b2d0a90198f7742517c9ac61f7cce --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java @@ -0,0 +1,157 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; +import java.util.Map; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.ChartColor; +import com.xeiam.xchart.Series; +import com.xeiam.xchart.internal.interfaces.IChartPart; +import com.xeiam.xchart.internal.interfaces.IHideable; +import com.xeiam.xchart.internal.markers.Marker; + +/** + * @author timmolter + */ +public class Legend implements IChartPart, IHideable { + + private static final int LEGEND_PADDING = 10; + + /** parent */ + private final Chart chart; + + /** the visibility state of legend */ + protected boolean isVisible = true; // default to true + + /** the font */ + public Font font; + + /** the background color */ + public Color backgroundColor; + + /** the bounds */ + private Rectangle bounds; + + /** + * Constructor + * + * @param chart + */ + public Legend(Chart chart) { + + this.chart = chart; + backgroundColor = ChartColor.getAWTColor(ChartColor.LIGHT_GREY); // default background color + font = new Font(Font.SANS_SERIF, Font.PLAIN, 11); // default font + } + + @Override + public void setVisible(boolean isVisible) { + + this.isVisible = isVisible; + } + + @Override + public void paint(Graphics2D g) { + + bounds = new Rectangle(); + g.setFont(font); + + if (isVisible) { + + Map<Integer, Series> seriesMap = chart.axisPair.seriesMap; + + // determine legend text content max width + int legendTextContentMaxWidth = 0; + int legendTextContentMaxHeight = 0; + + for (Integer seriesId : seriesMap.keySet()) { + Series series = seriesMap.get(seriesId); + TextLayout textLayout = new TextLayout(series.name, font, new FontRenderContext(null, true, false)); + Rectangle rectangle = textLayout.getPixelBounds(null, 0, 0); + // System.out.println(rectangle); + if (rectangle.getWidth() > legendTextContentMaxWidth) { + legendTextContentMaxWidth = (int) rectangle.getWidth(); + } + if (rectangle.getHeight() > legendTextContentMaxHeight) { + legendTextContentMaxHeight = (int) rectangle.getHeight(); + } + } + + // determine legend content height + int legendContentHeight = 0; + int maxContentHeight = Math.max(legendTextContentMaxHeight, Marker.SIZE); + legendContentHeight = maxContentHeight * seriesMap.size() + LEGEND_PADDING * (seriesMap.size() - 1); + + // determine legend content width + int legendContentWidth = (int) (3.0 * Marker.SIZE + LEGEND_PADDING + legendTextContentMaxWidth); + + // Draw Legend Box + int legendBoxWidth = legendContentWidth + 2 * LEGEND_PADDING; + int legendBoxHeight = legendContentHeight + 2 * LEGEND_PADDING; + int xOffset = chart.width - legendBoxWidth - Chart.CHART_PADDING; + int yOffset = (int) ((chart.height - legendBoxHeight) / 2.0 + chart.chartTitle.getBounds().getY() + chart.chartTitle.getBounds().getHeight()); + + g.setColor(chart.bordersColor); + g.drawRect(xOffset, yOffset, legendBoxWidth, legendBoxHeight); + g.setColor(backgroundColor); + g.fillRect(xOffset + 1, yOffset + 1, legendBoxWidth - 1, legendBoxHeight - 1); + + // Draw legend content inside legend box + int startx = xOffset + LEGEND_PADDING; + int starty = yOffset + LEGEND_PADDING; + for (Integer seriesId : seriesMap.keySet()) { + Series series = seriesMap.get(seriesId); + // paint line + if (series.stroke != null) { + g.setColor(series.strokeColor); + g.setStroke(series.stroke); + g.drawLine(startx, starty - Marker.Y_OFFSET, (int) (startx + Marker.SIZE * 3.0), starty - Marker.Y_OFFSET); + } + // paint marker + if (series.marker != null) { + g.setColor(series.markerColor); + series.marker.paint(g, (int) (startx + (Marker.SIZE * 1.5)), starty - Marker.Y_OFFSET); + } + + // paint series name + g.setColor(chart.fontColor); + TextLayout layout = new TextLayout(series.name, font, new FontRenderContext(null, true, false)); + layout.draw(g, (float) (startx + Marker.SIZE + (Marker.SIZE * 1.5) + LEGEND_PADDING), (starty + Marker.SIZE)); + starty = starty + legendTextContentMaxHeight + LEGEND_PADDING; + } + + // bounds + bounds = new Rectangle(xOffset, yOffset, legendBoxWidth, legendBoxHeight); + // g.setColor(Color.blue); + // g.draw(bounds); + } + + } + + @Override + public Rectangle getBounds() { + + return bounds; + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/Plot.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/Plot.java new file mode 100644 index 0000000000000000000000000000000000000000..ae1c5f1118e65fd90048f8f02605d214ddfebdd3 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/Plot.java @@ -0,0 +1,73 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.internal.interfaces.IChartPart; + +/** + * @author timmolter + */ +public class Plot implements IChartPart { + + /** parent */ + protected Chart chart; + + public PlotSurface plotSurface; + + protected PlotContent plotContent; + + public static final int PLOT_PADDING = 3; + + /** the bounds */ + private Rectangle bounds; + + public Plot(Chart chart) { + + this.chart = chart; + this.plotSurface = new PlotSurface(this); + this.plotContent = new PlotContent(this); + } + + @Override + public Rectangle getBounds() { + + return bounds; + } + + @Override + public void paint(Graphics2D g) { + + bounds = new Rectangle(); + + // calculate bounds + int xOffset = (int) (chart.axisPair.yAxis.getBounds().getX() + chart.axisPair.yAxis.getBounds().getWidth() + (chart.axisPair.yAxis.axisTick.isVisible ? (Plot.PLOT_PADDING + 1) : 0)); + int yOffset = (int) (chart.axisPair.yAxis.getBounds().getY()); + int width = (int) chart.axisPair.xAxis.getBounds().getWidth(); + int height = (int) chart.axisPair.yAxis.getBounds().getHeight(); + bounds = new Rectangle(xOffset, yOffset, width, height); + // g.setColor(Color.green); + // g.draw(bounds); + + plotSurface.paint(g); + plotContent.paint(g); + + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContent.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContent.java new file mode 100644 index 0000000000000000000000000000000000000000..96ea20cc22227f62212b62b74c39bd760eaa8864 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContent.java @@ -0,0 +1,162 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.BasicStroke; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.math.BigDecimal; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.Map; + +import com.xeiam.xchart.Series; +import com.xeiam.xchart.internal.chartpart.Axis.AxisType; +import com.xeiam.xchart.internal.interfaces.IChartPart; + +/** + * @author timmolter + */ +public class PlotContent implements IChartPart { + + /** parent */ + private Plot plot; + + /** + * Constructor + * + * @param plot + */ + protected PlotContent(Plot plot) { + + this.plot = plot; + } + + @Override + public Rectangle getBounds() { + + return plot.getBounds(); + } + + @Override + public void paint(Graphics2D g) { + + Rectangle bounds = plot.getBounds(); + + Map<Integer, Series> seriesMap = plot.chart.axisPair.seriesMap; + for (Integer seriesId : seriesMap.keySet()) { + + Series series = seriesMap.get(seriesId); + + // X-Axis + int xTickSpace = AxisPair.getTickSpace((int) bounds.getWidth()); + int xLeftMargin = AxisPair.getMargin((int) bounds.getWidth(), xTickSpace); + + // Y-Axis + int yTickSpace = AxisPair.getTickSpace((int) bounds.getHeight()); + int yTopMargin = AxisPair.getMargin((int) bounds.getHeight(), yTickSpace); + + // data points + Collection<?> xData = series.xData; + BigDecimal xMin = plot.chart.axisPair.xAxis.min; + BigDecimal xMax = plot.chart.axisPair.xAxis.max; + Collection<Number> yData = series.yData; + BigDecimal yMin = plot.chart.axisPair.yAxis.min; + BigDecimal yMax = plot.chart.axisPair.yAxis.max; + Collection<Number> errorBars = series.errorBars; + + int previousX = Integer.MIN_VALUE; + int previousY = Integer.MIN_VALUE; + + Iterator<?> xItr = xData.iterator(); + Iterator<Number> yItr = yData.iterator(); + Iterator<Number> ebItr = null; + if (errorBars != null) { + ebItr = errorBars.iterator(); + } + while (xItr.hasNext()) { + + BigDecimal x = null; + if (plot.chart.axisPair.xAxis.axisType == AxisType.NUMBER) { + x = new BigDecimal(((Number) xItr.next()).doubleValue()); + } + if (plot.chart.axisPair.xAxis.axisType == AxisType.DATE) { + x = new BigDecimal(((Date) xItr.next()).getTime()); + // System.out.println(x); + } + + BigDecimal y = new BigDecimal(yItr.next().doubleValue()); + // System.out.println(y); + double eb = 0.0; + if (errorBars != null) { + eb = ebItr.next().doubleValue(); + } + + // int xTransform = (int) (xLeftMargin + ((x - xMin) / (xMax - xMin) * xTickSpace)); + int xTransform = (int) (xLeftMargin + (x.subtract(xMin).doubleValue() / xMax.subtract(xMin).doubleValue() * xTickSpace)); + // int yTransform = (int) (bounds.getHeight() - (yTopMargin + (y - yMin) / (yMax - yMin) * yTickSpace)); + int yTransform = (int) (bounds.getHeight() - (yTopMargin + y.subtract(yMin).doubleValue() / yMax.subtract(yMin).doubleValue() * yTickSpace)); + + // a check if all y data are the exact same values + if (Math.abs(xMax.subtract(xMin).doubleValue()) / 5 == 0.0) { + xTransform = (int) (bounds.getWidth() / 2.0); + } + + // a check if all y data are the exact same values + if (Math.abs(yMax.subtract(yMin).doubleValue()) / 5 == 0.0) { + yTransform = (int) (bounds.getHeight() / 2.0); + } + + int xOffset = (int) (bounds.getX() + xTransform - 1); + int yOffset = (int) (bounds.getY() + yTransform); + // System.out.println(yOffset); + // System.out.println(yTransform); + + // paint line + if (series.stroke != null) { + if (previousX != Integer.MIN_VALUE && previousY != Integer.MIN_VALUE) { + g.setColor(series.strokeColor); + g.setStroke(series.stroke); + g.drawLine(previousX, previousY, xOffset, yOffset); + } + previousX = xOffset; + previousY = yOffset; + } + + // paint marker + if (series.marker != null) { + g.setColor(series.markerColor); + series.marker.paint(g, xOffset, yOffset); + } + + // paint errorbar + if (errorBars != null) { + g.setColor(plot.chart.bordersColor); + g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + int bottom = (int) (-1 * bounds.getHeight() * eb / (yMax.subtract(yMin).doubleValue())); + int top = (int) (bounds.getHeight() * eb / (yMax.subtract(yMin).doubleValue())); + g.drawLine(xOffset, yOffset + bottom, xOffset, yOffset + top); + g.drawLine(xOffset - 3, yOffset + bottom, xOffset + 3, yOffset + bottom); + g.drawLine(xOffset - 3, yOffset + top, xOffset + 3, yOffset + top); + } + } + + } + + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/PlotSurface.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/PlotSurface.java new file mode 100644 index 0000000000000000000000000000000000000000..6f51c6228b3718b30b0532ebc75a7dd3f3081b0e --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/chartpart/PlotSurface.java @@ -0,0 +1,131 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.chartpart; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.util.List; + +import com.xeiam.xchart.ChartColor; +import com.xeiam.xchart.internal.interfaces.IChartPart; +import com.xeiam.xchart.internal.interfaces.IHideable; + +/** + * @author timmolter + */ +public class PlotSurface implements IChartPart, IHideable { + + /** parent */ + private Plot plot; + + /** the gridLines Color */ + private Color gridLinesColor; + + /** the background color */ + private Color foregroundColor; + + /** the line style */ + private BasicStroke stroke; + + /** the visibility state of PlotSurface */ + protected boolean isVisible = true; // default to true + + /** + * Constructor + * + * @param plot + */ + protected PlotSurface(Plot plot) { + + this.plot = plot; + gridLinesColor = ChartColor.getAWTColor(ChartColor.GREY); // default gridLines color + foregroundColor = ChartColor.getAWTColor(ChartColor.LIGHT_GREY); // default foreground Color color + stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10.0f, new float[] { 3.0f, 3.0f }, 0.0f); + } + + @Override + public Rectangle getBounds() { + + return plot.getBounds(); + } + + @Override + public void paint(Graphics2D g) { + + Rectangle bounds = plot.getBounds(); + + // paint foreground + Rectangle backgroundRectangle = new Rectangle((int) bounds.getX() - 1, (int) bounds.getY(), (int) (bounds.getWidth()), (int) bounds.getHeight()); + g.setColor(foregroundColor); + g.fill(backgroundRectangle); + Rectangle borderRectangle = new Rectangle((int) bounds.getX() - 1, (int) bounds.getY(), (int) (bounds.getWidth()), (int) bounds.getHeight()); + g.setColor(plot.chart.bordersColor); + g.draw(borderRectangle); + + // paint grid lines + if (isVisible) { + // horizontal + List<Integer> yAxisTickLocations = plot.chart.axisPair.yAxis.axisTick.tickLocations; + for (int i = 0; i < yAxisTickLocations.size(); i++) { + + int tickLocation = yAxisTickLocations.get(i); + + g.setColor(gridLinesColor); + g.setStroke(stroke); + // System.out.println("bounds.getY()= " + bounds.getY()); + g.drawLine((int) bounds.getX(), (int) (bounds.getY() + bounds.getHeight() - tickLocation), (int) (bounds.getX() + bounds.getWidth() - 2), + (int) (bounds.getY() + bounds.getHeight() - tickLocation)); + } + + // vertical + List<Integer> xAxisTickLocations = plot.chart.axisPair.xAxis.axisTick.tickLocations; + for (int i = 0; i < xAxisTickLocations.size(); i++) { + + int tickLocation = xAxisTickLocations.get(i); + + g.setColor(gridLinesColor); + g.setStroke(stroke); + + g.drawLine((int) (bounds.getX() + tickLocation - 1), (int) (bounds.getY() + 1), (int) (bounds.getX() + tickLocation - 1), (int) (bounds.getY() + bounds.getHeight() - 1)); + } + } + } + + @Override + public void setVisible(boolean isVisible) { + + this.isVisible = isVisible; + } + + /** + * @param gridLinesColor the gridLinesColor to set + */ + public void setGridLinesColor(Color gridLinesColor) { + + this.gridLinesColor = gridLinesColor; + } + + /** + * @param foregroundColor the foregroundColor to set + */ + public void setForegroundColor(Color foregroundColor) { + + this.foregroundColor = foregroundColor; + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/interfaces/IChartPart.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/interfaces/IChartPart.java new file mode 100644 index 0000000000000000000000000000000000000000..e88165d5a5c0523951a0c47c07ff19279d7fb817 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/interfaces/IChartPart.java @@ -0,0 +1,32 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.interfaces; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +/** + * All components of a chart that need to be painted should implement this interface + * + * @author timmolter + */ +public interface IChartPart { + + public Rectangle getBounds(); + + public void paint(final Graphics2D g); + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/interfaces/IHideable.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/interfaces/IHideable.java new file mode 100644 index 0000000000000000000000000000000000000000..b546fc47fbf4dda488b53b80828f5c3d924c1d72 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/interfaces/IHideable.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2008-2011 SWTChart project. All rights reserved. + * + * This code is distributed under the terms of the Eclipse Public License v1.0 + * which is available at http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package com.xeiam.xchart.internal.interfaces; + +/** + * ChartParts that can be set visible or not should implement this interface + * + * @author timmolter + */ +public interface IHideable extends IChartPart { + + public void setVisible(boolean isVisible); + +} \ No newline at end of file diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Circle.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Circle.java new file mode 100644 index 0000000000000000000000000000000000000000..b3d1950d3bb8b45aff3d563f8281b0151343075d --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Circle.java @@ -0,0 +1,33 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.markers; + +import java.awt.Graphics2D; + +/** + * @author timmolter + */ +public class Circle extends Marker { + + @Override + 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); + + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Diamond.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Diamond.java new file mode 100644 index 0000000000000000000000000000000000000000..13f43d0b96d8eb6a19c4f649972484e6e5efcbfe --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Diamond.java @@ -0,0 +1,52 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.markers; + +import java.awt.Graphics2D; +import java.awt.Polygon; + +/** + * @author timmolter + */ +public class Diamond extends Marker { + + @Override + public void paint(Graphics2D g, int xOffset, int yOffset) { + + g.setStroke(stroke); + + int[] x = new int[4]; + int[] y = new int[4]; + int n = 4; + + // Make a diamond + 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[3] = xOffset - halfSize + halfSize; + + y[0] = 1 + yOffset - halfSize + halfSize; + y[1] = 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); + + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Marker.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Marker.java new file mode 100644 index 0000000000000000000000000000000000000000..da1b55f968c47e1532cf58473d981d80c62cf24b --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Marker.java @@ -0,0 +1,34 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.markers; + +import java.awt.BasicStroke; +import java.awt.Graphics2D; + +/** + * @author timmolter + */ +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 int X_OFFSET = (int) (-1.0 * (SIZE / 2.0)); + public static final int Y_OFFSET = (int) (-1.0 * (SIZE / 2.0)); + + public abstract void paint(Graphics2D g, int xOffset, int yOffset); +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Square.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Square.java new file mode 100644 index 0000000000000000000000000000000000000000..02503bcaa86a414f21db8f91fbbe560b2ff1f270 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/Square.java @@ -0,0 +1,34 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.markers; + +import java.awt.Graphics2D; +import java.awt.Rectangle; + +/** + * @author timmolter + */ +public class Square extends Marker { + + @Override + 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)); + + } + +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/TriangleDown.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/TriangleDown.java new file mode 100644 index 0000000000000000000000000000000000000000..59325ad0dc430ab65dafc2957e1a7fb96291d1f4 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/TriangleDown.java @@ -0,0 +1,49 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.markers; + +import java.awt.Graphics2D; +import java.awt.Polygon; + +/** + * @author timmolter + */ +public class TriangleDown extends Marker { + + @Override + public void paint(Graphics2D g, int xOffset, int yOffset) { + + g.setStroke(stroke); + + int[] x = new int[3]; + int[] y = new int[3]; + int n = 3; + + // Make a triangle + 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; + + y[0] = 1 + yOffset - halfSize + 0; + y[1] = 1 + yOffset - halfSize + Marker.SIZE + 1; + y[2] = 1 + yOffset - halfSize + 0; + + Polygon triangle = new Polygon(x, y, n); + g.fillPolygon(triangle); + + } +} diff --git a/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/TriangleUp.java b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/TriangleUp.java new file mode 100644 index 0000000000000000000000000000000000000000..15ded2417ecd133bf21b43660d95bbf565c4cdb1 --- /dev/null +++ b/xchange-examples/src/main/java/com/xeiam/xchart/internal/markers/TriangleUp.java @@ -0,0 +1,49 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.internal.markers; + +import java.awt.Graphics2D; +import java.awt.Polygon; + +/** + * @author timmolter + */ +public class TriangleUp extends Marker { + + @Override + public void paint(Graphics2D g, int xOffset, int yOffset) { + + g.setStroke(stroke); + + int[] x = new int[3]; + int[] y = new int[3]; + int n = 3; + + // 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[2] = xOffset - halfSize + halfSize; + + y[0] = yOffset - halfSize + Marker.SIZE + 1; + y[1] = yOffset - halfSize + Marker.SIZE + 1; + y[2] = yOffset - halfSize + 0; + + Polygon triangle = new Polygon(x, y, n); + g.fillPolygon(triangle); + + } +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example0.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example0.java new file mode 100644 index 0000000000000000000000000000000000000000..142f568d987b98570fba5863b0adf8571a4195e3 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example0.java @@ -0,0 +1,45 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import com.xeiam.xchart.BitmapEncoder; +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.QuickChart; +import com.xeiam.xchart.SwingWrapper; + +/** + * Creates a simple Chart using {@link com.xeiam.xchart.QuickChart} + * + * @author timmolter + */ +public class Example0 { + + public static void main(String[] args) throws Exception { + + double[] xData = new double[] { 0.0, 1.0, 2.0 }; + double[] yData = new double[] { 2.0, 1.0, 0.0 }; + + // Create Chart + Chart chart = QuickChart.getChart("Sample Chart", "X", "Y", "y(x)", xData, yData); + + // Show it + new SwingWrapper(chart).displayChart(); + + // Save it + BitmapEncoder.savePNG(chart, "./Sample_Chart.png"); + + } +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example1.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example1.java new file mode 100644 index 0000000000000000000000000000000000000000..bf0ade2373673bcedf295463c0b325fc63dc6189 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example1.java @@ -0,0 +1,47 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import java.util.Arrays; +import java.util.Collection; + +import com.xeiam.xchart.BitmapEncoder; +import com.xeiam.xchart.Chart; + +/** + * Creates a simple Chart and saves it as a PNG and JPEG image file. + * + * @author timmolter + */ +public class Example1 { + + public static void main(String[] args) throws Exception { + + Collection<Number> xData = Arrays.asList(new Number[] { 0.0, 1.0, 2.0 }); + Collection<Number> yData = Arrays.asList(new Number[] { 0.0, 1.0, 2.0 }); + + // Create Chart + Chart chart = new Chart(500, 400); + chart.setTitle("Sample Chart"); + chart.setXAxisTitle("X"); + chart.setYAxisTitle("Y"); + chart.addSeries("y(x)", xData, yData); + + BitmapEncoder.savePNG(chart, "./Sample_Chart.png"); + BitmapEncoder.saveJPG(chart, "./Sample_Chart.jpg", 0.95f); + + } +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example10.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example10.java new file mode 100644 index 0000000000000000000000000000000000000000..f4e7ab5267fc03bb976fff1b93067ccb223d8f4a --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example10.java @@ -0,0 +1,78 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import java.util.Arrays; +import java.util.Collection; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.Series; +import com.xeiam.xchart.SeriesMarker; +import com.xeiam.xchart.SwingWrapper; + +/** + * Embed a Chart in a simple Swing application + * + * @author timmolter + */ +public class Example10 { + + public static void main(String[] args) { + + // data + Number[] xDataArray = new Number[] { 0.0, 0.03139525976465669, 0.06266661678215213, 0.0936906572928623, 0.1243449435824274, 0.1545084971874737, 0.184062276342339, 0.21288964578253636, + 0.24087683705085766, 0.26791339748949833, 0.29389262614623657, 0.3187119948743448, 0.34227355296434425, 0.3644843137107057, 0.38525662138789457, 0.4045084971874737, 0.42216396275100754, + 0.43815334002193185, 0.4524135262330098, 0.46488824294412573, 0.4755282581475768, 0.4842915805643156, 0.49114362536434436, 0.49605735065723894, 0.4990133642141358, 0.5, 0.4990133642141358, + 0.4960573506572389, 0.4911436253643443, 0.4842915805643155, 0.4755282581475767, 0.46488824294412556, 0.4524135262330097, 0.4381533400219316, 0.42216396275100737, 0.4045084971874735, + 0.38525662138789435, 0.36448431371070544, 0.342273552964344, 0.31871199487434443, 0.29389262614623607, 0.2679133974894978, 0.24087683705085702, 0.21288964578253586, 0.18406227634233846, + 0.15450849718747314, 0.12434494358242676, 0.09369065729286163, 0.0626666167821514, 0.0313952597646559, -6.049014748177263E-16, -0.03139525976465733, -0.06266661678215281, + -0.09369065729286304, -0.12434494358242815, -0.1545084971874745, -0.1840622763423398, -0.21288964578253713, -0.24087683705085847, -0.26791339748949894, -0.29389262614623723, + -0.31871199487434554, -0.342273552964345, -0.3644843137107064, -0.38525662138789524, -0.40450849718747445, -0.42216396275100815, -0.43815334002193224, -0.45241352623301023, + -0.46488824294412606, -0.47552825814757715, -0.4842915805643158, -0.4911436253643446, -0.49605735065723905, -0.4990133642141359, -0.5, -0.49901336421413567, -0.49605735065723877, + -0.491143625364344, -0.4842915805643152, -0.47552825814757643, -0.4648882429441252, -0.4524135262330092, -0.438153340021931, -0.42216396275100676, -0.4045084971874727, -0.3852566213878937, + -0.36448431371070455, -0.3422735529643432, -0.31871199487434343, -0.29389262614623524, -0.26791339748949666, -0.2408768370508561, -0.2128896457825349, -0.18406227634233727, + -0.15450849718747214, -0.12434494358242552, -0.0936906572928606, -0.06266661678215013, -0.03139525976465486, 2.097981369335578E-15 }; + Collection<Number> xData = Arrays.asList(xDataArray); + + Number[] yDataArray = new Number[] { 0.0, 1.5702142318133935E-5, 3.13688735543879E-5, 4.703341403158832E-5, 6.303295245179154E-5, 8.092859563778825E-5, 1.0594882618710001E-4, + 1.558236372723155E-4, 2.7329707705089635E-4, 5.199254519985949E-4, 9.014386029378818E-4, 0.0013306621873173169, 0.0017306604364273927, 0.0020715324272834947, 0.0023569051679597362, + 0.0025927070538466638, 0.0027886026991513404, 0.002952502529028644, 0.0030880047369627284, 0.0032003236220216743, 0.003291666404197254, 0.0033648801628904596, 0.003421046591348078, + 0.0034608642835927588, 0.0034853783634585696, 0.0034948715689020367, 0.0034897171052496183, 0.0034701613190169425, 0.0034365427075935128, 0.003389087289131133, 0.0033280335272856142, + 0.003253771246701497, 0.0031666186473881487, 0.00306689011690467, 0.0029550247059562454, 0.0028314794027288065, 0.0026967349463042378, 0.002551357830616439, 0.002395898998210993, + 0.0022309713675244328, 0.002057244774600177, 0.0018753905860785436, 0.0016861342273231793, 0.0014902252697364343, 0.0012884341340577633, 0.0010815578443189703, 8.704131639000351E-4, + 6.558335341671071E-4, 4.3866560733456445E-4, 2.19766427583401E-4, -4.234301271122286E-18, -2.1976644564027456E-4, -4.3866524602280996E-4, -6.558321784509378E-4, -8.703966842877769E-4, + -0.0010814873042787273, -0.0012881467574255387, -0.0014891336787390336, -0.0016823672042564418, -0.0018627630869467102, -0.0020181202111633698, -0.002119632929541168, -0.002114609338758541, + -0.0019593967275554746, -0.0016730082089855846, -0.0013440006960966345, -0.0010483972455089105, -8.149512680002023E-4, -6.433644138995512E-4, -5.209373197845712E-4, -4.34946817866983E-4, + -3.7661743777884615E-4, -3.3739281674167966E-4, -3.099970594128415E-4, -2.9070472170425525E-4, -2.77636367693098E-4, -2.68102425931983E-4, -2.6019714020176945E-4, -2.536145792301906E-4, + -2.4744573769866404E-4, -2.4122358912925663E-4, -2.3473774775902484E-4, -2.2772135357722773E-4, -2.2006305955750752E-4, -2.1171197663128998E-4, -2.026763153011749E-4, -1.928814887412768E-4, + -1.8242620113215842E-4, -1.712818057089484E-4, -1.5947175495155755E-4, -1.470534737044005E-4, -1.340464949116753E-4, -1.2051929111759324E-4, -1.0651565202537847E-4, -9.209212285608304E-5, + -7.730521584738858E-5, -6.221344753211741E-5, -4.687672566856378E-5, -3.135450711247751E-5, -1.5708413280955366E-5, 1.0498035802487025E-18 }; + Collection<Number> yData = Arrays.asList(yDataArray); + + // Create Chart + Chart chart = new Chart(800, 600); + + // Customize Chart + chart.setTitleVisible(false); + chart.setLegendVisible(false); + + // Series 1 + Series series1 = chart.addSeries("data", xData, yData); + series1.setMarker(SeriesMarker.NONE); + + new SwingWrapper(chart).displayChart(); + } +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example11.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example11.java new file mode 100644 index 0000000000000000000000000000000000000000..10430447c77e104458b93a808201c5a319290f42 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example11.java @@ -0,0 +1,93 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import java.util.Arrays; +import java.util.Collection; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.Series; +import com.xeiam.xchart.SeriesMarker; +import com.xeiam.xchart.SwingWrapper; + +/** + * Embed a Chart in a simple Swing application + * + * @author timmolter + */ +public class Example11 { + + public static void main(String[] args) { + + // data + Number[] xDataArray = new Number[] { 0.0, 2.0E-6, 4.0E-6, 6.0E-6, 8.0E-6, 9.999999999999999E-6, 1.1999999999999999E-5, 1.3999999999999998E-5, 1.6E-5, 1.8E-5, 2.0E-5, 2.2000000000000003E-5, + 2.4000000000000004E-5, 2.6000000000000005E-5, 2.8000000000000006E-5, 3.0000000000000008E-5, 3.2000000000000005E-5, 3.4000000000000007E-5, 3.600000000000001E-5, 3.800000000000001E-5, + 4.000000000000001E-5, 4.200000000000001E-5, 4.400000000000001E-5, 4.6000000000000014E-5, 4.8000000000000015E-5, 5.0000000000000016E-5, 5.200000000000002E-5, 5.400000000000002E-5, + 5.600000000000002E-5, 5.800000000000002E-5, 6.000000000000002E-5, 6.200000000000002E-5, 6.400000000000001E-5, 6.6E-5, 6.8E-5, 7.0E-5, 7.199999999999999E-5, 7.399999999999998E-5, + 7.599999999999998E-5, 7.799999999999997E-5, 7.999999999999997E-5, 8.199999999999996E-5, 8.399999999999995E-5, 8.599999999999995E-5, 8.799999999999994E-5, 8.999999999999994E-5, + 9.199999999999993E-5, 9.399999999999993E-5, 9.599999999999992E-5, 9.799999999999992E-5, 9.999999999999991E-5, 1.019999999999999E-4, 1.039999999999999E-4, 1.0599999999999989E-4, + 1.0799999999999989E-4, 1.0999999999999988E-4, 1.1199999999999988E-4, 1.1399999999999987E-4, 1.1599999999999987E-4, 1.1799999999999986E-4, 1.1999999999999985E-4, 1.2199999999999985E-4, + 1.2399999999999984E-4, 1.2599999999999984E-4, 1.2799999999999983E-4, 1.2999999999999983E-4, 1.3199999999999982E-4, 1.3399999999999981E-4, 1.359999999999998E-4, 1.379999999999998E-4, + 1.399999999999998E-4, 1.419999999999998E-4, 1.439999999999998E-4, 1.4599999999999978E-4, 1.4799999999999978E-4, 1.4999999999999977E-4, 1.5199999999999976E-4, 1.5399999999999976E-4, + 1.5599999999999975E-4, 1.5799999999999975E-4, 1.5999999999999974E-4, 1.6199999999999974E-4, 1.6399999999999973E-4, 1.6599999999999973E-4, 1.6799999999999972E-4, 1.6999999999999971E-4, + 1.719999999999997E-4, 1.739999999999997E-4, 1.759999999999997E-4, 1.779999999999997E-4, 1.7999999999999969E-4, 1.8199999999999968E-4, 1.8399999999999967E-4, 1.8599999999999967E-4, + 1.8799999999999966E-4, 1.8999999999999966E-4, 1.9199999999999965E-4, 1.9399999999999965E-4, 1.9599999999999964E-4, 1.9799999999999964E-4, 1.9999999999999963E-4, 2.0199999999999962E-4, + 2.0399999999999962E-4, 2.059999999999996E-4, 2.079999999999996E-4, 2.099999999999996E-4, 2.119999999999996E-4, 2.139999999999996E-4, 2.1599999999999959E-4, 2.1799999999999958E-4, + 2.1999999999999957E-4, 2.2199999999999957E-4, 2.2399999999999956E-4, 2.2599999999999956E-4, 2.2799999999999955E-4, 2.2999999999999955E-4, 2.3199999999999954E-4, 2.3399999999999953E-4, + 2.3599999999999953E-4, 2.3799999999999952E-4, 2.3999999999999952E-4, 2.419999999999995E-4, 2.439999999999995E-4, 2.4599999999999953E-4, 2.479999999999995E-4, 2.499999999999995E-4, + 2.519999999999995E-4, 2.539999999999995E-4, 2.559999999999995E-4, 2.579999999999995E-4, 2.599999999999995E-4, 2.619999999999995E-4, 2.639999999999995E-4, 2.6599999999999947E-4, + 2.6799999999999947E-4, 2.6999999999999946E-4, 2.7199999999999946E-4, 2.7399999999999945E-4, 2.7599999999999944E-4, 2.7799999999999944E-4, 2.7999999999999943E-4, 2.8199999999999943E-4, + 2.839999999999994E-4, 2.859999999999994E-4, 2.879999999999994E-4, 2.899999999999994E-4, 2.919999999999994E-4, 2.939999999999994E-4, 2.959999999999994E-4, 2.979999999999994E-4, + 2.999999999999994E-4, 3.0199999999999937E-4, 3.0399999999999937E-4, 3.0599999999999936E-4, 3.0799999999999936E-4, 3.0999999999999935E-4, 3.1199999999999934E-4, 3.1399999999999934E-4, + 3.1599999999999933E-4, 3.179999999999993E-4, 3.199999999999993E-4, 3.219999999999993E-4, 3.239999999999993E-4, 3.259999999999993E-4, 3.279999999999993E-4, 3.299999999999993E-4, + 3.319999999999993E-4, 3.339999999999993E-4, 3.359999999999993E-4, 3.3799999999999927E-4, 3.3999999999999927E-4, 3.4199999999999926E-4, 3.4399999999999925E-4, 3.4599999999999925E-4, + 3.4799999999999924E-4, 3.4999999999999924E-4, 3.5199999999999923E-4, 3.539999999999992E-4, 3.559999999999992E-4, 3.579999999999992E-4, 3.599999999999992E-4, 3.619999999999992E-4, + 3.639999999999992E-4, 3.659999999999992E-4, 3.679999999999992E-4, 3.699999999999992E-4, 3.719999999999992E-4, 3.7399999999999917E-4, 3.7599999999999916E-4, 3.7799999999999916E-4, + 3.7999999999999915E-4, 3.8199999999999915E-4, 3.8399999999999914E-4, 3.8599999999999914E-4, 3.8799999999999913E-4, 3.899999999999991E-4, 3.919999999999991E-4, 3.939999999999991E-4, + 3.959999999999991E-4, 3.979999999999991E-4, 3.999999999999991E-4, 4.019999999999991E-4 }; + Collection<Number> xData = Arrays.asList(xDataArray); + + Number[] yDataArray = new Number[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6372101692308739, + 0.6333108573262538, 0.6295378262991362, 0.6259234359720381, 0.6226800066605563, 0.6195071339906413, 0.6166201487693563, 0.613787621947162, 0.6108988791636593, 0.6082244232360293, + 0.6056170503744838, 0.6031132424617048, 0.600721461522759, 0.5985311868828369, 0.5964073518335689, 0.5942410772230486, 0.5922453479977628, 0.5901765175165123, 0.5882822154061506, + 0.5864532990597335, 0.5846724904863335, 0.58297796864999, 0.5813406710959594, 0.5796660243243492, 0.5782002672376352, 0.5766565927458179, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6231997030387646, 0.621204395714257, 0.6191737313408935, 0.6171961639533186, 0.6152254530814898, + 0.6134505469540993, 0.6116785919218266, 0.6099093025992627, 0.6081388759571905, 0.6065055388348788, 0.6048612569349429, 0.6033243742714489, 0.6017010826285737, 0.6002252301825577, + 0.5986650199672785, 0.597230396889992, 0.5958314437746937, 0.5944185272326469, 0.593065510924995, 0.5917359663724286, 0.5904117737773237, 0.5891005037981919, 0.5878558348315347, + 0.5866748898114135, 0.5854834223130877, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6102542598144771, + 0.6088615058903939, 0.6075165945246479, 0.606173865264273, 0.6048892886319646, 0.6036269945746775, 0.6024031054359631, 0.6012060990636389, 0.5999707073752844, 0.5987445851044376, + 0.5976670759284103, 0.5964760539465047, 0.5953596186235112, 0.5942083942859213, 0.5931534018292057, 0.5920553037922442, 0.5909328610294284, 0.5899221607557993, 0.5888796149501155, + 0.5878477730026161, 0.5868619466225057, 0.5859043952287553, 0.5849217522473235, 0.5839384045103886, 0.582972125771751, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.597725222494134, 0.5967165514126065, 0.595690065134673, 0.5946455873652494, 0.5936749101268612, 0.5927272236764601, + 0.5917600038873098, 0.5907636148444239, 0.5897911064021713, 0.5888437521080321, 0.5879184432039671, 0.5869713714610235, 0.5861140207841755, 0.585241586718861, 0.5843729271284958, + 0.5834786347516403, 0.5826219070584836, 0.58179223726965, 0.5809457169899226, 0.5801700375138839, 0.5793487282645163, 0.5785614443246223, 0.5777884312743851, 0.5769659838524158, + 0.5762259275606331, 0.0 }; + Collection<Number> yData = Arrays.asList(yDataArray); + + // Create Chart + Chart chart = new Chart(800, 600); + + // Customize Chart + chart.setTitleVisible(false); + chart.setLegendVisible(false); + + // Series 1 + Series series1 = chart.addSeries("data", xData, yData); + series1.setMarker(SeriesMarker.NONE); + + new SwingWrapper(chart).displayChart(); + } +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example2.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example2.java new file mode 100644 index 0000000000000000000000000000000000000000..c2009ff628d244d66109798844655cb645517273 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example2.java @@ -0,0 +1,64 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import java.util.ArrayList; +import java.util.Collection; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.Series; +import com.xeiam.xchart.SeriesColor; +import com.xeiam.xchart.SeriesLineStyle; +import com.xeiam.xchart.SeriesMarker; +import com.xeiam.xchart.SwingWrapper; + +/** + * Embed a Chart in a simple Swing application + * + * @author timmolter + */ +public class Example2 { + + public static void main(String[] args) { + + // generates sine data + int size = 30; + Collection<Number> xData1 = new ArrayList<Number>(); + Collection<Number> yData1 = new ArrayList<Number>(); + for (int i = 0; i <= size; i++) { + double radians = (Math.PI / (size / 2) * i); + xData1.add(i - size / 2); + yData1.add(size * Math.sin(radians)); + } + + // Create Chart + Chart chart = new Chart(440, 300); + + // Customize Chart + chart.setTitleVisible(false); + chart.setLegendVisible(false); + + // Series 1 + Series series1 = chart.addSeries("y=sin(x)", xData1, yData1); + series1.setLineColor(SeriesColor.PURPLE); + series1.setLineStyle(SeriesLineStyle.DASH_DASH); + series1.setMarkerColor(SeriesColor.GREEN); + series1.setMarker(SeriesMarker.SQUARE); + + new SwingWrapper(chart).displayChart(); + } + +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example3.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example3.java new file mode 100644 index 0000000000000000000000000000000000000000..b57c080cdf38729acf3692710b4177f101ac2d36 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example3.java @@ -0,0 +1,59 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import java.util.ArrayList; +import java.util.Collection; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.SwingWrapper; + +/** + * Create multiple curves on one Chart + * + * @author timmolter + */ +public class Example3 { + + public static void main(String[] args) { + + // Create Chart + Chart chart = new Chart(700, 500); + + for (int i = 1; i <= 14; i++) { + + // generates linear data + int b = 20; + Collection<Number> xData = new ArrayList<Number>(); + Collection<Number> yData = new ArrayList<Number>(); + for (int x = 0; x <= b; x++) { + xData.add(2 * x - b); + yData.add(2 * i * x - i * b); + } + + // Customize Chart + chart.setTitle("Sample Chart"); + chart.setXAxisTitle("X"); + chart.setYAxisTitle("Y"); + + String seriesName = "y=" + 2 * i + "x-" + i * b + "b"; + chart.addSeries(seriesName, xData, yData); + + } + // JFrame testFrame = new TestFrame(chart); + new SwingWrapper(chart).displayChart(); + } +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example4.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example4.java new file mode 100644 index 0000000000000000000000000000000000000000..1d9373f9e9850f7550186304c4d2d0070d4026c7 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example4.java @@ -0,0 +1,60 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import java.util.ArrayList; +import java.util.List; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.QuickChart; +import com.xeiam.xchart.SwingWrapper; + +/** + * Create a Chart matrix + * + * @author timmolter + */ +public class Example4 { + + public static void main(String[] args) { + + int numCharts = 4; + + List<Chart> charts = new ArrayList<Chart>(); + + for (int i = 0; i < numCharts; i++) { + charts.add(QuickChart.getChart("" + i, "X", "Y", null, null, getRandomWalk(1000))); + } + new SwingWrapper(charts).displayChartMatrix(); + } + + /** + * Generates a set of random walk data + * + * @param numPoints + * @return + */ + private static double[] getRandomWalk(int numPoints) { + + double[] y = new double[numPoints]; + y[0] = 0; + for (int i = 1; i < y.length; i++) { + y[i] = y[i - 1] + Math.random() - .5; + } + return y; + } + +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example5.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example5.java new file mode 100644 index 0000000000000000000000000000000000000000..46808f16c3656aeda3ce762467119ee58edc4174 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example5.java @@ -0,0 +1,44 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.SwingWrapper; + +/** + * Plot vertical and horizontal lines + * + * @author timmolter + */ +public class Example5 { + + public static void main(String[] args) { + + // Create Chart + Chart chart = new Chart(700, 500); + + // Customize Chart + chart.setTitle("Sample Chart"); + chart.setXAxisTitle("X"); + chart.setYAxisTitle("Y"); + + chart.addSeries("vertical", new double[] { 1, 1 }, new double[] { -10, 10 }); + chart.addSeries("horizontal", new double[] { -10, 10 }, new double[] { 0, 0 }); + + new SwingWrapper(chart).displayChart(); + } + +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example6.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example6.java new file mode 100644 index 0000000000000000000000000000000000000000..b4238270caa7bd1bf516bd90b2154c94966782b2 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example6.java @@ -0,0 +1,43 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.SwingWrapper; + +/** + * Create Chart with single point + * + * @author timmolter + */ +public class Example6 { + + public static void main(String[] args) { + + // Create Chart + Chart chart = new Chart(700, 500); + + // Customize Chart + chart.setTitle("Sample Chart"); + chart.setXAxisTitle("X"); + chart.setYAxisTitle("Y"); + + chart.addSeries("single point (1,1)", new double[] { 1 }, new double[] { 1 }); + + new SwingWrapper(chart).displayChart(); + } + +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example7.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example7.java new file mode 100644 index 0000000000000000000000000000000000000000..82a716d7b532725735448cc97336afa8f735d0e0 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example7.java @@ -0,0 +1,47 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import java.util.Arrays; +import java.util.Collection; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.SwingWrapper; + +/** + * Creates a simple Chart using Longs as X-Axis data + * + * @author timmolter + */ +public class Example7 { + + public static void main(String[] args) throws Exception { + + Collection<Number> xData = Arrays.asList(new Number[] { 12228120L, 12228984L, 12229848L, 12230712L, 12231576L, 12232440L, 12233304L, 12234168L, 12235032L, 12235896L }); + Collection<Number> yData = Arrays.asList(new Number[] { 0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 0.0 }); + + // Create Chart + Chart chart = new Chart(700, 500); + chart.setTitle("Sample Chart"); + chart.setXAxisTitle("X"); + chart.setYAxisTitle("Y"); + chart.addSeries("y(x)", xData, yData); + + new SwingWrapper(chart).displayChart(); + + } + +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example8.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example8.java new file mode 100644 index 0000000000000000000000000000000000000000..7e773e3a41fa144ba6c18af23a29ab4f5908ecd8 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example8.java @@ -0,0 +1,66 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import java.util.ArrayList; +import java.util.Collection; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.Series; +import com.xeiam.xchart.SeriesColor; +import com.xeiam.xchart.SeriesLineStyle; +import com.xeiam.xchart.SeriesMarker; +import com.xeiam.xchart.SwingWrapper; + +/** + * Create a Chart with error bars + * + * @author timmolter + */ +public class Example8 { + + public static void main(String[] args) { + + // generates data + int size = 10; + Collection<Number> xData1 = new ArrayList<Number>(); + Collection<Number> yData1 = new ArrayList<Number>(); + Collection<Number> errorBars = new ArrayList<Number>(); + for (int i = 0; i <= size; i++) { + xData1.add(i); + yData1.add(10 * Math.exp(-i)); + errorBars.add(Math.random() + .3); + } + + // Create Chart + Chart chart = new Chart(600, 400); + + // Customize Chart + chart.setTitleVisible(false); + chart.setLegendVisible(false); + chart.setAxisTitlesVisible(false); + + // Series 1 + Series series1 = chart.addSeries("10^(-x)", xData1, yData1, errorBars); + series1.setLineColor(SeriesColor.PURPLE); + series1.setLineStyle(SeriesLineStyle.DASH_DASH); + series1.setMarkerColor(SeriesColor.GREEN); + series1.setMarker(SeriesMarker.SQUARE); + + new SwingWrapper(chart).displayChart(); + } + +} diff --git a/xchange-examples/src/test/java/com/xeiam/xchart/example/Example9.java b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example9.java new file mode 100644 index 0000000000000000000000000000000000000000..5fee0c9ae7758ed0559045691dee773544a50e58 --- /dev/null +++ b/xchange-examples/src/test/java/com/xeiam/xchart/example/Example9.java @@ -0,0 +1,87 @@ +/** + * Copyright 2011-2013 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.example; + +import java.awt.Color; +import java.awt.Font; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Locale; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.ChartColor; +import com.xeiam.xchart.Series; +import com.xeiam.xchart.SeriesColor; +import com.xeiam.xchart.SeriesLineStyle; +import com.xeiam.xchart.SeriesMarker; +import com.xeiam.xchart.SwingWrapper; + +/** + * Create a Chart with a Date x-axis and extensive chart customization + * + * @author timmolter + */ +public class Example9 { + + public static void main(String[] args) throws ParseException { + + // Create Chart + Chart chart = new Chart(700, 500); + + // generates linear data + Collection<Date> xData = new ArrayList<Date>(); + Collection<Number> yData = new ArrayList<Number>(); + + DateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); + for (int i = 1; i <= 10; i++) { + Date date = sdf.parse(i + ".10.2008"); + xData.add(date); + yData.add(Math.random() * i); + } + + // Customize Chart + chart.setTitle("Sample Chart with Date X-Axis"); + chart.setXAxisTitle("X"); + chart.setYAxisTitle("Y"); + chart.setForegroundColor(ChartColor.getAWTColor(ChartColor.GREY)); + chart.setGridLinesColor(new Color(255, 255, 255)); + chart.setBackgroundColor(Color.WHITE); + chart.setLegendBackgroundColor(Color.PINK); + chart.setLinesColor(Color.GREEN); + chart.setFontColor(Color.MAGENTA); + chart.setTitleFont(new Font(Font.MONOSPACED, Font.BOLD, 24)); + chart.setLegendFont(new Font(Font.SERIF, Font.PLAIN, 18)); + chart.setAxisTitleFont(new Font(Font.SANS_SERIF, Font.ITALIC, 18)); + chart.setTickLabelFont(new Font(Font.SANS_SERIF, Font.ITALIC, 18)); + chart.setTickLabelFont(new Font(Font.SERIF, Font.PLAIN, 11)); + chart.setDateFormatter("dd-MMM"); + chart.setDecmialFormatter("#.000"); + chart.setLocale(Locale.GERMAN); + + Series series = chart.addDateSeries("Fake Data", xData, yData); + series.setLineColor(SeriesColor.BLUE); + series.setMarkerColor(Color.ORANGE); + series.setMarker(SeriesMarker.CIRCLE); + series.setLineStyle(SeriesLineStyle.SOLID); + + new SwingWrapper(chart).displayChart(); + } + +}