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; 034 035import com.orsoncharts.axis.CategoryAxis3D; 036import com.orsoncharts.axis.LabelOrientation; 037import com.orsoncharts.axis.StandardCategoryAxis3D; 038import com.orsoncharts.axis.NumberAxis3D; 039import com.orsoncharts.axis.ValueAxis3D; 040import com.orsoncharts.data.category.CategoryDataset3D; 041import com.orsoncharts.data.PieDataset3D; 042import com.orsoncharts.data.function.Function3D; 043import com.orsoncharts.data.xyz.XYZDataset; 044import com.orsoncharts.data.xyz.XYZSeriesCollection; 045import com.orsoncharts.legend.ColorScaleLegendBuilder; 046import com.orsoncharts.plot.CategoryPlot3D; 047import com.orsoncharts.plot.PiePlot3D; 048import com.orsoncharts.plot.XYZPlot; 049import com.orsoncharts.renderer.xyz.BarXYZRenderer; 050import com.orsoncharts.renderer.xyz.XYZRenderer; 051import com.orsoncharts.renderer.category.AreaRenderer3D; 052import com.orsoncharts.renderer.category.BarRenderer3D; 053import com.orsoncharts.renderer.category.CategoryRenderer3D; 054import com.orsoncharts.renderer.category.LineRenderer3D; 055import com.orsoncharts.renderer.category.StackedBarRenderer3D; 056import com.orsoncharts.renderer.xyz.LineXYZRenderer; 057import com.orsoncharts.renderer.xyz.ScatterXYZRenderer; 058import com.orsoncharts.renderer.xyz.SurfaceRenderer; 059import com.orsoncharts.style.ChartStyle; 060import com.orsoncharts.style.StandardChartStyle; 061import com.orsoncharts.util.ArgChecks; 062 063/** 064 * Utility methods for constructing common chart types. Charts can be 065 * assembled piece-wise, but usually it is simpler to use the methods in this 066 * class then customise the resulting chart as necessary. 067 */ 068public class Chart3DFactory { 069 070 /** 071 * Private constructor prevents instantiation which is unnecessary. 072 */ 073 private Chart3DFactory() { 074 // no need to instantiate this ever 075 } 076 077 /** The chart style that will be used when creating a new chart. */ 078 static ChartStyle defaultStyle = new StandardChartStyle(); 079 080 /** 081 * Returns a new instance of the default chart style (so that, by default, 082 * all charts will have an independent style instance). 083 * 084 * @return The default chart style (never {@code null}). 085 * 086 * @since 1.2 087 */ 088 public static ChartStyle getDefaultChartStyle() { 089 return defaultStyle.clone(); 090 } 091 092 /** 093 * Sets the style that will be used when creating new charts. 094 * 095 * @param style the style ({@code null} not permitted). 096 * 097 * @since 1.2 098 */ 099 public static void setDefaultChartStyle(ChartStyle style) { 100 ArgChecks.nullNotPermitted(style, "style"); 101 defaultStyle = style.clone(); 102 } 103 104 /** 105 * Creates and returns a pie chart based on the supplied dataset. The 106 * chart returned by this method will be constructed using a 107 * {@link PiePlot3D} instance (so it is safe to cast the result of 108 * {@code chart.getPlot()}). 109 * <br><br> 110 * For reference, here is a sample pie chart: 111 * <div> 112 * <object id="ABC" data="../../doc-files/PieChart3DDemo1.svg" 113 * type="image/svg+xml" width="500" height="359"> 114 * </object> 115 * </div> 116 * 117 * @param title the chart title ({@code null} permitted). 118 * @param subtitle the chart subtitle ({@code null} permitted). 119 * @param dataset the dataset ({@code null} not permitted). 120 * 121 * @return A pie chart (never {@code null}). 122 */ 123 public static Chart3D createPieChart(String title, String subtitle, 124 PieDataset3D dataset) { 125 PiePlot3D plot = new PiePlot3D(dataset); 126 return new Chart3D(title, subtitle, plot); 127 } 128 129 /** 130 * Creates and returns a bar chart based on the supplied dataset. The chart 131 * returned by this method will be constructed with a 132 * {@link CategoryPlot3D} using a {@link BarRenderer3D} (so it is 133 * safe to cast the plot and/or renderer to customise attributes that are 134 * specific to those subclasses). 135 * <br><br> 136 * For reference, here is a sample bar chart: 137 * <div> 138 * <object id="ABC" data="../../doc-files/BarChart3DDemo1.svg" 139 * type="image/svg+xml" width="500" height="359"> 140 * </object> 141 * </div> 142 * 143 * @param title the chart title ({@code null} permitted). 144 * @param subtitle the chart subtitle ({@code null} permitted). 145 * @param dataset the dataset ({@code null} not permitted). 146 * @param rowAxisLabel the row axis label ({@code null} permitted). 147 * @param columnAxisLabel the column axis label ({@code null} 148 * permitted). 149 * @param valueAxisLabel the value axis label ({@code null} permitted). 150 * 151 * @return A bar chart (never {@code null}). 152 */ 153 public static Chart3D createBarChart(String title, String subtitle, 154 CategoryDataset3D dataset, String rowAxisLabel, 155 String columnAxisLabel, String valueAxisLabel) { 156 StandardCategoryAxis3D rowAxis 157 = new StandardCategoryAxis3D(rowAxisLabel); 158 rowAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 159 CategoryAxis3D columnAxis = new StandardCategoryAxis3D(columnAxisLabel); 160 NumberAxis3D valueAxis = new NumberAxis3D(valueAxisLabel, 161 new Range(0.0, 1.0)); 162 valueAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 163 CategoryRenderer3D renderer = new BarRenderer3D(); 164 CategoryPlot3D plot = new CategoryPlot3D(dataset, renderer, 165 rowAxis, columnAxis, valueAxis); 166 return new Chart3D(title, subtitle, plot); 167 } 168 169 /** 170 * Creates and returns a stacked bar chart based on the supplied dataset. 171 * The chart returned by this method will be constructed with a 172 * {@link CategoryPlot3D} using a {@link StackedBarRenderer3D} (so it is 173 * safe to cast the plot and/or renderer to customise attributes that 174 * are specific to those subclasses). 175 * <br><br> 176 * For reference, here is a sample stacked bar chart: 177 * <div> 178 * <object id="ABC" data="../../doc-files/StackedBarChart3DDemo1.svg" 179 * type="image/svg+xml" width="500" height="359"> 180 * </object> 181 * </div> 182 * 183 * @param title the chart title ({@code null} permitted). 184 * @param subtitle the chart subtitle ({@code null} permitted). 185 * @param dataset the dataset ({@code null} not permitted). 186 * @param rowAxisLabel the row axis label ({@code null} permitted). 187 * @param columnAxisLabel the column axis label ({@code null} permitted). 188 * @param valueAxisLabel the value axis label ({@code null} permitted). 189 * 190 * @return A stacked bar chart (never {@code null}). 191 */ 192 public static Chart3D createStackedBarChart(String title, String subtitle, 193 CategoryDataset3D dataset, String rowAxisLabel, 194 String columnAxisLabel, String valueAxisLabel) { 195 StandardCategoryAxis3D rowAxis 196 = new StandardCategoryAxis3D(rowAxisLabel); 197 rowAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 198 CategoryAxis3D columnAxis = new StandardCategoryAxis3D(columnAxisLabel); 199 NumberAxis3D valueAxis = new NumberAxis3D(valueAxisLabel, 200 new Range(0.0, 1.0)); 201 valueAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 202 CategoryRenderer3D renderer = new StackedBarRenderer3D(); 203 CategoryPlot3D plot = new CategoryPlot3D(dataset, renderer, rowAxis, 204 columnAxis, valueAxis); 205 return new Chart3D(title, subtitle, plot); 206 } 207 208 /** 209 * Creates and returns an area chart based on the supplied dataset. The 210 * chart returned by this method will be constructed with a 211 * {@link CategoryPlot3D} using an {@link AreaRenderer3D} (so it is safe 212 * to cast the plot and/or renderer to customise attributes that are 213 * specific to those subclasses). 214 * <br><br> 215 * For reference, here is a sample area chart: 216 * <div> 217 * <object id="ABC" data="../../doc-files/AreaChart3DDemo1.svg" 218 * type="image/svg+xml" width="500" height="359"> 219 * </object> 220 * </div> 221 * 222 * @param title the chart title ({@code null} permitted). 223 * @param subtitle the chart subtitle ({@code null} permitted). 224 * @param dataset the dataset ({@code null} not permitted). 225 * @param rowAxisLabel the row axis label ({@code null} permitted). 226 * @param columnAxisLabel the column axis label ({@code null} permitted). 227 * @param valueAxisLabel the value axis label ({@code null} permitted). 228 * 229 * @return An area chart (never {@code null}). 230 */ 231 public static Chart3D createAreaChart(String title, String subtitle, 232 CategoryDataset3D dataset, String rowAxisLabel, 233 String columnAxisLabel, String valueAxisLabel) { 234 StandardCategoryAxis3D rowAxis 235 = new StandardCategoryAxis3D(rowAxisLabel); 236 rowAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 237 StandardCategoryAxis3D columnAxis = new StandardCategoryAxis3D( 238 columnAxisLabel); 239 columnAxis.setFirstCategoryHalfWidth(true); 240 columnAxis.setLastCategoryHalfWidth(true); 241 NumberAxis3D valueAxis = new NumberAxis3D(valueAxisLabel, 242 new Range(0.0, 1.0)); 243 valueAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 244 CategoryRenderer3D renderer = new AreaRenderer3D(); 245 CategoryPlot3D plot = new CategoryPlot3D(dataset, renderer, rowAxis, 246 columnAxis, valueAxis); 247 return new Chart3D(title, subtitle, plot); 248 } 249 250 /** 251 * Creates and returns a line chart based on the supplied dataset. The 252 * chart returned by this method will be constructed with a 253 * {@link CategoryPlot3D} using a {@link LineRenderer3D} (so it is safe 254 * to cast the plot and/or renderer to customise attributes that are 255 * specific to those subclasses). 256 * <br><br> 257 * For reference, here is a sample line chart: 258 * <div> 259 * <object id="ABC" data="../../doc-files/LineChart3DDemo1.svg" 260 * type="image/svg+xml" width="500" height="359"> 261 * </object> 262 * </div> 263 * 264 * @param title the chart title ({@code null} permitted). 265 * @param subtitle the chart subtitle ({@code null} permitted). 266 * @param dataset the dataset ({@code null} not permitted). 267 * @param rowAxisLabel the row axis label ({@code null} permitted). 268 * @param columnAxisLabel the column axis label ({@code null} permitted). 269 * @param valueAxisLabel the value axis label ({@code null} permitted). 270 * 271 * @return A line chart (never {@code null}). 272 */ 273 public static Chart3D createLineChart(String title, String subtitle, 274 CategoryDataset3D dataset, String rowAxisLabel, 275 String columnAxisLabel, String valueAxisLabel) { 276 StandardCategoryAxis3D rowAxis 277 = new StandardCategoryAxis3D(rowAxisLabel); 278 rowAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 279 StandardCategoryAxis3D columnAxis 280 = new StandardCategoryAxis3D(columnAxisLabel); 281 columnAxis.setFirstCategoryHalfWidth(true); 282 columnAxis.setLastCategoryHalfWidth(true); 283 NumberAxis3D valueAxis = new NumberAxis3D(valueAxisLabel, 284 new Range(0.0, 1.0)); 285 valueAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 286 CategoryRenderer3D renderer = new LineRenderer3D(); 287 CategoryPlot3D plot = new CategoryPlot3D(dataset, renderer, rowAxis, 288 columnAxis, valueAxis); 289 return new Chart3D(title, subtitle, plot); 290 } 291 292 /** 293 * Creates and returns a scatter plot based on the supplied dataset 294 * (containing one or more series of {@code (x, y, z)} values). The 295 * chart returned by this method will be constructed with an 296 * {@link XYZPlot} using a {@link ScatterXYZRenderer} (so it is safe 297 * to cast the plot and/or renderer to customise attributes that are 298 * specific to those subclasses). 299 * <br><br> 300 * For reference, here is a sample scatter chart: 301 * <div> 302 * <object id="ABC" data="../../doc-files/ScatterPlot3DDemo1.svg" 303 * type="image/svg+xml" width="564" height="351"> 304 * </object> 305 * </div> 306 * 307 * @param title the chart title ({@code null} permitted). 308 * @param subtitle the chart subtitle ({@code null} permitted). 309 * @param dataset the dataset ({@code null} not permitted). 310 * @param xAxisLabel the x-axis label ({@code null} permitted). 311 * @param yAxisLabel the y-axis label ({@code null} permitted). 312 * @param zAxisLabel the z-axis label ({@code null} permitted). 313 * 314 * @return The chart. 315 */ 316 public static Chart3D createScatterChart(String title, String subtitle, 317 XYZDataset dataset, String xAxisLabel, String yAxisLabel, 318 String zAxisLabel) { 319 NumberAxis3D xAxis = new NumberAxis3D(xAxisLabel); 320 NumberAxis3D yAxis = new NumberAxis3D(yAxisLabel); 321 yAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 322 NumberAxis3D zAxis = new NumberAxis3D(zAxisLabel); 323 XYZRenderer renderer = new ScatterXYZRenderer(); 324 XYZPlot plot = new XYZPlot(dataset, renderer, xAxis, yAxis, zAxis); 325 return new Chart3D(title, subtitle, plot); 326 } 327 328 /** 329 * Creates a surface chart for the specified function. 330 * <br><br> 331 * For reference, here is a sample surface chart: 332 * <div> 333 * <object id="SurfaceRenderer3DDemo2" data="../../doc-files/SurfaceRendererDemo2.svg" 334 * type="image/svg+xml" width="562" height="408"> 335 * </object> 336 * </div> 337 * 338 * @param title the chart title ({@code null} permitted). 339 * @param subtitle the chart subtitle ({@code null} permitted). 340 * @param function the function ({@code null} not permitted). 341 * @param xAxisLabel the x-axis label ({@code null} permitted). 342 * @param yAxisLabel the y-axis label ({@code null} permitted). 343 * @param zAxisLabel the z-axis label ({@code null} permitted). 344 * 345 * @return The chart. 346 * 347 * @since 1.1 348 */ 349 public static Chart3D createSurfaceChart(String title, String subtitle, 350 Function3D function, String xAxisLabel, String yAxisLabel, 351 String zAxisLabel) { 352 NumberAxis3D xAxis = new NumberAxis3D(xAxisLabel); 353 NumberAxis3D yAxis = new NumberAxis3D(yAxisLabel); 354 yAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 355 NumberAxis3D zAxis = new NumberAxis3D(zAxisLabel); 356 XYZRenderer renderer = new SurfaceRenderer(function); 357 // we pass an empty dataset because the plot must have a non-null 358 // dataset, but the renderer never looks at it... 359 XYZPlot plot = new XYZPlot(new XYZSeriesCollection(), renderer, xAxis, 360 yAxis, zAxis); 361 362 Chart3D chart = new Chart3D(title, subtitle, plot); 363 chart.setLegendBuilder(new ColorScaleLegendBuilder()); 364 return chart; 365 } 366 367 /** 368 * Creates and returns a bar chart based on the supplied dataset (this is 369 * for special cases, most general cases will be covered by the 370 * {@link #createBarChart(String, String, CategoryDataset3D, String, String, String) } 371 * method). The chart returned by this method will be constructed with an 372 * {@link XYZPlot} using a {@link BarXYZRenderer} (so it is safe 373 * to cast the plot and/or renderer to customise attributes that are 374 * specific to those subclasses). 375 * <br><br> 376 * For reference, here is a sample XYZ bar chart: 377 * <div> 378 * <object id="ABC" data="../../doc-files/XYZBarChart3DDemo1.svg" 379 * type="image/svg+xml" width="500" height="359"> 380 * </object> 381 * </div> 382 * 383 * @param title the chart title ({@code null} permitted). 384 * @param subtitle the chart subtitle ({@code null} permitted). 385 * @param dataset the dataset ({@code null} not permitted). 386 * @param xAxisLabel the x-axis label ({@code null} permitted). 387 * @param yAxisLabel the y-axis label ({@code null} permitted). 388 * @param zAxisLabel the z-axis label ({@code null} permitted). 389 * 390 * @return The chart. 391 */ 392 public static Chart3D createXYZBarChart(String title, String subtitle, 393 XYZDataset dataset, String xAxisLabel, String yAxisLabel, 394 String zAxisLabel) { 395 ValueAxis3D xAxis = new NumberAxis3D(xAxisLabel); 396 NumberAxis3D yAxis = new NumberAxis3D(yAxisLabel); 397 yAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 398 ValueAxis3D zAxis = new NumberAxis3D(zAxisLabel); 399 XYZRenderer renderer = new BarXYZRenderer(); 400 XYZPlot plot = new XYZPlot(dataset, renderer, xAxis, yAxis, zAxis); 401 return new Chart3D(title, subtitle, plot); 402 } 403 404 /** 405 * Creates and returns a line chart based on the supplied dataset. The 406 * chart returned by this method will be constructed with an 407 * {@link XYZPlot} using a {@link LineXYZRenderer} (so it is safe 408 * to cast the plot and/or renderer to customise attributes that are 409 * specific to those subclasses). 410 * 411 * @param title the chart title ({@code null} permitted). 412 * @param subtitle the chart subtitle ({@code null} permitted). 413 * @param dataset the dataset ({@code null} not permitted). 414 * @param xAxisLabel the x-axis label ({@code null} permitted). 415 * @param yAxisLabel the y-axis label ({@code null} permitted). 416 * @param zAxisLabel the z-axis label ({@code null} permitted). 417 * 418 * @return The chart. 419 * 420 * @since 1.5 421 */ 422 public static Chart3D createXYZLineChart(String title, String subtitle, 423 XYZDataset dataset, String xAxisLabel, String yAxisLabel, 424 String zAxisLabel) { 425 ValueAxis3D xAxis = new NumberAxis3D(xAxisLabel); 426 NumberAxis3D yAxis = new NumberAxis3D(yAxisLabel); 427 yAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR); 428 ValueAxis3D zAxis = new NumberAxis3D(zAxisLabel); 429 XYZRenderer renderer = new LineXYZRenderer(); 430 XYZPlot plot = new XYZPlot(dataset, renderer, xAxis, yAxis, zAxis); 431 return new Chart3D(title, subtitle, plot); 432 } 433}