1

I am using this code to generate an XYChart but the line always goes down to the origin and then continues following the points. How can I prevent this?

import java.awt.Color; import java.awt.BasicStroke; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries;import org.jfree.ui.ApplicationFrame; import org.jfree.ui.RefineryUtilities; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.ChartFactory; import org.jfree.chart.plot.PlotOrientation; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
public class Graph  extends ApplicationFrame {
    static MenuCode mc = new MenuCode();

    public static void main(String args []) {
        Graph chart = new Graph(mc.eq,mc.eq);
        chart.pack();          
        RefineryUtilities.centerFrameOnScreen(chart);          
        chart.setVisible(true); 
    }

    private XYDataset createDataset() {
        final XYSeries equation1 = new XYSeries(mc.eq);          
        for (short i = 0; i<200; i++){
            equation1.add(mc.x[i] , mc.y[i]);
        }

        //for (short i = 0; i<200; i++){
            //equation2.add(mc.x[i] , mc.y[i]);
        //}      

        final XYSeriesCollection dataset = new XYSeriesCollection();          
        dataset.addSeries(equation1);          
        //dataset.addSeries(eq2);          
        return dataset;
    }
    
    public Graph( String applicationTitle, String chartTitle ) {
        super(applicationTitle);
        JFreeChart xylineChart = ChartFactory.createXYLineChart(chartTitle, "X", "Y", createDataset(), PlotOrientation.VERTICAL ,true , true , false);
        ChartPanel chartPanel = new ChartPanel(xylineChart);
        chartPanel.setPreferredSize(new java.awt.Dimension(2560 , 1600));
        final XYPlot plot = xylineChart.getXYPlot();
        
        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
        renderer.setSeriesPaint(0, Color.RED);
        renderer.setSeriesStroke(0, new BasicStroke(3.0f));
        //renderer.setSeriesPaint(1 , Color.GREEN);
        //renderer.setSeriesStroke(1, new BasicStroke(3.0f));
        plot.setRenderer(renderer); 
        setContentPane(chartPanel); 
    }
}

The x-axis and y-axis points are taken from an array in another class. Screenshot: XYPlot Chart

Fildor
  • 14,510
  • 4
  • 35
  • 67

1 Answers1

1

It looks like you want to graph points selected from two geometric lines: y = 2x + 2 and y = -2x - 2. Since the two lines intersect at the point (-1, 0), it's pretty clear that you're adding an extra point when x is zero.

I changed your example to show how I'd sample each line from -N … N to make an XYSeries based on its equation.

Also, you create a new XYLineAndShapeRenderer, but you can reuse the one created by ChartFactory.createXYLineChart().

lines chart 2

Could it be a setting?

XYSeries automatically sorts the data and forbids duplicates. Calling series.add(0, 0) in createSeries() exactly reproduces your result. Try setting allowDuplicateXValues to false like this:

…new XYSeries("y = " + m + "x + " + b, true, false);

If your data includes a duplicate, the compiler will throw SeriesException:

Exception in thread "main"
    org.jfree.data.general.SeriesException:
        X-value already exists.
import java.awt.BasicStroke;
import java.awt.Dimension;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

//* https://stackoverflow.com/q/70242185/261156 */
public class LineTest {

    private static final int N = 4;

    private static XYSeries createSeries(int m, int b) {
        XYSeries series = new XYSeries("y = " + m + "x + " + b, true, true);
        for (int x = -N; x <= N; x++) {
            series.add(x, m * x + b);
        }
        return series;
    }

    private static XYDataset createDataset() {
        XYSeriesCollection collection = new XYSeriesCollection();
        collection.addSeries(createSeries(2, 2));
        collection.addSeries(createSeries(-2, -2));
        return collection;
    }

    private static JFreeChart createChart(final XYDataset dataset) {
        JFreeChart chart = ChartFactory.createXYLineChart(
            "Linear Equations", "X", "Y", dataset);
        XYPlot p = (XYPlot) chart.getPlot();
        p.setDomainCrosshairVisible(true);
        p.setRangeCrosshairVisible(true);
        XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) p.getRenderer();
        r.setDefaultShapesVisible(true);
        BasicStroke s = new BasicStroke(3.0f);
        for (int i = 0; i < dataset.getSeriesCount(); i++) {
            r.setSeriesStroke(i, s);
        }
        return chart;
    }

    public static void main(String[] args) {

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        XYDataset dataset = createDataset();
        JFreeChart chart = createChart(dataset);
        ChartPanel chartPanel = new ChartPanel(chart) {

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(600, 400);
            }
        };
        f.add(chartPanel);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}
Catalina Island
  • 7,027
  • 2
  • 23
  • 42