diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/bar/BarChart06.java b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/bar/BarChart06.java new file mode 100644 index 0000000000000000000000000000000000000000..acd8fc00f9212b34f2ab610b28061029dd0ff169 --- /dev/null +++ b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/bar/BarChart06.java @@ -0,0 +1,71 @@ +/** + * Copyright 2011 - 2014 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.demo.charts.bar; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.ChartBuilder; +import com.xeiam.xchart.StyleManager.ChartType; +import com.xeiam.xchart.StyleManager.LegendPosition; +import com.xeiam.xchart.SwingWrapper; +import com.xeiam.xchart.demo.charts.ExampleChart; + +/** + * Basic Bar Chart + * <p> + * Demonstrates the following: + * <ul> + * <li>Histogram + */ +public class BarChart06 implements ExampleChart { + + public static void main(String[] args) { + + ExampleChart exampleChart = new BarChart06(); + Chart chart = exampleChart.getChart(); + new SwingWrapper(chart).displayChart(); + } + + @Override + public Chart getChart() { + + // Create Chart + Chart chart = new ChartBuilder().chartType(ChartType.Bar).width(800).height(600).title("Score Histogram").xAxisTitle("Score").yAxisTitle("Count").build(); + + chart.addSeries("histogram 1", getGaussianData(1000), 11, -30, 30); + chart.addSeries("histogram 2", getGaussianData(1000), 11, -30, 30); + + // Customize Chart + chart.getStyleManager().setLegendPosition(LegendPosition.InsideNW); + + return chart; + } + + private List<Double> getGaussianData(int count) { + + List<Double> data = new ArrayList<Double>(count); + Random r = new Random(); + for (int i = 0; i < count; i++) { + // data.add(r.nextGaussian() * 10); + data.add(r.nextDouble() * 60 - 30); + } + return data; + } + +} diff --git a/xchart/src/main/java/com/xeiam/xchart/Chart.java b/xchart/src/main/java/com/xeiam/xchart/Chart.java index ff2c99d1cd384d910f98fac28aeafd59e06afd44..8825732f22bbc745aa67ae9c5b437dcb370b5549 100644 --- a/xchart/src/main/java/com/xeiam/xchart/Chart.java +++ b/xchart/src/main/java/com/xeiam/xchart/Chart.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Map; import com.xeiam.xchart.StyleManager.ChartTheme; +import com.xeiam.xchart.internal.Histogram; import com.xeiam.xchart.internal.chartpart.ChartPainter; import com.xeiam.xchart.internal.style.Theme; @@ -43,7 +44,6 @@ public class Chart { public Chart(int width, int height) { chartPainter = new ChartPainter(width, height); - } /** @@ -177,7 +177,7 @@ public class Chart { } /** - * Add a series to the chart using double arrays + * Add a series to the chart using int arrays * * @param seriesName * @param xData the X-Axis data @@ -190,7 +190,7 @@ public class Chart { } /** - * Add a series to the chart using double arrays with error bars + * Add a series to the chart using int arrays with error bars * * @param seriesName * @param xData the X-Axis data @@ -222,6 +222,23 @@ public class Chart { return chartPainter.getAxisPair().addSeries(seriesName, xDataNumber, yDataNumber, errorBarDataNumber); } + /** + * Add a series for a histogram + * + * @param seriesName + * @param data + * @param numBins + * @param min + * @param max + * @return + */ + public Series addSeries(String seriesName, Collection<? extends Number> data, int numBins, double min, double max) { + + Histogram histogram1 = new Histogram(data, numBins, min, max); + + return chartPainter.getAxisPair().addSeries(seriesName, histogram1.getxAxisData(), histogram1.getyAxisData(), null); + } + /** * Set the chart title * diff --git a/xchart/src/main/java/com/xeiam/xchart/StyleManager.java b/xchart/src/main/java/com/xeiam/xchart/StyleManager.java index 452f3096e3f71f6a028a0c76e981caeca3901b90..3b396e4c4efb09ac098c0cc0b9f60533ce52b944 100644 --- a/xchart/src/main/java/com/xeiam/xchart/StyleManager.java +++ b/xchart/src/main/java/com/xeiam/xchart/StyleManager.java @@ -38,7 +38,7 @@ public class StyleManager { */ public enum ChartType { - Line, Scatter, Area, Bar + Line, Scatter, Area, Bar, Histogram } public enum LegendPosition { @@ -116,7 +116,7 @@ public class StyleManager { private Double xAxisMax; private Double yAxisMin; private Double yAxisMax; - private double axisTickSpaceRatio; + private double axisTickSpaceRatio; // Chart Plot Area /////////////////////////////// private boolean isPlotGridLinesVisible; @@ -850,11 +850,13 @@ public class StyleManager { } public void setAxisTickSpaceRatio(double axisTickSpaceRatio) { + this.axisTickSpaceRatio = axisTickSpaceRatio; } public double getAxisTickSpaceRatio() { - return axisTickSpaceRatio; + + return axisTickSpaceRatio; } // Chart Plot Area /////////////////////////////// diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/Histogram.java b/xchart/src/main/java/com/xeiam/xchart/internal/Histogram.java new file mode 100644 index 0000000000000000000000000000000000000000..cfd5d8a8a35411bfc18547a69cef6e5e6c5efabc --- /dev/null +++ b/xchart/src/main/java/com/xeiam/xchart/internal/Histogram.java @@ -0,0 +1,106 @@ +/** + * Copyright 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; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * @author timmolter + */ +public class Histogram { + + private final List<Double> xAxisData; // bin centers + private final List<Double> yAxisData; // frequency counts + private final Collection<? extends Number> originalData; + private final int numBins; + private final double min; + private final double max; + + /** + * Constructor + */ + public Histogram(Collection<? extends Number> data, int numBins, double min, double max) { + + this.numBins = numBins; + this.originalData = data; + // Arrays.sort(data); + this.min = min; + this.max = max; + // this.min = data[0]; + // this.max = data[data.length - 1]; + + double[] tempYAxisData = new double[numBins]; + final double binSize = (max - min) / numBins; + + // y axis data + Iterator<? extends Number> itr = data.iterator(); + while (itr.hasNext()) { + + int bin = (int) (((Double) itr.next() - min) / binSize); // changed this from numBins + if (bin < 0) { /* this data is smaller than min */ + } + else if (bin >= numBins) { /* this data point is bigger than max */ + } + else { + tempYAxisData[bin] += 1; + } + } + yAxisData = new ArrayList<Double>(numBins); + for (double d : tempYAxisData) { + yAxisData.add(new Double(d)); + } + + // x axis data + xAxisData = new ArrayList<Double>(numBins); + for (int i = 0; i < numBins; i++) { + xAxisData.add(((i * (max - min)) / numBins + min) + binSize / 2); + } + } + + public List<Double> getxAxisData() { + + return xAxisData; + } + + public List<Double> getyAxisData() { + + return yAxisData; + } + + public Collection<? extends Number> getOriginalData() { + + return originalData; + } + + public int getNumBins() { + + return numBins; + } + + public double getMin() { + + return min; + } + + public double getMax() { + + return max; + } + +}