List of usage examples for org.jfree.data.xy XYSeriesCollection getDomainLowerBound
@Override public double getDomainLowerBound(boolean includeInterval)
From source file:org.lmn.fc.frameworks.starbase.plugins.observatory.ui.tabs.charts.ChartHelper.java
/*********************************************************************************************** * Dump the (partial) contents of each Series in an XYdatset. * * @param dump/*from w w w . j a va 2 s . c o m*/ * @param calendar * @param dataset * @param dumprowcount * @param title */ public static void dumpXYDataset(final boolean dump, final Calendar calendar, final XYDataset dataset, final int dumprowcount, final String title) { final String SOURCE = "ChartHelper.dumpXYDataset() "; if (dump) { LOGGER.log(title); if ((dataset != null) && (dataset instanceof XYSeriesCollection)) { final XYSeriesCollection seriesCollection; seriesCollection = (XYSeriesCollection) dataset; LOGGER.log("XYSeriesCollection"); LOGGER.log(" [series.count=" + seriesCollection.getSeriesCount() + "]"); LOGGER.log(" [domain.lowerbound.interval.true=" + (long) seriesCollection.getDomainLowerBound(true) + "]"); LOGGER.log(" [domain.lowerbound.interval.false=" + (long) seriesCollection.getDomainLowerBound(false) + "]"); LOGGER.log(" [domain.upperbound.interval.true=" + (long) seriesCollection.getDomainUpperBound(true) + "]"); LOGGER.log(" [domain.upperbound.interval.false=" + (long) seriesCollection.getDomainUpperBound(false) + "]"); LOGGER.log(" [domain.order=" + seriesCollection.getDomainOrder() + "]"); for (int intSeriesIndex = 0; intSeriesIndex < seriesCollection.getSeriesCount(); intSeriesIndex++) { final XYSeries xySeries; LOGGER.log(""); LOGGER.log(" [xyseries.index=" + intSeriesIndex + "]"); xySeries = seriesCollection.getSeries(intSeriesIndex); LOGGER.log(" [xyseries.itemcount=" + xySeries.getItemCount() + "]"); LOGGER.log(" [xyseries.key=" + xySeries.getKey() + "]"); LOGGER.log(" [xyseries.xmin=" + xySeries.getMinX() + "]"); LOGGER.log(" [xyseries.xmax=" + xySeries.getMaxX() + "]"); LOGGER.log(" [xyseries.ymin=" + xySeries.getMinY() + "]"); LOGGER.log(" [xyseries.ymax=" + xySeries.getMaxY() + "]"); LOGGER.log(" [xyseries.description=" + xySeries.getDescription() + "]"); LOGGER.log(" [xyseries.autosort=" + xySeries.getAutoSort() + "]"); LOGGER.log(" [xyseries.allowduplicatex=" + xySeries.getAllowDuplicateXValues() + "]"); // Dump the first chunk for (int intItemIndex = 0; intItemIndex < (Math.min(dumprowcount, xySeries.getItemCount())); intItemIndex++) { final XYDataItem item; item = xySeries.getDataItem(intItemIndex); LOGGER.log(" [item.index=" + intItemIndex + "] [item.x=" + item.getXValue() + "] [item.y=" + item.getYValue() + "]"); } LOGGER.log(" ..."); // Dump the last chunk for (int intItemIndex = 0; intItemIndex < (Math.min(dumprowcount, xySeries.getItemCount())); intItemIndex++) { final XYDataItem item; final int intIndex; intIndex = Math.max(0, xySeries.getItemCount() - dumprowcount) + intItemIndex; item = xySeries.getDataItem(intIndex); LOGGER.log(" [item.index=" + intIndex + "] [item.x=" + item.getXValue() + "] [item.y=" + item.getYValue() + "]"); } } } else if ((dataset != null) && (dataset instanceof TimeSeriesCollection)) { final TimeSeriesCollection seriesCollection; seriesCollection = (TimeSeriesCollection) dataset; LOGGER.log("TimeSeriesCollection"); LOGGER.log(" [series.count=" + seriesCollection.getSeriesCount() + "]"); LOGGER.log(" [domain.lowerbound.interval.true=" + (long) seriesCollection.getDomainLowerBound(true) + "]"); LOGGER.log(" [domain.lowerbound.interval.false=" + (long) seriesCollection.getDomainLowerBound(false) + "]"); LOGGER.log(" [domain.upperbound.interval.true=" + (long) seriesCollection.getDomainUpperBound(true) + "]"); LOGGER.log(" [domain.upperbound.interval.false=" + (long) seriesCollection.getDomainUpperBound(false) + "]"); LOGGER.log(" [domain.order=" + seriesCollection.getDomainOrder() + "]"); for (int intSeriesIndex = 0; intSeriesIndex < seriesCollection.getSeriesCount(); intSeriesIndex++) { final TimeSeries timeSeries; LOGGER.log(""); LOGGER.log(" [timeseries.index=" + intSeriesIndex + "]"); timeSeries = seriesCollection.getSeries(intSeriesIndex); LOGGER.log(" [timeseries.itemcount=" + timeSeries.getItemCount() + "]"); LOGGER.log(" [timeseries.key=" + timeSeries.getKey() + "]"); LOGGER.log(" [timeseries.ymin=" + timeSeries.getMinY() + "]"); LOGGER.log(" [timeseries.ymax=" + timeSeries.getMaxY() + "]"); LOGGER.log(" [timeseries.domain=" + timeSeries.getDomainDescription() + "]"); LOGGER.log(" [timeseries.range=" + timeSeries.getRangeDescription() + "]"); LOGGER.log( " [timeseries.timeperiodclass=" + timeSeries.getTimePeriodClass().getName() + "]"); for (int intItemIndex = 0; intItemIndex < (Math.min(dumprowcount, timeSeries.getItemCount())); intItemIndex++) { final TimeSeriesDataItem item; item = timeSeries.getDataItem(intItemIndex); LOGGER.log(" [item.index=" + intItemIndex + "] [item.period.serialindex=" + item.getPeriod().getSerialIndex() + "] [item.period.firstmillis=" + item.getPeriod().getFirstMillisecond(calendar) + "] [item.value=" + item.getValue() + "]"); } LOGGER.log(" ..."); for (int intItemIndex = 0; intItemIndex < (Math.min(dumprowcount, timeSeries.getItemCount())); intItemIndex++) { final TimeSeriesDataItem item; final int intIndex; intIndex = Math.max(0, timeSeries.getItemCount() - dumprowcount) + intItemIndex; item = timeSeries.getDataItem(intIndex); LOGGER.log(" [item.index=" + intIndex + "] [item.period.serialindex=" + item.getPeriod().getSerialIndex() + "] [item.period.firstmillis=" + item.getPeriod().getFirstMillisecond(calendar) + "] [item.value=" + item.getValue() + "]"); } } } else { LOGGER.error(SOURCE + "Unsupported XYDataset type"); } } }
From source file:org.lmn.fc.frameworks.starbase.plugins.observatory.ui.tabs.charts.ChartUIComponent.java
/*********************************************************************************************** * Update the existing Chart referenced by the DAO, by applying the specified datasets, * using all existing channel selections and range selections. * This implementation ASSUMES a ChannelSelector is present. * * @param dao/*from ww w.j a va 2s . c om*/ * @param datasettype * @param primarydataset * @param secondarydatasets * @param displaylimit * @param domainstartpoint * @param domainendpoint * @param channelselector * @param debug */ public void updateChartForSelection(final ObservatoryInstrumentDAOInterface dao, final DatasetType datasettype, final XYDataset primarydataset, final List<XYDataset> secondarydatasets, final int displaylimit, final int domainstartpoint, final int domainendpoint, final ChannelSelectorUIComponentInterface channelselector, final boolean debug) { final String SOURCE = "ChartUIComponent.updateChartForSelection() "; if ((dao != null) && (dao.getChartUI() != null) && (dao.getChartUI().getChartPanel() != null) && (dao.getChartUI().getChartPanel().getChart() != null) && (dao.getChartUI().getChartPanel().getChart().getXYPlot() != null) && (datasettype != null) && (primarydataset != null) && (secondarydatasets != null) && (channelselector != null)) { final XYDataset xyNewPrimaryDataset; final List<XYDataset> listNewSecondaryDatasets; final List<XYDataset> listParentSecondaryDatasetForSeries; final Iterator iterOriginalSecondaryDatasets; final Calendar calObservatory; // Either find the Current Observatory calendar, or provide a default calObservatory = ObservatoryInstrumentHelper.getCurrentObservatoryCalendar(REGISTRY.getFramework(), dao, debug); // Create a list of NewSecondaryDatasets for display // Add an appropriate *empty* new dataset for every one existing in the secondary set // and record the parent new Dataset for each Series in each original Dataset // So much complexity just to handle the very few cases of secondary datasets... listNewSecondaryDatasets = new ArrayList<XYDataset>(10); listParentSecondaryDatasetForSeries = new ArrayList<XYDataset>(10); iterOriginalSecondaryDatasets = secondarydatasets.iterator(); while (iterOriginalSecondaryDatasets.hasNext()) { final XYDataset xyDatasetOriginal; xyDatasetOriginal = (XYDataset) iterOriginalSecondaryDatasets.next(); if ((xyDatasetOriginal != null) && (xyDatasetOriginal.getSeriesCount() > 0)) { final XYDataset xyDatasetNew; // Create an empty Dataset to correspond with the original if (datasettype.getName().equals(DatasetType.XY.getName())) { xyDatasetNew = new XYSeriesCollection(); listNewSecondaryDatasets.add(xyDatasetNew); } else if (datasettype.getName().equals(DatasetType.TIMESTAMPED.getName())) { xyDatasetNew = new TimeSeriesCollection(calObservatory.getTimeZone()); listNewSecondaryDatasets.add(xyDatasetNew); } else { xyDatasetNew = new XYSeriesCollection(); listNewSecondaryDatasets.add(xyDatasetNew); } // Record the *same* parent Dataset for each Series in each original Secondary Dataset // This creates a List in channel order, but with references to Datasets not Series for (int i = 0; i < xyDatasetOriginal.getSeriesCount(); i++) { listParentSecondaryDatasetForSeries.add(xyDatasetNew); } } } // Confirm the DatasetType if ((datasettype.getName().equals(DatasetType.XY.getName())) && (primarydataset instanceof XYSeriesCollection)) { final XYSeriesCollection collectionPrimary; // Prepare a new XYSeriesCollection for display xyNewPrimaryDataset = new XYSeriesCollection(); // There should be a collection of <channelcount> XYSeries in the Primary Dataset // but there may also be some in the Secondary Datasets collectionPrimary = (XYSeriesCollection) primarydataset; // ToDo Make this work for ChannelSelector NULL, get channel count from primary and secondaries? Set mode to X1? if ((collectionPrimary.getSeriesCount() > 0) && (collectionPrimary.getSeries() != null) && (channelselector.getChannelSelectionModes() != null)) { LOGGER.debug(debug, SOURCE + "XY domainstartpoint=" + domainstartpoint + " domainendpoint=" + domainendpoint); ChartHelper.dumpXYDataset(debug, calObservatory, collectionPrimary, 4, SOURCE + "XYSeriesCollection --> Original Dataset"); // Find which channels and data range to use this time round for (int intChannelIndex = 0; intChannelIndex < channelselector.getChannelSelectionModes() .size(); intChannelIndex++) { final ChannelSelectionMode selectionMode; selectionMode = channelselector.getChannelSelectionModes().get(intChannelIndex); if (!ChannelSelectionMode.OFF.equals(selectionMode)) { final XYSeries seriesOriginalData; // We needed to know about the secondary datasets in order to get the correct index seriesOriginalData = (XYSeries) ChartHelper.getSeriesForIndex(datasettype, primarydataset, secondarydatasets, intChannelIndex, debug); if (seriesOriginalData != null) { final XYSeries seriesChangedData; final List listOriginalDataItems; int intStartIndex; int intEndIndex; listOriginalDataItems = seriesOriginalData.getItems(); // Prepare a new Series for the changed data, with the same Key seriesChangedData = new XYSeries(seriesOriginalData.getKey()); if (listOriginalDataItems.size() > 0) { // Map the slider values to data indexes intStartIndex = ChartHelper.transformDomainSliderValueToSeriesIndex( ChartUIComponentPlugin.DOMAIN_SLIDER_MINIMUM, ChartUIComponentPlugin.DOMAIN_SLIDER_MAXIMUM, domainstartpoint, DatasetDomainUIComponentInterface.INDEX_LEFT, collectionPrimary.getDomainLowerBound(true), collectionPrimary.getDomainUpperBound(true), DatasetType.XY, calObservatory, seriesOriginalData, debug); intEndIndex = ChartHelper.transformDomainSliderValueToSeriesIndex( ChartUIComponentPlugin.DOMAIN_SLIDER_MINIMUM, ChartUIComponentPlugin.DOMAIN_SLIDER_MAXIMUM, domainendpoint, DatasetDomainUIComponentInterface.INDEX_RIGHT, collectionPrimary.getDomainLowerBound(true), collectionPrimary.getDomainUpperBound(true), DatasetType.XY, calObservatory, seriesOriginalData, debug); if ((intStartIndex == -1) || (intEndIndex == -1)) { // If either index is returned as -1, then there's nothing to do... // ...so stop the for() loop intStartIndex = 0; intEndIndex = 0; } else if (intEndIndex <= intStartIndex) { intEndIndex = intStartIndex + 1; } LOGGER.debug(debug, SOURCE + "before copy of selected series subset [channel=" + intChannelIndex + "] [index.start=" + intStartIndex + "] [index.end=" + intEndIndex + "]"); // Copy over only the selected range from the Slider for (int intDataIndex = intStartIndex; intDataIndex < intEndIndex; intDataIndex++) { final XYDataItem dataOriginalItem; final XYDataItem dataChangedItem; dataOriginalItem = (XYDataItem) listOriginalDataItems.get(intDataIndex); if (!ChannelSelectionMode.X1.equals(selectionMode)) { // Change each value of the series according to the multiplier dataChangedItem = new XYDataItem(dataOriginalItem.getX(), dataOriginalItem.getY().doubleValue() * selectionMode.getMultiplier()); } else { // Just use the whole series unaltered for gain of X1 dataChangedItem = new XYDataItem(dataOriginalItem.getX(), dataOriginalItem.getY()); } seriesChangedData.add(dataChangedItem); } // Did we collect any data for this Series? // If not, place a dummy point at the origin of the *visible* chart if (seriesChangedData.getItemCount() == 0) { // TODO ChartHelper.createDummyXYSeriesDataItemAtOrigin() seriesChangedData.add(new XYDataItem(0, 0)); } // Place the changed series in the correct collection // to correspond with the original if (intChannelIndex < collectionPrimary.getSeriesCount()) { // Simply add the changed Primary series to the PrimaryDataset collection ((XYSeriesCollection) xyNewPrimaryDataset).addSeries(seriesChangedData); } else { // It must be a secondary dataset // Add the changed Secondary series to the parent SecondaryDataset // given by the *secondary* channel index ChartHelper.addSecondarySeries(datasettype, listParentSecondaryDatasetForSeries, seriesChangedData, intChannelIndex - collectionPrimary.getSeriesCount()); } } else { LOGGER.warn(SOURCE + "OriginalData XYSeries unexpectedly NULL"); } } else { // There are no data! Do nothing... LOGGER.warn(SOURCE + "There are no data, so do nothing"); } } } LOGGER.debug(debug, SOURCE + "Update the data shown on existing Chart"); // The outputs are xyNewPrimaryDataset and listNewSecondaryDatasets // This Chart does not use secondary datasets (yet) // Dump the (partial) contents of each Series in the new XYdataset ChartHelper.dumpXYDataset(debug, calObservatory, xyNewPrimaryDataset, 4, SOURCE + "XYSeriesCollection --> setDataset"); dao.getChartUI().getChartPanel().getChart().getXYPlot().setDataset(INDEX_DATA, xyNewPrimaryDataset); } else { LOGGER.error(SOURCE + " The XYSeriesCollection does not have any XYSeries"); } } else if ((datasettype.getName().equals(DatasetType.TIMESTAMPED.getName())) && (primarydataset instanceof TimeSeriesCollection)) { final TimeSeriesCollection collectionPrimary; LOGGER.debug(debug, SOURCE + "TIMESTAMPED domainstartpoint=" + domainstartpoint + " domainendpoint=" + domainendpoint); // Prepare a new TimeSeriesCollection for display xyNewPrimaryDataset = new TimeSeriesCollection(calObservatory.getTimeZone()); // There should be a collection of <channelcount> TimeSeries in the Primary Dataset // but there may also be some in the Secondary Datasets collectionPrimary = (TimeSeriesCollection) primarydataset; if ((collectionPrimary.getSeriesCount() > 0) && (collectionPrimary.getSeries() != null) && (channelselector.getChannelSelectionModes() != null)) { ChartHelper.dumpXYDataset(debug, calObservatory, collectionPrimary, 4, SOURCE + "TimeSeriesCollection PrimaryDataset --> Original Dataset"); // Find which channels and data range to use this time round for (int intChannelIndex = 0; intChannelIndex < channelselector.getChannelSelectionModes() .size(); intChannelIndex++) { final ChannelSelectionMode selectionMode; selectionMode = channelselector.getChannelSelectionModes().get(intChannelIndex); if (!ChannelSelectionMode.OFF.equals(selectionMode)) { final TimeSeries seriesOriginalData; // We needed to know about the secondary datasets in order to get the correct index seriesOriginalData = (TimeSeries) ChartHelper.getSeriesForIndex(datasettype, primarydataset, secondarydatasets, intChannelIndex, debug); if (seriesOriginalData != null) { final List listOriginalDataItems; final TimeSeries seriesChangedData; listOriginalDataItems = seriesOriginalData.getItems(); // Prepare a new Series for the changed data, with the same Key seriesChangedData = new TimeSeries(seriesOriginalData.getKey().toString(), seriesOriginalData.getTimePeriodClass()); if (listOriginalDataItems.size() > 0) { int intStartIndex; int intEndIndex; // Map the slider values to data indexes intStartIndex = ChartHelper.transformDomainSliderValueToSeriesIndex( ChartUIComponentPlugin.DOMAIN_SLIDER_MINIMUM, ChartUIComponentPlugin.DOMAIN_SLIDER_MAXIMUM, domainstartpoint, DatasetDomainUIComponentInterface.INDEX_LEFT, collectionPrimary.getDomainLowerBound(true), collectionPrimary.getDomainUpperBound(true), DatasetType.TIMESTAMPED, calObservatory, seriesOriginalData, debug); intEndIndex = ChartHelper.transformDomainSliderValueToSeriesIndex( ChartUIComponentPlugin.DOMAIN_SLIDER_MINIMUM, ChartUIComponentPlugin.DOMAIN_SLIDER_MAXIMUM, domainendpoint, DatasetDomainUIComponentInterface.INDEX_RIGHT, collectionPrimary.getDomainLowerBound(true), collectionPrimary.getDomainUpperBound(true), DatasetType.TIMESTAMPED, calObservatory, seriesOriginalData, debug); if ((intStartIndex == -1) || (intEndIndex == -1)) { // If either index is returned as -1, then there's nothing to do... // ...so stop the for() loop LOGGER.debug(debug, SOURCE + "Set EndIndex = StartIndex = 0"); intStartIndex = 0; intEndIndex = 0; } else if (intEndIndex <= intStartIndex) { LOGGER.debug(debug, SOURCE + "Correcting EndIndex less than StartIndex"); intEndIndex = intStartIndex + 1; } LOGGER.debug(debug, SOURCE + "before copy of selected series subset [channel=" + intChannelIndex + "] [start_index=" + intStartIndex + "] [end_index=" + intEndIndex + "]"); // Copy over only the selected range from the Slider for (int intDataIndex = intStartIndex; intDataIndex < intEndIndex; intDataIndex++) { final TimeSeriesDataItem dataOriginalItem; final TimeSeriesDataItem dataChangedItem; dataOriginalItem = (TimeSeriesDataItem) listOriginalDataItems .get(intDataIndex); if (!ChannelSelectionMode.X1.equals(selectionMode)) { // Change each value of the series according to the multiplier dataChangedItem = new TimeSeriesDataItem(dataOriginalItem.getPeriod(), dataOriginalItem.getValue().doubleValue() * selectionMode.getMultiplier()); } else { // Just use the whole series unaltered for gain of X1 dataChangedItem = new TimeSeriesDataItem(dataOriginalItem.getPeriod(), dataOriginalItem.getValue().doubleValue()); } seriesChangedData.add(dataChangedItem); } // Did we collect any data for this Series? // If not, place a dummy point at the origin of the *visible* chart if (seriesChangedData.getItemCount() == 0) { seriesChangedData.add(ChartHelper.createDummyTimeSeriesDataItemAtOrigin( collectionPrimary, seriesOriginalData, domainstartpoint, debug)); } // Place the changed series in the correct collection // to correspond with the original if (intChannelIndex < collectionPrimary.getSeriesCount()) { // Simply add the changed Primary series to the PrimaryDataset collection ((TimeSeriesCollection) xyNewPrimaryDataset).addSeries(seriesChangedData); } else { // It must be a secondary dataset // Add the changed Secondary series to the parent SecondaryDataset // given by the *secondary* channel index ChartHelper.addSecondarySeries(datasettype, listParentSecondaryDatasetForSeries, seriesChangedData, intChannelIndex - collectionPrimary.getSeriesCount()); } } else { // There are no data! Do nothing... LOGGER.warn(SOURCE + "There are no data, so do nothing [channel.index=" + intChannelIndex + "]"); } } else { LOGGER.warn(SOURCE + "OriginalData TimeSeries unexpectedly NULL [channel.index=" + intChannelIndex + "]"); } } else { LOGGER.debug(debug, SOURCE + "Channel is OFF [channel.index=" + intChannelIndex + "]"); } } LOGGER.debug(debug, SOURCE + "Update the data shown on existing Chart"); // The outputs are xyNewPrimaryDataset and listNewSecondaryDatasets // This Chart superclass does not use secondary datasets (yet) // Dump the (partial) contents of each Series in the new XYdataset ChartHelper.dumpXYDataset(debug, calObservatory, xyNewPrimaryDataset, 4, SOURCE + "TimeSeriesCollection NewPrimaryDataset --> setDataset"); dao.getChartUI().getChartPanel().getChart().getXYPlot().setDataset(INDEX_DATA, xyNewPrimaryDataset); } else { LOGGER.error(SOURCE + " The TimeSeriesCollection does not have any TimeSeries"); } } else { LOGGER.error(SOURCE + " The Dataset is of an invalid type"); } } else { LOGGER.debug(debug, SOURCE + " Unable to change the Chart - invalid parameters"); } }
From source file:org.lmn.fc.frameworks.starbase.plugins.observatory.ui.tabs.charts.ChartHelper.java
/*********************************************************************************************** * Create a new Chart to show only those channels which are selected. * This must work even if the ChannelSelector is NULL. * * @param chartui/*from ww w . j a va 2 s . c om*/ * @param dao * @param datasettype * @param primarydataset * @param secondarydatasets * @param updatetype * @param isrefreshable * @param isclickrefresh * @param displaylimit * @param domainstartpoint * @param domainendpoint * @param channelselector * @param debug * * @return JFreeChart */ private static JFreeChart createChartForSelection(final ChartUIComponentPlugin chartui, final ObservatoryInstrumentDAOInterface dao, final DatasetType datasettype, final XYDataset primarydataset, final List<XYDataset> secondarydatasets, final DataUpdateType updatetype, final boolean isrefreshable, final boolean isclickrefresh, final int displaylimit, final int domainstartpoint, final int domainendpoint, final ChannelSelectorUIComponentInterface channelselector, final boolean debug) { final String SOURCE = "ChartHelper.createChartForSelection() "; final JFreeChart jFreeChart; LOGGER.debug(debug, SOURCE); if ((datasettype != null) && (primarydataset != null) && (secondarydatasets != null) && (updatetype != null)) { final XYDataset xyNewPrimaryDataset; final List<XYDataset> listNewSecondaryDatasets; final List<XYDataset> listParentSecondaryDatasetForSeries; final Iterator iterOriginalSecondaryDatasets; final Calendar calObservatory; // Create a list of NewSecondaryDatasets for display // Add an appropriate *empty* new dataset for every one existing in the secondary set // and record the parent new Dataset for each Series in each original Dataset // So much complexity just to handle the very few cases of secondary datasets... listNewSecondaryDatasets = new ArrayList<XYDataset>(10); listParentSecondaryDatasetForSeries = new ArrayList<XYDataset>(10); iterOriginalSecondaryDatasets = secondarydatasets.iterator(); // Either find the Current Observatory calendar, or provide a default calObservatory = ObservatoryInstrumentHelper.getCurrentObservatoryCalendar(REGISTRY.getFramework(), dao, debug); while (iterOriginalSecondaryDatasets.hasNext()) { final XYDataset xyDatasetOriginal; xyDatasetOriginal = (XYDataset) iterOriginalSecondaryDatasets.next(); if ((xyDatasetOriginal != null) && (xyDatasetOriginal.getSeriesCount() > 0)) { final XYDataset xyDatasetNew; // Create an empty Dataset to correspond with the original if (datasettype.getName().equals(DatasetType.XY.getName())) { xyDatasetNew = new XYSeriesCollection(); listNewSecondaryDatasets.add(xyDatasetNew); } else if (datasettype.getName().equals(DatasetType.TIMESTAMPED.getName())) { xyDatasetNew = new TimeSeriesCollection(calObservatory.getTimeZone()); listNewSecondaryDatasets.add(xyDatasetNew); } else { xyDatasetNew = new XYSeriesCollection(); listNewSecondaryDatasets.add(xyDatasetNew); } // Record the *same* parent Dataset for each Series in each original Secondary Dataset // This creates a List in channel order, but with references to Datasets not Series for (int i = 0; i < xyDatasetOriginal.getSeriesCount(); i++) { listParentSecondaryDatasetForSeries.add(xyDatasetNew); } } } LOGGER.debug(debug, SOURCE + "Check the DatasetType"); // Confirm the DatasetType if ((datasettype.getName().equals(DatasetType.XY.getName())) && (primarydataset instanceof XYSeriesCollection)) { final XYSeriesCollection collectionPrimary; // Prepare a new XYSeriesCollection for display xyNewPrimaryDataset = new XYSeriesCollection(); // There should be a collection of <channelcount> XYSeries in the Primary Dataset // but there may also be some in the Secondary Datasets collectionPrimary = (XYSeriesCollection) primarydataset; if ((collectionPrimary.getSeriesCount() > 0) && (collectionPrimary.getSeries() != null)) { final int intChannelCount; if (channelselector != null) { channelselector.debugSelector(debug, SOURCE); if ((channelselector.getChannelSelectionModes() != null) && (channelselector.showChannels())) { intChannelCount = channelselector.getChannelSelectionModes().size(); LOGGER.debug(debug, SOURCE + "[channelcount.channelselector=" + intChannelCount + "]"); } else if (dao != null) { intChannelCount = dao.getRawDataChannelCount(); LOGGER.debug(debug, SOURCE + "[channelcount.dao.raw=" + intChannelCount + "] (has channelselector?)"); } else { intChannelCount = collectionPrimary.getSeriesCount(); LOGGER.debug(debug, SOURCE + "[channelcount.primary.series=" + intChannelCount + "]"); } } else if (dao != null) { intChannelCount = dao.getRawDataChannelCount(); LOGGER.debug(debug, SOURCE + "[channelcount.dao.raw" + intChannelCount + "] (no channelselector)"); } else { // This should never happen! intChannelCount = collectionPrimary.getSeriesCount(); LOGGER.debug(debug, SOURCE + "[channelcount.primary.series" + intChannelCount + "] (last resort)"); } LOGGER.debug(debug, SOURCE + DatasetType.XY.getName() + " [domain.start.point=" + domainstartpoint + "] [domain.end.point=" + domainendpoint + "] [channelcount.inferred=" + intChannelCount + "]"); // Find which channels to use this time round for (int intChannelIndex = 0; intChannelIndex < intChannelCount; intChannelIndex++) { final ChannelSelectionMode selectionMode; // Use the ChannelSelectionMode if we can if ((channelselector != null) && (channelselector.getChannelSelectionModes() != null) && (channelselector.showChannels())) { selectionMode = channelselector.getChannelSelectionModes().get(intChannelIndex); } else { // If there is no ChannelSelector then we can safely assume the Channel is ON selectionMode = ChannelSelectionMode.X1; } if (!ChannelSelectionMode.OFF.equals(selectionMode)) { final XYSeries seriesOriginalData; seriesOriginalData = (XYSeries) getSeriesForIndex(datasettype, primarydataset, secondarydatasets, intChannelIndex, debug); if (seriesOriginalData != null) { final XYSeries seriesChangedData; final List listOriginalDataItems; int intStartIndex; int intEndIndex; listOriginalDataItems = seriesOriginalData.getItems(); // Prepare a new Series for the changed data, with the same Key seriesChangedData = new XYSeries(seriesOriginalData.getKey()); // Map the slider values to data indexes intStartIndex = transformDomainSliderValueToSeriesIndex( ChartUIComponentPlugin.DOMAIN_SLIDER_MINIMUM, ChartUIComponentPlugin.DOMAIN_SLIDER_MAXIMUM, domainstartpoint, DatasetDomainUIComponentInterface.INDEX_LEFT, collectionPrimary.getDomainLowerBound(true), collectionPrimary.getDomainUpperBound(true), DatasetType.XY, calObservatory, seriesOriginalData, debug); intEndIndex = transformDomainSliderValueToSeriesIndex( ChartUIComponentPlugin.DOMAIN_SLIDER_MINIMUM, ChartUIComponentPlugin.DOMAIN_SLIDER_MAXIMUM, domainendpoint, DatasetDomainUIComponentInterface.INDEX_RIGHT, collectionPrimary.getDomainLowerBound(true), collectionPrimary.getDomainUpperBound(true), DatasetType.XY, calObservatory, seriesOriginalData, debug); if ((intStartIndex == -1) || (intEndIndex == -1)) { // If either index is returned as -1, then there's nothing to do... // ...so stop the for() loop intStartIndex = 0; intEndIndex = 0; } else if (intEndIndex <= intStartIndex) { intEndIndex = intStartIndex + 1; } LOGGER.debug(debug, SOURCE + "before copy of selected series subset [channel=" + intChannelIndex + "] [index.start=" + intStartIndex + "] [index.end=" + intEndIndex + "] [show.ticks=" + ((intEndIndex - intStartIndex) <= 25) + "]"); // Copy over only the selected range from the Slider for (int intDataIndex = intStartIndex; ((intDataIndex < intEndIndex) && (listOriginalDataItems.size() > 0)); intDataIndex++) { final XYDataItem dataOriginalItem; final XYDataItem dataChangedItem; dataOriginalItem = (XYDataItem) listOriginalDataItems.get(intDataIndex); if (!ChannelSelectionMode.X1.equals(selectionMode)) { // Change each value of the series according to the multiplier dataChangedItem = new XYDataItem(dataOriginalItem.getX(), dataOriginalItem.getY().doubleValue() * selectionMode.getMultiplier()); } else { // Just use the whole series unaltered for gain of X1 dataChangedItem = new XYDataItem(dataOriginalItem.getX(), dataOriginalItem.getY()); } seriesChangedData.add(dataChangedItem); } // Place the changed series in the correct collection // to correspond with the original // Did we collect any data for this Series? // If not, place a dummy point at the origin of the *visible* chart if (seriesChangedData.getItemCount() == 0) { // TODO seriesChangedData.add(new XYDataItem(0, 0)); } if (intChannelIndex < collectionPrimary.getSeriesCount()) { // Simply add the changed Primary series to the PrimaryDataset collection ((XYSeriesCollection) xyNewPrimaryDataset).addSeries(seriesChangedData); } else { // It must be a secondary dataset // Add the changed Secondary series to the parent SecondaryDataset // given by the *secondary* channel index addSecondarySeries(datasettype, listParentSecondaryDatasetForSeries, seriesChangedData, intChannelIndex - collectionPrimary.getSeriesCount()); } } else { LOGGER.warn(SOURCE + "OriginalData XYSeries unexpectedly NULL"); } } } // Dump the (partial) contents of each Series in the composite XYdataset dumpXYDataset(debug, calObservatory, xyNewPrimaryDataset, 4, SOURCE + "XYSeriesCollection --> createCustomisedChart() xyNewPrimaryDataset"); jFreeChart = chartui.createCustomisedChart(datasettype, xyNewPrimaryDataset, listNewSecondaryDatasets, updatetype, displaylimit, channelselector, debug); } else { LOGGER.error(SOURCE + " The XYSeriesCollection does not have any XYSeries"); jFreeChart = null; } } else if ((datasettype.getName().equals(DatasetType.TIMESTAMPED.getName())) && (primarydataset instanceof TimeSeriesCollection)) { final TimeSeriesCollection collectionPrimary; // Prepare a new TimeSeriesCollection for display xyNewPrimaryDataset = new TimeSeriesCollection(calObservatory.getTimeZone()); // There should be a collection of <channelcount> TimeSeries in the Primary Dataset // but there may also be some in the Secondary Datasets collectionPrimary = (TimeSeriesCollection) primarydataset; if ((collectionPrimary.getSeriesCount() > 0) && (collectionPrimary.getSeries() != null)) { final int intChannelCount; if (channelselector != null) { channelselector.debugSelector(debug, SOURCE); if ((channelselector.getChannelSelectionModes() != null) && (channelselector.showChannels())) { intChannelCount = channelselector.getChannelSelectionModes().size(); LOGGER.debug(debug, SOURCE + "[channelcount.channelselector=" + intChannelCount + "]"); } else if (dao != null) { intChannelCount = dao.getRawDataChannelCount(); LOGGER.debug(debug, SOURCE + "[channelcount.dao.raw=" + intChannelCount + "] (has channelselector)"); } else { intChannelCount = collectionPrimary.getSeriesCount(); LOGGER.debug(debug, SOURCE + "[channelcount.primary.series=" + intChannelCount + "]"); } } else if (dao != null) { intChannelCount = dao.getRawDataChannelCount(); LOGGER.debug(debug, SOURCE + "[channelcount.dao.raw=" + intChannelCount + "] (no channelselector)"); } else { // This should never happen! intChannelCount = collectionPrimary.getSeriesCount(); LOGGER.debug(debug, SOURCE + "[channelcount.primary.series=" + intChannelCount + "] (last resort)"); } LOGGER.debug(debug, SOURCE + DatasetType.TIMESTAMPED.getName() + " [domain.startpoint=" + domainstartpoint + "] [domain.endpoint=" + domainendpoint + "] [domain.lowerbound=" + (long) collectionPrimary.getDomainLowerBound(true) + "] [domain.upperbound=" + (long) collectionPrimary.getDomainUpperBound(true) + "] [channelcount.inferred=" + intChannelCount + "]"); // Find which channels to use this time round for (int intChannelIndex = 0; intChannelIndex < intChannelCount; intChannelIndex++) { final ChannelSelectionMode selectionMode; // Use the ChannelSelectionMode if we can if ((channelselector != null) && (channelselector.getChannelSelectionModes() != null) && (channelselector.showChannels())) { selectionMode = channelselector.getChannelSelectionModes().get(intChannelIndex); } else { // If there is no ChannelSelector then we can safely assume the Channel is ON selectionMode = ChannelSelectionMode.X1; } if (!ChannelSelectionMode.OFF.equals(selectionMode)) { final TimeSeries seriesOriginalData; seriesOriginalData = (TimeSeries) getSeriesForIndex(datasettype, primarydataset, secondarydatasets, intChannelIndex, debug); if (seriesOriginalData != null) { final TimeSeries seriesChangedData; final List listOriginalDataItems; int intStartIndex; int intEndIndex; listOriginalDataItems = seriesOriginalData.getItems(); // Prepare a new Series for the changed data, with the same Key seriesChangedData = new TimeSeries(seriesOriginalData.getKey().toString(), seriesOriginalData.getTimePeriodClass()); // Map the slider values to data indexes intStartIndex = transformDomainSliderValueToSeriesIndex( ChartUIComponentPlugin.DOMAIN_SLIDER_MINIMUM, ChartUIComponentPlugin.DOMAIN_SLIDER_MAXIMUM, domainstartpoint, DatasetDomainUIComponentInterface.INDEX_LEFT, collectionPrimary.getDomainLowerBound(true), collectionPrimary.getDomainUpperBound(true), DatasetType.TIMESTAMPED, calObservatory, seriesOriginalData, debug); intEndIndex = transformDomainSliderValueToSeriesIndex( ChartUIComponentPlugin.DOMAIN_SLIDER_MINIMUM, ChartUIComponentPlugin.DOMAIN_SLIDER_MAXIMUM, domainendpoint, DatasetDomainUIComponentInterface.INDEX_RIGHT, collectionPrimary.getDomainLowerBound(true), collectionPrimary.getDomainUpperBound(true), DatasetType.TIMESTAMPED, calObservatory, seriesOriginalData, debug); if ((intStartIndex == -1) || (intEndIndex == -1)) { // If either index is returned as -1, then there's nothing to do... // ...so stop the for() loop intStartIndex = 0; intEndIndex = 0; } else if (intEndIndex <= intStartIndex) { intEndIndex = intStartIndex + 1; } LOGGER.debug(debug, SOURCE + "before copy of selected series subset [channel=" + intChannelIndex + "] [index.start=" + intStartIndex + "] [index.end=" + intEndIndex + "] [item.count=" + listOriginalDataItems.size() + "]"); // Copy over only the selected range from the Slider for (int intDataIndex = intStartIndex; ((intDataIndex < intEndIndex) && (intDataIndex < listOriginalDataItems.size())); intDataIndex++) { final TimeSeriesDataItem dataOriginalItem; final TimeSeriesDataItem dataChangedItem; dataOriginalItem = (TimeSeriesDataItem) listOriginalDataItems.get(intDataIndex); if (!ChannelSelectionMode.X1.equals(selectionMode)) { // Change each value of the series according to the multiplier dataChangedItem = new TimeSeriesDataItem(dataOriginalItem.getPeriod(), dataOriginalItem.getValue().doubleValue() * selectionMode.getMultiplier()); } else { // Just use the whole series unaltered for gain of X1 dataChangedItem = new TimeSeriesDataItem(dataOriginalItem.getPeriod(), dataOriginalItem.getValue().doubleValue()); } seriesChangedData.add(dataChangedItem); } // Did we collect any data for this Series? // If not, place a dummy point at the origin of the *visible* chart if (seriesChangedData.getItemCount() == 0) { seriesChangedData.add(createDummyTimeSeriesDataItemAtOrigin(collectionPrimary, seriesOriginalData, domainstartpoint, debug)); } // Place the changed series in the correct collection // to correspond with the original if (intChannelIndex < collectionPrimary.getSeriesCount()) { // Simply add the changed Primary series to the PrimaryDataset collection ((TimeSeriesCollection) xyNewPrimaryDataset).addSeries(seriesChangedData); } else { // It must be a secondary dataset // Add the changed Secondary series to the parent SecondaryDataset // given by the *secondary* channel index addSecondarySeries(datasettype, listParentSecondaryDatasetForSeries, seriesChangedData, intChannelIndex - collectionPrimary.getSeriesCount()); } } else { LOGGER.warn(SOURCE + "OriginalData TimeSeries unexpectedly NULL"); } } } // Dump the (partial) contents of each Series in the composite XYdataset dumpXYDataset(debug, calObservatory, xyNewPrimaryDataset, 4, SOURCE + "TimeSeriesCollection --> createCustomisedChart() xyNewPrimaryDataset"); jFreeChart = chartui.createCustomisedChart(datasettype, xyNewPrimaryDataset, listNewSecondaryDatasets, updatetype, displaylimit, channelselector, debug); } else { LOGGER.error(SOURCE + " The TimeSeriesCollection does not have any TimeSeries"); jFreeChart = null; } } else { LOGGER.error(SOURCE + " The Dataset is of an invalid type"); jFreeChart = null; } } else { LOGGER.debug(debug, SOURCE + " Unable to change the Chart - invalid parameters"); jFreeChart = null; } return (jFreeChart); }