i want to create a moving graph whose y value progresses with the slider value.i am confused whether to implement it using JFreechart.Is there a simpler method?

How should i go about doing this?

Recommended Answers

All 13 Replies

The graphs I've created has been done with JFreeChart, I think it works pretty good for my needs.
I found this link however that might help you:
http://www.codemiles.com/java/a-moving-graph-sortof-widget-build-using-swing-t373.html
It is done in swing

I have written the following code for moving graphs but the output that the graph shows is incorrect. also,the output does not change dynamically with the slider values.please help me.I'm working with graphics for the first time.

here is the code.

import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.ChartFactory;
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.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import javax.swing.*;
import java.io.*;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.ui.RefineryUtilities;
import java.awt.*;
import org.jfree.chart.plot.XYPlot;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class magmelt extends ApplicationFrame{

   
	public magmelt(String args) throws IOException
{	super("Melting Point");
	final double array[]=new double[751658];
	double z=0;
	File file=new File(args);
	final BufferedReader br = new BufferedReader(new FileReader(file));
	final int segmentLength = 751658 / 800; // numberOfPoints is the number of points in your data file.
	for(int i=0;i<segmentLength;i++)
  { 	String line=br.readLine();
	if(line==null) break;
	try{
 	z = Double.parseDouble(line.trim());
	}catch(Exception e)
	{System.out.println(e.getMessage());}
	array[i]=z;
  }
        final XYSeries mps=new XYSeries("meltingpoints");
	
	final XYSeriesCollection data = new XYSeriesCollection();
        data.addSeries(mps);
	
        JFreeChart chart = ChartFactory.createXYLineChart("Melting Point","Base position","Melting point",data,PlotOrientation.VERTICAL,true,true, false);
        
	final XYPlot plot = (XYPlot) chart.getPlot();
        final NumberAxis axis = (NumberAxis) plot.getRangeAxis();
        axis.setAutoRangeIncludesZero(false);
       
	axis.setAutoRangeMinimumSize(1.0);

	ChartPanel chartPanel = new ChartPanel(chart);

	chartPanel.setLayout(new BorderLayout());

	final JSlider slider=new  JSlider(JSlider.HORIZONTAL,0,751658,0);	
	final JPanel main = new JPanel(new BorderLayout());
        final JPanel optionsPanel = new JPanel();
	optionsPanel.add(slider);
	main.add(optionsPanel, BorderLayout.SOUTH);
        main.add(chartPanel);
        setContentPane(main);
	slider.setPreferredSize(new java.awt.Dimension(600,100));
        slider.setBorder(BorderFactory.createTitledBorder("Positions"));	
    	slider.setMajorTickSpacing(100000);
    	slider.setMinorTickSpacing(60);
        slider.setPaintTicks(true);
	slider.setPaintLabels(true); 
	slider.setSnapToTicks(true); 
	slider.addChangeListener (new ChangeListener(){ public void stateChanged (ChangeEvent e)
	 {
	int slidervalue=slider.getValue();
       //System.out.println(slidervalue);
	for(int i=0;i<10;i++)
  {	
  	mps.add(i+1,array[slidervalue]);
	slidervalue++;
  }
 }//end of statechanged
      
});
  
}//end 

public static void main(String args[]) throws IOException
{

magmelt chart=new magmelt(args[0]);
chart.pack();
RefineryUtilities.centerFrameOnScreen(chart);
chart.setVisible(true);
}


}//end class

the input file has a large number of double values which are put into an array.basically the slider gives the array position and i need to plot the first 10 values from the position of the array.

Ok, bear with me, I might be off here but anyway:
First of all, it looks like you don't set the data until the users uses the slider.
Apart from that, I think you need to get the xAxis and set the range on that, like:

ValueAxis xAxis = (ValueAxis)plot.getDomainAxis();
xAxis.setRange(x,y);

You would need to do this whenever the slider is changed, so read the slider value and set range as sliderValue to sliderValue+10.
Also, if you want the graph to only contain the data that is visible (if there is a lot of data), then you would need to update mps as well. Pretty much as you do, except that I think you need to also remove the old values from the set.

okay...but I don't think it works here.What else might be missing?

What do you mean does not apply?
I tried your code and made those modifications, so unless I've completly missunderstood what you want to do, this do apply.

see i have done what you had told me.I also cleared mps from the exisiting data value each time the slider was moved.but the problem is still i cannot get the values plotted on the graph.
I also gave the first then values from the array to mps initially.but only these values gets plotted .As soon as the slider is moved i see only an empty graph. the X-axis values change but no value read from the array gets plotted.you can see the code

import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.ChartFactory;
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.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import javax.swing.*;
import java.io.*;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.ui.RefineryUtilities;
import java.awt.*;
import org.jfree.chart.plot.XYPlot;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jfree.chart.axis.ValueAxis;


public class magmelt extends ApplicationFrame{

  

