diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart04.java b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart04.java index efbb76ef49fc778a99623e8c29cef7b2dd2b22c1..9e95afd49cdaf766ad02a2fe9d609294b5fd066f 100644 --- a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart04.java +++ b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart04.java @@ -48,7 +48,7 @@ public class LineChart04 implements ExampleChart { chart.getStyleManager().setLegendVisible(false); for (int i = 0; i < 200; i++) { - Series series = chart.addSeries("A", new double[] { Math.random(), Math.random() }, new double[] { Math.random(), Math.random() }); + Series series = chart.addSeries("A" + i, new double[] { Math.random(), Math.random() }, new double[] { Math.random(), Math.random() }); series.setLineColor(SeriesColor.BLUE); series.setLineStyle(SeriesLineStyle.SOLID); series.setMarker(SeriesMarker.CIRCLE); diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/standalone/RealtimeAttempt.java b/xchart-demo/src/main/java/com/xeiam/xchart/standalone/RealtimeAttempt.java index cfdae014aa4bed02d46d8bea003b21d4caf82c93..905b5b20aa3e56485c61f02a04e1a2fd079293a5 100644 --- a/xchart-demo/src/main/java/com/xeiam/xchart/standalone/RealtimeAttempt.java +++ b/xchart-demo/src/main/java/com/xeiam/xchart/standalone/RealtimeAttempt.java @@ -1,4 +1,4 @@ -/* +/** * Copyright 2013 Xeiam, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,121 +15,129 @@ */ package com.xeiam.xchart.standalone; -import com.xeiam.xchart.Chart; -import com.xeiam.xchart.Series; -import com.xeiam.xchart.SeriesMarker; -import com.xeiam.xchart.XChartPanel; import java.util.ArrayList; import java.util.Collection; import java.util.Timer; import java.util.TimerTask; + import javax.swing.JFrame; import javax.swing.JPanel; +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.Series; +import com.xeiam.xchart.SeriesMarker; +import com.xeiam.xchart.XChartPanel; + /** - * * @author rossjourdain */ public class RealtimeAttempt { - - private Chart chart; - private JPanel chartPanel; - - public static void main(String[] args) throws Exception { - - // Setup the panel - final RealtimeAttempt realtimeAttempt = new RealtimeAttempt(); - realtimeAttempt.buildPanel(); - - // 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.add(realtimeAttempt.getChartPanel()); - - // Display the window. - frame.pack(); - frame.setVisible(true); - } - }); - - // Simulate a data feed - TimerTask chartUpdaterTask = new TimerTask() { - @Override - public void run() { - realtimeAttempt.updateData(); - } - }; - - Timer timer = new Timer(); - timer.scheduleAtFixedRate(chartUpdaterTask, 0, 1000); - } - - public void buildPanel() { - Collection<Number> yData = getRandomData(5); - - // Create Chart - chart = new Chart(500, 400); - chart.setChartTitle("Sample Chart"); - chart.setXAxisTitle("X"); - chart.setYAxisTitle("Y"); - Series series = chart.addSeries("y(x)", null, yData); - series.setMarker(SeriesMarker.CIRCLE); - - chartPanel = new XChartPanel(chart); - } - - public void updateData() { - // Get some new data - Collection<Number> newData = getRandomData(1); - - - // Replace the existing - ArrayList<Number> replacementData = new ArrayList<Number>(); - - Series oldSeries = (Series) chart.getSeriesMap().values().toArray()[0]; - Collection<Number> oldData = oldSeries.getyData(); - replacementData.addAll(oldData); - - replacementData.addAll(newData); - - // Limit the total number of points - while (replacementData.size() > 20) { - replacementData.remove(0); - } - - // Swap out the data - chart.getSeriesMap().clear(); - Series newSeries = chart.addSeries(oldSeries.getName(), null, replacementData); - newSeries.setLineColor(oldSeries.getStrokeColor()); - newSeries.setLineStyle(oldSeries.getStroke()); - newSeries.setMarkerColor(oldSeries.getMarkerColor()); - //etc - - // Re-display the chart - chartPanel.revalidate(); - chartPanel.repaint(); - } + private Chart chart; + private JPanel chartPanel; - public Chart getChart() { - return chart; - } + public static void main(String[] args) throws Exception { + + // Setup the panel + final RealtimeAttempt realtimeAttempt = new RealtimeAttempt(); + realtimeAttempt.buildPanel(); + + // 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.add(realtimeAttempt.getChartPanel()); + + // Display the window. + frame.pack(); + frame.setVisible(true); + } + }); + + // Simulate a data feed + TimerTask chartUpdaterTask = new TimerTask() { - public JPanel getChartPanel() { - return chartPanel; + @Override + public void run() { + + realtimeAttempt.updateData(); + } + }; + + Timer timer = new Timer(); + timer.scheduleAtFixedRate(chartUpdaterTask, 0, 500); + + } + + public void buildPanel() { + + Collection<Number> yData = getRandomData(5); + + // Create Chart + chart = new Chart(500, 400); + chart.setChartTitle("Sample Chart"); + chart.setXAxisTitle("X"); + chart.setYAxisTitle("Y"); + Series series = chart.addSeries("y(x)", null, yData); + series.setMarker(SeriesMarker.CIRCLE); + + chartPanel = new XChartPanel(chart); + } + + public void updateData() { + + // Get some new data + Collection<Number> newData = getRandomData(1); + + // Replace the existing + ArrayList<Number> replacementData = new ArrayList<Number>(); + + Series oldSeries = (Series) chart.getSeriesMap().values().toArray()[0]; + Collection<Number> oldData = oldSeries.getYData(); + replacementData.addAll(oldData); + + replacementData.addAll(newData); + + // Limit the total number of points + while (replacementData.size() > 20) { + replacementData.remove(0); } - - private static Collection<Number> getRandomData(int numPoints) { - ArrayList<Number> data = new ArrayList<Number>(); - for (int i = 0; i < numPoints; i++) { - data.add(Math.random() * 100); - } - return data; + + // Swap out the data + chart.getSeriesMap().clear(); + Series newSeries = chart.addSeries(oldSeries.getName(), null, replacementData); + newSeries.setLineColor(oldSeries.getStrokeColor()); + newSeries.setLineStyle(oldSeries.getStroke()); + newSeries.setMarkerColor(oldSeries.getMarkerColor()); + // etc + + // Re-display the chart + chartPanel.revalidate(); + chartPanel.repaint(); + } + + public Chart getChart() { + + return chart; + } + + public JPanel getChartPanel() { + + return chartPanel; + } + + private static Collection<Number> getRandomData(int numPoints) { + + ArrayList<Number> data = new ArrayList<Number>(); + for (int i = 0; i < numPoints; i++) { + data.add(Math.random() * 100); } + return data; + } } diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/standalone/RealtimeAttempt2.java b/xchart-demo/src/main/java/com/xeiam/xchart/standalone/RealtimeAttempt2.java new file mode 100644 index 0000000000000000000000000000000000000000..b127bd1cefa8cae570b34549599f83c09088b87b --- /dev/null +++ b/xchart-demo/src/main/java/com/xeiam/xchart/standalone/RealtimeAttempt2.java @@ -0,0 +1,125 @@ +/** + * 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.standalone; + +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.XChartPanel; + +/** + * @author timmolter + */ +public class RealtimeAttempt2 { + + private Chart chart; + private XChartPanel chartPanel; + private static final String SERIES_NAME = "series1"; + private List<Number> yData; + + public static void main(String[] args) throws Exception { + + // Setup the panel + final RealtimeAttempt2 realtimeAttempt = new RealtimeAttempt2(); + realtimeAttempt.buildPanel(); + + // 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.add(realtimeAttempt.getChartPanel()); + + // Display the window. + frame.pack(); + frame.setVisible(true); + } + }); + + // Simulate a data feed + TimerTask chartUpdaterTask = new TimerTask() { + + @Override + public void run() { + + realtimeAttempt.updateData(); + } + }; + + Timer timer = new Timer(); + timer.scheduleAtFixedRate(chartUpdaterTask, 0, 500); + + } + + public void buildPanel() { + + yData = getRandomData(5); + + // Create Chart + chart = new Chart(500, 400); + chart.setChartTitle("Sample Real-time Chart"); + chart.setXAxisTitle("X"); + chart.setYAxisTitle("Y"); + chart.addSeries(SERIES_NAME, null, yData); + + chartPanel = new XChartPanel(chart); + } + + public void updateData() { + + // Get some new data + List<Number> newData = getRandomData(1); + + yData.addAll(newData); + + // Limit the total number of points + while (yData.size() > 20) { + yData.remove(0); + } + + chartPanel.updateSeries(SERIES_NAME, yData); + } + + public Chart getChart() { + + return chart; + } + + public JPanel getChartPanel() { + + return chartPanel; + } + + private static List<Number> getRandomData(int numPoints) { + + List<Number> data = new ArrayList<Number>(); + for (int i = 0; i < numPoints; i++) { + data.add(Math.random() * 100); + } + return data; + } +} diff --git a/xchart/src/main/java/com/xeiam/xchart/CSVExporter.java b/xchart/src/main/java/com/xeiam/xchart/CSVExporter.java index 463f7fd9a36f06ff4815c836ccaef66fe0c150b6..9e66bc8117472c6709ba64f4a8bc1bf07bc2428f 100644 --- a/xchart/src/main/java/com/xeiam/xchart/CSVExporter.java +++ b/xchart/src/main/java/com/xeiam/xchart/CSVExporter.java @@ -45,9 +45,9 @@ public class CSVExporter { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile), "UTF8")); - String csv = join(series.getxData(), ",") + System.getProperty("line.separator"); + String csv = join(series.getXData(), ",") + System.getProperty("line.separator"); out.write(csv); - csv = join(series.getyData(), ",") + System.getProperty("line.separator"); + csv = join(series.getYData(), ",") + System.getProperty("line.separator"); out.write(csv); if (series.getErrorBars() != null) { csv = join(series.getErrorBars(), ",") + System.getProperty("line.separator"); @@ -81,8 +81,8 @@ public class CSVExporter { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile), "UTF8")); - Collection<?> xData = series.getxData(); - Collection<Number> yData = series.getyData(); + Collection<?> xData = series.getXData(); + Collection<Number> yData = series.getYData(); Collection<Number> errorBarData = series.getErrorBars(); Iterator<?> itrx = xData.iterator(); Iterator<Number> itry = yData.iterator(); diff --git a/xchart/src/main/java/com/xeiam/xchart/Chart.java b/xchart/src/main/java/com/xeiam/xchart/Chart.java index c2f5b74915a7cf9be66b67f943c068b56375d452..be6497b19c5deaafb8c64c22e47079f8b1addd24 100644 --- a/xchart/src/main/java/com/xeiam/xchart/Chart.java +++ b/xchart/src/main/java/com/xeiam/xchart/Chart.java @@ -25,7 +25,6 @@ import com.xeiam.xchart.StyleManager.ChartTheme; import com.xeiam.xchart.internal.chartpart.ChartPainter; import com.xeiam.xchart.internal.style.GGPlot2Theme; import com.xeiam.xchart.internal.style.MatlabTheme; -import com.xeiam.xchart.internal.style.Theme; import com.xeiam.xchart.internal.style.XChartTheme; /** @@ -61,13 +60,13 @@ public class Chart { chartPainter = new ChartPainter(width, height); if (chartTheme == ChartTheme.XChart) { - setTheme(new XChartTheme()); + chartPainter.getStyleManager().setTheme(new XChartTheme()); } else if (chartTheme == ChartTheme.GGPlot2) { - setTheme(new GGPlot2Theme()); + chartPainter.getStyleManager().setTheme(new GGPlot2Theme()); } else if (chartTheme == ChartTheme.Matlab) { - setTheme(new MatlabTheme()); + chartPainter.getStyleManager().setTheme(new MatlabTheme()); } } @@ -97,8 +96,6 @@ public class Chart { /** * @param g - * @param width - * @param height */ public void paint(Graphics2D g) { @@ -258,16 +255,6 @@ public class Chart { return chartPainter.getStyleManager(); } - /** - * Set the theme the Chart's style manager should use - * - * @param theme - */ - public void setTheme(Theme theme) { - - chartPainter.getStyleManager().setTheme(theme); - } - public int getWidth() { return chartPainter.getWidth(); @@ -278,7 +265,7 @@ public class Chart { return chartPainter.getHeight(); } - public Map<Integer, Series> getSeriesMap() { + public Map<String, Series> getSeriesMap() { return chartPainter.getAxisPair().getSeriesMap(); } diff --git a/xchart/src/main/java/com/xeiam/xchart/Series.java b/xchart/src/main/java/com/xeiam/xchart/Series.java index 26504f6e4d832cb5c30ecfef9070c33f1e7eb6c7..015c7c476debbae009a1339cda60bb9a8a654623 100644 --- a/xchart/src/main/java/com/xeiam/xchart/Series.java +++ b/xchart/src/main/java/com/xeiam/xchart/Series.java @@ -21,6 +21,7 @@ import java.math.BigDecimal; import java.util.Collection; import java.util.Date; import java.util.Iterator; +import java.util.List; import com.xeiam.xchart.internal.chartpart.Axis.AxisType; import com.xeiam.xchart.internal.markers.Marker; @@ -36,8 +37,10 @@ public class Series { private String name = ""; private Collection<?> xData; + private AxisType xAxisType; private Collection<Number> yData; + private AxisType yAxisType; private Collection<Number> errorBars; @@ -74,6 +77,7 @@ public class Series { * @param yData * @param yAxisType * @param errorBars + * @param seriesColorMarkerLineStyle */ public Series(String name, Collection<?> xData, AxisType xAxisType, Collection<Number> yData, AxisType yAxisType, Collection<Number> errorBars, SeriesColorMarkerLineStyle seriesColorMarkerLineStyle) { @@ -82,7 +86,9 @@ public class Series { } this.name = name; this.xData = xData; + this.xAxisType = xAxisType; this.yData = yData; + this.yAxisType = yAxisType; this.errorBars = errorBars; strokeColor = seriesColorMarkerLineStyle.getColor(); @@ -90,23 +96,8 @@ public class Series { marker = seriesColorMarkerLineStyle.getMarker(); stroke = seriesColorMarkerLineStyle.getStroke(); - // xData - BigDecimal[] xMinMax = findMinMax(xData, xAxisType); - xMin = xMinMax[0]; - xMax = xMinMax[1]; + calculateMinMax(); - // 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); } /** @@ -246,12 +237,12 @@ public class Series { this.markerColor = color; } - public Collection<?> getxData() { + public Collection<?> getXData() { return xData; } - public Collection<Number> getyData() { + public Collection<Number> getYData() { return yData; } @@ -305,4 +296,37 @@ public class Series { return name; } + + void replaceXData(List<Number> newXData) { + + xData = newXData; + calculateMinMax(); + } + + void replaceYData(List<Number> newYData) { + + yData = newYData; + calculateMinMax(); + } + + private void calculateMinMax() { + + // 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); + } } diff --git a/xchart/src/main/java/com/xeiam/xchart/XChartPanel.java b/xchart/src/main/java/com/xeiam/xchart/XChartPanel.java index 6a7f9e8eb5d2bec12c1ce3f8f0751ef53c5280b2..28e4acb84b1ab1e7979b48698a498d83bcb19455 100644 --- a/xchart/src/main/java/com/xeiam/xchart/XChartPanel.java +++ b/xchart/src/main/java/com/xeiam/xchart/XChartPanel.java @@ -26,6 +26,8 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import javax.swing.AbstractAction; import javax.swing.JFileChooser; @@ -240,4 +242,30 @@ public class XChartPanel extends JPanel { add(saveAsMenuItem); } } + + /** + * update a series by only updating the Y-Axis data + * + * @param seriesName + * @param newYData + */ + public void updateSeries(String seriesName, List<Number> newYData) { + + Series series = chart.getSeriesMap().get(seriesName); + if (series == null) { + throw new IllegalArgumentException("Series name >" + seriesName + "< not found!!!"); + } + series.replaceYData(newYData); + + // generate X-Data + List<Number> generatedXData = new ArrayList<Number>(); + for (int i = 1; i < newYData.size() + 1; i++) { + generatedXData.add(i); + } + series.replaceXData(generatedXData); + + // Re-display the chart + revalidate(); + repaint(); + } } diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java index 37d18f2c3153c131794b7c36290733507df28d75..9222636323f4a487df41c9c78470475b72552e1f 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java @@ -36,9 +36,7 @@ public class AxisPair implements ChartPart { /** parent */ private final ChartPainter chartPainter; - private Map<Integer, Series> seriesMap = new LinkedHashMap<Integer, Series>(); - - private int seriesCount = 0; + private Map<String, Series> seriesMap = new LinkedHashMap<String, Series>(); private Axis xAxis; private Axis yAxis; @@ -115,11 +113,11 @@ public class AxisPair implements ChartPart { throw new IllegalArgumentException("errorbars and Y-Axis sizes are not the same!!!"); } - seriesMap.put(seriesCount++, series); + if (seriesMap.keySet().contains(seriesName)) { + throw new IllegalArgumentException("Series name >" + seriesName + "< has already been used. Use unique names for each series!!!"); + } - // add min/max to axis - xAxis.addMinMax(series.getxMin(), series.getxMax()); - yAxis.addMinMax(series.getyMin(), series.getyMax()); + seriesMap.put(seriesName, series); return series; } @@ -145,7 +143,7 @@ public class AxisPair implements ChartPart { // Getters ///////////////////////////////////////////////// - public Map<Integer, Series> getSeriesMap() { + public Map<String, Series> getSeriesMap() { return seriesMap; } diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java index c131fda1425919440357953b368f1c6e0855d9b0..d918e1a8849f58f2d7e63a92f37d5a29b9c12f7e 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java @@ -18,7 +18,6 @@ package com.xeiam.xchart.internal.chartpart; import java.math.BigDecimal; import java.util.Date; import java.util.Iterator; -import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -49,7 +48,7 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { calculate(chart); } - private void calculate(ChartPainter chart) { + private void calculate(ChartPainter chartPainter) { // tick space - a percentage of the working space available for ticks, i.e. 95% int tickSpace = Utils.getTickSpace(workingSpace); // in plot space @@ -59,20 +58,18 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { // get all categories Set<Object> categories = new TreeSet<Object>(); - Map<Integer, Series> seriesMap = chart.getAxisPair().getSeriesMap(); - for (Integer seriesId : seriesMap.keySet()) { + for (Series series : chartPainter.getAxisPair().getSeriesMap().values()) { - Series series = seriesMap.get(seriesId); - Iterator<?> xItr = series.getxData().iterator(); + Iterator<?> xItr = series.getXData().iterator(); while (xItr.hasNext()) { Object x = null; - if (chart.getAxisPair().getxAxis().getAxisType() == AxisType.Number) { + if (chartPainter.getAxisPair().getxAxis().getAxisType() == AxisType.Number) { x = new BigDecimal(((Number) xItr.next()).doubleValue()); } - else if (chart.getAxisPair().getxAxis().getAxisType() == AxisType.Date) { + else if (chartPainter.getAxisPair().getxAxis().getAxisType() == AxisType.Date) { x = new BigDecimal(((Date) xItr.next()).getTime()); } - else if (chart.getAxisPair().getxAxis().getAxisType() == AxisType.String) { + else if (chartPainter.getAxisPair().getxAxis().getAxisType() == AxisType.String) { x = xItr.next(); } categories.add(x); @@ -88,24 +85,24 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { NumberFormatter numberFormatter = null; DateFormatter dateFormatter = null; - if (chart.getAxisPair().getxAxis().getAxisType() == AxisType.Number) { + if (chartPainter.getAxisPair().getxAxis().getAxisType() == AxisType.Number) { numberFormatter = new NumberFormatter(styleManager); } - else if (chart.getAxisPair().getxAxis().getAxisType() == AxisType.Date) { - dateFormatter = new DateFormatter(chart.getStyleManager()); + else if (chartPainter.getAxisPair().getxAxis().getAxisType() == AxisType.Date) { + dateFormatter = new DateFormatter(chartPainter.getStyleManager()); } int counter = 0; for (Object category : categories) { - if (chart.getAxisPair().getxAxis().getAxisType() == AxisType.Number) { + if (chartPainter.getAxisPair().getxAxis().getAxisType() == AxisType.Number) { tickLabels.add(numberFormatter.formatNumber((BigDecimal) category)); } - else if (chart.getAxisPair().getxAxis().getAxisType() == AxisType.Date) { + else if (chartPainter.getAxisPair().getxAxis().getAxisType() == AxisType.Date) { long span = Math.abs(maxValue.subtract(minValue).longValue()); // in data space long gridStepHint = (long) (span / (double) tickSpace * DEFAULT_TICK_MARK_STEP_HINT_X); long timeUnit = dateFormatter.getTimeUnit(gridStepHint); tickLabels.add(dateFormatter.formatDate((BigDecimal) category, timeUnit)); } - else if (chart.getAxisPair().getxAxis().getAxisType() == AxisType.String) { + else if (chartPainter.getAxisPair().getxAxis().getAxisType() == AxisType.String) { tickLabels.add(category.toString()); } int tickLabelPosition = margin + firstPosition + gridStep * counter++; diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/ChartPainter.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/ChartPainter.java index 7d660cbc23ac4e3eefdca0297057c5dd6d701290..ad01901dc0bd5e42ec5a44e78f728e19f5e465de 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/ChartPainter.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/ChartPainter.java @@ -21,6 +21,7 @@ import java.awt.Shape; import java.awt.geom.Rectangle2D; import java.math.BigDecimal; +import com.xeiam.xchart.Series; import com.xeiam.xchart.StyleManager; /** @@ -42,7 +43,8 @@ public class ChartPainter { /** * Constructor * - * @param chart + * @param width + * @param height */ public ChartPainter(int width, int height) { @@ -74,6 +76,13 @@ public class ChartPainter { */ public void paint(Graphics2D g) { + // calc axis min and max + for (Series series : getAxisPair().getSeriesMap().values()) { + // add min/max to axis + axisPair.getxAxis().addMinMax(series.getxMin(), series.getxMax()); + axisPair.getyAxis().addMinMax(series.getyMin(), series.getyMax()); + } + // Sanity checks if (axisPair.getSeriesMap().isEmpty()) { throw new RuntimeException("No series defined for Chart!!!"); diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java index 708a877783accea81d01d1479aea46c4bbd6e177..c22006023f56fca61b1240b30517322f702a1a5b 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/Legend.java @@ -22,7 +22,6 @@ import java.awt.font.FontRenderContext; import java.awt.font.TextLayout; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; -import java.util.Map; import com.xeiam.xchart.Series; import com.xeiam.xchart.StyleManager.ChartType; @@ -61,14 +60,12 @@ public class Legend implements ChartPart { if (chartPainter.getStyleManager().isLegendVisible()) { - Map<Integer, Series> seriesMap = chartPainter.getAxisPair().getSeriesMap(); - // determine legend text content max width double legendTextContentMaxWidth = 0; double legendTextContentMaxHeight = 0; - for (Integer seriesId : seriesMap.keySet()) { - Series series = seriesMap.get(seriesId); + for (Series series : chartPainter.getAxisPair().getSeriesMap().values()) { + TextLayout textLayout = new TextLayout(series.getName(), chartPainter.getStyleManager().getLegendFont(), new FontRenderContext(null, true, false)); Rectangle2D rectangle = textLayout.getBounds(); // System.out.println(rectangle); @@ -88,7 +85,8 @@ public class Legend implements ChartPart { else { maxContentHeight = Math.max(legendTextContentMaxHeight, BOX_SIZE); } - double legendContentHeight = maxContentHeight * seriesMap.size() + chartPainter.getStyleManager().getLegendPadding() * (seriesMap.size() - 1); + double legendContentHeight = + maxContentHeight * getChartPainter().getAxisPair().getSeriesMap().size() + chartPainter.getStyleManager().getLegendPadding() * (getChartPainter().getAxisPair().getSeriesMap().size() - 1); // determine legend content width double legendContentWidth = 0; @@ -116,8 +114,6 @@ public class Legend implements ChartPart { if (chartPainter.getStyleManager().isLegendVisible()) { - Map<Integer, Series> seriesMap = chartPainter.getAxisPair().getSeriesMap(); - double legendBoxWidth = getSizeHint()[0]; double legendBoxHeight = getSizeHint()[1]; double maxContentHeight = getSizeHint()[2]; @@ -164,8 +160,8 @@ public class Legend implements ChartPart { // Draw legend content inside legend box double startx = xOffset + chartPainter.getStyleManager().getLegendPadding(); double starty = yOffset + chartPainter.getStyleManager().getLegendPadding(); - for (Integer seriesId : seriesMap.keySet()) { - Series series = seriesMap.get(seriesId); + + for (Series series : chartPainter.getAxisPair().getSeriesMap().values()) { if (getChartPainter().getStyleManager().getChartType() != ChartType.Bar) { diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentBarChart.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentBarChart.java index 07140e1b178379b5bc6450dfcedd89f59f312580..0c2ebbfe51b5042a376a3d8a42c39c802d0892d4 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentBarChart.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentBarChart.java @@ -21,7 +21,6 @@ import java.awt.geom.Rectangle2D; import java.math.BigDecimal; import java.util.Collection; import java.util.Iterator; -import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -58,11 +57,9 @@ public class PlotContentBarChart extends PlotContent { // get all categories Set<Object> categories = new TreeSet<Object>(); - Map<Integer, Series> seriesMap = getChartPainter().getAxisPair().getSeriesMap(); - for (Integer seriesId : seriesMap.keySet()) { + for (Series series : getChartPainter().getAxisPair().getSeriesMap().values()) { - Series series = seriesMap.get(seriesId); - Iterator<?> xItr = series.getxData().iterator(); + Iterator<?> xItr = series.getXData().iterator(); while (xItr.hasNext()) { categories.add(xItr.next()); } @@ -72,14 +69,12 @@ public class PlotContentBarChart extends PlotContent { // plot series int seriesCounter = 0; - for (Integer seriesId : seriesMap.keySet()) { - - Series series = seriesMap.get(seriesId); + for (Series series : getChartPainter().getAxisPair().getSeriesMap().values()) { // data points - Collection<?> xData = series.getxData(); + Collection<?> xData = series.getXData(); - Collection<Number> yData = series.getyData(); + Collection<Number> yData = series.getYData(); BigDecimal yMin = getChartPainter().getAxisPair().getyAxis().getMin(); BigDecimal yMax = getChartPainter().getAxisPair().getyAxis().getMax(); @@ -174,7 +169,7 @@ public class PlotContentBarChart extends PlotContent { double zeroOffset = bounds.getY() + zeroTransform + 1; // paint bar - double barWidth = gridStep / seriesMap.size() / 1.1; + double barWidth = gridStep / getChartPainter().getAxisPair().getSeriesMap().size() / 1.1; double barMargin = gridStep * .05; double xOffset = bounds.getX() + xLeftMargin + gridStep * barCounter++ + seriesCounter * barWidth + barMargin; g.setColor(series.getStrokeColor()); diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentLineChart.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentLineChart.java index d91c180ed227441751b59bf4e1ef4208bcabdb11..e8582720405a8ef08ccf5363b2da5fb5319aa1e4 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentLineChart.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentLineChart.java @@ -24,7 +24,6 @@ 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.StyleManager.ChartType; @@ -59,17 +58,14 @@ public class PlotContentLineChart extends PlotContent { int yTickSpace = Utils.getTickSpace((int) bounds.getHeight()); int yTopMargin = Utils.getTickStartOffset((int) bounds.getHeight(), yTickSpace); - Map<Integer, Series> seriesMap = getChartPainter().getAxisPair().getSeriesMap(); - for (Integer seriesId : seriesMap.keySet()) { - - Series series = seriesMap.get(seriesId); + for (Series series : getChartPainter().getAxisPair().getSeriesMap().values()) { // data points - Collection<?> xData = series.getxData(); + Collection<?> xData = series.getXData(); BigDecimal xMin = getChartPainter().getAxisPair().getxAxis().getMin(); BigDecimal xMax = getChartPainter().getAxisPair().getxAxis().getMax(); - Collection<Number> yData = series.getyData(); + Collection<Number> yData = series.getYData(); BigDecimal yMin = getChartPainter().getAxisPair().getyAxis().getMin(); BigDecimal yMax = getChartPainter().getAxisPair().getyAxis().getMax();