/* (non-Javadoc)
   * @see com.alpine.datamining.api.impl.visual.ImageVisualizationType#generateOutPut(com.alpine.datamining.api.AnalyticOutPut)
   */
  @Override
  public VisualizationOutPut generateOutPut(AnalyticOutPut analyzerOutPut) {
    AnalyzerOutPutBoxWhisker obj = null;
    if (analyzerOutPut instanceof AnalyzerOutPutBoxWhisker) {
      obj = (AnalyzerOutPutBoxWhisker) analyzerOutPut;
    }
    List<BoxAndWhiskerItem> list = obj.getItemList();
    BoxAndWhiskerDataset dataset = new BoxAndWhiskerDataset();
    String variableName = null;
    String seriesName = null;
    String typeName = null;

    double[] maxArray = new double[list.size()];
    double[] minArray = new double[list.size()];
    // find max and min
    for (int i = 0; i < list.size(); i++) {
      maxArray[i] = list.get(i).getMax().doubleValue();
      minArray[i] = list.get(i).getMin().doubleValue();
    }

    Arrays.sort(maxArray);
    Arrays.sort(minArray);

    double max = maxArray[maxArray.length - 1];
    double min = minArray[0];

    long n = AlpineMath.adjustUnits(min, max);

    for (BoxAndWhiskerItem item : list) {
      dataset.add(
          item.getMean().doubleValue() / n,
          item.getMedian().doubleValue() / n,
          item.getQ1().doubleValue() / n,
          item.getQ3().doubleValue() / n,
          item.getMin().doubleValue() / n,
          item.getMax().doubleValue() / n,
          0,
          0,
          null,
          item.getSeries(),
          item.getType());
    }
    if (list != null && list.size() > 0) {
      variableName = list.get(0).getVariableName();
      if (variableName == null) variableName = "";
      seriesName = list.get(0).getSeriesName();
      if (seriesName == null) seriesName = "";
      typeName = list.get(0).getTypeName();
      if (typeName == null) typeName = "";
    }

    String yLabel =
        n == 1
            ? variableName
            : variableName
                + " "
                + VisualLanguagePack.getMessage(VisualLanguagePack.UNITS, locale)
                + " ("
                + com.alpine.datamining.api.utility.AlpineMath.powExpression(n)
                + ")";

    final CategoryAxis xAxis = new CategoryAxis(typeName);
    xAxis.setLabelFont(VisualResource.getChartFont());
    final NumberAxis yAxis = new NumberAxis(yLabel);
    yAxis.setLabelFont(VisualResource.getChartFont());
    yAxis.setAutoRangeIncludesZero(false);

    final BoxAndWhiskerRenderer renderer = new BoxAndWhiskerRenderer();
    if (list != null && list.size() < 5) {
      renderer.setMaximumBarWidth(0.2);
      renderer.setItemMargin(0.7);
    }

    renderer.setToolTipGenerator(new BoxAndWhiskerToolTipGenerator());
    CategoryPlot plot = new CategoryPlot(dataset, xAxis, yAxis, renderer);

    DrawingSupplier supplier =
        new DefaultDrawingSupplier(
            createPaintArray(),
            DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE);
    plot.setDrawingSupplier(supplier);
    plot.setBackgroundPaint(Color.lightGray);
    plot.setRangeGridlinesVisible(true);
    plot.setRangeGridlinePaint(Color.white);

    final JFreeChart chart = new JFreeChart(" ", VisualResource.getChartFont(), plot, true);
    chart.removeLegend();
    if (!seriesName.trim().equals("")) {
      final TextTitle subtitle = new TextTitle(seriesName, VisualResource.getChartFont());
      chart.addSubtitle(subtitle);
      chart.addLegend(new LegendTitle(plot));
      chart.getLegend().setItemFont(VisualResource.getChartFont());
    }
    JFreeChartImageVisualizationOutPut output = new JFreeChartImageVisualizationOutPut(chart);
    output.setName(analyzerOutPut.getAnalyticNode().getName());
    return output;
  }