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.category;
034
035import java.awt.Color;
036import java.io.Serializable;
037import org.jfree.chart3d.internal.Args;
038import org.jfree.chart3d.data.DataUtils;
039import org.jfree.chart3d.data.Range;
040import org.jfree.chart3d.data.Values3D;
041import org.jfree.chart3d.graphics3d.Offset3D;
042import org.jfree.chart3d.internal.ObjectUtils;
043import org.jfree.chart3d.label.CategoryItemLabelGenerator;
044import org.jfree.chart3d.plot.CategoryPlot3D;
045import org.jfree.chart3d.renderer.AbstractRenderer3D;
046import org.jfree.chart3d.renderer.Renderer3DChangeEvent;
047
048/**
049 * A base class that can be used to implement renderers for a 
050 * {@link CategoryPlot3D}.
051 */
052public abstract class AbstractCategoryRenderer3D extends AbstractRenderer3D 
053        implements CategoryRenderer3D, Serializable {
054    
055    /** A reference to the plot that the renderer is currently assigned to. */
056    private CategoryPlot3D plot;
057   
058    /** 
059     * The color source is used to determine the color for each item drawn
060     * by the renderer (never {@code null}).
061     */
062    private CategoryColorSource colorSource;
063    
064    /** 
065     * An object that generates item labels for the chart.  Can be null.
066     */
067    private CategoryItemLabelGenerator itemLabelGenerator;
068    
069    /** The item label offsets. */
070    private Offset3D itemLabelOffsets;
071    
072    /**
073     * Default constructor.
074     */
075    public AbstractCategoryRenderer3D() {
076        this.colorSource = new StandardCategoryColorSource();
077        this.itemLabelGenerator = null;
078        this.itemLabelOffsets = new Offset3D(0.0, 0.05, 1.1);
079    }
080    
081    /**
082     * Returns the plot that the renderer is currently assigned to, if any.
083     * 
084     * @return The plot or {@code null}.
085     */
086    @Override
087    public CategoryPlot3D getPlot() {
088        return this.plot;
089    }
090    
091    /**
092     * Sets the plot that the renderer is assigned to.  You do not need to 
093     * call this method yourself, the plot takes care of it when you call
094     * the {@code setRenderer()} method on the plot.
095     * 
096     * @param plot  the plot ({@code null} permitted).
097     */
098    @Override
099    public void setPlot(CategoryPlot3D plot) {
100        this.plot = plot;
101    }
102
103    /**
104     * Returns the color source for the renderer.  This is used to determine
105     * the colors used for individual items in the chart, and the color to 
106     * display for a series in the chart legend.
107     * 
108     * @return The color source (never {@code null}). 
109     */
110    @Override
111    public CategoryColorSource getColorSource() {
112        return this.colorSource;
113    }
114    
115    /**
116     * Sets the color source for the renderer and sends a 
117     * {@link Renderer3DChangeEvent} to all registered listeners.
118     * 
119     * @param colorSource  the color source ({@code null} not permitted). 
120     */
121    @Override
122    public void setColorSource(CategoryColorSource colorSource) {
123        Args.nullNotPermitted(colorSource, "colorSource");
124        this.colorSource = colorSource;
125        fireChangeEvent(true);
126    }
127    
128    /**
129     * Sets a new color source for the renderer using the specified colors and
130     * sends a {@link Renderer3DChangeEvent} to all registered listeners. This 
131     * is a convenience method that is equivalent to 
132     * {@code setColorSource(new StandardCategoryColorSource(colors))}.
133     * 
134     * @param colors  one or more colors ({@code null} not permitted).
135     * 
136     * @since 1.1
137     */
138    @Override
139    public void setColors(Color... colors) {
140        setColorSource(new StandardCategoryColorSource(colors));
141    }
142
143    /**
144     * Returns the item label generator for the renderer (possibly 
145     * {@code null}).
146     * 
147     * @return The item label generator (possibly {@code null}).
148     * 
149     * @since 1.3
150     */
151    public CategoryItemLabelGenerator getItemLabelGenerator() {
152        return itemLabelGenerator;
153    }
154
155    /**
156     * Sets the item label generator for the renderer and sends a change event
157     * to all registered listeners.
158     * 
159     * @param generator  the generator ({@code null} permitted).
160     * 
161     * @since 1.3
162     */
163    public void setItemLabelGenerator(CategoryItemLabelGenerator generator) {
164        this.itemLabelGenerator = generator;
165        fireChangeEvent(true);
166    }
167
168    /**
169     * Returns the item label offsets.
170     * 
171     * @return The item label offsets (never {@code null}).
172     * 
173     * @since 1.3
174     */
175    public Offset3D getItemLabelOffsets() {
176        return this.itemLabelOffsets;
177    }
178    
179    /**
180     * Sets the item label offsets and sends a change event to all registered
181     * listeners.
182     * 
183     * @param offsets  the offsets ({@code null} not permitted).
184     * 
185     * @since 1.3
186     */
187    public void setItemLabelOffsets(Offset3D offsets) {
188        Args.nullNotPermitted(offsets, "offsets");
189        this.itemLabelOffsets = offsets;
190        fireChangeEvent(true);
191    }
192    
193    /**
194     * Returns the range of values that will be required on the value axis
195     * to see all the data from the dataset.
196     * 
197     * @param data  the data ({@code null} not permitted).
198     * 
199     * @return The range (possibly {@code null}) 
200     */
201    @Override
202    public Range findValueRange(Values3D<? extends Number> data) {
203        return DataUtils.findValueRange(data);
204    }
205    
206    /**
207     * Tests this renderer for equality with an arbitrary object.
208     * 
209     * @param obj  the object ({@code null} permitted).
210     * 
211     * @return A boolean. 
212     */
213    @Override
214    public boolean equals(Object obj) {
215        if (obj == this) {
216            return true;
217        } 
218        if (!(obj instanceof AbstractCategoryRenderer3D)) {
219            return false;
220        }
221        AbstractCategoryRenderer3D that = (AbstractCategoryRenderer3D) obj;
222        if (!this.colorSource.equals(that.colorSource)) {
223            return false;
224        }
225        if (!ObjectUtils.equals(this.itemLabelGenerator, 
226                that.itemLabelGenerator)) {
227            return false;
228        }
229        if (!this.itemLabelOffsets.equals(that.itemLabelOffsets)) {
230            return false;
231        }
232        return super.equals(obj);
233    }
234    
235}