Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shu work issue#168 #247

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 67 additions & 12 deletions src/main/java/org/jfree/chart/renderer/xy/XYSplineRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,23 +128,31 @@ public XYSplineState(PlotRenderingInfo info) {
private FillType fillType;

private GradientPaintTransformer gradientPaintTransformer;



/**
* Creates a new instance with the precision attribute defaulting to 5
* CS427: Issue link: https://github.com/jfree/jfreechart/issues/168
* A tolerance for absolute difference of y_val between neighboring points
* if ABS(point1.y - point2.y) <= diffYTol, no spline interpolation
*/
private double diffYTol;

/**
* Creates a new instance with the precision attribute defaulting to 5, diffYtol defaulting to 1e-6,
* and no fill of the area 'under' the spline.
*/
public XYSplineRenderer() {
this(5, FillType.NONE);
this(5, 1e-6, FillType.NONE);
}

/**
* Creates a new renderer with the specified precision
* Creates a new renderer with the specified precision, diffYtol defaulting to 1e-6,
* and no fill of the area 'under' (between '0' and) the spline.
*
* @param precision the number of points between data items.
*/
public XYSplineRenderer(int precision) {
this(precision, FillType.NONE);
this(precision, 1e-6, FillType.NONE);
}

/**
Expand All @@ -157,13 +165,17 @@ public XYSplineRenderer(int precision) {
*
* @since 1.0.17
*/
public XYSplineRenderer(int precision, FillType fillType) {
public XYSplineRenderer(int precision, double diffYTol, FillType fillType) {
super();
if (precision <= 0) {
throw new IllegalArgumentException("Requires precision > 0.");
}
if (diffYTol< 0) {
throw new IllegalArgumentException("Requires diffYTol >= 0.0");
}
Args.nullNotPermitted(fillType, "fillType");
this.precision = precision;
this.diffYTol = diffYTol;
this.fillType = fillType;
this.gradientPaintTransformer = new StandardGradientPaintTransformer();
}
Expand Down Expand Up @@ -196,6 +208,33 @@ public void setPrecision(int p) {
fireChangeEvent();
}

/**
* Returns a tolerance for absolute difference of y_val between neighboring points
* if ABS(point1.y - point2.y) <= diffYTol, no spline interpolation
*
* @return y tolerance.
*
* @see #setDiffYTol(double)
*/
public double getDiffYTol() {
return this.diffYTol;
}

/**
* Set a tolerance for absolute difference of y_val between neighboring points and sends a {@link RendererChangeEvent}
* to all registered listeners.
*
* @param tol a tolerance for absolute difference of y_val between neighboring points
*
* @see #getDiffYTol()
*/
public void setDiffYTol(double tol) {
if (tol < 0.0) {
throw new IllegalArgumentException("Requires y tolerance >= 0.");
}
this.diffYTol = tol;
fireChangeEvent();
}
/**
* Returns the type of fill that the renderer draws beneath the curve.
*
Expand Down Expand Up @@ -313,8 +352,9 @@ protected void drawPrimaryLineAsPath(XYItemRendererState state,
Point2D p = plot.getOrientation() == PlotOrientation.HORIZONTAL
? new Point2D.Float((float) transY1, (float) transX1)
: new Point2D.Float((float) transX1, (float) transY1);
if (!s.points.contains(p))
if (!s.points.contains(p)) {
s.points.add(p);
}
}

if (item == dataset.getItemCount(series) - 1) { // construct path
Expand Down Expand Up @@ -386,9 +426,9 @@ protected void drawPrimaryLineAsPath(XYItemRendererState state,
d[i] = cpi.y;
}

for (int i = 1; i <= np - 1; i++)
for (int i = 1; i <= np - 1; i++) {
h[i] = x[i] - x[i - 1];

}
float[] sub = new float[np - 1];
float[] diag = new float[np - 1];
float[] sup = new float[np - 1];
Expand All @@ -405,8 +445,10 @@ protected void drawPrimaryLineAsPath(XYItemRendererState state,
// note that a[0]=a[np-1]=0
oldt = x[0];
oldy = d[0];
for (int i = 1; i <= np - 1; i++) {
// loop over intervals between nodes
for (int i=1; i<=np-1; i++){
// loop over intervals between nodes
// If two neighboring points are close, no spline interpolation
if (Math.abs(d[i-1]-d[i])>diffYTol){
for (int j = 1; j <= this.precision; j++) {
t1 = (h[i] * j) / this.precision;
t2 = h[i] - t1;
Expand All @@ -420,6 +462,14 @@ protected void drawPrimaryLineAsPath(XYItemRendererState state,
}
}
}
else{
s.seriesPath.lineTo(x[i], d[i]);
if (this.fillType != FillType.NONE) {
s.fillArea.lineTo(x[i], d[i]);
s.fillArea.closePath();
}
}
}
}
// Add last point @ y=0 for fillPath and close path
if (this.fillType != FillType.NONE) {
Expand Down Expand Up @@ -473,8 +523,9 @@ where a(i,i-1) = sub[i] for 2<=i<=n
b[i] -= sub[i] * b[i - 1];
}
b[n] /= diag[n];
for (i = n - 1; i >= 1; i--)
for (i = n - 1; i >= 1; i--) {
b[i] = (b[i] - sup[i] * b[i + 1]) / diag[i];
}
}

/**
Expand All @@ -496,6 +547,10 @@ public boolean equals(Object obj) {
if (this.precision != that.precision) {
return false;
}
if (this.diffYTol != that.diffYTol) {
return false;
}

if (this.fillType != that.fillType) {
return false;
}
Expand Down
117 changes: 117 additions & 0 deletions src/test/java/org/jfree/chart/demo/XYSplineRendererDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package org.jfree.chart.demo;

import java.awt.Color;

import javax.swing.JPanel;


import org.jfree.chart.swing.ChartPanel;
import org.jfree.chart.swing.ApplicationFrame;
import org.jfree.chart.swing.UIUtils;
import org.jfree.chart.ChartUtils;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYSplineRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.chart.api.RectangleInsets;

/**
* A demo showing a line chart drawn using spline curves.
* Demonstrate the solution to Issue #168
*/
public class XYSplineRendererDemo extends ApplicationFrame {

/**
* Creates a new instance of the demo application.
*
* @param title the frame title.
*/
public XYSplineRendererDemo(String title) {
super(title);
JPanel content = createDemoPanel();
content.setPreferredSize(new java.awt.Dimension(500, 270));
getContentPane().add(content);
}

/**
* Creates a panel for the demo (used by SuperDemo.java).
*
* @return A panel.
*/
public static JPanel createDemoPanel() {

// create plot...
NumberAxis xAxis = new NumberAxis("X");
xAxis.setAutoRangeIncludesZero(false);
NumberAxis yAxis = new NumberAxis("Y");
yAxis.setAutoRangeIncludesZero(false);

XYSplineRenderer renderer1 = new XYSplineRenderer();
XYPlot plot = new XYPlot(createSampleData(), xAxis, yAxis, renderer1);
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setAxisOffset(new RectangleInsets(4, 4, 4, 4));
NumberAxis range = (NumberAxis) plot.getRangeAxis();
range.setRange(-10.0, 40.0);

// create and return the chart panel...
JFreeChart chart = new JFreeChart("XYSplineRenderer",
JFreeChart.DEFAULT_TITLE_FONT, plot, true);
ChartUtils.applyCurrentTheme(chart);
ChartPanel chartPanel = new ChartPanel(chart);
return chartPanel;
}

/**
* Creates and returns a sample dataset. The data was randomly
* generated.
*
* @return a sample dataset.
*/
private static XYDataset createSampleData() {
XYSeries series = new XYSeries("Series 1");
series.add(2.0, 0);
series.add(3.0, 0);
series.add(4.0, 0);
series.add(5.0, 0);
series.add(6.0, 30);
series.add(7.0, 0);
series.add(8.0, 0);
series.add(9.0, 0);
series.add(10.0, 0);
series.add(11.0, 0);
XYSeriesCollection result = new XYSeriesCollection(series);
// XYSeries series2 = new XYSeries("Series 2");
// series2.add(11.0, 56.27);
// series2.add(10.0, 41.32);
// series2.add(9.0, 31.45);
// series2.add(8.0, 30.05);
// series2.add(7.0, 24.69);
// series2.add(6.0, 19.78);
// series2.add(5.0, 20.94);
// series2.add(4.0, 16.73);
// series2.add(3.0, 14.21);
// series2.add(2.0, 12.44);
// result.addSeries(series2);
return result;
}

/**
* The starting point for the regression demo.
*
* @param args ignored.
*/
public static void main(String args[]) {
XYSplineRendererDemo appFrame = new XYSplineRendererDemo(
"JFreeChart: XYSplineRendererDemo.java");
appFrame.pack();
UIUtils.centerFrameOnScreen(appFrame);
appFrame.setVisible(true);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.junit.jupiter.api.Test;

/**
* CS427: Issue link: https://github.com/jfree/jfreechart/issues/168
* Tests for the {@link XYSplineRenderer} class.
*/
public class XYSplineRendererTest {
Expand All @@ -68,7 +69,12 @@ public void testEquals() {
assertFalse(r1.equals(r2));
r2.setPrecision(9);
assertTrue(r1.equals(r2));


r1.setDiffYTol(1e-3);
assertFalse(r1.equals(r2));
r2.setDiffYTol(1e-3);
assertTrue(r1.equals(r2));

r1.setFillType(XYSplineRenderer.FillType.TO_ZERO);
assertFalse(r1.equals(r2));
r2.setFillType(XYSplineRenderer.FillType.TO_ZERO);
Expand Down