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.style;
034
035import java.awt.Color;
036import java.awt.Font;
037import java.util.HashMap;
038import java.util.Map;
039import org.jfree.chart3d.Chart3D;
040import org.jfree.chart3d.ChartElement;
041import org.jfree.chart3d.ChartElementVisitor;
042import org.jfree.chart3d.axis.Axis3D;
043import org.jfree.chart3d.axis.CategoryAxis3D;
044import org.jfree.chart3d.axis.ValueAxis3D;
045import org.jfree.chart3d.marker.CategoryMarker;
046import org.jfree.chart3d.marker.Marker;
047import org.jfree.chart3d.marker.NumberMarker;
048import org.jfree.chart3d.marker.RangeMarker;
049import org.jfree.chart3d.plot.CategoryPlot3D;
050import org.jfree.chart3d.plot.PiePlot3D;
051import org.jfree.chart3d.plot.Plot3D;
052import org.jfree.chart3d.plot.XYZPlot;
053import org.jfree.chart3d.renderer.Renderer3D;
054import org.jfree.chart3d.renderer.category.CategoryRenderer3D;
055import org.jfree.chart3d.renderer.xyz.XYZRenderer;
056import org.jfree.chart3d.table.TableElement;
057import org.jfree.chart3d.table.TableElementStyler;
058
059/**
060 * A {@link ChartElementVisitor} that applies a chart style to the elements
061 * of a chart.
062 * 
063 * @since 1.2
064 */
065public class ChartStyler implements ChartElementVisitor {
066    
067    /** The chart style. */
068    private final ChartStyle style;
069    
070    /**
071     * Creates a new instance.
072     * 
073     * @param style  the style ({@code null} not permitted). 
074     */
075    public ChartStyler(ChartStyle style) {
076        this.style = style;
077    }
078
079    /**
080     * Visits a chart element and applies the current style to that element.
081     * 
082     * @param element  the chart element (never {@code null}). 
083     */
084    @Override
085    public void visit(ChartElement element) {
086        if (element instanceof Chart3D) {
087            Chart3D chart = (Chart3D) element;
088            styleChart(chart);
089        }
090        if (element instanceof Plot3D) {
091            Plot3D plot = (Plot3D) element;
092            stylePlot(plot);
093        }
094        if (element instanceof Axis3D) {
095            Axis3D axis = (Axis3D) element;
096            styleAxis(axis);
097        }
098        if (element instanceof Renderer3D) {
099            Renderer3D renderer = (Renderer3D) element;
100            styleRenderer(renderer);
101        }
102        if (element instanceof Marker) {
103            Marker marker = (Marker) element;
104            styleMarker(marker);
105        }
106    }
107    
108    /**
109     * Applies the current style to a chart.
110     * 
111     * @param chart  the chart ({@code null} not permitted). 
112     */
113    protected void styleChart(Chart3D chart) {
114        chart.setBackground(this.style.getBackgroundPainter());
115
116        // if the chart title font changed, visit all table elements in the
117        // chart title and change the font for any element that is tagged as
118        // "CHART_TITLE"
119        TableElement chartTitle = chart.getTitle();
120        if (chartTitle != null) {
121            Map<String, Font> fontChanges = new HashMap<>();
122            fontChanges.put("CHART_TITLE", this.style.getTitleFont());
123            fontChanges.put("CHART_SUBTITLE", this.style.getSubtitleFont());
124            Map<String, Color> bgChanges = new HashMap<>();
125            bgChanges.put("CHART_TITLE", this.style.getTitleBackgroundColor());
126            bgChanges.put("CHART_SUBTITLE", 
127                    this.style.getSubtitleBackgroundColor());
128            Map<String, Color> fgChanges = new HashMap<>();
129            fgChanges.put("CHART_TITLE", this.style.getTitleColor());
130            fgChanges.put("CHART_SUBTITLE", this.style.getSubtitleColor());
131            TableElementStyler m1 = new TableElementStyler(fontChanges, 
132                    fgChanges, bgChanges);
133            chartTitle.receive(m1);
134        }
135        chart.setChartBoxColor(this.style.getChartBoxColor());
136    }
137    
138    /**
139     * Applies the current style to the plot.
140     * 
141     * @param plot  the plot ({@code null} not permitted). 
142     */
143    protected void stylePlot(Plot3D plot) {
144        if (plot instanceof PiePlot3D) {
145            PiePlot3D p = (PiePlot3D) plot;
146            p.getSectionLabelFontSource().style(
147                    this.style.getSectionLabelFont());
148            p.getSectionLabelColorSource().style(
149                    this.style.getSectionLabelColor());
150            p.getSectionColorSource().style(
151                    this.style.getStandardColors());
152        }
153        if (plot instanceof CategoryPlot3D) {
154            CategoryPlot3D p = (CategoryPlot3D) plot;
155            
156            // gridline paint and stroke for rows, columns and values
157            p.setGridlinesVisibleForColumns(
158                    this.style.getColumnAxisGridlinesVisible());
159            p.setGridlinesVisibleForRows(
160                    this.style.getRowAxisGridlinesVisible());
161            p.setGridlinesVisibleForValues(
162                    this.style.getYAxisGridlinesVisible());
163            p.setGridlinePaintForRows(this.style.getGridlineColor());
164            p.setGridlinePaintForColumns(this.style.getGridlineColor());
165            p.setGridlinePaintForValues(this.style.getGridlineColor());
166            p.setGridlineStrokeForColumns(this.style.getGridlineStroke());
167            p.setGridlineStrokeForRows(this.style.getGridlineStroke());
168            p.setGridlineStrokeForValues(this.style.getGridlineStroke());
169        }
170        if (plot instanceof XYZPlot) {
171            XYZPlot p = (XYZPlot) plot;
172            p.setGridlinesVisibleX(this.style.getXAxisGridlinesVisible());
173            p.setGridlinesVisibleY(this.style.getYAxisGridlinesVisible());
174            p.setGridlinesVisibleZ(this.style.getZAxisGridlinesVisible());
175            p.setGridlinePaintX(this.style.getGridlineColor());
176            p.setGridlinePaintY(this.style.getGridlineColor());
177            p.setGridlinePaintZ(this.style.getGridlineColor());
178            p.setGridlineStrokeX(this.style.getGridlineStroke());
179            p.setGridlineStrokeY(this.style.getGridlineStroke());
180            p.setGridlineStrokeZ(this.style.getGridlineStroke());
181        }
182    }
183    
184    /**
185     * Applies the current style to the axis.
186     * 
187     * @param axis  the axis ({@code null} not permitted). 
188     */
189    protected void styleAxis(Axis3D axis) {
190        // axis line visible, stroke and paint TODO
191        // tick marks visible, stroke and paint TODO
192        axis.setLabelFont(this.style.getAxisLabelFont());
193        axis.setLabelColor(this.style.getAxisLabelColor());
194        axis.setTickLabelFont(this.style.getAxisTickLabelFont());
195        axis.setTickLabelColor(this.style.getAxisTickLabelColor());
196        if (axis instanceof CategoryAxis3D) {
197            styleCategoryAxis((CategoryAxis3D) axis);
198        }
199        if (axis instanceof ValueAxis3D) {
200            styleValueAxis((ValueAxis3D) axis);
201        }   
202    }
203    
204    /**
205     * Applies the current style to a category axis.  This implementation does
206     * nothing, it is here for overriding.
207     * 
208     * @param axis  the axis ({@code null} not permitted). 
209     */
210    protected void styleCategoryAxis(CategoryAxis3D axis) {
211        // for overriding
212    }
213    
214    /**
215     * Applies the current style to a value axis.  This implementation does
216     * nothing, it is here for overriding.
217     * 
218     * @param axis  the axis ({@code null} not permitted). 
219     */
220    protected void styleValueAxis(ValueAxis3D axis) {
221        // for overriding
222    }
223    
224    /**
225     * Applies the current style to the renderer.
226     * 
227     * @param renderer  the renderer ({@code null} not permitted). 
228     */
229    protected void styleRenderer(Renderer3D renderer) {
230        if (renderer instanceof CategoryRenderer3D) {
231            styleCategoryRenderer3D((CategoryRenderer3D) renderer);
232        }
233        if (renderer instanceof XYZRenderer) {
234            styleXYZRenderer((XYZRenderer) renderer);
235        }
236    }
237    
238    /**
239     * Applies the current style to a category renderer.
240     * 
241     * @param renderer  the renderer ({@code null} not permitted). 
242     */
243    protected void styleCategoryRenderer3D(CategoryRenderer3D renderer) {
244        renderer.getColorSource().style(this.style.getStandardColors());
245    }
246    
247    /**
248     * Applies the current style to an XYZ renderer.
249     * 
250     * @param renderer  the renderer ({@code null} not permitted). 
251     */
252    protected void styleXYZRenderer(XYZRenderer renderer) {
253        renderer.getColorSource().style(this.style.getStandardColors());
254    }
255    
256    /**
257     * Applies the current style to a marker.
258     * 
259     * @param marker  the marker ({@code null} not permitted). 
260     */
261    protected void styleMarker(Marker marker) {
262        if (marker instanceof CategoryMarker) {
263            CategoryMarker cm = (CategoryMarker) marker;
264            cm.setFont(this.style.getMarkerLabelFont());
265            cm.setLabelColor(this.style.getMarkerLabelColor());
266            cm.setLineColor(this.style.getMarkerLineColor());
267            cm.setLineStroke(this.style.getMarkerLineStroke());
268            cm.setFillColor(this.style.getMarkerFillColor());            
269        } else if (marker instanceof NumberMarker) {
270            NumberMarker nm = (NumberMarker) marker;
271            nm.setFont(this.style.getMarkerLabelFont());
272            nm.setLabelColor(this.style.getMarkerLabelColor());
273            nm.setLineColor(this.style.getMarkerLineColor());
274            nm.setLineStroke(this.style.getMarkerLineStroke());
275        } else if (marker instanceof RangeMarker) {
276            RangeMarker rm = (RangeMarker) marker;
277            rm.setFont(this.style.getMarkerLabelFont());
278            rm.setLabelColor(this.style.getMarkerLabelColor());
279            rm.setFillColor(this.style.getMarkerFillColor());
280            
281            rm.getStart().setFont(this.style.getMarkerLabelFont());
282            rm.getStart().setLabelColor(this.style.getMarkerLabelColor());
283            rm.getStart().setLineColor(this.style.getMarkerLineColor());
284            rm.getStart().setLineStroke(this.style.getMarkerLineStroke());
285            rm.getEnd().setFont(this.style.getMarkerLabelFont());
286            rm.getEnd().setLabelColor(this.style.getMarkerLabelColor());
287            rm.getEnd().setLineColor(this.style.getMarkerLineColor());
288            rm.getEnd().setLineStroke(this.style.getMarkerLineStroke());   
289        }
290    }
291}