/** * * The MIT License * * Copyright (c) 2011 the original author or authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.googlecode.charts4j; import static com.googlecode.charts4j.collect.Preconditions.checkArgument; import static com.googlecode.charts4j.collect.Preconditions.checkNotNull; import java.util.List; import com.googlecode.charts4j.collect.ImmutableList; import com.googlecode.charts4j.collect.Lists; /** * Plot implementation class. This class must always remain package private. It * is constructed via the {@link Plots} static factory class. * * @author Julien Chastang (julien.c.chastang at gmail dot com) * */ final class PlotImpl implements BarChartPlot, Line, RadarPlot, ScatterPlotData, XYLine { /** X data series for this plot. **/ private final Data xData; /** Y data series for this plot. **/ private final Data yData; /** List of marked points for this plot. **/ private final List<MarkedPoints> markedPointsList = Lists.newLinkedList(); /** List of markers to be added to all point on this plot. **/ private final List<Marker> markers = Lists.newLinkedList(); /** Individual colors for bars in bar chart. **/ private final List<BarColor> barColors = Lists.newLinkedList(); /** Color of this plot. **/ private Color color; /** Legend for this plot. **/ private String legend; /** Point sizes for this scatter plot. **/ private Data pointSizes; /** Fill area color for this plot. **/ private Color fillAreaColor; /** Zero line if this is a bar chart. */ private double zeroLine = Data.MIN_VALUE; /** Dataline for this bar chart. */ private DataLine dataLine; /** The line style for this plot. */ private LineStyle lineStyle; /** The priority for this plot. **/ private Priority priority; /** * Construct a plot with x and y data. * * @param xdata * x data series * @param ydata * y data series */ PlotImpl(final Data xdata, final Data ydata) { this.xData = xdata; this.yData = ydata; } /** * Construct a plot with y data. Y data is evenly spread on x axis. * * @param data * y data series */ PlotImpl(final Data data) { this.yData = data; //Below, the * / 100 is to prevent ill-conditioned math. int inc = 0; if (data.getSize() > 1) { inc = ((int)Data.MAX_VALUE) * 100 / (data.getSize() - 1); } final List<Number> xVals = Lists.newLinkedList(); double x = Data.MIN_VALUE; for (int i = (int) Data.MIN_VALUE; i < data.getSize(); i++) { xVals.add(x / 100); x = x + inc; } this.xData = Data.newData(xVals); } /** * Copy constructor. * * @param plotImpl * object to be copied. */ private PlotImpl(final PlotImpl plotImpl) { xData = plotImpl.xData; yData = plotImpl.yData; markedPointsList.addAll(plotImpl.markedPointsList); barColors.addAll(plotImpl.barColors); markers.addAll(plotImpl.markers); color = plotImpl.color; legend = plotImpl.legend; pointSizes = plotImpl.pointSizes; fillAreaColor = plotImpl.fillAreaColor; zeroLine = plotImpl.zeroLine; dataLine = plotImpl.dataLine; lineStyle = plotImpl.lineStyle; priority = plotImpl.priority; } public Plot klone() { return new PlotImpl(this); } /** * Get the Y series data. * * @return the y series data. */ Data getData() { return yData; } /** * Get the X series data. * * @return the x series data. */ Data getXData() { return xData; } /** * Get the Y series data. * * @return the y series data. */ Data getYData() { return yData; } /** * Get the legend for this plot. * * * @return the legend as a string. */ String getLegend() { return legend; } /** * {@inheritDoc} */ public void setLegend(final String legend) { checkNotNull(legend, "legend cannot be null"); this.legend = legend; } /** * Get the color of this plot. * * @return the color of this plot. Could return null. */ Color getColor() { return color; } /** * {@inheritDoc} */ public void setColor(final Color color) { checkNotNull(color, "color cannot be null"); this.color = color; } /** * Get the individually colored bars in a bar chart. * * @return a list of individually colored bars. */ public ImmutableList<BarColor> getBarColors() { return Lists.copyOf(barColors); } /** * {@inheritDoc} */ public void setColor(final Color color, final int index) { checkNotNull(color, "color cannot be null"); checkArgument(index >= 0, "index must be >= 0"); checkArgument(index < yData.getSize(), "index out of bounds"); barColors.add(new BarColor(color,index)); } /** * Get the fill area color for this plot. * * @return the fill area for this plot. Could be null. */ Color getFillAreaColor() { return fillAreaColor; } /** * {@inheritDoc} */ public void setFillAreaColor(final Color color) { checkNotNull(color, "color cannot be null"); this.fillAreaColor = color; } /** * Get the list of marked points for this plot. * * @return an immutable list of marked points. */ ImmutableList<MarkedPoints> getMarkedPointsList() { return Lists.copyOf(markedPointsList); } /** * Get the list of markers for this plot. * * @return an immutable list of markers. */ ImmutableList<Marker> getMarkers() { return Lists.copyOf(markers); } /** * {@inheritDoc} */ public void addShapeMarker(final Shape shape, final Color color, final int size, final int index) { checkNotNull(shape, "shape cannot be null"); checkNotNull(color, "color cannot be null"); checkArgument(index >= 0, "index must be >= 0"); checkArgument(index < yData.getSize(), "index is out of bounds"); markedPointsList.add(new MarkedPoints(Markers.newShapeMarker(shape, color, size), index)); } /** * {@inheritDoc} */ public void addTextMarker(final String text, final Color color, final int size, final int index) { checkNotNull(text, "text cannot be null"); checkNotNull(color, "color cannot be null"); checkArgument(index >= 0, "index must be >= 0"); checkArgument(index < yData.getSize(), "index is out of bounds"); markedPointsList.add(new MarkedPoints(Markers.newTextMarker(text, color, size), index)); } /** * {@inheritDoc} */ public void addShapeMarkers(final Shape shape, final Color color, final int size) { checkNotNull(shape, "shape cannot be null"); checkNotNull(color, "color cannot be null"); markers.add(Markers.newShapeMarker(shape, color, size)); } /** * {@inheritDoc} */ public void addMarker(final Marker marker, final int index) { checkNotNull(marker, "marker cannot be null"); checkArgument(index >= 0, "index must be >= 0"); markedPointsList.add(new MarkedPoints(marker, index)); } /** * {@inheritDoc} */ public void addMarkers(final Marker marker) { checkNotNull(marker, "marker cannot be null"); markers.add(marker); } /** * {@inheritDoc} */ public void addMarkers(final Marker marker, final int startIndex, final int endIndex, final int n) { checkNotNull(marker, "marker cannot be null"); checkArgument(startIndex >= 0, "start index must be >= 0"); checkArgument(endIndex > 0, "end index must be > 0"); checkArgument(endIndex > startIndex, "end index must be > start index"); checkArgument(n > 0, "n must be > 0"); markedPointsList.add(new MarkedPoints(marker, startIndex, endIndex, n)); } /** * {@inheritDoc} */ public void addMarkers(final Marker marker, final int n) { addMarkers(marker, 0, yData.getSize(), n); } /** * {@inheritDoc} */ public void addMarkers(final Marker marker, final int startIndex, final int endIndex) { addMarkers(marker, startIndex, endIndex, 1); } /** * {@inheritDoc} */ public void setDataLine(final int dataLineSize, final Color color, final Priority priority) { checkNotNull(color, "color cannot be null"); checkNotNull(priority, "priority cannot be null"); checkArgument(dataLineSize >= 0, "data line size must be >= 0"); dataLine = new DataLine(dataLineSize, color, priority); } /** * Get the data line for bar charts. * * @return the data line for bar charts. */ DataLine getDataLine() { return dataLine; } /** * Get the zero line for bar charts. * * @return the zero line for bar charts. */ double getZeroLine() { return zeroLine; } /** * {@inheritDoc} */ public void setZeroLine(final double zeroLine) { checkArgument(zeroLine >= Data.MIN_VALUE && zeroLine <= Data.MAX_VALUE, "Zero line must be between " + Data.MIN_VALUE + " and " + Data.MAX_VALUE); this.zeroLine = zeroLine; } /** * {@inheritDoc} */ public void setPriority(final Priority priority) { checkNotNull(priority, "priority cannot be null"); this.priority = priority; } /** * {@inheritDoc} */ public void setLineStyle(final LineStyle lineStyle) { checkNotNull(lineStyle, "line style cannot be null"); this.lineStyle = lineStyle; } /** * Get the line style for this plot. * * @return the line style for this plot. */ LineStyle getLineStyle() { return lineStyle; } /** * {@inheritDoc} */ public void setPointSizes(final Data pointSizes) { checkNotNull(pointSizes, "point sizes cannot be null"); this.pointSizes = pointSizes; } /** * Get the point sizes for scatter plots. * * @return the point sizes for scatter plots. */ Data getPointSizes() { return pointSizes; } /** * Get the priority for this plot. * * @return the priority for this plot */ Priority getPriority() { return priority; } }