	public magmelt(String args) throws IOException
{	super("Melting Point");
	final double array[]=new double[751658];
	double z=0;
	File file=new File(args);
	final BufferedReader br = new BufferedReader(new FileReader(file));
	final int segmentLength = 751658 / 800; // numberOfPoints is the number of points in your data file.
	for(int i=0;i<segmentLength;i++)
  { 	String line=br.readLine();
	if(line==null) break;
	try{
 	z = Double.parseDouble(line.trim());
	}catch(Exception e)
	{System.out.println(e.getMessage());}
	array[i]=z;
  }
        final XYSeries mps=new XYSeries("meltingpoints");
	
	final XYSeriesCollection data = new XYSeriesCollection();
        data.addSeries(mps);
	
	final JSlider slider=new  JSlider(JSlider.HORIZONTAL,0,751658,0);
	for(int i=0;i<10;i++)
  {	
  	mps.add(i+1,array[i]);
  }
	slider.setPreferredSize(new java.awt.Dimension(600,100));
        slider.setBorder(BorderFactory.createTitledBorder("Positions"));	
    	slider.setMajorTickSpacing(100000);
    	slider.setMinorTickSpacing(60);
        slider.setPaintTicks(true);
	slider.setPaintLabels(true); 
	slider.setSnapToTicks(true); 
	
	
        JFreeChart chart = ChartFactory.createXYLineChart("Melting Point","Base position","Melting point",data,PlotOrientation.VERTICAL,true,true, false);
        
	final XYPlot plot = (XYPlot) chart.getPlot();
        final NumberAxis axis = (NumberAxis) plot.getRangeAxis();
        axis.setAutoRangeIncludesZero(false);
       
	axis.setAutoRangeMinimumSize(1.0);
	
	ChartPanel chartPanel = new ChartPanel(chart);

	chartPanel.setLayout(new BorderLayout());
		
	final JPanel main = new JPanel(new BorderLayout());
        final JPanel optionsPanel = new JPanel();
	optionsPanel.add(slider);
	main.add(optionsPanel, BorderLayout.SOUTH);
        main.add(chartPanel);
        setContentPane(main);
	
	slider.addChangeListener (new ChangeListener(){ public void stateChanged (ChangeEvent e)
	 {
	mps.clear();
	
	int slidervalue=slider.getValue();
	
	ValueAxis xAxis = (ValueAxis)plot.getDomainAxis();
	xAxis.setRange(slidervalue,slidervalue+10);
       System.out.println(slidervalue);
	for(int i=0;i<10;i++)
  {	
  	mps.add(i+1,array[slidervalue]);
	slidervalue++;
  }
 }//end of statechanged
      
});	
  
}//end 

public static void main(String args[]) throws IOException
{

magmelt chart=new magmelt(args[0]);
chart.pack();
RefineryUtilities.centerFrameOnScreen(chart);
chart.setVisible(true);
}
   
}//end class

Divide slider's value with majortick spacing.

...
int slidervalue=slider.getValue()/100000;
...

i did this but it gives me the graph for only the major ticks on the slider.i want it for each element.What should i do?is there any solution?:(

How does you file look like that you read from?
This is kinda of a long shot, but try to do a repaint on the chart panel. This is how my listener looks like:

slider.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        int slidervalue = slider.getValue();
        // System.out.println(slidervalue);
        mps.clear();
        for (int i = 0; i <= 10; i++) {
          mps.add(slidervalue+i, array[slidervalue+i]);
        }
        xAxis.setRange(slidervalue, slidervalue+10);
        chartPanel.repaint();

      }// end of statechanged

    });

And of course there is a solution, we just need to find it :)

How does you file look like that you read from?
This is kinda of a long shot, but try to do a repaint on the chart panel. This is how my listener looks like:

Help with Code Tags java Syntax (Toggle Plain Text)

slider.addChangeListener(new ChangeListener() {      public void stateChanged(ChangeEvent e) {        int slidervalue = slider.getValue();        // System.out.println(slidervalue);        mps.clear();        for (int i = 0; i <= 10; i++) {          mps.add(slidervalue+i, array[slidervalue+i]);        }        xAxis.setRange(slidervalue, slidervalue+10);        chartPanel.repaint();       }// end of statechanged     });slider.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        int slidervalue = slider.getValue();
        // System.out.println(slidervalue);
        mps.clear();
        for (int i = 0; i <= 10; i++) {
          mps.add(slidervalue+i, array[slidervalue+i]);
        }
        xAxis.setRange(slidervalue, slidervalue+10);
        chartPanel.repaint();

      }// end of statechanged

    });

And of course there is a solution, we just need to find it

it worked........thanks a lot!!!that was a great help
:)

hi,my previous doubt was solved but now i need to do another thing.This is a moving graph whose x-axis values corresponds to the slider value.now what i need to do is add a symbol beneath each x-axis tick.So now on moving the slider,the slider value corresponds to a symbol and x-axis value.

Can anyone tell me how should i proceed.the existing code is posted above with minor modifications.

my problem is that the symbols i have are in a string.and now they need to be converted into an array of strings i.e each string array consists of a single character from the string.


Please help me.I'm badly stuck with this.

Not sure what you want to do, but what is displayed on the axis depends on the Dataset, so modify the dataset accordingly.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.