Java tutorial
/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2017 Hitachi Vantara.. All rights reserved. */ package org.pentaho.plugin.jfreereport.reportcharts; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.DateTickUnit; import org.jfree.chart.axis.LogarithmicAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.NumberTickUnit; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.labels.StandardXYItemLabelGenerator; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.title.TextTitle; import org.jfree.data.general.Dataset; import org.jfree.data.time.Day; import org.jfree.data.time.Hour; import org.jfree.data.time.Minute; import org.jfree.data.time.Month; import org.jfree.data.time.Second; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.data.time.TimeSeriesDataItem; import org.jfree.data.time.Year; import org.jfree.data.xy.TableXYDataset; import org.jfree.data.xy.XYDataItem; import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.ui.RectangleEdge; import org.pentaho.plugin.jfreereport.reportcharts.backport.ExtCategoryTableXYDataset; import org.pentaho.plugin.jfreereport.reportcharts.backport.ExtTimeTableXYDataset; import org.pentaho.plugin.jfreereport.reportcharts.backport.FastNumberTickUnit; import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot; import org.pentaho.reporting.engine.classic.core.LegacyUpdateHandler; import org.pentaho.reporting.engine.classic.core.function.Expression; import org.pentaho.reporting.libraries.base.util.StringUtils; import org.pentaho.reporting.libraries.formatting.FastDecimalFormat; import java.awt.Color; import java.awt.Font; import java.awt.Paint; import java.text.DateFormatSymbols; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.List; /** * This class allows you to embed xy charts into JFreeReport XML definitions. * * @author gmoran */ public abstract class XYChartExpression extends AbstractChartExpression implements LegacyUpdateHandler { private String titlePositionText; private Paint borderPaint; private boolean horizontal; // private Paint plotBackgroundPaint; private boolean stacked; private boolean domainVerticalTickLabels; private boolean domainIncludesZero; private boolean domainStickyZero; private NumberFormat domainTickFormat; private String domainTickFormatString; private String domainTitle; private Font domainTitleFont; private Font domainTickFont; private double domainMinimum; private double domainMaximum; private boolean domainAxisAutoRange; // used if the chart is using a DateAxis as Domain-Axis private Class domainTimePeriod; private double domainPeriodCount; private String rangeTitle; private Font rangeTitleFont; private Font rangeTickFont; private double rangeMinimum; private double rangeMaximum; private boolean rangeIncludesZero; private boolean rangeStickyZero; private boolean rangeAxisAutoRange; private NumberFormat rangeTickFormat; private String rangeTickFormatString; private boolean humanReadableLogarithmicFormat; private boolean logarithmicAxis; private Class rangeTimePeriod; private double rangePeriodCount; // private Font legendFont = null; protected XYChartExpression() { domainPeriodCount = 0; titlePositionText = "top"; borderPaint = Color.BLACK; horizontal = false; stacked = false; domainVerticalTickLabels = false; domainIncludesZero = false; domainStickyZero = false; rangeIncludesZero = true; rangeStickyZero = true; domainTitle = null; domainTitleFont = TextTitle.DEFAULT_FONT; domainTickFont = null; domainTickFormat = null; domainMinimum = 0; domainMaximum = 1; domainAxisAutoRange = true; rangeTitle = null; rangeTitleFont = TextTitle.DEFAULT_FONT; rangeMinimum = 0; rangeMaximum = 1; rangeAxisAutoRange = true; } public boolean isDomainAxisAutoRange() { return domainAxisAutoRange; } public void setDomainAxisAutoRange(final boolean domainAxisAutoRange) { this.domainAxisAutoRange = domainAxisAutoRange; } public boolean isRangeAxisAutoRange() { return rangeAxisAutoRange; } public void setRangeAxisAutoRange(final boolean rangeAxisAutoRange) { this.rangeAxisAutoRange = rangeAxisAutoRange; } public Class getDomainTimePeriod() { return domainTimePeriod; } public void setDomainTimePeriod(final Class domainTimePeriod) { this.domainTimePeriod = domainTimePeriod; } public Class getRangeTimePeriod() { return rangeTimePeriod; } public void setRangeTimePeriod(final Class rangeTimePeriod) { this.rangeTimePeriod = rangeTimePeriod; } public boolean isHumanReadableLogarithmicFormat() { return humanReadableLogarithmicFormat; } public void setHumanReadableLogarithmicFormat(final boolean humanReadableLogarithmicFormat) { this.humanReadableLogarithmicFormat = humanReadableLogarithmicFormat; } public boolean isLogarithmicAxis() { return logarithmicAxis; } public void setLogarithmicAxis(final boolean logarithmicAxis) { this.logarithmicAxis = logarithmicAxis; } /** * Return a completly separated copy of this function. The copy does no longer share any changeable objects with the * original function. * * @return a copy of this function. */ public Expression getInstance() { final XYChartExpression chartExpression = (XYChartExpression) super.getInstance(); if (chartExpression.domainTickFormat != null) { chartExpression.domainTickFormat = (NumberFormat) chartExpression.domainTickFormat.clone(); } if (chartExpression.rangeTickFormat != null) { chartExpression.rangeTickFormat = (NumberFormat) chartExpression.rangeTickFormat.clone(); } return chartExpression; } /** * @return Returns the stacked. */ public boolean isStacked() { return stacked; } /** * @param stacked The stacked to set. */ public void setStacked(final boolean stacked) { this.stacked = stacked; } /** * @return Returns the verticalTickLabels. */ public boolean isDomainVerticalTickLabels() { return domainVerticalTickLabels; } /** * @param domainVerticalTickLabels The domainVerticalLabels to set. */ public void setDomainVerticalTickLabels(final boolean domainVerticalTickLabels) { this.domainVerticalTickLabels = domainVerticalTickLabels; } /** * @return Returns the domainIncludeZero. */ public boolean isDomainIncludesZero() { return domainIncludesZero; } /** * @param domainIncludesZero The domainIncludesZero to set. */ public void setDomainIncludesZero(final boolean domainIncludesZero) { this.domainIncludesZero = domainIncludesZero; } /** * @return Returns the domainStickyZero. */ public boolean isDomainStickyZero() { return domainStickyZero; } /** * @param domainStickyZero The domainStickyZero to set. */ public void setDomainStickyZero(final boolean domainStickyZero) { this.domainStickyZero = domainStickyZero; } /** * @return Returns the rangeIncludeZero. */ public boolean isRangeIncludesZero() { return rangeIncludesZero; } /** * @param rangeIncludesZero The domainIncludesZero to set. */ public void setRangeIncludesZero(final boolean rangeIncludesZero) { this.rangeIncludesZero = rangeIncludesZero; } /** * @return Returns the rangeStickyZero. */ public boolean isRangeStickyZero() { return rangeStickyZero; } /** * @param rangeStickyZero The rangeStickyZero to set. */ public void setRangeStickyZero(final boolean rangeStickyZero) { this.rangeStickyZero = rangeStickyZero; } public void setPlotBackgroundColor(final Color plotBackgroundPaint) { if (plotBackgroundPaint != null) { super.setPlotBackgroundColor(plotBackgroundPaint); } } public Color getPlotBackgroundColor() { return super.getPlotBackgroundColor(); } /** * @param plotBackgroundPaint * @deprecated this property is declared but not used anywhere */ public void setPlotBackgroundPaint(final Paint plotBackgroundPaint) { this.setPlotBackgroundColor((Color) plotBackgroundPaint); } /** * @deprecated this property is declared but not used anywhere */ public Paint getPlotBackgroundPaint() { return this.getPlotBackgroundColor(); } public boolean isHorizontal() { return horizontal; } public void setHorizontal(final boolean value) { horizontal = value; } /** * @return Returns the borderVisible. * @deprecated */ public boolean isBorderVisible() { return isShowBorder(); } /** * @param borderVisible The borderVisible to set. * @deprecated */ public void setBorderVisible(final boolean borderVisible) { setShowBorder(borderVisible); } /** * @return Returns the borderPaint. * @deprecated Is not used anywhere ... */ public Paint getBorderPaint() { return borderPaint; } /** * @param borderPaint The borderPaint to set. * @deprecated is not used anywhere */ public void setBorderPaint(final Paint borderPaint) { this.borderPaint = borderPaint; } public String getTitlePositionText() { return titlePositionText; } public void setTitlePositionText(final String titlePositionText) { this.titlePositionText = titlePositionText; } /** * @return Returns the titlePosition. * @deprecated Dont use that. */ public RectangleEdge getTitlePosition() { return translateEdge(titlePositionText); } /** * @param titlePosition The titlePosition to set. * @deprecated Dont use that. */ public void setTitlePosition(final RectangleEdge titlePosition) { if (RectangleEdge.TOP.equals(titlePosition)) { this.titlePositionText = "top"; } else if (RectangleEdge.LEFT.equals(titlePosition)) { this.titlePositionText = "left"; } else if (RectangleEdge.BOTTOM.equals(titlePosition)) { this.titlePositionText = "bottom"; } else if (RectangleEdge.RIGHT.equals(titlePosition)) { this.titlePositionText = "right"; } else { this.titlePositionText = "left"; } } /** * @return Returns the domainTitle. */ public String getDomainTitle() { return domainTitle; } /** * @param domainTitle The domainTitle to set. */ public void setDomainTitle(final String domainTitle) { this.domainTitle = domainTitle; } /** * @return Returns the rangeTitle. */ public String getRangeTitle() { return rangeTitle; } /** * @param rangeTitle The rangeTitle to set. */ public void setRangeTitle(final String rangeTitle) { this.rangeTitle = rangeTitle; } /** * @return Returns the domainTitleFont. */ public Font getDomainTitleFont() { return domainTitleFont; } /** * @param domainTitleFont The domainTitleFont to set. */ public void setDomainTitleFont(final Font domainTitleFont) { this.domainTitleFont = domainTitleFont; } /** * Return the java.awt.Font to be used to display the range axis tick labels * * @return Font The Font for the range axis tick labels */ public Font getDomainTickFont() { return domainTickFont; } /** * @param domainTickFont The domainTickFont to set. */ public void setDomainTickFont(final Font domainTickFont) { this.domainTickFont = domainTickFont; } /** * @return Returns the rangeTickFormat. */ public NumberFormat getDomainTickFormat() { return domainTickFormat; } /** * @param domainTickFormat The range tick number format to set. */ public void setDomainTickFormat(final NumberFormat domainTickFormat) { this.domainTickFormat = domainTickFormat; } /** * @return Returns the rangeTitleFont. */ public Font getRangeTitleFont() { return rangeTitleFont; } /** * @param rangeTitleFont The rangeTitleFont to set. */ public void setRangeTitleFont(final Font rangeTitleFont) { this.rangeTitleFont = rangeTitleFont; } /** * @return Returns the rangeTickFormat. */ public NumberFormat getRangeTickFormat() { return rangeTickFormat; } /** * @param rangeTickFormat The range tick number format to set. */ public void setRangeTickFormat(final NumberFormat rangeTickFormat) { this.rangeTickFormat = rangeTickFormat; } public String getDomainTickFormatString() { return domainTickFormatString; } public void setDomainTickFormatString(final String domainTickFormatString) { this.domainTickFormatString = domainTickFormatString; } public String getRangeTickFormatString() { return rangeTickFormatString; } public void setRangeTickFormatString(final String rangeTickFormatString) { this.rangeTickFormatString = rangeTickFormatString; } /** * Return the java.awt.Font to be used to display the range axis tick labels * * @return Font The Font for the range axis tick labels */ public Font getRangeTickFont() { return rangeTickFont; } /** * @param rangeTickFont The rangeTitleFont to set. */ public void setRangeTickFont(final Font rangeTickFont) { this.rangeTickFont = rangeTickFont; } /** * Return the range axis' minimum value * * @return double Range axis' minimum value */ public double getRangeMinimum() { return rangeMinimum; } /** * @param rangeMinimum Set the minimum value of the range axis. */ public void setRangeMinimum(final double rangeMinimum) { this.rangeMinimum = rangeMinimum; } /** * Return the range axis' maximum value * * @return double Range axis' maximum value */ public double getRangeMaximum() { return rangeMaximum; } /** * @param rangeMaximum Set the maximum value of the range axis. */ public void setRangeMaximum(final double rangeMaximum) { this.rangeMaximum = rangeMaximum; } /** * Return the domain axis' minimum value * * @return double domain axis' minimum value */ public double getDomainMinimum() { return domainMinimum; } /** * @param domainMinimum Set the minimum value of the domain axis. */ public void setDomainMinimum(final double domainMinimum) { this.domainMinimum = domainMinimum; } /** * Return the domain axis' maximum value * * @return double domain axis' maximum value */ public double getDomainMaximum() { return domainMaximum; } /** * @param domainMaximum Set the maximum value of the domain axis. */ public void setDomainMaximum(final double domainMaximum) { this.domainMaximum = domainMaximum; } protected JFreeChart computeChart(final Dataset dataset) { if (dataset instanceof XYDataset == false) { return computeXYChart(null); } final XYDataset xyDataset = (XYDataset) dataset; return computeXYChart(xyDataset); } protected void configureLogarithmicAxis(final XYPlot plot) { if (isLogarithmicAxis()) { final LogarithmicAxis logarithmicAxis; if (isHumanReadableLogarithmicFormat()) { plot.getRenderer().setBaseItemLabelGenerator(new LogXYItemLabelGenerator()); logarithmicAxis = new ScalingLogarithmicAxis(getRangeTitle()); logarithmicAxis.setStrictValuesFlag(false); } else { logarithmicAxis = new LogarithmicAxis(getRangeTitle()); logarithmicAxis.setStrictValuesFlag(false); } plot.setRangeAxis(logarithmicAxis); } } protected JFreeChart computeXYChart(final XYDataset xyDataset) { return getChart(xyDataset); } protected void configureChart(final JFreeChart chart) { super.configureChart(chart); final XYPlot plot = chart.getXYPlot(); final XYItemRenderer renderer = plot.getRenderer(); if (StringUtils.isEmpty(getTooltipFormula()) == false) { renderer.setBaseToolTipGenerator(new FormulaXYZTooltipGenerator(getRuntime(), getTooltipFormula())); } if (StringUtils.isEmpty(getUrlFormula()) == false) { renderer.setURLGenerator(new FormulaXYZURLGenerator(getRuntime(), getUrlFormula())); } renderer.setBaseItemLabelGenerator(new StandardXYItemLabelGenerator()); renderer.setBaseItemLabelsVisible(Boolean.TRUE.equals(getItemsLabelVisible())); if (getItemLabelFont() != null) { renderer.setBaseItemLabelFont(getItemLabelFont()); } plot.setOrientation(computePlotOrientation()); // May be an axis that supports dates final ValueAxis domainAxis = plot.getDomainAxis(); if (domainAxis instanceof NumberAxis) { final NumberAxis numberAxis = (NumberAxis) domainAxis; numberAxis.setAutoRangeIncludesZero(isDomainIncludesZero()); numberAxis.setAutoRangeStickyZero(isDomainStickyZero()); if (getDomainPeriodCount() > 0) { if (getDomainTickFormat() != null) { numberAxis.setTickUnit(new NumberTickUnit(getDomainPeriodCount(), getDomainTickFormat())); } else if (getDomainTickFormatString() != null) { final FastDecimalFormat formatter = new FastDecimalFormat(getDomainTickFormatString(), getResourceBundleFactory().getLocale()); numberAxis.setTickUnit(new FastNumberTickUnit(getDomainPeriodCount(), formatter)); } else { numberAxis.setTickUnit(new FastNumberTickUnit(getDomainPeriodCount())); } } else { if (getDomainTickFormat() != null) { numberAxis.setNumberFormatOverride(getDomainTickFormat()); } else if (getDomainTickFormatString() != null) { final DecimalFormat formatter = new DecimalFormat(getDomainTickFormatString(), new DecimalFormatSymbols(getResourceBundleFactory().getLocale())); numberAxis.setNumberFormatOverride(formatter); } } } else if (domainAxis instanceof DateAxis) { final DateAxis numberAxis = (DateAxis) domainAxis; if (getDomainPeriodCount() > 0 && getDomainTimePeriod() != null) { if (getDomainTickFormatString() != null) { final SimpleDateFormat formatter = new SimpleDateFormat(getDomainTickFormatString(), new DateFormatSymbols(getResourceBundleFactory().getLocale())); numberAxis.setTickUnit(new DateTickUnit(getDateUnitAsInt(getDomainTimePeriod()), (int) getDomainPeriodCount(), formatter)); } else { numberAxis.setTickUnit(new DateTickUnit(getDateUnitAsInt(getDomainTimePeriod()), (int) getDomainPeriodCount())); } } } if (domainAxis != null) { domainAxis.setLabel(getDomainTitle()); if (getDomainTitleFont() != null) { domainAxis.setLabelFont(getDomainTitleFont()); } domainAxis.setVerticalTickLabels(isDomainVerticalTickLabels()); if (getDomainTickFont() != null) { domainAxis.setTickLabelFont(getDomainTickFont()); } final int level = getRuntime().getProcessingContext().getCompatibilityLevel(); if (ClassicEngineBoot.isEnforceCompatibilityFor(level, 3, 8)) { if (getDomainMinimum() != 0) { domainAxis.setLowerBound(getDomainMinimum()); } if (getDomainMaximum() != 1) { domainAxis.setUpperBound(getDomainMaximum()); } if (getDomainMinimum() == 0 && getDomainMaximum() == 0) { domainAxis.setLowerBound(0); domainAxis.setUpperBound(1); domainAxis.setAutoRange(true); } } else { domainAxis.setLowerBound(getDomainMinimum()); domainAxis.setUpperBound(getDomainMaximum()); domainAxis.setAutoRange(isDomainAxisAutoRange()); } } final ValueAxis rangeAxis = plot.getRangeAxis(); if (rangeAxis instanceof NumberAxis) { final NumberAxis numberAxis = (NumberAxis) rangeAxis; numberAxis.setAutoRangeIncludesZero(isRangeIncludesZero()); numberAxis.setAutoRangeStickyZero(isRangeStickyZero()); if (getRangePeriodCount() > 0) { if (getRangeTickFormat() != null) { numberAxis.setTickUnit(new NumberTickUnit(getRangePeriodCount(), getRangeTickFormat())); } else if (getRangeTickFormatString() != null) { final FastDecimalFormat formatter = new FastDecimalFormat(getRangeTickFormatString(), getResourceBundleFactory().getLocale()); numberAxis.setTickUnit(new FastNumberTickUnit(getRangePeriodCount(), formatter)); } else { numberAxis.setTickUnit(new FastNumberTickUnit(getRangePeriodCount())); } } else { if (getRangeTickFormat() != null) { numberAxis.setNumberFormatOverride(getRangeTickFormat()); } else if (getRangeTickFormatString() != null) { final DecimalFormat formatter = new DecimalFormat(getRangeTickFormatString(), new DecimalFormatSymbols(getResourceBundleFactory().getLocale())); numberAxis.setNumberFormatOverride(formatter); standardTickUnitsApplyFormat(numberAxis, formatter); } } } else if (rangeAxis instanceof DateAxis) { final DateAxis numberAxis = (DateAxis) rangeAxis; if (getRangePeriodCount() > 0 && getRangeTimePeriod() != null) { if (getRangeTickFormatString() != null) { final SimpleDateFormat formatter = new SimpleDateFormat(getRangeTickFormatString(), new DateFormatSymbols(getResourceBundleFactory().getLocale())); numberAxis.setTickUnit(new DateTickUnit(getDateUnitAsInt(getRangeTimePeriod()), (int) getRangePeriodCount(), formatter)); } else { numberAxis.setTickUnit( new DateTickUnit(getDateUnitAsInt(getRangeTimePeriod()), (int) getRangePeriodCount())); } } else { if (getRangeTickFormatString() != null) { final SimpleDateFormat formatter = new SimpleDateFormat(getRangeTickFormatString(), new DateFormatSymbols(getResourceBundleFactory().getLocale())); numberAxis.setDateFormatOverride(formatter); } } } if (rangeAxis != null) { rangeAxis.setLabel(getRangeTitle()); if (getRangeTitleFont() != null) { rangeAxis.setLabelFont(getRangeTitleFont()); } if (getRangeTickFont() != null) { rangeAxis.setTickLabelFont(getRangeTickFont()); } final int level = getRuntime().getProcessingContext().getCompatibilityLevel(); if (ClassicEngineBoot.isEnforceCompatibilityFor(level, 3, 8)) { if (getRangeMinimum() != 0) { rangeAxis.setLowerBound(getRangeMinimum()); } if (getRangeMaximum() != 1) { rangeAxis.setUpperBound(getRangeMaximum()); } if (getRangeMinimum() == 0 && getRangeMaximum() == 0) { rangeAxis.setLowerBound(0); rangeAxis.setUpperBound(1); rangeAxis.setAutoRange(true); } } else { rangeAxis.setLowerBound(getRangeMinimum()); rangeAxis.setUpperBound(getRangeMaximum()); rangeAxis.setAutoRange(isRangeAxisAutoRange()); } } final String[] colors = getSeriesColor(); for (int i = 0; i < colors.length; i++) { renderer.setSeriesPaint(i, parseColorFromString(colors[i])); } } protected PlotOrientation computePlotOrientation() { final PlotOrientation orientation; if (isHorizontal()) { orientation = PlotOrientation.HORIZONTAL; } else { orientation = PlotOrientation.VERTICAL; } return orientation; } //-------------------------------------------------- /** * @return Returns the subTitles. * @deprecated Subtitles are not used. */ public List getSubtitles() { return Collections.emptyList(); } /** * @return Returns the subTitles. * @deprecated Subtitles are not used. */ public void addSubTitle(final String subTitle) { } /** * @param xyDataset * @return * @deprecated Not public, no getter */ public JFreeChart getChart(final XYDataset xyDataset) { return null; } /** * @return * @deprecated Not used anywhere. You might want to use "itemLabelVisible" */ public boolean isDisplayLabels() { return false; } public double getDomainPeriodCount() { return domainPeriodCount; } public void setDomainPeriodCount(final double domainPeriodCount) { this.domainPeriodCount = domainPeriodCount; } public double getRangePeriodCount() { return rangePeriodCount; } public void setRangePeriodCount(final double rangePeriodCount) { this.rangePeriodCount = rangePeriodCount; } private int getDateUnitAsInt(final Class domainTimePeriod) { if (Second.class.equals(domainTimePeriod)) { return DateTickUnit.SECOND; } if (Minute.class.equals(domainTimePeriod)) { return DateTickUnit.MINUTE; } if (Hour.class.equals(domainTimePeriod)) { return DateTickUnit.HOUR; } if (Day.class.equals(domainTimePeriod)) { return DateTickUnit.DAY; } if (Month.class.equals(domainTimePeriod)) { return DateTickUnit.MONTH; } if (Year.class.equals(domainTimePeriod)) { return DateTickUnit.YEAR; } if (Second.class.equals(domainTimePeriod)) { return DateTickUnit.MILLISECOND; } return DateTickUnit.DAY; } protected ExtTimeTableXYDataset convertToTable(final XYDataset xyDataset) { final TimeSeriesCollection timeSeriesCollection = (TimeSeriesCollection) xyDataset; final ExtTimeTableXYDataset tableXYDataset = new ExtTimeTableXYDataset(); final int count = timeSeriesCollection.getSeriesCount(); for (int i = 0; i < count; i++) { final Comparable key = timeSeriesCollection.getSeriesKey(i); final TimeSeries timeSeries = timeSeriesCollection.getSeries(i); final int itemCount = timeSeries.getItemCount(); for (int ic = 0; ic < itemCount; ic++) { final TimeSeriesDataItem seriesDataItem = timeSeries.getDataItem(ic); tableXYDataset.add(seriesDataItem.getPeriod(), seriesDataItem.getValue(), key, false); } } return tableXYDataset; } protected TableXYDataset convertToTable(final XYSeriesCollection xyDataset) { final ExtCategoryTableXYDataset tableXYDataset = new ExtCategoryTableXYDataset(); final int count = xyDataset.getSeriesCount(); for (int i = 0; i < count; i++) { final XYSeries timeSeries = xyDataset.getSeries(i); final Comparable key = timeSeries.getKey(); final int itemCount = timeSeries.getItemCount(); for (int ic = 0; ic < itemCount; ic++) { final XYDataItem seriesDataItem = timeSeries.getDataItem(ic); tableXYDataset.add(seriesDataItem.getX(), seriesDataItem.getY(), key, false); } } return tableXYDataset; } public void reconfigureForCompatibility(final int versionTag) { if (ClassicEngineBoot.isEnforceCompatibilityFor(versionTag, 3, 8)) { setRangeAxisAutoRange(getRangeMinimum() == 0 && getRangeMaximum() == 1); setDomainAxisAutoRange(getDomainMinimum() == 0 && getDomainMaximum() == 1); } } }