/**
  * Creates and returns a line chart based on the supplied dataset. The chart returned by this
  * method will be constructed with an {@link XYZPlot} using a {@link LineXYZRenderer} (so it is
  * safe to cast the plot and/or renderer to customise attributes that are specific to those
  * subclasses).
  *
  * @param title the chart title ({@code null} permitted).
  * @param subtitle the chart subtitle ({@code null} permitted).
  * @param dataset the dataset ({@code null} not permitted).
  * @param xAxisLabel the x-axis label ({@code null} permitted).
  * @param yAxisLabel the y-axis label ({@code null} permitted).
  * @param zAxisLabel the z-axis label ({@code null} permitted).
  * @return The chart.
  * @since 1.5
  */
 public static Chart3D createXYZLineChart(
     String title,
     String subtitle,
     XYZDataset dataset,
     String xAxisLabel,
     String yAxisLabel,
     String zAxisLabel) {
   ValueAxis3D xAxis = new NumberAxis3D(xAxisLabel);
   NumberAxis3D yAxis = new NumberAxis3D(yAxisLabel);
   yAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR);
   ValueAxis3D zAxis = new NumberAxis3D(zAxisLabel);
   XYZRenderer renderer = new LineXYZRenderer();
   XYZPlot plot = new XYZPlot(dataset, renderer, xAxis, yAxis, zAxis);
   return new Chart3D(title, subtitle, plot);
 }
 /**
  * Creates and returns a stacked bar chart based on the supplied dataset. The chart returned by
  * this method will be constructed with a {@link CategoryPlot3D} using a {@link
  * StackedBarRenderer3D} (so it is safe to cast the plot and/or renderer to customise attributes
  * that are specific to those subclasses). <br>
  * <br>
  * For reference, here is a sample stacked bar chart: <div> <object id="ABC"
  * data="../../doc-files/StackedBarChart3DDemo1.svg" type="image/svg+xml" width="500"
  * height="359"> </object> </div>
  *
  * @param title the chart title ({@code null} permitted).
  * @param subtitle the chart subtitle ({@code null} permitted).
  * @param dataset the dataset ({@code null} not permitted).
  * @param rowAxisLabel the row axis label ({@code null} permitted).
  * @param columnAxisLabel the column axis label ({@code null} permitted).
  * @param valueAxisLabel the value axis label ({@code null} permitted).
  * @return A stacked bar chart (never {@code null}).
  */
 public static Chart3D createStackedBarChart(
     String title,
     String subtitle,
     CategoryDataset3D dataset,
     String rowAxisLabel,
     String columnAxisLabel,
     String valueAxisLabel) {
   StandardCategoryAxis3D rowAxis = new StandardCategoryAxis3D(rowAxisLabel);
   rowAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR);
   CategoryAxis3D columnAxis = new StandardCategoryAxis3D(columnAxisLabel);
   NumberAxis3D valueAxis = new NumberAxis3D(valueAxisLabel, new Range(0.0, 1.0));
   valueAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR);
   CategoryRenderer3D renderer = new StackedBarRenderer3D();
   CategoryPlot3D plot = new CategoryPlot3D(dataset, renderer, rowAxis, columnAxis, valueAxis);
   return new Chart3D(title, subtitle, plot);
 }
  /**
   * Creates a surface chart for the specified function. <br>
   * <br>
   * For reference, here is a sample surface chart: <div> <object id="SurfaceRenderer3DDemo2"
   * data="../../doc-files/SurfaceRendererDemo2.svg" type="image/svg+xml" width="562" height="408">
   * </object> </div>
   *
   * @param title the chart title ({@code null} permitted).
   * @param subtitle the chart subtitle ({@code null} permitted).
   * @param function the function ({@code null} not permitted).
   * @param xAxisLabel the x-axis label ({@code null} permitted).
   * @param yAxisLabel the y-axis label ({@code null} permitted).
   * @param zAxisLabel the z-axis label ({@code null} permitted).
   * @return The chart.
   * @since 1.1
   */
  public static Chart3D createSurfaceChart(
      String title,
      String subtitle,
      Function3D function,
      String xAxisLabel,
      String yAxisLabel,
      String zAxisLabel) {
    NumberAxis3D xAxis = new NumberAxis3D(xAxisLabel);
    NumberAxis3D yAxis = new NumberAxis3D(yAxisLabel);
    yAxis.setTickLabelOrientation(LabelOrientation.PERPENDICULAR);
    NumberAxis3D zAxis = new NumberAxis3D(zAxisLabel);
    XYZRenderer renderer = new SurfaceRenderer(function);
    // we pass an empty dataset because the plot must have a non-null
    // dataset, but the renderer never looks at it...
    XYZPlot plot = new XYZPlot(new XYZSeriesCollection(), renderer, xAxis, yAxis, zAxis);

    Chart3D chart = new Chart3D(title, subtitle, plot);
    chart.setLegendBuilder(new ColorScaleLegendBuilder());
    return chart;
  }