001/* ===========================================================
002 * Orson Charts : a 3D chart library for the Java(tm) platform
003 * ===========================================================
004 * 
005 * (C)opyright 2013-2016, by Object Refinery Limited.  All rights reserved.
006 * 
007 * http://www.object-refinery.com/orsoncharts/index.html
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 com.orsoncharts.style;
034
035import java.awt.Color;
036import java.awt.Font;
037import java.util.HashMap;
038import java.util.Map;
039import com.orsoncharts.Chart3D;
040import com.orsoncharts.ChartElement;
041import com.orsoncharts.ChartElementVisitor;
042import com.orsoncharts.axis.Axis3D;
043import com.orsoncharts.axis.CategoryAxis3D;
044import com.orsoncharts.axis.ValueAxis3D;
045import com.orsoncharts.marker.CategoryMarker;
046import com.orsoncharts.marker.Marker;
047import com.orsoncharts.marker.NumberMarker;
048import com.orsoncharts.marker.RangeMarker;
049import com.orsoncharts.plot.CategoryPlot3D;
050import com.orsoncharts.plot.PiePlot3D;
051import com.orsoncharts.plot.Plot3D;
052import com.orsoncharts.plot.XYZPlot;
053import com.orsoncharts.renderer.Renderer3D;
054import com.orsoncharts.renderer.category.CategoryRenderer3D;
055import com.orsoncharts.renderer.xyz.XYZRenderer;
056import com.orsoncharts.table.TableElement;
057import com.orsoncharts.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 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<String, Font>();
122            fontChanges.put("CHART_TITLE", this.style.getTitleFont());
123            fontChanges.put("CHART_SUBTITLE", this.style.getSubtitleFont());
124            Map<String, Color> bgChanges = new HashMap<String, Color>();
125            bgChanges.put("CHART_TITLE", this.style.getTitleBackgroundColor());
126            bgChanges.put("CHART_SUBTITLE", 
127                    this.style.getSubtitleBackgroundColor());
128            Map<String, Color> fgChanges = new HashMap<String, Color>();
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    protected void styleCategoryAxis(CategoryAxis3D axis) {
205    }
206    
207    protected void styleValueAxis(ValueAxis3D axis) {
208    }
209    
210    protected void styleRenderer(Renderer3D renderer) {
211        if (renderer instanceof CategoryRenderer3D) {
212            styleCategoryRenderer3D((CategoryRenderer3D) renderer);
213        }
214        if (renderer instanceof XYZRenderer) {
215            styleXYZRenderer((XYZRenderer) renderer);
216        }
217    }
218    
219    protected void styleCategoryRenderer3D(CategoryRenderer3D renderer) {
220        renderer.getColorSource().style(this.style.getStandardColors());
221    }
222    
223    protected void styleXYZRenderer(XYZRenderer renderer) {
224        renderer.getColorSource().style(this.style.getStandardColors());
225    }
226    
227    protected void styleMarker(Marker marker) {
228        if (marker instanceof CategoryMarker) {
229            CategoryMarker cm = (CategoryMarker) marker;
230            cm.setFont(this.style.getMarkerLabelFont());
231            cm.setLabelColor(this.style.getMarkerLabelColor());
232            cm.setLineColor(this.style.getMarkerLineColor());
233            cm.setLineStroke(this.style.getMarkerLineStroke());
234            cm.setFillColor(this.style.getMarkerFillColor());            
235        } else if (marker instanceof NumberMarker) {
236            NumberMarker nm = (NumberMarker) marker;
237            nm.setFont(this.style.getMarkerLabelFont());
238            nm.setLabelColor(this.style.getMarkerLabelColor());
239            nm.setLineColor(this.style.getMarkerLineColor());
240            nm.setLineStroke(this.style.getMarkerLineStroke());
241        } else if (marker instanceof RangeMarker) {
242            RangeMarker rm = (RangeMarker) marker;
243            rm.setFont(this.style.getMarkerLabelFont());
244            rm.setLabelColor(this.style.getMarkerLabelColor());
245            rm.setFillColor(this.style.getMarkerFillColor());
246            
247            rm.getStart().setFont(this.style.getMarkerLabelFont());
248            rm.getStart().setLabelColor(this.style.getMarkerLabelColor());
249            rm.getStart().setLineColor(this.style.getMarkerLineColor());
250            rm.getStart().setLineStroke(this.style.getMarkerLineStroke());
251            rm.getEnd().setFont(this.style.getMarkerLabelFont());
252            rm.getEnd().setLabelColor(this.style.getMarkerLabelColor());
253            rm.getEnd().setLineColor(this.style.getMarkerLineColor());
254            rm.getEnd().setLineStroke(this.style.getMarkerLineStroke());   
255        }
256    }
257}