报告趋势线 [英] Reporting Trend Line

查看:207
本文介绍了报告趋势线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

除了显示数据点之外,您如何在JasperReports中创建一条跟随数据趋势的线?以下是拍摄前后:

How would you create a line in JasperReports that follows the trend for the data, in addition to showing the data points? Here are before and after shots:

之前

之后

时间序列报告似乎没有任何此类选项来绘制橙色线。 (橙色线应该是平滑的,更薄,但这是一般的想法。)

The Time Series report does not appear to have any such option to draw the orange line. (The orange line should be smooth, and thinner, but that's the general idea.)

任何想法如何用iReport 3.7.1制作这样的报告?

Any ideas how to craft such a report with iReport 3.7.1?

推荐答案

一个解决方案需要以下项目:

One solution requires the following items:


  • BezierLineCustomizer 使线条弯曲。

  • RunningAverageIncrementer 计算正在运行基于变量的平均值。

  • 使用 RunningAverageIncremeter 的iReport变量。

  • BezierLineCustomizer to make the lines curved.
  • RunningAverageIncrementer to calculate a running average based on a variable.
  • iReport variable that uses the RunningAverageIncremeter.

BezierLineCustomizer Class

public class BezierLineCustomizer
  implements JRChartCustomizer {
  public BezierLineCustomizer() {
  }

  public void customize( JFreeChart jFreeChart, JRChart jrChart ) {
    XYPlot xyPlot = ( XYPlot )jFreeChart.getPlot();

    XYSplineRenderer splineRenderer = new XYSplineRenderer();

    // Make the spline line thick and orange.
    //
    splineRenderer.setSeriesShapesVisible( 0, false );
    splineRenderer.setSeriesShapesVisible( 1, false );
    splineRenderer.setSeriesLinesVisible( 1, false );
    splineRenderer.setSeriesStroke(
        0, new BasicStroke(
            4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
            1.0f, null, 0.0f
        )
    );

    splineRenderer.setSeriesPaint( 0, new Color( 255, 140, 0 ) );
    splineRenderer.setSeriesVisibleInLegend( 1, Boolean.FALSE );

    // Duplicate the data into a new dataset to control its line independently.
    //
    xyPlot.setDataset( 1, xyPlot.getDataset(0) );

    XYItemRenderer defaultRenderer = new XYLineAndShapeRenderer();
    defaultRenderer.setSeriesVisible( 0, Boolean.FALSE );
    defaultRenderer.setSeriesVisibleInLegend( 0, Boolean.FALSE );

    xyPlot.setRenderer( 1, defaultRenderer );
    xyPlot.setRenderer( 0, splineRenderer );
  }
}

RunningAverageIncrementer Class

public class RunningAverageIncrementer
  implements JRIncrementer {
  /** Default number of tallies. */
  private static final int DEFAULT_TALLIES = 128;

  /** Number of tallies within the sliding window. */
  private static final int DEFAULT_SLIDING_WINDOW_SIZE = 30;

  /** Stores a sliding window of values. */
  private List<Double> values = new ArrayList<Double>( DEFAULT_TALLIES );

  /**
   * Instantiated by the RunningAverageIncrementerFactory class.
   */
  public RunningAverageIncrementer() {
  }

  /**
   * Calculates the average of previously known values.
   * @return The average of the list of values returned by getValues().
   */
  private double calculateAverage() {
    double result = 0.0;
    List<Double> values = getValues();

    for( Double d: getValues() ) {
      result += d.doubleValue();
    }

    return result / values.size();
  }

  /**
   * Called each time a new value to be averaged is received.
   * @param value The new value to include for the average.
   */
  private void recordValue( Double value ) {
    List<Double> values = getValues();

    // Throw out 
    //
    if( values.size() > getSlidingWindowSize() ) {
      values.remove( 0 );
    }

    this.values.add( value );
  }

  private List<Double> getValues() {
    return values;
  }

  private int getIterations() {
    return getValues().size();
  }

  /**
   * Returns the newly incremented value, which is calculated by averaging
   * the previous value from the previous call to this method.
   * 
   * @param jrFillVariable Unused.
   * @param tally New data point to average.
   * @param abstractValueProvider Unused.
   * @return The newly incremented value.
   */
  public Object increment( JRFillVariable jrFillVariable, Object tally, 
                           AbstractValueProvider abstractValueProvider ) {
    double value = ((Number)tally).doubleValue();

    recordValue( value );

    double previousAverage = calculateAverage();
    double newAverage = 
      ( ( value - previousAverage ) / ( getIterations() + 1 ) ) + previousAverage;

    return new BigDecimal( newAverage );
  }

  protected int getSlidingWindowSize() {
    return DEFAULT_SLIDING_WINDOW_SIZE;
  }
}

iReport Variable

创建一个使用 RunningAverageIncrementerFactory 类的变量(练习留给读者)。将其变量表达式设置为绘制值。将其初始值表达式设置为零。

Create a variable that uses the RunningAverageIncrementerFactory class (exercise left to the reader). Set its variable expression to the plotted value. Set its initial value expression to zero.

样条

设置 Customizer Class 属性使用 BezierLineCustomizer 类。

结果

经过这些修改后,可以清楚看到运行平均值:

After these modifications, the running average is clearly visible:

这篇关于报告趋势线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