00001
00002
00003
00004
00005
00006
00007 package org.swtchart.internal.series;
00008
00009 import java.math.BigDecimal;
00010 import java.util.LinkedHashMap;
00011 import java.util.Map.Entry;
00012 import java.util.Set;
00013
00014 import org.eclipse.swt.SWT;
00015 import org.eclipse.swt.graphics.Point;
00016 import org.swtchart.Chart;
00017 import org.swtchart.IAxis;
00018 import org.swtchart.IAxis.Direction;
00019 import org.swtchart.ISeries;
00020 import org.swtchart.ISeries.SeriesType;
00021 import org.swtchart.ISeriesSet;
00022 import org.swtchart.Range;
00023 import org.swtchart.internal.axis.Axis;
00024 import org.swtchart.internal.compress.CompressConfig;
00025 import org.swtchart.internal.compress.ICompress;
00026
00030 public class SeriesSet implements ISeriesSet {
00031
00033 private final Chart chart;
00034
00036 private LinkedHashMap<String, Series> seriesMap;
00037
00044 public SeriesSet(Chart chart) {
00045 this.chart = chart;
00046
00047 seriesMap = new LinkedHashMap<String, Series>();
00048 }
00049
00050
00051
00052
00053 public ISeries createSeries(SeriesType type, String id) {
00054 if (id == null) {
00055 SWT.error(SWT.ERROR_NULL_ARGUMENT);
00056 return null;
00057 }
00058
00059 String identifier = id.trim();
00060
00061 if ("".equals(identifier)) {
00062 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
00063 }
00064
00065 Series series = null;
00066 if (type == SeriesType.BAR) {
00067 series = new BarSeries(chart, identifier);
00068 } else if (type == SeriesType.LINE) {
00069 series = new LineSeries(chart, identifier);
00070 } else {
00071 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
00072 return null;
00073 }
00074
00075 Series oldSeries = seriesMap.get(identifier);
00076 if (oldSeries != null) {
00077 oldSeries.dispose();
00078 }
00079
00080 int[] xAxisIds = chart.getAxisSet().getXAxisIds();
00081 int[] yAxisIds = chart.getAxisSet().getYAxisIds();
00082 series.setXAxisId(xAxisIds[0]);
00083 series.setYAxisId(yAxisIds[0]);
00084
00085 seriesMap.put(identifier, series);
00086
00087 Axis axis = (Axis) chart.getAxisSet().getXAxis(xAxisIds[0]);
00088 if (axis != null) {
00089 updateStackAndRiserData();
00090 }
00091
00092
00093 chart.updateLayout();
00094
00095 return series;
00096 }
00097
00098
00099
00100
00101 public ISeries getSeries(String id) {
00102 if (id == null) {
00103 SWT.error(SWT.ERROR_NULL_ARGUMENT);
00104 }
00105
00106 return seriesMap.get(id);
00107 }
00108
00109
00110
00111
00112 public ISeries[] getSeries() {
00113 Set<String> keys = seriesMap.keySet();
00114 ISeries[] series = new ISeries[keys.size()];
00115 int i = 0;
00116 for (String key : keys) {
00117 series[i++] = seriesMap.get(key);
00118 }
00119 return series;
00120 }
00121
00122
00123
00124
00125 public void deleteSeries(String id) {
00126 validateSeriesId(id);
00127
00128 seriesMap.get(id).dispose();
00129 seriesMap.remove(id);
00130
00131 updateStackAndRiserData();
00132
00133
00134 chart.updateLayout();
00135 }
00136
00137
00138
00139
00140 public void bringForward(String id) {
00141 validateSeriesId(id);
00142
00143 String seriesId = null;
00144 LinkedHashMap<String, Series> newSeriesMap = new LinkedHashMap<String, Series>();
00145 for (Entry<String, Series> entry : seriesMap.entrySet()) {
00146
00147 if (entry.getKey().equals(id)) {
00148 seriesId = id;
00149 continue;
00150 }
00151
00152 newSeriesMap.put(entry.getKey(), entry.getValue());
00153
00154 if (seriesId != null) {
00155 newSeriesMap.put(seriesId, seriesMap.get(seriesId));
00156 seriesId = null;
00157 }
00158 }
00159 if (seriesId != null) {
00160 newSeriesMap.put(seriesId, seriesMap.get(seriesId));
00161 }
00162 seriesMap = newSeriesMap;
00163
00164 updateStackAndRiserData();
00165 chart.updateLayout();
00166 }
00167
00168
00169
00170
00171 public void bringToFront(String id) {
00172 validateSeriesId(id);
00173
00174 Series series = seriesMap.get(id);
00175 seriesMap.remove(id);
00176 seriesMap.put(series.getId(), series);
00177
00178 updateStackAndRiserData();
00179 chart.updateLayout();
00180 }
00181
00182
00183
00184
00185 public void sendBackward(String id) {
00186 validateSeriesId(id);
00187
00188 String seriesId = null;
00189 LinkedHashMap<String, Series> newSeriesMap = new LinkedHashMap<String, Series>();
00190 for (Entry<String, Series> entry : seriesMap.entrySet()) {
00191
00192 if (!entry.getKey().equals(id) || seriesId == null) {
00193 newSeriesMap.put(entry.getKey(), entry.getValue());
00194 seriesId = entry.getKey();
00195 continue;
00196 }
00197
00198 newSeriesMap.remove(seriesId);
00199 newSeriesMap.put(entry.getKey(), entry.getValue());
00200 newSeriesMap.put(seriesId, seriesMap.get(seriesId));
00201 }
00202 seriesMap = newSeriesMap;
00203
00204 updateStackAndRiserData();
00205 chart.updateLayout();
00206 }
00207
00208
00209
00210
00211 public void sendToBack(String id) {
00212 validateSeriesId(id);
00213
00214 LinkedHashMap<String, Series> newSeriesMap = new LinkedHashMap<String, Series>();
00215 newSeriesMap.put(id, seriesMap.get(id));
00216 for (Entry<String, Series> entry : seriesMap.entrySet()) {
00217 if (!entry.getKey().equals(id)) {
00218 newSeriesMap.put(entry.getKey(), entry.getValue());
00219 }
00220 }
00221 seriesMap = newSeriesMap;
00222
00223 updateStackAndRiserData();
00224 chart.updateLayout();
00225 }
00226
00230 public void dispose() {
00231 for (Entry<String, Series> entry : seriesMap.entrySet()) {
00232 entry.getValue().dispose();
00233 }
00234 }
00235
00242 private void validateSeriesId(String id) {
00243 if (id == null) {
00244 SWT.error(SWT.ERROR_NULL_ARGUMENT);
00245 }
00246 if (seriesMap.get(id) == null) {
00247 throw new IllegalArgumentException("Given series id doesn't exist");
00248 }
00249 }
00250
00254 public void compressAllSeries() {
00255 if (!chart.isCompressEnabled()) {
00256 return;
00257 }
00258
00259 CompressConfig config = new CompressConfig();
00260
00261 final int PRECISION = 2;
00262 Point p = chart.getPlotArea().getSize();
00263 int width = p.x * PRECISION;
00264 int height = p.y * PRECISION;
00265 config.setSizeInPixel(width, height);
00266
00267 for (ISeries series : getSeries()) {
00268 int xAxisId = series.getXAxisId();
00269 int yAxisId = series.getYAxisId();
00270
00271 IAxis xAxis = chart.getAxisSet().getXAxis(xAxisId);
00272 IAxis yAxis = chart.getAxisSet().getYAxis(yAxisId);
00273 if (xAxis == null || yAxis == null) {
00274 continue;
00275 }
00276 Range xRange = xAxis.getRange();
00277 Range yRange = yAxis.getRange();
00278
00279 if (xRange == null || yRange == null) {
00280 continue;
00281 }
00282
00283 double xMin = xRange.lower;
00284 double xMax = xRange.upper;
00285 double yMin = yRange.lower;
00286 double yMax = yRange.upper;
00287
00288 config.setXLogScale(xAxis.isLogScaleEnabled());
00289 config.setYLogScale(yAxis.isLogScaleEnabled());
00290
00291 double lower = xMin - (xMax - xMin) * 0.015;
00292 double upper = xMax + (xMax - xMin) * 0.015;
00293 if (xAxis.isLogScaleEnabled()) {
00294 lower = ((Series) series).getXRange().lower;
00295 }
00296 config.setXRange(lower, upper);
00297 lower = yMin - (yMax - yMin) * 0.015;
00298 upper = yMax + (yMax - yMin) * 0.015;
00299 if (yAxis.isLogScaleEnabled()) {
00300 lower = ((Series) series).getYRange().lower;
00301 }
00302 config.setYRange(lower, upper);
00303
00304 ICompress compressor = ((Series) series).getCompressor();
00305 compressor.compress(config);
00306 }
00307 }
00308
00319 public void updateCompressor(Axis axis) {
00320 for (ISeries series : getSeries()) {
00321 int axisId = (axis.getDirection() == Direction.X) ? series
00322 .getXAxisId() : series.getYAxisId();
00323 if (axisId != axis.getId()) {
00324 continue;
00325 }
00326
00327 ICompress compressor = ((Series) series).getCompressor();
00328 if (axis.isValidCategoryAxis()) {
00329 String[] categorySeries = axis.getCategorySeries();
00330 if (categorySeries == null) {
00331 continue;
00332 }
00333 double[] xSeries = new double[categorySeries.length];
00334 for (int i = 0; i < xSeries.length; i++) {
00335 xSeries[i] = i;
00336 }
00337 compressor.setXSeries(xSeries);
00338 } else if (((Series) series).getXSeries() != null) {
00339 compressor.setXSeries(((Series) series).getXSeries());
00340 }
00341 }
00342 compressAllSeries();
00343 }
00344
00348 public void updateStackAndRiserData() {
00349 if (chart.isUpdateSuspended()) {
00350 return;
00351 }
00352
00353 for (IAxis xAxis : chart.getAxisSet().getXAxes()) {
00354 ((Axis) xAxis).setNumRisers(0);
00355 for (IAxis yAxis : chart.getAxisSet().getYAxes()) {
00356 updateStackAndRiserData(xAxis, yAxis);
00357 }
00358 }
00359 }
00360
00369 private void updateStackAndRiserData(IAxis xAxis, IAxis yAxis) {
00370
00371 int riserCnt = 0;
00372 int stackRiserPosition = -1;
00373 double[] stackBarSeries = null;
00374 double[] stackLineSeries = null;
00375
00376 if (((Axis) xAxis).isValidCategoryAxis()) {
00377 String[] categorySeries = xAxis.getCategorySeries();
00378 if (categorySeries != null) {
00379 int size = categorySeries.length;
00380 stackBarSeries = new double[size];
00381 stackLineSeries = new double[size];
00382 }
00383 }
00384
00385 for (ISeries series : getSeries()) {
00386 if (series.getXAxisId() != xAxis.getId()
00387 || series.getYAxisId() != yAxis.getId()
00388 || !series.isVisible()) {
00389 continue;
00390 }
00391
00392 if (series.isStackEnabled()
00393 && !chart.getAxisSet().getYAxis(series.getYAxisId())
00394 .isLogScaleEnabled()
00395 && ((Axis) xAxis).isValidCategoryAxis()) {
00396 if (series.getType() == SeriesType.BAR) {
00397 if (stackRiserPosition == -1) {
00398 stackRiserPosition = riserCnt;
00399 riserCnt++;
00400 }
00401 ((BarSeries) series).setRiserIndex(((Axis) xAxis)
00402 .getNumRisers() + stackRiserPosition);
00403 setStackSeries(stackBarSeries, series);
00404 } else if (series.getType() == SeriesType.LINE) {
00405 setStackSeries(stackLineSeries, series);
00406 }
00407 } else {
00408 if (series.getType() == SeriesType.BAR) {
00409 ((BarSeries) series).setRiserIndex(((Axis) xAxis)
00410 .getNumRisers() + riserCnt++);
00411 }
00412 }
00413 }
00414
00415 ((Axis) xAxis).setNumRisers(((Axis) xAxis).getNumRisers() + riserCnt);
00416 }
00417
00426 private static void setStackSeries(double[] stackSeries, ISeries series) {
00427 double[] ySeries = series.getYSeries();
00428 if (ySeries == null || stackSeries == null) {
00429 return;
00430 }
00431
00432 for (int i = 0; i < stackSeries.length; i++) {
00433 if (i >= ySeries.length) {
00434 break;
00435 }
00436 stackSeries[i] = BigDecimal.valueOf(stackSeries[i])
00437 .add(BigDecimal.valueOf(ySeries[i])).doubleValue();
00438 }
00439 double[] copiedStackSeries = new double[stackSeries.length];
00440 System.arraycopy(stackSeries, 0, copiedStackSeries, 0,
00441 stackSeries.length);
00442 ((Series) series).setStackSeries(copiedStackSeries);
00443 }
00444 }