001/* ===========================================================
002 * Orson Charts : a 3D chart library for the Java(tm) platform
003 * ===========================================================
004 * 
005 * (C)opyright 2013-2022, by David Gilbert.  All rights reserved.
006 * 
007 * https://github.com/jfree/orson-charts
008 * 
009 * This program is free software: you can redistribute it and/or modify
010 * it under the terms of the GNU General Public License as published by
011 * the Free Software Foundation, either version 3 of the License, or
012 * (at your option) any later version.
013 *
014 * This program is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017 * GNU General Public License for more details.
018 *
019 * You should have received a copy of the GNU General Public License
020 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
021 * 
022 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 
023 * Other names may be trademarks of their respective owners.]
024 * 
025 * If you do not wish to be bound by the terms of the GPL, an alternative
026 * commercial license can be purchased.  For details, please see visit the
027 * Orson Charts home page:
028 * 
029 * http://www.object-refinery.com/orsoncharts/index.html
030 * 
031 */
032
033package org.jfree.chart3d.renderer.xyz;
034
035import java.awt.Color;
036import org.jfree.chart3d.data.DataUtils;
037import org.jfree.chart3d.data.Range;
038import org.jfree.chart3d.data.xyz.XYZDataset;
039import org.jfree.chart3d.graphics3d.Dimension3D;
040import org.jfree.chart3d.graphics3d.World;
041import org.jfree.chart3d.internal.Args;
042import org.jfree.chart3d.internal.ObjectUtils;
043import org.jfree.chart3d.label.XYZItemLabelGenerator;
044import org.jfree.chart3d.plot.XYZPlot;
045import org.jfree.chart3d.renderer.AbstractRenderer3D;
046import org.jfree.chart3d.renderer.ComposeType;
047import org.jfree.chart3d.renderer.Renderer3DChangeEvent;
048
049/**
050 * An abstract base class that can be used to create new {@link XYZRenderer}
051 * subclasses.
052 */
053public class AbstractXYZRenderer extends AbstractRenderer3D {
054
055    private XYZPlot plot;
056  
057    private XYZColorSource colorSource;
058  
059    /** 
060     * An object that generates item labels for the chart.  Can be null.
061     */
062    private XYZItemLabelGenerator itemLabelGenerator;
063
064    /**
065     * Creates a new default instance.
066     */
067    protected AbstractXYZRenderer() {
068        this.colorSource = new StandardXYZColorSource();
069        this.itemLabelGenerator = null;
070    }
071  
072    /**
073     * Returns the plot that the renderer is assigned to, if any.
074     * 
075     * @return The plot (possibly {@code null}). 
076     */
077    public XYZPlot getPlot() {
078        return this.plot;
079    }
080  
081    /**
082     * Sets the plot that the renderer is assigned to.
083     * 
084     * @param plot  the plot ({@code null} permitted). 
085     */
086    public void setPlot(XYZPlot plot) {
087        this.plot = plot;
088    }
089
090    /**
091     * Returns the item label generator for the renderer.  The default value
092     * is {@code null}.  Not all subclasses will use this generator 
093     * (for example, the {@link SurfaceRenderer} does not display item labels).
094     * 
095     * @return The item label generator (possibly {@code null}).
096     * 
097     * @since 1.3
098     */
099    public XYZItemLabelGenerator getItemLabelGenerator() {
100        return this.itemLabelGenerator;
101    }
102
103    /**
104     * Sets the item label generator and sends a change event to all registered
105     * listeners.  You can set this to {@code null} in which case no
106     * item labels will be generated.
107     * 
108     * @param generator  the new generator ({@code null} permitted).
109     * 
110     * @since 1.3
111     */
112    public void setItemLabelGenerator(XYZItemLabelGenerator generator) {
113        this.itemLabelGenerator = generator;
114    }
115
116    /**
117     * Returns the type of composition performed by this renderer.  The default
118     * is {@code PER_ITEM} which means the plot will ask the renderer
119     * to compose one data item at a time into the 3D model.  Some renderers
120     * will override this method to return {@code ALL}, which means the
121     * renderer will compose all of the data items in one go (the plot calls
122     * the {@link #composeAll(XYZPlot, World, Dimension3D, double, double, double)} 
123     * method to trigger this).
124     * 
125     * @return The compose type (never {@code null}).
126     * 
127     * @since 1.1
128     */
129    public ComposeType getComposeType() {
130        return ComposeType.PER_ITEM;
131    }
132    
133    /**
134     * Adds objects to the {@code world} to represent all the data items
135     * that this renderer is responsible for.  This method is only called for
136     * renderers that return {@link ComposeType#ALL} from the 
137     * {@link #getComposeType()} method.
138     * 
139     * @param plot  the plot (not {@code null}).
140     * @param world  the 3D model (not {@code null}).
141     * @param dimensions  the dimensions of the plot (not {@code null}).
142     * @param xOffset  the x-offset.
143     * @param yOffset  the y-offset.
144     * @param zOffset  the z-offset.
145     */
146    public void composeAll(XYZPlot plot, World world, Dimension3D dimensions, 
147            double xOffset, double yOffset, double zOffset) {
148        throw new UnsupportedOperationException();
149    }
150    
151    /**
152     * Returns the object that provides the color instances for items drawn
153     * by the renderer.
154     * 
155     * @return The color source (never {@code null}). 
156     */
157    public XYZColorSource getColorSource() {
158        return this.colorSource;
159    }
160    
161    /**
162     * Sets the color source and sends a {@link Renderer3DChangeEvent} to all
163     * registered listeners.
164     * 
165     * @param colorSource  the color source ({@code null} not permitted). 
166     */
167    public void setColorSource(XYZColorSource colorSource) {
168        Args.nullNotPermitted(colorSource, "colorSource");
169        this.colorSource = colorSource;
170        fireChangeEvent(true);
171    }
172  
173    
174    /**
175     * Sets a new color source for the renderer using the specified colors and
176     * sends a {@link Renderer3DChangeEvent} to all registered listeners. This 
177     * is a convenience method that is equivalent to 
178     * {@code setColorSource(new StandardXYZColorSource(colors))}.
179     * 
180     * @param colors  one or more colors ({@code null} not permitted).
181     * 
182     * @since 1.1
183     */
184    public void setColors(Color... colors) {
185        setColorSource(new StandardXYZColorSource(colors));
186    }
187    
188    /**
189     * Returns the range that is required on the x-axis for this renderer
190     * to display all the items in the specified dataset.
191     * 
192     * @param dataset  the dataset ({@code null} not permitted).
193     * 
194     * @return The x-range. 
195     */
196    public Range findXRange(XYZDataset dataset) {
197        return DataUtils.findXRange(dataset);
198    }
199    
200    /**
201     * Returns the range that is required on the y-axis for this renderer
202     * to display all the items in the specified dataset.
203     * 
204     * @param dataset  the dataset ({@code null} not permitted).
205     * 
206     * @return The y-range. 
207     */
208    public Range findYRange(XYZDataset dataset) {
209        return DataUtils.findYRange(dataset);
210    }
211    
212    /**
213     * Returns the range that is required on the z-axis for this renderer
214     * to display all the items in the specified dataset.
215     * 
216     * @param dataset  the dataset ({@code null} not permitted).
217     * 
218     * @return The z-range. 
219     */
220    public Range findZRange(XYZDataset dataset) {
221        return DataUtils.findZRange(dataset);
222    }
223    
224    /**
225     * Tests this renderer for equality with an arbitrary object.
226     * 
227     * @param obj  the object ({@code null} permitted).
228     * 
229     * @return A boolean.
230     */
231    @Override
232    public boolean equals(Object obj) {
233        if (obj == this) {
234            return true;
235        }
236        if (!(obj instanceof AbstractXYZRenderer)) {
237            return false;
238        }
239        AbstractXYZRenderer that = (AbstractXYZRenderer) obj;
240        if (!this.colorSource.equals(that.colorSource)) {
241            return false;
242        }
243        if (!ObjectUtils.equals(this.itemLabelGenerator, 
244                that.itemLabelGenerator)) {
245            return false;
246        }
247        return super.equals(obj);
248    }
249
250}