public void testPieExplodePercentStyle() throws Exception {
    final ChartDocumentContext cdc =
        ChartFactory.generateChart(
            getClass().getResource("PieExplodePercentStyleTest.xml")); // $NON-NLS-1$
    final ChartDocument cd = cdc.getChartDocument();
    assertNotNull(cd);
    final ChartElement element = cd.getRootElement();
    assertNotNull(element);

    final CSSNumericValue[] passValues =
        new CSSNumericValue[] {
          CSSNumericValue.createValue(CSSNumericType.PERCENTAGE, 0), // $NON-NLS-1$
          CSSNumericValue.createValue(CSSNumericType.PERCENTAGE, 100), // $NON-NLS-1$
          CSSNumericValue.createValue(CSSNumericType.PERCENTAGE, 75), // $NON-NLS-1$
          CSSNumericValue.createValue(CSSNumericType.PERCENTAGE, 5), // $NON-NLS-1$
          CSSNumericValue.createValue(CSSNumericType.PERCENTAGE, 0), // $NON-NLS-1$
          CSSNumericValue.createValue(CSSNumericType.PERCENTAGE, 0), // $NON-NLS-1$
        };

    int counter = 0;
    final int lenArray = passValues.length;
    ChartElement child = element.getFirstChildItem();

    while (child != null) {
      final LayoutStyle layoutStyle = child.getLayoutStyle();
      assertNotNull(layoutStyle);
      System.out.println(
          "Expected: "
              + passValues[counter]
              + " - Got: "
              + layoutStyle.getValue(
                  ChartStyleKeys.PIE_EXPLODE_PERCENT)); // $NON-NLS-1$ //$NON-NLS-2$
      assertEquals(
          passValues[counter++].getCSSText(),
          layoutStyle.getValue(ChartStyleKeys.PIE_EXPLODE_PERCENT).getCSSText());
      child = child.getNextItem();
    }

    if (counter < lenArray - 1) {
      throw new IllegalStateException("Not all tests covered!"); // $NON-NLS-1$
    }
  }
  public void testLineVisible() throws IllegalStateException, ResourceException {
    final ChartDocumentContext cdc =
        ChartFactory.generateChart(
            getClass().getResource("ChartLineVisibleTest.xml")); // $NON-NLS-1$
    final ChartDocument cd = cdc.getChartDocument();
    assertNotNull(cd);
    final ChartElement element = cd.getRootElement();
    assertNotNull(element);

    final CSSConstant[] passValues =
        new CSSConstant[] {
          ChartLineVisibleType.VISIBLE,
          ChartLineVisibleType.VISIBLE,
          ChartLineVisibleType.HIDDEN,
          ChartLineVisibleType.VISIBLE,
          ChartLineVisibleType.VISIBLE,
          ChartLineVisibleType.VISIBLE,
        };

    int counter = 0;
    final int lenArray = passValues.length;
    ChartElement child = element.getFirstChildItem();

    while (child != null) {
      final LayoutStyle layoutStyle = child.getLayoutStyle();
      assertNotNull(layoutStyle);
      System.out.println(
          "Expected: "
              + passValues[counter]
              + " - Got: "
              + layoutStyle.getValue(ChartStyleKeys.LINE_VISIBLE)); // $NON-NLS-1$ //$NON-NLS-2$
      assertEquals(passValues[counter++], layoutStyle.getValue(ChartStyleKeys.LINE_VISIBLE));
      child = child.getNextItem();
    }

    if (counter < lenArray - 1) {
      throw new IllegalStateException("Not all tests covered!"); // $NON-NLS-1$
    }
  }
  /**
   * This method iterates through the rows and columns to populate a DefaultCategoryDataset. Since a
   * CategoryDataset stores values based on a multikey hash we supply as the keys either the
   * metadata column name or the column number and the metadata row name or row number as the keys.
   *
   * <p>As it's processing the data from the ChartTableModel into the DefaultCategoryDataset it
   * applies the scale specified in the
   *
   * @param chartDocContext - Chart document context for the current chart.
   * @param data - Data for the current chart.
   * @param columnIndexArr - Contains column position information. When not null, we would get data
   *     from specified columns.
   * @return DefaultCategoryDataset that can be used as a source for JFreeChart
   */
  private DefaultCategoryDataset createDefaultCategoryDataset(
      final ChartDocumentContext chartDocContext,
      final ChartTableModel data,
      final Integer[] columnIndexArr) {
    final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    final int rowCount = data.getRowCount();
    final int colCount = data.getColumnCount();
    final Configuration config = ChartBoot.getInstance().getGlobalConfig();
    final String noRowNameSpecified =
        config.getConfigProperty("org.pentaho.chart.namespace.row_name_not_defined"); // $NON-NLS-1$
    final String noColumnName =
        config.getConfigProperty(
            "org.pentaho.chart.namespace.column_name_not_defined"); //$NON-NLS-1$
    final ChartDocument chartDocument = chartDocContext.getChartDocument();
    final double scale = JFreeChartUtils.getScale(chartDocument);

    // Only if we have to separate datasets then do we do some column processing in the given data
    // else we simply process all rows and all columns
    if (columnIndexArr != null) {
      final int columnIndexArrLength = columnIndexArr.length;
      for (int row = 0; row < rowCount; row++) {
        int columnIndexArrCounter = 0;
        for (int column = 0; column < colCount; column++) {
          if (columnIndexArrCounter < columnIndexArrLength) {
            // if the current column is what we want in the dataset (based on column indexes in
            // columnIndexArr),
            // then process the data
            // Else move to the next column
            if (column == columnIndexArr[columnIndexArrCounter]) {
              updateDatasetBasedOnScale(
                  chartDocument,
                  data,
                  dataset,
                  row,
                  column,
                  noRowNameSpecified,
                  noColumnName,
                  scale);
              // Increment the counter so that we can process the next column in the columnIndexArr
              columnIndexArrCounter++;
            }
          } else {
            // if we have reached beyond the last element in the column index array then simply
            // start processing
            // the next row of data.
            break;
          }
        }
      }
    }
    // If we do not want to process entire data as is (without dividing the dataset)
    // then simply process all the dataset
    else {
      for (int row = 0; row < rowCount; row++) {
        for (int column = 0; column < colCount; column++) {
          updateDatasetBasedOnScale(
              chartDocument, data, dataset, row, column, noRowNameSpecified, noColumnName, scale);
        }
      }
    }
    return dataset;
  }
  protected JFreeChart doCreateChart(
      final ChartDocumentContext chartDocContext, final ChartTableModel data) {
    final ChartDocument chartDocument = chartDocContext.getChartDocument();

    // ~ plot
    // ========================================================================================================

    DialPlot dialPlot = new SquareDialPlot();

    // ~ data
    // ========================================================================================================

    // ~ params begin
    final ValueDataset dataset =
        (ValueDataset) datasetGeneratorFactory.createDataset(chartDocContext, data);
    // ~ params end

    dialPlot.setDataset(dataset);

    // ~ frame type: either circular or arc
    // ==========================================================================

    setDialFrame(chartDocument, dialPlot);

    // ~ annotation
    // ==================================================================================================

    setDialTextAnnotation(chartDocument, dialPlot);

    // ~ value indicator: prints value of dial as text
    // ===============================================================

    setDialValueIndicator(chartDocument, dialPlot);

    // ~ ticks
    // =======================================================================================================

    setDialScale(chartDocument, dialPlot);

    // ~ cap over pointer
    // ============================================================================================

    setDialCap(chartDocument, dialPlot);

    // ~ ranges
    // ======================================================================================================

    setDialRange(chartDocument, dialPlot);

    // ~ background
    // ==================================================================================================

    setDialBackground(chartDocument, dialPlot);

    // ~ pointer: either pin or pointer
    // ==============================================================================

    setDialPointer(chartDocument, dialPlot);

    JFreeChart chart = new JFreeChart(getTitle(chartDocument), dialPlot);
    return chart;
  }